summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Olbrich <m.olbrich@pengutronix.de>2012-11-22 10:03:50 +0100
committerMichael Olbrich <m.olbrich@pengutronix.de>2012-11-24 10:35:14 +0100
commitd573b5dfe9064a280d6d77fc71bf2d419bb6bb14 (patch)
tree98d3875620c8b8e7686d159dd728e655bbac0a88
parent01a192d19c95d694ce3bad3bd1134ddc1459d556 (diff)
downloadplatform-pengutronix-raspberrypi-d573b5dfe9064a280d6d77fc71bf2d419bb6bb14.tar.gz
platform-pengutronix-raspberrypi-d573b5dfe9064a280d6d77fc71bf2d419bb6bb14.tar.xz
kernel: new version & patches
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
-rw-r--r--kernelconfig-3.6.7 (renamed from kernelconfig-3.2.27)843
-rw-r--r--patches/linux-3.2.27/0038-net-usb-smsc95xx-fix-mtu.patch32
-rw-r--r--patches/linux-3.2.27/0057-mmc-use-really-long-write-timeout-to-deal-with-crapp.patch59
-rw-r--r--patches/linux-3.2.27/0144-Fix-for-KALLSYMS_EXTRA_PASS-requirement.-Thanks-asb-.patch23
-rw-r--r--patches/linux-3.2.27/0201-Release-raspberrypi-20120915.patch22
-rw-r--r--patches/linux-3.2.27/series157
-rw-r--r--patches/linux-3.6.7/0001-Add-dwc_otg-driver.patch (renamed from patches/linux-3.2.27/0001-Add-dwc_otg-driver.patch)85
-rw-r--r--patches/linux-3.6.7/0002-Main-bcm2708-linux-port.patch (renamed from patches/linux-3.2.27/0002-Main-bcm2708-linux-port.patch)174
-rw-r--r--patches/linux-3.6.7/0003-bcm2708-watchdog-driver.patch (renamed from patches/linux-3.2.27/0003-bcm2708-watchdog-driver.patch)14
-rw-r--r--patches/linux-3.6.7/0004-bcm2708-framebuffer-driver.patch (renamed from patches/linux-3.2.27/0004-bcm2708-framebuffer-driver.patch)6
-rw-r--r--patches/linux-3.6.7/0005-bcm2708-vchiq-driver.patch (renamed from patches/linux-3.2.27/0005-bcm2708-vchiq-driver.patch)25
-rw-r--r--patches/linux-3.6.7/0006-Allow-mac-address-to-be-set-in-smsc95xx.patch (renamed from patches/linux-3.2.27/0006-Allow-mac-address-to-be-set-in-smsc95xx.patch)8
-rw-r--r--patches/linux-3.6.7/0007-Fix-headers-for-vchiq-vcos-to-be-GPLv2.patch (renamed from patches/linux-3.2.27/0007-Fix-headers-for-vchiq-vcos-to-be-GPLv2.patch)90
-rw-r--r--patches/linux-3.6.7/0008-Fix-some-issues-reported.-Lower-case-module-paramete.patch (renamed from patches/linux-3.2.27/0008-Fix-some-issues-reported.-Lower-case-module-paramete.patch)10
-rw-r--r--patches/linux-3.6.7/0009-Build-anything-reasonable-as-a-module.-Thanks-to-asb.patch (renamed from patches/linux-3.2.27/0009-Build-anything-reasonable-as-a-module.-Thanks-to-asb.patch)0
-rw-r--r--patches/linux-3.6.7/0010-Add-config-option-to-enable-L2-cache.patch (renamed from patches/linux-3.2.27/0010-Add-config-option-to-enable-L2-cache.patch)4
-rw-r--r--patches/linux-3.6.7/0011-Fix-bug-where-vchiq-fails-when-L2-enabled.patch (renamed from patches/linux-3.2.27/0011-Fix-bug-where-vchiq-fails-when-L2-enabled.patch)2
-rw-r--r--patches/linux-3.6.7/0012-Add-devtmpfs-for-archlinux-and-emergency-and-debug-c.patch (renamed from patches/linux-3.2.27/0012-Add-devtmpfs-for-archlinux-and-emergency-and-debug-c.patch)6
-rw-r--r--patches/linux-3.6.7/0013-Fix-32bpp-framebuffer-by-adding-alpha-bits.patch (renamed from patches/linux-3.2.27/0013-Fix-32bpp-framebuffer-by-adding-alpha-bits.patch)2
-rw-r--r--patches/linux-3.6.7/0014-Enable-L2-cache-is-now-the-default.-Invert-sense-of-.patch (renamed from patches/linux-3.2.27/0014-Enable-L2-cache-is-now-the-default.-Invert-sense-of-.patch)4
-rw-r--r--patches/linux-3.6.7/0015-Allow-24bpp-for-framebuffer.patch (renamed from patches/linux-3.2.27/0015-Allow-24bpp-for-framebuffer.patch)2
-rw-r--r--patches/linux-3.6.7/0016-Disable-debug-code-in-dwc_otg-driver-unless-CONFIG_U.patch (renamed from patches/linux-3.2.27/0016-Disable-debug-code-in-dwc_otg-driver-unless-CONFIG_U.patch)6
-rw-r--r--patches/linux-3.6.7/0017-Enable-high-resolution-timers.patch (renamed from patches/linux-3.2.27/0017-Enable-high-resolution-timers.patch)6
-rw-r--r--patches/linux-3.6.7/0018-Fix-for-mmc-timeouts-when-erasing-multiple-blocks.patch (renamed from patches/linux-3.2.27/0018-Fix-for-mmc-timeouts-when-erasing-multiple-blocks.patch)4
-rw-r--r--patches/linux-3.6.7/0019-Fix-problem-with-dma-that-could-corrupt-sdcard-espec.patch (renamed from patches/linux-3.2.27/0019-Fix-problem-with-dma-that-could-corrupt-sdcard-espec.patch)2
-rw-r--r--patches/linux-3.6.7/0020-Update-to-match-latest-vc-side-vchiq.-Allows-vchiq-c.patch (renamed from patches/linux-3.2.27/0020-Update-to-match-latest-vc-side-vchiq.-Allows-vchiq-c.patch)30
-rw-r--r--patches/linux-3.6.7/0021-First-pass-at-alsa-sound-driver.-Some-functionality-.patch (renamed from patches/linux-3.2.27/0021-First-pass-at-alsa-sound-driver.-Some-functionality-.patch)18
-rw-r--r--patches/linux-3.6.7/0022-Cast-to-avoid-warning.patch (renamed from patches/linux-3.2.27/0022-Cast-to-avoid-warning.patch)2
-rw-r--r--patches/linux-3.6.7/0023-Add-new-ioctl-to-match-latest-vc-side-code.patch (renamed from patches/linux-3.2.27/0023-Add-new-ioctl-to-match-latest-vc-side-code.patch)2
-rw-r--r--patches/linux-3.6.7/0024-Enable-sound-kernel-modules.-Tidy-formatting.-Fix-ct.patch (renamed from patches/linux-3.2.27/0024-Enable-sound-kernel-modules.-Tidy-formatting.-Fix-ct.patch)16
-rw-r--r--patches/linux-3.6.7/0025-Add-missing-header-file-update-for-vc_mem-iocts.patch (renamed from patches/linux-3.2.27/0025-Add-missing-header-file-update-for-vc_mem-iocts.patch)2
-rw-r--r--patches/linux-3.6.7/0026-Remove-most-of-the-alsa-debug-messages.patch (renamed from patches/linux-3.2.27/0026-Remove-most-of-the-alsa-debug-messages.patch)6
-rw-r--r--patches/linux-3.6.7/0027-add-temporary-workaround-for-fbset-crashes.patch (renamed from patches/linux-3.2.27/0027-add-temporary-workaround-for-fbset-crashes.patch)2
-rw-r--r--patches/linux-3.6.7/0028-Fix-harmless-base-size-typo.patch (renamed from patches/linux-3.2.27/0028-Fix-harmless-base-size-typo.patch)2
-rw-r--r--patches/linux-3.6.7/0029-Replace-if-1-sections-by-local-configuration-defines.patch (renamed from patches/linux-3.2.27/0029-Replace-if-1-sections-by-local-configuration-defines.patch)2
-rw-r--r--patches/linux-3.6.7/0030-Don-t-send-data-block-when-emitting-silence.patch (renamed from patches/linux-3.2.27/0030-Don-t-send-data-block-when-emitting-silence.patch)2
-rw-r--r--patches/linux-3.6.7/0031-Fix-hopefully-for-DWC_MEMCPY-kernel-panics.-Thanks-t.patch (renamed from patches/linux-3.2.27/0031-Fix-hopefully-for-DWC_MEMCPY-kernel-panics.-Thanks-t.patch)4
-rw-r--r--patches/linux-3.6.7/0032-Build-modules-needed-for-USB-booting-into-kernel.patch (renamed from patches/linux-3.2.27/0032-Build-modules-needed-for-USB-booting-into-kernel.patch)4
-rw-r--r--patches/linux-3.6.7/0033-Whitespace-tidy.-Thanks-Roger.patch (renamed from patches/linux-3.2.27/0033-Whitespace-tidy.-Thanks-Roger.patch)2
-rw-r--r--patches/linux-3.6.7/0034-Update-vchiq-to-match-GPU-version.-Should-still-be-c.patch (renamed from patches/linux-3.2.27/0034-Update-vchiq-to-match-GPU-version.-Should-still-be-c.patch)8
-rw-r--r--patches/linux-3.6.7/0035-added-support-for-TT-in-the-USB-driver.-Thanks-Naren.patch (renamed from patches/linux-3.2.27/0035-added-support-for-TT-in-the-USB-driver.-Thanks-Naren.patch)10
-rw-r--r--patches/linux-3.6.7/0036-Swap-Red-and-Blue-over-in-32bpp-framebuffer-mode.patch (renamed from patches/linux-3.2.27/0036-Swap-Red-and-Blue-over-in-32bpp-framebuffer-mode.patch)2
-rw-r--r--patches/linux-3.6.7/0037-Update-emergency-config-to-match-latest-debug-one.patch (renamed from patches/linux-3.2.27/0037-Update-emergency-config-to-match-latest-debug-one.patch)2
-rw-r--r--patches/linux-3.6.7/0038-Use-dwc_alloc_atomic.-Thanks-bootc.patch (renamed from patches/linux-3.2.27/0039-Use-dwc_alloc_atomic.-Thanks-bootc.patch)2
-rw-r--r--patches/linux-3.6.7/0039-possible-fix-for-sdcard-missing-status.-Thank-naren.patch (renamed from patches/linux-3.2.27/0040-possible-fix-for-sdcard-missing-status.-Thank-naren.patch)2
-rw-r--r--patches/linux-3.6.7/0040-Fix-BUG-in-bcm2708_fb_set_par-doesn-t-work-if-the-co.patch (renamed from patches/linux-3.2.27/0041-Fix-BUG-in-bcm2708_fb_set_par-doesn-t-work-if-the-co.patch)2
-rw-r--r--patches/linux-3.6.7/0041-Fix-for-DWC-OTG-HCD-URB-Dequeue-has-NULL-URB-panic.-.patch (renamed from patches/linux-3.2.27/0042-Fix-for-DWC-OTG-HCD-URB-Dequeue-has-NULL-URB-panic.-.patch)2
-rw-r--r--patches/linux-3.6.7/0042-Fix-for-bug-in-mbox_read.-Thanks-lp0.patch (renamed from patches/linux-3.2.27/0043-Fix-for-bug-in-mbox_read.-Thanks-lp0.patch)6
-rw-r--r--patches/linux-3.6.7/0043-Add-__VCCOREVER__-to-makefile.patch (renamed from patches/linux-3.2.27/0044-Add-__VCCOREVER__-to-makefile.patch)2
-rw-r--r--patches/linux-3.6.7/0044-Change-PHYS_OFFSET-to-PLAT_PHYS_OFFSET.patch (renamed from patches/linux-3.2.27/0045-Change-PHYS_OFFSET-to-PLAT_PHYS_OFFSET.patch)2
-rw-r--r--patches/linux-3.6.7/0045-sdcard-patch-improvements-from-naren.patch (renamed from patches/linux-3.2.27/0046-sdcard-patch-improvements-from-naren.patch)2
-rw-r--r--patches/linux-3.6.7/0046-Invert-sense-of-sdcard-access-trigger-OK-LED-so-it-i.patch (renamed from patches/linux-3.2.27/0047-Invert-sense-of-sdcard-access-trigger-OK-LED-so-it-i.patch)2
-rw-r--r--patches/linux-3.6.7/0047-Added-power-off-message-to-allow-kexec-to-work.-Than.patch (renamed from patches/linux-3.2.27/0048-Added-power-off-message-to-allow-kexec-to-work.-Than.patch)4
-rw-r--r--patches/linux-3.6.7/0048-remove-unwanted-file.patch (renamed from patches/linux-3.2.27/0049-remove-unwanted-file.patch)2
-rw-r--r--patches/linux-3.6.7/0049-Enable-PREEMPT-and-SCHED_AUTOGROUP.patch (renamed from patches/linux-3.2.27/0050-Enable-PREEMPT-and-SCHED_AUTOGROUP.patch)4
-rw-r--r--patches/linux-3.6.7/0050-Added-support-for-USB-webcams.patch (renamed from patches/linux-3.2.27/0051-Added-support-for-USB-webcams.patch)4
-rw-r--r--patches/linux-3.6.7/0051-Enable-ipv6-due-to-popular-demand.patch (renamed from patches/linux-3.2.27/0052-Enable-ipv6-due-to-popular-demand.patch)4
-rw-r--r--patches/linux-3.6.7/0052-Fix-regression-in-debug-kernel-config-options.patch (renamed from patches/linux-3.2.27/0053-Fix-regression-in-debug-kernel-config-options.patch)2
-rw-r--r--patches/linux-3.6.7/0053-bcm2835-ctl-fix-alsamixer-control.patch (renamed from patches/linux-3.2.27/0054-bcm2835-ctl-fix-alsamixer-control.patch)2
-rw-r--r--patches/linux-3.6.7/0054-bcm2835-ctl-limit-maximal-volume-to-4db.patch (renamed from patches/linux-3.2.27/0055-bcm2835-ctl-limit-maximal-volume-to-4db.patch)2
-rw-r--r--patches/linux-3.6.7/0055-Add-iptables-and-devtmpfs_mount-to-non-cutdown-confi.patch (renamed from patches/linux-3.2.27/0056-Add-iptables-and-devtmpfs_mount-to-non-cutdown-confi.patch)4
-rw-r--r--patches/linux-3.6.7/0056-sdhci-bcm2708-speed-up-DMA-sync.patch (renamed from patches/linux-3.2.27/0058-sdhci-bcm2708-speed-up-DMA-sync.patch)2
-rw-r--r--patches/linux-3.6.7/0057-sdhci-bcm2708-remove-custom-clock-handling.patch (renamed from patches/linux-3.2.27/0059-sdhci-bcm2708-remove-custom-clock-handling.patch)2
-rw-r--r--patches/linux-3.6.7/0058-sdhci-bcm2708-add-additional-quirks.patch (renamed from patches/linux-3.2.27/0060-sdhci-bcm2708-add-additional-quirks.patch)2
-rw-r--r--patches/linux-3.6.7/0059-sdhci-bcm2708-add-allow_highspeed-parameter.patch (renamed from patches/linux-3.2.27/0061-sdhci-bcm2708-add-allow_highspeed-parameter.patch)2
-rw-r--r--patches/linux-3.6.7/0060-sdhci-bcm2708-assume-50-MHz-eMMC-clock.patch (renamed from patches/linux-3.2.27/0062-sdhci-bcm2708-assume-50-MHz-eMMC-clock.patch)2
-rw-r--r--patches/linux-3.6.7/0061-Allow-emmc-clock-to-be-specified-as-command-line-par.patch (renamed from patches/linux-3.2.27/0063-Allow-emmc-clock-to-be-specified-as-command-line-par.patch)2
-rw-r--r--patches/linux-3.6.7/0062-sdhci-bcm2708-raise-DMA-sync-timeout.patch (renamed from patches/linux-3.2.27/0064-sdhci-bcm2708-raise-DMA-sync-timeout.patch)2
-rw-r--r--patches/linux-3.6.7/0063-Fix-bool-int-error.patch (renamed from patches/linux-3.2.27/0065-Fix-bool-int-error.patch)2
-rw-r--r--patches/linux-3.6.7/0064-Fix-bool-int-error-part-2.patch (renamed from patches/linux-3.2.27/0066-Fix-bool-int-error-part-2.patch)4
-rw-r--r--patches/linux-3.6.7/0065-More-config-options-for-iptables-device-mapper-PPP_M.patch (renamed from patches/linux-3.2.27/0067-More-config-options-for-iptables-device-mapper-PPP_M.patch)2
-rw-r--r--patches/linux-3.6.7/0066-Explicitly-set-usb-host-channels-to-8-as-in-the-spec.patch (renamed from patches/linux-3.2.27/0068-Explicitly-set-usb-host-channels-to-8-as-in-the-spec.patch)2
-rw-r--r--patches/linux-3.6.7/0067-Add-hfs-hfsplus-modules.patch (renamed from patches/linux-3.2.27/0069-Add-hfs-hfsplus-modules.patch)2
-rw-r--r--patches/linux-3.6.7/0068-Remove-silence-method-and-use-atomic-flags-for-kmall.patch (renamed from patches/linux-3.2.27/0070-Remove-silence-method-and-use-atomic-flags-for-kmall.patch)4
-rw-r--r--patches/linux-3.6.7/0069-Fix-unintended-line-swap-that-cause-cause-memory-lea.patch (renamed from patches/linux-3.2.27/0071-Fix-unintended-line-swap-that-cause-cause-memory-lea.patch)2
-rw-r--r--patches/linux-3.6.7/0070-Use-ndelay-rather-than-udelay.-Thanks-lb.patch (renamed from patches/linux-3.2.27/0072-Use-ndelay-rather-than-udelay.-Thanks-lb.patch)4
-rw-r--r--patches/linux-3.6.7/0071-Add-NFSD.-Add-some-dvb-options.-Add-CONFIG_LOCALVERS.patch (renamed from patches/linux-3.2.27/0073-Add-NFSD.-Add-some-dvb-options.-Add-CONFIG_LOCALVERS.patch)4
-rw-r--r--patches/linux-3.6.7/0072-Fixed-issue-with-some-keyboards-giving-too-much-data.patch (renamed from patches/linux-3.2.27/0074-Fixed-issue-with-some-keyboards-giving-too-much-data.patch)6
-rw-r--r--patches/linux-3.6.7/0073-Add-802.1q-vlan-module.patch (renamed from patches/linux-3.2.27/0075-Add-802.1q-vlan-module.patch)2
-rw-r--r--patches/linux-3.6.7/0074-Add-interrupt-support-to-gpio-driver.-Thanks-Mrkva.patch (renamed from patches/linux-3.2.27/0076-Add-interrupt-support-to-gpio-driver.-Thanks-Mrkva.patch)6
-rw-r--r--patches/linux-3.6.7/0075-Add-a-pm_power_off-function-that-resets-us-and-indic.patch (renamed from patches/linux-3.2.27/0077-Add-a-pm_power_off-function-that-resets-us-and-indic.patch)4
-rw-r--r--patches/linux-3.6.7/0076-Store-palette-info-where-GPU-can-see-it-so-8bpp-mode.patch (renamed from patches/linux-3.2.27/0078-Store-palette-info-where-GPU-can-see-it-so-8bpp-mode.patch)2
-rw-r--r--patches/linux-3.6.7/0077-Avoid-blanking-console-when-not-in-palettised-mode.patch (renamed from patches/linux-3.2.27/0079-Avoid-blanking-console-when-not-in-palettised-mode.patch)2
-rw-r--r--patches/linux-3.6.7/0078-Add-mechanism-to-reduce-the-number-of-SOF-interrupts.patch (renamed from patches/linux-3.2.27/0080-Add-mechanism-to-reduce-the-number-of-SOF-interrupts.patch)14
-rw-r--r--patches/linux-3.6.7/0079-Updating-dwc_otg-driver-to-fix-issue-releasing-pcm-s.patch (renamed from patches/linux-3.2.27/0081-Updating-dwc_otg-driver-to-fix-issue-releasing-pcm-s.patch)2
-rw-r--r--patches/linux-3.6.7/0080-Backport-of-Chris-Boot-s-i2c-and-spi-drivers.patch (renamed from patches/linux-3.2.27/0082-Backport-of-Chris-Boot-s-i2c-and-spi-drivers.patch)34
-rw-r--r--patches/linux-3.6.7/0081-forgotten-files.patch (renamed from patches/linux-3.2.27/0083-forgotten-files.patch)4
-rw-r--r--patches/linux-3.6.7/0082-Enable-I2C-and-SPI-modules-in-full-config.patch (renamed from patches/linux-3.2.27/0084-Enable-I2C-and-SPI-modules-in-full-config.patch)4
-rw-r--r--patches/linux-3.6.7/0083-Possible-fix-for-failure-to-boot-with-compressed-ker.patch (renamed from patches/linux-3.2.27/0085-Possible-fix-for-failure-to-boot-with-compressed-ker.patch)2
-rw-r--r--patches/linux-3.6.7/0084-Another-try-at-fixing-compressed-kernel-booting.patch (renamed from patches/linux-3.2.27/0086-Another-try-at-fixing-compressed-kernel-booting.patch)2
-rw-r--r--patches/linux-3.6.7/0085-Add-missing-UART0_CLOCK-from-last-commit.patch (renamed from patches/linux-3.2.27/0087-Add-missing-UART0_CLOCK-from-last-commit.patch)4
-rw-r--r--patches/linux-3.6.7/0086-Change-to-add-SCSI-tape-support-as-loadable-modules-.patch (renamed from patches/linux-3.2.27/0088-Change-to-add-SCSI-tape-support-as-loadable-modules-.patch)2
-rw-r--r--patches/linux-3.6.7/0087-Add-temporary-fix-for-hang-when-quitting-X.patch (renamed from patches/linux-3.2.27/0089-Add-temporary-fix-for-hang-when-quitting-X.patch)2
-rw-r--r--patches/linux-3.6.7/0088-Better-fix-for-quitting-X-hang.-Interrupted-mailbox-.patch (renamed from patches/linux-3.2.27/0090-Better-fix-for-quitting-X-hang.-Interrupted-mailbox-.patch)4
-rw-r--r--patches/linux-3.6.7/0089-Add-sync_after_dma-module-parameter.patch (renamed from patches/linux-3.2.27/0091-Add-sync_after_dma-module-parameter.patch)2
-rw-r--r--patches/linux-3.6.7/0090-Add-SPI_SPI_DEV-module.patch (renamed from patches/linux-3.2.27/0092-Add-SPI_SPI_DEV-module.patch)2
-rw-r--r--patches/linux-3.6.7/0091-Fix-var.width-var.height.-They-actually-mean-display.patch (renamed from patches/linux-3.2.27/0093-Fix-var.width-var.height.-They-actually-mean-display.patch)2
-rw-r--r--patches/linux-3.6.7/0092-The-TIMER_PERIOD-should-be-calculated-using-the-time.patch (renamed from patches/linux-3.2.27/0094-The-TIMER_PERIOD-should-be-calculated-using-the-time.patch)2
-rw-r--r--patches/linux-3.6.7/0093-update-bcmrpi_defconfig-with-various-user-requests.patch (renamed from patches/linux-3.2.27/0095-update-bcmrpi_defconfig-with-various-user-requests.patch)2
-rw-r--r--patches/linux-3.6.7/0094-Possible-fix-for-USB-packets-going-missing.-Thank-gs.patch (renamed from patches/linux-3.2.27/0096-Possible-fix-for-USB-packets-going-missing.-Thank-gs.patch)2
-rw-r--r--patches/linux-3.6.7/0095-Revert-Possible-fix-for-USB-packets-going-missing.-T.patch (renamed from patches/linux-3.2.27/0097-Revert-Possible-fix-for-USB-packets-going-missing.-T.patch)2
-rw-r--r--patches/linux-3.6.7/0096-dwc_common_port-remove-unused-cruft-with-onerous-dep.patch (renamed from patches/linux-3.2.27/0098-dwc_common_port-remove-unused-cruft-with-onerous-dep.patch)16
-rw-r--r--patches/linux-3.6.7/0097-arm-remove-divdi3-it-s-not-necessary-at-all.patch (renamed from patches/linux-3.2.27/0099-arm-remove-divdi3-it-s-not-necessary-at-all.patch)55
-rw-r--r--patches/linux-3.6.7/0098-Remove-some-patch-backup-files.patch (renamed from patches/linux-3.2.27/0100-Remove-some-patch-backup-files.patch)4
-rw-r--r--patches/linux-3.6.7/0099-mach-bcm2708-fix-mach-debug-macro.S-so-that-early-pr.patch (renamed from patches/linux-3.2.27/0101-mach-bcm2708-fix-mach-debug-macro.S-so-that-early-pr.patch)2
-rw-r--r--patches/linux-3.6.7/0100-sound-arm-bcm2835.c-add-linux-module.h-include.patch (renamed from patches/linux-3.2.27/0102-sound-arm-bcm2835.c-add-linux-module.h-include.patch)2
-rw-r--r--patches/linux-3.6.7/0101-vcos-add-linux-kernel.h-include.patch (renamed from patches/linux-3.2.27/0103-vcos-add-linux-kernel.h-include.patch)2
-rw-r--r--patches/linux-3.6.7/0102-bcm2708-update-for-3.2-kernel.patch (renamed from patches/linux-3.2.27/0104-bcm2708-update-for-3.2-kernel.patch)22
-rw-r--r--patches/linux-3.6.7/0103-bcm2708-use-a-constant-SC_MULT-SC_SHIFT.patch (renamed from patches/linux-3.2.27/0105-bcm2708-use-a-constant-SC_MULT-SC_SHIFT.patch)2
-rw-r--r--patches/linux-3.6.7/0104-Sync-with-bootc-s-file.patch (renamed from patches/linux-3.2.27/0106-Sync-with-bootc-s-file.patch)2
-rw-r--r--patches/linux-3.6.7/0105-sdhci-bcm2708-use-extension-FIFO-to-buffer-DMA-trans.patch (renamed from patches/linux-3.2.27/0107-sdhci-bcm2708-use-extension-FIFO-to-buffer-DMA-trans.patch)2
-rw-r--r--patches/linux-3.6.7/0106-sdhci-bcm2708-use-multiblock-type-transfers-for-sing.patch (renamed from patches/linux-3.2.27/0108-sdhci-bcm2708-use-multiblock-type-transfers-for-sing.patch)22
-rw-r--r--patches/linux-3.6.7/0107-Add-module-parameter-for-missing_status-quirk.-sdhci.patch (renamed from patches/linux-3.2.27/0109-Add-module-parameter-for-missing_status-quirk.-sdhci.patch)2
-rw-r--r--patches/linux-3.6.7/0108-Some-fixed-for-ALSA.-Mute-and-volume-changing-should.patch (renamed from patches/linux-3.2.27/0110-Some-fixed-for-ALSA.-Mute-and-volume-changing-should.patch)8
-rw-r--r--patches/linux-3.6.7/0109-Fix-spinlock-recursion-in-sdhci-bcm2708.c.patch (renamed from patches/linux-3.2.27/0111-Fix-spinlock-recursion-in-sdhci-bcm2708.c.patch)2
-rw-r--r--patches/linux-3.6.7/0110-Revert-Add-mechanism-to-reduce-the-number-of-SOF-int.patch (renamed from patches/linux-3.2.27/0112-Revert-Add-mechanism-to-reduce-the-number-of-SOF-int.patch)14
-rw-r--r--patches/linux-3.6.7/0111-Enable-CONFIG_CRYPTO_XTS.patch (renamed from patches/linux-3.2.27/0113-Enable-CONFIG_CRYPTO_XTS.patch)2
-rw-r--r--patches/linux-3.6.7/0112-Update-Synopsys-USB-OTG-driver-to-v2.94a-and-disable.patch (renamed from patches/linux-3.2.27/0114-Update-Synopsys-USB-OTG-driver-to-v2.94a-and-disable.patch)722
-rw-r--r--patches/linux-3.6.7/0113-Merged-in-microframe-scheduler-currently-disabled.-E.patch (renamed from patches/linux-3.2.27/0115-Merged-in-microframe-scheduler-currently-disabled.-E.patch)12
-rw-r--r--patches/linux-3.6.7/0114-Make-microframe-schedule-patch-a-little-closer-to-de.patch (renamed from patches/linux-3.2.27/0116-Make-microframe-schedule-patch-a-little-closer-to-de.patch)10
-rw-r--r--patches/linux-3.6.7/0115-Remove-remove-documentation-from-the-source-tree.patch (renamed from patches/linux-3.2.27/0117-Remove-remove-documentation-from-the-source-tree.patch)2
-rw-r--r--patches/linux-3.6.7/0116-Fix-for-broken-GPIO-with-3.2-kernel.patch (renamed from patches/linux-3.2.27/0118-Fix-for-broken-GPIO-with-3.2-kernel.patch)4
-rw-r--r--patches/linux-3.6.7/0117-Revert-Disable-IRQs-in-dwc_otg_hcd_qh_free-because-D.patch (renamed from patches/linux-3.2.27/0119-Revert-Disable-IRQs-in-dwc_otg_hcd_qh_free-because-D.patch)2
-rw-r--r--patches/linux-3.6.7/0118-Regenerate-defconfigs-for-udpated-kernel-verision.patch (renamed from patches/linux-3.2.27/0120-Regenerate-defconfigs-for-udpated-kernel-verision.patch)4
-rw-r--r--patches/linux-3.6.7/0119-Another-fix-for-10-second-hang-on-closing-sound-driv.patch (renamed from patches/linux-3.2.27/0121-Another-fix-for-10-second-hang-on-closing-sound-driv.patch)4
-rw-r--r--patches/linux-3.6.7/0120-amba-pl011-Don-t-send-a-character-during-startup.patch (renamed from patches/linux-3.2.27/0122-amba-pl011-Don-t-send-a-character-during-startup.patch)12
-rw-r--r--patches/linux-3.6.7/0121-Revert-Regenerate-defconfigs-for-udpated-kernel-veri.patch (renamed from patches/linux-3.2.27/0123-Revert-Regenerate-defconfigs-for-udpated-kernel-veri.patch)4
-rw-r--r--patches/linux-3.6.7/0122-Regenerate-defconfigs-for-updated-kernel-verision-tr.patch (renamed from patches/linux-3.2.27/0124-Regenerate-defconfigs-for-updated-kernel-verision-tr.patch)4
-rw-r--r--patches/linux-3.6.7/0123-Read-memory-size-for-vc_mem-through-mailbox-property.patch (renamed from patches/linux-3.2.27/0125-Read-memory-size-for-vc_mem-through-mailbox-property.patch)6
-rw-r--r--patches/linux-3.6.7/0124-Revert-amba-pl011-Don-t-send-a-character-during-star.patch (renamed from patches/linux-3.2.27/0126-Revert-amba-pl011-Don-t-send-a-character-during-star.patch)12
-rw-r--r--patches/linux-3.6.7/0125-Update-to-dwc_otg-3.00.-Seems-to-be-a-very-minor-upd.patch (renamed from patches/linux-3.2.27/0127-Update-to-dwc_otg-3.00.-Seems-to-be-a-very-minor-upd.patch)22
-rw-r--r--patches/linux-3.6.7/0126-enabling-the-realtime-clock-1-wire-chip-DS1307-and-1.patch (renamed from patches/linux-3.2.27/0128-enabling-the-realtime-clock-1-wire-chip-DS1307-and-1.patch)4
-rw-r--r--patches/linux-3.6.7/0127-Switch-of-tracing-options-in-kernel.-Costs-20-in-ipe.patch (renamed from patches/linux-3.2.27/0129-Switch-of-tracing-options-in-kernel.-Costs-20-in-ipe.patch)2
-rw-r--r--patches/linux-3.6.7/0128-Turn-on-microframe_schedule-by-default.-Can-still-be.patch (renamed from patches/linux-3.2.27/0130-Turn-on-microframe_schedule-by-default.-Can-still-be.patch)2
-rw-r--r--patches/linux-3.6.7/0129-Add-low-latency-mode-to-sdcard-driver.-Enable-with-s.patch (renamed from patches/linux-3.2.27/0131-Add-low-latency-mode-to-sdcard-driver.-Enable-with-s.patch)126
-rw-r--r--patches/linux-3.6.7/0130-Fix-build-for-non-preempt-case.-Fix-warning.patch (renamed from patches/linux-3.2.27/0132-Fix-build-for-non-preempt-case.-Fix-warning.patch)16
-rw-r--r--patches/linux-3.6.7/0131-Add-config-options-to-allow-iotop-to-run.patch (renamed from patches/linux-3.2.27/0133-Add-config-options-to-allow-iotop-to-run.patch)2
-rw-r--r--patches/linux-3.6.7/0132-Fix-for-vmalloc-failure-with-modprobe-and-cutdown-ke.patch (renamed from patches/linux-3.2.27/0134-Fix-for-vmalloc-failure-with-modprobe-and-cutdown-ke.patch)8
-rw-r--r--patches/linux-3.6.7/0133-Enable-low-latency-mode-by-default-in-sdcard-driver..patch (renamed from patches/linux-3.2.27/0135-Enable-low-latency-mode-by-default-in-sdcard-driver..patch)2
-rw-r--r--patches/linux-3.6.7/0134-Add-FIQ-patch-to-dwc_otg-driver.-Enable-with-dwc_otg.patch (renamed from patches/linux-3.2.27/0136-Add-FIQ-patch-to-dwc_otg-driver.-Enable-with-dwc_otg.patch)52
-rw-r--r--patches/linux-3.6.7/0135-Fix-typo.patch (renamed from patches/linux-3.2.27/0137-Fix-typo.patch)6
-rw-r--r--patches/linux-3.6.7/0136-Add-non-mainline-source-for-rtl8188cu-wireless-drive.patch (renamed from patches/linux-3.2.27/0138-Add-non-mainline-source-for-rtl8188cu-wireless-drive.patch)355
-rw-r--r--patches/linux-3.6.7/0137-Add-verious-user-config-requests.patch (renamed from patches/linux-3.2.27/0139-Add-verious-user-config-requests.patch)2
-rw-r--r--patches/linux-3.6.7/0138-Don-t-believe-KDIR-is-required-when-building-as-part.patch (renamed from patches/linux-3.2.27/0140-Don-t-believe-KDIR-is-required-when-building-as-part.patch)4
-rw-r--r--patches/linux-3.6.7/0139-Avoid-dynamic-memory-allocation-for-channel-lock-in-.patch (renamed from patches/linux-3.2.27/0141-Avoid-dynamic-memory-allocation-for-channel-lock-in-.patch)8
-rw-r--r--patches/linux-3.6.7/0140-Add-cpufreq-driver.patch (renamed from patches/linux-3.2.27/0142-Add-cpufreq-driver.patch)43
-rw-r--r--patches/linux-3.6.7/0141-Tidy-up-debug-messages.patch (renamed from patches/linux-3.2.27/0143-Tidy-up-debug-messages.patch)2
-rw-r--r--patches/linux-3.6.7/0142-Enable-fiq-fix-by-default.-Add-NAK-holdoff-scheme.-E.patch (renamed from patches/linux-3.2.27/0145-Enable-fiq-fix-by-default.-Add-NAK-holdoff-scheme.-E.patch)10
-rw-r--r--patches/linux-3.6.7/0143-Added-hwmon-thermal-driver-for-reporting-core-temper.patch (renamed from patches/linux-3.2.27/0146-Added-hwmon-thermal-driver-for-reporting-core-temper.patch)44
-rw-r--r--patches/linux-3.6.7/0144-Add-config-options-for-thermal-sensor-L2TP-RT2800USB.patch (renamed from patches/linux-3.2.27/0147-Add-config-options-for-thermal-sensor-L2TP-RT2800USB.patch)14
-rw-r--r--patches/linux-3.6.7/0145-Remove-some-unnecessary-dmesg-output.patch193
-rw-r--r--patches/linux-3.6.7/0146-Switch-to-powersave-governor.-We-ll-enable-ondemand-.patch26
-rw-r--r--patches/linux-3.6.7/0147-Enable-multiple-ALSA-channels.patch61
-rw-r--r--patches/linux-3.6.7/0148-Remove-vcos-abstraction-layer-from-ALSA-driver.-Than.patch384
-rw-r--r--patches/linux-3.6.7/0149-Fix-Kernel-OOPS-in-SDHCI-on-boot-with-the-llm-patch..patch45
-rw-r--r--patches/linux-3.6.7/0150-Use-system-timer-for-udelay-so-unaffected-by-cpufreq.patch49
-rw-r--r--patches/linux-3.6.7/0151-Move-__delay-function-into-assembly-to-get-accurate-.patch67
-rw-r--r--patches/linux-3.6.7/0152-set-i2c-speed-via-module-parameter-or-menuconfig.-Th.patch73
-rw-r--r--patches/linux-3.6.7/0153-Allow-the-number-of-cycles-delay-between-sdcard-peri.patch40
-rw-r--r--patches/linux-3.6.7/0154-Fix-vc-mem-by-using-module-parameters.patch244
-rw-r--r--patches/linux-3.6.7/0155-Move-to-version-5-of-VCHIQ.-Note-this-requires-a-cor.patch25103
-rw-r--r--patches/linux-3.6.7/0156-Add-in-missed-vchiq-files.patch398
-rw-r--r--patches/linux-3.6.7/0157-Make-vchiq-enabled-by-default.-Tidy-Kconfig-file.patch119
-rw-r--r--patches/linux-3.6.7/0158-Support-dummy-vc-mem-ioctl-used-by-vcdbg.patch46
-rw-r--r--patches/linux-3.6.7/0159-Remove-BUG-call-from-vchiq-that-is-trigger-when-alsa.patch22
-rw-r--r--patches/linux-3.6.7/0160-Fix-up-issues-with-rebase.patch2470
-rw-r--r--patches/linux-3.6.7/0161-Add-vc_cma-driver-to-enable-use-of-CMA.patch97
-rw-r--r--patches/linux-3.6.7/0162-Add-missing-CMA-files.patch998
-rw-r--r--patches/linux-3.6.7/0163-Fix-reboot-with-new-restart-method-of-machine-driver.patch76
-rw-r--r--patches/linux-3.6.7/0164-smsc95xx-sleep-before-read-for-lengthy-operations.patch45
-rw-r--r--patches/linux-3.6.7/0165-smsc95xx-remove-unnecessary-variables.patch133
-rw-r--r--patches/linux-3.6.7/0166-smsc95xx-check-return-code-from-control-messages.patch702
-rw-r--r--patches/linux-3.6.7/0167-smsc95xx-fix-resume-when-usb-device-is-reset.patch25
-rw-r--r--patches/linux-3.6.7/0168-smsc95xx-enable-power-saving-mode-during-system-susp.patch86
-rw-r--r--patches/linux-3.6.7/0169-smsc95xx-add-wol-magic-packet-support.patch283
-rw-r--r--patches/linux-3.6.7/0170-smsc95xx-fix-tx-checksum-offload-for-big-endian.patch33
-rw-r--r--patches/linux-3.6.7/0171-Update-to-latest-vchiq.patch961
-rw-r--r--patches/linux-3.6.7/0172-Make-sure-we-wait-for-the-reset-to-finish.patch21
-rw-r--r--patches/linux-3.6.7/0173-Add-missing-pctv452e-DVB-module.patch29
-rw-r--r--patches/linux-3.6.7/0174-Add-Simon-Hall-s-dma-helper-module-useful-in-future-.patch799
-rw-r--r--patches/linux-3.6.7/0175-Add-missing-options-from-more-recent-3.2.27-kernel-c.patch298
-rw-r--r--patches/linux-3.6.7/0176-lirc-added-support-for-RaspberryPi-GPIO.patch733
-rw-r--r--patches/linux-3.6.7/0177-Enable-building-of-lirc-rpi.patch20
-rw-r--r--patches/linux-3.6.7/0201-Release-raspberrypi-20121120.patch22
-rw-r--r--patches/linux-3.6.7/series187
-rw-r--r--platformconfig4
186 files changed, 36402 insertions, 2073 deletions
diff --git a/kernelconfig-3.2.27 b/kernelconfig-3.6.7
index 74cdf34..1cf2e4f 100644
--- a/kernelconfig-3.2.27
+++ b/kernelconfig-3.6.7
@@ -1,30 +1,24 @@
#
# Automatically generated file; DO NOT EDIT.
-# Linux/arm 3.2.27-20120915 Kernel Configuration
+# Linux/arm 3.6.7-20121120 Kernel Configuration
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_HAVE_SCHED_CLOCK=y
CONFIG_GENERIC_GPIO=y
-# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_KTIME_SCALAR=y
CONFIG_HAVE_PROC_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_ARCH_HAS_CPUFREQ=y
-CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_FIQ=y
CONFIG_VECTORS_BASE=0xffff0000
# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_NEED_MACH_IO_H=y
CONFIG_NEED_MACH_MEMORY_H=y
CONFIG_GENERIC_BUG=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -42,9 +36,11 @@ CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
# CONFIG_KERNEL_LZO is not set
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SWAP=y
@@ -60,22 +56,32 @@ CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_AUDIT=y
+CONFIG_AUDIT_LOGINUID_IMMUTABLE=y
CONFIG_HAVE_GENERIC_HARDIRQS=y
#
# IRQ subsystem
#
CONFIG_GENERIC_HARDIRQS=y
-CONFIG_HAVE_SPARSE_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
-# CONFIG_SPARSE_IRQ is not set
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
#
# RCU Subsystem
#
CONFIG_TINY_PREEMPT_RCU=y
CONFIG_PREEMPT_RCU=y
-# CONFIG_RCU_TRACE is not set
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_RCU_BOOST is not set
CONFIG_IKCONFIG=y
@@ -88,7 +94,7 @@ CONFIG_CGROUP_DEVICE=y
# CONFIG_CPUSETS is not set
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
-# CONFIG_CGROUP_MEM_RES_CTLR is not set
+# CONFIG_MEMCG is not set
# CONFIG_CGROUP_PERF is not set
CONFIG_CGROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
@@ -96,10 +102,10 @@ CONFIG_FAIR_GROUP_SCHED=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
-CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_NET_NS=y
CONFIG_SCHED_AUTOGROUP=y
@@ -134,7 +140,6 @@ CONFIG_PERF_USE_VMALLOC=y
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
-# CONFIG_PERF_COUNTERS is not set
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
CONFIG_VM_EVENT_COUNTERS=y
# CONFIG_COMPAT_BRK is not set
@@ -145,13 +150,20 @@ CONFIG_PROFILING=y
CONFIG_OPROFILE=m
CONFIG_HAVE_OPROFILE=y
CONFIG_KPROBES=y
+CONFIG_JUMP_LABEL=y
CONFIG_KRETPROBES=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
#
# GCOV-based kernel profiling
@@ -175,6 +187,28 @@ CONFIG_LBDAF=y
CONFIG_BLK_DEV_THROTTLING=y
#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+# CONFIG_SYSV68_PARTITION is not set
+
+#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
@@ -191,7 +225,7 @@ CONFIG_DEFAULT_IOSCHED="cfq"
# CONFIG_INLINE_SPIN_LOCK_BH is not set
# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
-# CONFIG_INLINE_SPIN_UNLOCK is not set
+CONFIG_UNINLINE_SPIN_UNLOCK=y
# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
@@ -220,6 +254,7 @@ CONFIG_FREEZER=y
# System Type
#
CONFIG_MMU=y
+# CONFIG_ARCH_SOCFPGA is not set
# CONFIG_ARCH_INTEGRATOR is not set
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_VERSATILE is not set
@@ -241,9 +276,8 @@ CONFIG_MMU=y
# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IOP32X is not set
# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IXP23XX is not set
-# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_MVEBU is not set
# CONFIG_ARCH_DOVE is not set
# CONFIG_ARCH_KIRKWOOD is not set
# CONFIG_ARCH_LPC32XX is not set
@@ -260,14 +294,13 @@ CONFIG_MMU=y
# CONFIG_ARCH_SHMOBILE is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C24XX is not set
# CONFIG_ARCH_S3C64XX is not set
# CONFIG_ARCH_S5P64X0 is not set
# CONFIG_ARCH_S5PC100 is not set
# CONFIG_ARCH_S5PV210 is not set
# CONFIG_ARCH_EXYNOS is not set
# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_TCC_926 is not set
# CONFIG_ARCH_U300 is not set
# CONFIG_ARCH_U8500 is not set
# CONFIG_ARCH_NOMADIK is not set
@@ -280,16 +313,13 @@ CONFIG_ARCH_BCM2708=y
# CONFIG_GPIO_PCA953X is not set
#
-# System MMU
-#
-
-#
# Broadcom BCM2708 Implementations
#
CONFIG_MACH_BCM2708=y
CONFIG_BCM2708_GPIO=y
CONFIG_BCM2708_VCMEM=y
# CONFIG_BCM2708_NOL2CACHE is not set
+CONFIG_BCM2708_DMAER=m
#
# Processor Type
@@ -310,12 +340,15 @@ CONFIG_CPU_USE_DOMAINS=y
#
# Processor Features
#
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
CONFIG_ARM_THUMB=y
# CONFIG_CPU_ICACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_DISABLE is not set
# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_CACHE_L2X0 is not set
CONFIG_ARM_L1_CACHE_SHIFT=5
CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_ARM_NR_BANKS=8
CONFIG_CPU_HAS_PMU=y
# CONFIG_ARM_ERRATA_326103 is not set
CONFIG_ARM_ERRATA_411920=y
@@ -332,14 +365,11 @@ CONFIG_ARM_AMBA=y
#
# Kernel Features
#
-CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_VMSPLIT_3G=y
# CONFIG_VMSPLIT_2G is not set
# CONFIG_VMSPLIT_1G is not set
CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_ARCH_NR_GPIO=0
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
@@ -357,16 +387,20 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_HAVE_MEMBLOCK=y
+CONFIG_MEMORY_ISOLATION=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_COMPACTION is not set
+CONFIG_MIGRATION=y
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_CROSS_MEMORY_ATTACH=y
CONFIG_NEED_PER_CPU_KM=y
# CONFIG_CLEANCACHE is not set
+# CONFIG_FRONTSWAP is not set
CONFIG_FORCE_MAX_ZONEORDER=11
CONFIG_ALIGNMENT_TRAP=y
CONFIG_UACCESS_WITH_MEMCPY=y
@@ -415,10 +449,14 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
#
# ARM CPU frequency scaling drivers
#
+# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set
+# CONFIG_ARM_EXYNOS4X12_CPUFREQ is not set
+# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set
CONFIG_ARM_BCM2835_CPUFREQ=y
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_LADDER=y
CONFIG_CPU_IDLE_GOV_MENU=y
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
#
# Floating point emulation
@@ -435,6 +473,7 @@ CONFIG_VFP=y
# Userspace binary formats
#
CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
CONFIG_HAVE_AOUT=y
# CONFIG_BINFMT_AOUT is not set
@@ -446,6 +485,8 @@ CONFIG_BINFMT_MISC=m
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_PM_SLEEP=y
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
# CONFIG_PM_RUNTIME is not set
CONFIG_PM=y
# CONFIG_PM_DEBUG is not set
@@ -461,7 +502,9 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
CONFIG_UNIX=y
+# CONFIG_UNIX_DIAG is not set
CONFIG_XFRM=y
+CONFIG_XFRM_ALGO=y
CONFIG_XFRM_USER=y
# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
@@ -486,6 +529,7 @@ CONFIG_NET_IPIP=m
# CONFIG_IP_MROUTE is not set
# CONFIG_ARPD is not set
CONFIG_SYN_COOKIES=y
+# CONFIG_NET_IPVTI is not set
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
CONFIG_INET_IPCOMP=m
@@ -497,6 +541,7 @@ CONFIG_INET_XFRM_MODE_BEET=m
CONFIG_INET_LRO=m
CONFIG_INET_DIAG=m
CONFIG_INET_TCP_DIAG=m
+# CONFIG_INET_UDP_DIAG is not set
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -533,12 +578,15 @@ CONFIG_BRIDGE_NETFILTER=y
# Core Netfilter Configuration
#
CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_ACCT=m
CONFIG_NETFILTER_NETLINK_QUEUE=m
CONFIG_NETFILTER_NETLINK_LOG=m
CONFIG_NF_CONNTRACK=m
CONFIG_NF_CONNTRACK_MARK=y
CONFIG_NF_CONNTRACK_ZONES=y
+CONFIG_NF_CONNTRACK_PROCFS=y
CONFIG_NF_CONNTRACK_EVENTS=y
+# CONFIG_NF_CONNTRACK_TIMEOUT is not set
CONFIG_NF_CONNTRACK_TIMESTAMP=y
CONFIG_NF_CT_PROTO_DCCP=m
CONFIG_NF_CT_PROTO_GRE=m
@@ -556,6 +604,8 @@ CONFIG_NF_CONNTRACK_SANE=m
CONFIG_NF_CONNTRACK_SIP=m
CONFIG_NF_CONNTRACK_TFTP=m
CONFIG_NF_CT_NETLINK=m
+# CONFIG_NF_CT_NETLINK_TIMEOUT is not set
+# CONFIG_NETFILTER_NETLINK_QUEUE_CT is not set
CONFIG_NETFILTER_TPROXY=m
CONFIG_NETFILTER_XTABLES=m
@@ -576,8 +626,10 @@ CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
CONFIG_NETFILTER_XT_TARGET_CT=m
CONFIG_NETFILTER_XT_TARGET_DSCP=m
CONFIG_NETFILTER_XT_TARGET_HL=m
+# CONFIG_NETFILTER_XT_TARGET_HMARK is not set
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
CONFIG_NETFILTER_XT_TARGET_LED=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
CONFIG_NETFILTER_XT_TARGET_MARK=m
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -603,6 +655,7 @@ CONFIG_NETFILTER_XT_MATCH_CPU=m
CONFIG_NETFILTER_XT_MATCH_DCCP=m
CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ECN=m
CONFIG_NETFILTER_XT_MATCH_ESP=m
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
CONFIG_NETFILTER_XT_MATCH_HELPER=m
@@ -613,6 +666,7 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m
CONFIG_NETFILTER_XT_MATCH_MAC=m
CONFIG_NETFILTER_XT_MATCH_MARK=m
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
CONFIG_NETFILTER_XT_MATCH_OSF=m
CONFIG_NETFILTER_XT_MATCH_OWNER=m
CONFIG_NETFILTER_XT_MATCH_POLICY=m
@@ -655,10 +709,10 @@ CONFIG_NF_CONNTRACK_PROC_COMPAT=y
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_AH=m
CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_NF_NAT=m
CONFIG_NF_NAT_NEEDED=y
@@ -691,7 +745,6 @@ CONFIG_IP_NF_ARP_MANGLE=m
#
CONFIG_NF_DEFRAG_IPV6=m
CONFIG_NF_CONNTRACK_IPV6=m
-# CONFIG_IP6_NF_QUEUE is not set
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_EUI64=m
@@ -700,9 +753,9 @@ CONFIG_IP6_NF_MATCH_OPTS=m
CONFIG_IP6_NF_MATCH_HL=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
CONFIG_IP6_NF_MATCH_RT=m
CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
@@ -751,7 +804,6 @@ CONFIG_LLC=m
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
# CONFIG_IEEE802154 is not set
@@ -777,7 +829,10 @@ CONFIG_NET_SCH_DRR=m
CONFIG_NET_SCH_MQPRIO=m
CONFIG_NET_SCH_CHOKE=m
CONFIG_NET_SCH_QFQ=m
+CONFIG_NET_SCH_CODEL=m
+CONFIG_NET_SCH_FQ_CODEL=m
# CONFIG_NET_SCH_INGRESS is not set
+# CONFIG_NET_SCH_PLUG is not set
#
# Classification
@@ -801,6 +856,7 @@ CONFIG_NET_EMATCH_NBYTE=m
CONFIG_NET_EMATCH_U32=m
CONFIG_NET_EMATCH_META=m
CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_EMATCH_IPSET=m
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=m
CONFIG_NET_ACT_GACT=m
@@ -817,6 +873,10 @@ CONFIG_NET_SCH_FIFO=y
# CONFIG_DCB is not set
CONFIG_DNS_RESOLVER=y
# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+# CONFIG_NETPRIO_CGROUP is not set
+CONFIG_BQL=y
+CONFIG_BPF_JIT=y
#
# Network testing
@@ -884,8 +944,6 @@ CONFIG_USB_IRDA=m
CONFIG_SIGMATEL_FIR=m
CONFIG_MCS_FIR=m
CONFIG_BT=m
-CONFIG_BT_L2CAP=y
-CONFIG_BT_SCO=y
CONFIG_BT_RFCOMM=m
CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=m
@@ -918,11 +976,11 @@ CONFIG_CFG80211=m
# CONFIG_NL80211_TESTMODE is not set
# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
# CONFIG_CFG80211_REG_DEBUG is not set
+# CONFIG_CFG80211_CERTIFICATION_ONUS is not set
CONFIG_CFG80211_DEFAULT_PS=y
# CONFIG_CFG80211_DEBUGFS is not set
# CONFIG_CFG80211_INTERNAL_REGDB is not set
CONFIG_CFG80211_WEXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
CONFIG_LIB80211=m
CONFIG_LIB80211_CRYPT_WEP=m
CONFIG_LIB80211_CRYPT_CCMP=m
@@ -939,6 +997,7 @@ CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
CONFIG_MAC80211_MESH=y
CONFIG_MAC80211_LEDS=y
# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_MESSAGE_TRACING is not set
# CONFIG_MAC80211_DEBUG_MENU is not set
CONFIG_WIMAX=m
CONFIG_WIMAX_DEBUG_LEVEL=8
@@ -949,12 +1008,15 @@ CONFIG_NET_9P=m
# CONFIG_CEPH_LIB is not set
CONFIG_NFC=m
# CONFIG_NFC_NCI is not set
+# CONFIG_NFC_HCI is not set
+# CONFIG_NFC_LLCP is not set
#
# Near Field Communication (NFC) devices
#
# CONFIG_PN544_NFC is not set
CONFIG_NFC_PN533=m
+CONFIG_HAVE_BPF_JIT=y
#
# Device Drivers
@@ -974,6 +1036,21 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+# CONFIG_DMA_SHARED_BUFFER is not set
+CONFIG_CMA=y
+CONFIG_CMA_DEBUG=y
+
+#
+# Default contiguous memory area size:
+#
+CONFIG_CMA_SIZE_MBYTES=16
+CONFIG_CMA_SIZE_SEL_MBYTES=y
+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
+# CONFIG_CMA_SIZE_SEL_MIN is not set
+# CONFIG_CMA_SIZE_SEL_MAX is not set
+CONFIG_CMA_ALIGNMENT=8
+CONFIG_CMA_AREAS=7
CONFIG_CONNECTOR=m
# CONFIG_MTD is not set
# CONFIG_PARPORT is not set
@@ -996,8 +1073,11 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_MG_DISK is not set
# CONFIG_BLK_DEV_RBD is not set
+
+#
+# Misc devices
+#
# CONFIG_SENSORS_LIS3LV02D is not set
-CONFIG_MISC_DEVICES=y
# CONFIG_AD525X_DPOT is not set
# CONFIG_ATMEL_PWM is not set
# CONFIG_ICS932S401 is not set
@@ -1012,7 +1092,8 @@ CONFIG_MISC_DEVICES=y
# CONFIG_HMC6352 is not set
# CONFIG_DS1682 is not set
# CONFIG_TI_DAC7512 is not set
-# CONFIG_BMP085 is not set
+# CONFIG_BMP085_I2C is not set
+# CONFIG_BMP085_SPI is not set
# CONFIG_USB_SWITCH_FSA9480 is not set
# CONFIG_C2PORT is not set
@@ -1025,9 +1106,6 @@ CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_MAX6875 is not set
CONFIG_EEPROM_93CX6=m
# CONFIG_EEPROM_93XX46 is not set
-CONFIG_IWMC3200TOP=m
-# CONFIG_IWMC3200TOP_DEBUG is not set
-# CONFIG_IWMC3200TOP_DEBUGFS is not set
#
# Texas Instruments shared transport line discipline
@@ -1067,7 +1145,6 @@ CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
# CONFIG_SCSI_SCAN_ASYNC is not set
-CONFIG_SCSI_WAIT_SCAN=m
#
# SCSI Transports
@@ -1087,7 +1164,7 @@ CONFIG_BLK_DEV_MD=m
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
CONFIG_MD_RAID1=m
-# CONFIG_MD_RAID10 is not set
+CONFIG_MD_RAID10=m
CONFIG_MD_RAID456=m
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
@@ -1104,6 +1181,7 @@ CONFIG_DM_ZERO=m
CONFIG_DM_DELAY=m
# CONFIG_DM_UEVENT is not set
# CONFIG_DM_FLAKEY is not set
+# CONFIG_DM_VERITY is not set
# CONFIG_TARGET_CORE is not set
CONFIG_NETDEVICES=y
CONFIG_NET_CORE=y
@@ -1112,6 +1190,7 @@ CONFIG_BONDING=m
# CONFIG_EQUALIZER is not set
CONFIG_MII=y
# CONFIG_IFB is not set
+# CONFIG_NET_TEAM is not set
CONFIG_MACVLAN=m
# CONFIG_MACVTAP is not set
CONFIG_NETCONSOLE=m
@@ -1128,7 +1207,10 @@ CONFIG_TUN=m
CONFIG_ETHERNET=y
CONFIG_NET_VENDOR_BROADCOM=y
# CONFIG_B44 is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
CONFIG_NET_VENDOR_CHELSIO=y
+CONFIG_NET_VENDOR_CIRRUS=y
+# CONFIG_CS89x0 is not set
# CONFIG_DM9000 is not set
# CONFIG_DNET is not set
CONFIG_NET_VENDOR_FARADAY=y
@@ -1154,11 +1236,15 @@ CONFIG_NET_VENDOR_SMSC=y
# CONFIG_SMSC911X is not set
CONFIG_NET_VENDOR_STMICRO=y
# CONFIG_STMMAC_ETH is not set
+CONFIG_NET_VENDOR_WIZNET=y
+# CONFIG_WIZNET_W5100 is not set
+# CONFIG_WIZNET_W5300 is not set
CONFIG_PHYLIB=m
#
# MII PHY device drivers
#
+# CONFIG_AMD_PHY is not set
# CONFIG_MARVELL_PHY is not set
# CONFIG_DAVICOM_PHY is not set
# CONFIG_QSEMI_PHY is not set
@@ -1167,6 +1253,7 @@ CONFIG_PHYLIB=m
# CONFIG_VITESSE_PHY is not set
# CONFIG_SMSC_PHY is not set
# CONFIG_BROADCOM_PHY is not set
+# CONFIG_BCM87XX_PHY is not set
# CONFIG_ICPLUS_PHY is not set
# CONFIG_REALTEK_PHY is not set
# CONFIG_NATIONAL_PHY is not set
@@ -1175,6 +1262,7 @@ CONFIG_PHYLIB=m
# CONFIG_MICREL_PHY is not set
CONFIG_MDIO_BITBANG=m
# CONFIG_MDIO_GPIO is not set
+# CONFIG_MICREL_KS8995MA is not set
CONFIG_PPP=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPP_DEFLATE=m
@@ -1221,6 +1309,7 @@ CONFIG_USB_KC2190=y
# CONFIG_USB_NET_ZAURUS is not set
CONFIG_USB_NET_CX82310_ETH=m
CONFIG_USB_NET_KALMIA=m
+# CONFIG_USB_NET_QMI_WWAN is not set
CONFIG_USB_NET_INT51X1=m
CONFIG_USB_IPHETH=m
CONFIG_USB_SIERRA_NET=m
@@ -1239,6 +1328,7 @@ CONFIG_ATH_COMMON=m
# CONFIG_ATH_DEBUG is not set
CONFIG_ATH9K_HW=m
CONFIG_ATH9K_COMMON=m
+CONFIG_ATH9K_BTCOEX_SUPPORT=y
CONFIG_ATH9K=m
# CONFIG_ATH9K_AHB is not set
# CONFIG_ATH9K_DEBUGFS is not set
@@ -1269,8 +1359,6 @@ CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
# CONFIG_BRCMFMAC is not set
CONFIG_HOSTAP=m
# CONFIG_HOSTAP_FIRMWARE is not set
-CONFIG_IWM=m
-# CONFIG_IWM_DEBUG is not set
CONFIG_LIBERTAS=m
CONFIG_LIBERTAS_USB=m
CONFIG_LIBERTAS_SDIO=m
@@ -1296,15 +1384,12 @@ CONFIG_RT2X00_LIB_FIRMWARE=y
CONFIG_RT2X00_LIB_CRYPTO=y
CONFIG_RT2X00_LIB_LEDS=y
# CONFIG_RT2X00_DEBUG is not set
-CONFIG_WL1251=m
-# CONFIG_WL1251_SPI is not set
-# CONFIG_WL1251_SDIO is not set
-CONFIG_WL12XX_MENU=m
-# CONFIG_WL12XX is not set
+# CONFIG_WL_TI is not set
CONFIG_ZD1211RW=m
# CONFIG_ZD1211RW_DEBUG is not set
CONFIG_MWIFIEX=m
CONFIG_MWIFIEX_SDIO=m
+# CONFIG_MWIFIEX_USB is not set
CONFIG_RTL8192CU=m
#
@@ -1312,11 +1397,9 @@ CONFIG_RTL8192CU=m
#
CONFIG_WIMAX_I2400M=m
CONFIG_WIMAX_I2400M_USB=m
-# CONFIG_WIMAX_I2400M_SDIO is not set
CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8
# CONFIG_WAN is not set
# CONFIG_ISDN is not set
-# CONFIG_PHONE is not set
#
# Input device support
@@ -1325,6 +1408,7 @@ CONFIG_INPUT=y
CONFIG_INPUT_FF_MEMLESS=m
CONFIG_INPUT_POLLDEV=m
# CONFIG_INPUT_SPARSEKMAP is not set
+# CONFIG_INPUT_MATRIXKMAP is not set
#
# Userland interfaces
@@ -1352,6 +1436,8 @@ CONFIG_INPUT_AD714X_SPI=m
# CONFIG_INPUT_BMA150 is not set
# CONFIG_INPUT_MMA8450 is not set
# CONFIG_INPUT_MPU3050 is not set
+# CONFIG_INPUT_GP2A is not set
+# CONFIG_INPUT_GPIO_TILT_POLLED is not set
CONFIG_INPUT_ATI_REMOTE2=m
CONFIG_INPUT_KEYSPAN_REMOTE=m
# CONFIG_INPUT_KXTJ9 is not set
@@ -1427,7 +1513,8 @@ CONFIG_TTY_PRINTK=y
CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=256
# CONFIG_TCG_TPM is not set
-# CONFIG_RAMOOPS is not set
+CONFIG_BRCM_CHAR_DRIVERS=y
+CONFIG_BCM_VC_CMA=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_COMPAT=y
@@ -1443,8 +1530,10 @@ CONFIG_I2C_HELPER_AUTO=y
# I2C system bus drivers (mostly embedded / system-on-chip)
#
CONFIG_I2C_BCM2708=m
+CONFIG_I2C_BCM2708_BAUDRATE=100000
# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_NOMADIK is not set
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_PXA_PCI is not set
@@ -1480,6 +1569,7 @@ CONFIG_SPI_BCM2708=m
# CONFIG_SPI_OC_TINY is not set
# CONFIG_SPI_PL022 is not set
# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_XCOMM is not set
# CONFIG_SPI_XILINX is not set
# CONFIG_SPI_DESIGNWARE is not set
@@ -1488,6 +1578,7 @@ CONFIG_SPI_BCM2708=m
#
CONFIG_SPI_SPIDEV=m
# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_HSI is not set
#
# PPS support
@@ -1505,6 +1596,7 @@ CONFIG_SPI_SPIDEV=m
#
# Enable Device Drivers -> PPS to see the PTP clock options.
#
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_GPIOLIB=y
# CONFIG_DEBUG_GPIO is not set
@@ -1514,7 +1606,7 @@ CONFIG_GPIO_SYSFS=y
# Memory mapped GPIO drivers:
#
# CONFIG_GPIO_GENERIC_PLATFORM is not set
-# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_EM is not set
# CONFIG_GPIO_PL061 is not set
#
@@ -1568,20 +1660,26 @@ CONFIG_W1_SLAVE_DS2433=m
# CONFIG_W1_SLAVE_DS2433_CRC is not set
CONFIG_W1_SLAVE_DS2760=m
CONFIG_W1_SLAVE_DS2780=m
+# CONFIG_W1_SLAVE_DS2781 is not set
+# CONFIG_W1_SLAVE_DS28E04 is not set
CONFIG_W1_SLAVE_BQ27000=m
-CONFIG_POWER_SUPPLY=m
+CONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
# CONFIG_PDA_POWER is not set
# CONFIG_TEST_POWER is not set
# CONFIG_BATTERY_DS2760 is not set
# CONFIG_BATTERY_DS2780 is not set
+# CONFIG_BATTERY_DS2781 is not set
# CONFIG_BATTERY_DS2782 is not set
-# CONFIG_BATTERY_BQ20Z75 is not set
+# CONFIG_BATTERY_SBS is not set
# CONFIG_BATTERY_BQ27x00 is not set
# CONFIG_BATTERY_MAX17040 is not set
# CONFIG_BATTERY_MAX17042 is not set
# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_CHARGER_LP8727 is not set
# CONFIG_CHARGER_GPIO is not set
+# CONFIG_CHARGER_SMB347 is not set
+# CONFIG_POWER_AVS is not set
# CONFIG_HWMON is not set
CONFIG_THERMAL=y
CONFIG_THERMAL_BCM2835=y
@@ -1625,19 +1723,23 @@ CONFIG_BCMA_POSSIBLE=y
#
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_88PM800 is not set
+# CONFIG_MFD_88PM805 is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_MFD_ASIC3 is not set
# CONFIG_HTC_EGPIO is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_HTC_I2CPLD is not set
+# CONFIG_MFD_LM3533 is not set
# CONFIG_TPS6105X is not set
# CONFIG_TPS65010 is not set
# CONFIG_TPS6507X is not set
-# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_TPS65217 is not set
# CONFIG_MFD_TPS65910 is not set
# CONFIG_MFD_TPS65912_I2C is not set
# CONFIG_MFD_TPS65912_SPI is not set
# CONFIG_TWL4030_CORE is not set
+# CONFIG_TWL6040_CORE is not set
# CONFIG_MFD_STMPE is not set
# CONFIG_MFD_TC3589X is not set
# CONFIG_MFD_TMIO is not set
@@ -1645,466 +1747,47 @@ CONFIG_BCMA_POSSIBLE=y
# CONFIG_MFD_TC6387XB is not set
# CONFIG_MFD_TC6393XB is not set
# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_DA9052_I2C is not set
# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX77686 is not set
+# CONFIG_MFD_MAX77693 is not set
# CONFIG_MFD_MAX8925 is not set
# CONFIG_MFD_MAX8997 is not set
# CONFIG_MFD_MAX8998 is not set
+# CONFIG_MFD_SEC_CORE is not set
+# CONFIG_MFD_ARIZONA_I2C is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM831X_I2C is not set
# CONFIG_MFD_WM831X_SPI is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_WM8994 is not set
# CONFIG_MFD_PCF50633 is not set
-# CONFIG_MFD_MC13XXX is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_MFD_MC13XXX_I2C is not set
# CONFIG_ABX500_CORE is not set
# CONFIG_EZX_PCAP is not set
# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_TPS65090 is not set
# CONFIG_MFD_AAT2870_CORE is not set
+# CONFIG_MFD_RC5T583 is not set
+# CONFIG_MFD_PALMAS is not set
# CONFIG_REGULATOR is not set
CONFIG_MEDIA_SUPPORT=m
#
# Multimedia core support
#
-# CONFIG_MEDIA_CONTROLLER is not set
-CONFIG_VIDEO_DEV=m
-CONFIG_VIDEO_V4L2_COMMON=m
-CONFIG_DVB_CORE=m
-CONFIG_DVB_NET=y
-CONFIG_VIDEO_MEDIA=m
-
-#
-# Multimedia drivers
-#
-CONFIG_RC_CORE=m
-CONFIG_LIRC=m
-CONFIG_RC_MAP=m
-CONFIG_IR_NEC_DECODER=m
-CONFIG_IR_RC5_DECODER=m
-CONFIG_IR_RC6_DECODER=m
-CONFIG_IR_JVC_DECODER=m
-CONFIG_IR_SONY_DECODER=m
-CONFIG_IR_RC5_SZ_DECODER=m
-CONFIG_IR_MCE_KBD_DECODER=m
-CONFIG_IR_LIRC_CODEC=m
-CONFIG_RC_ATI_REMOTE=m
-CONFIG_IR_IMON=m
-CONFIG_IR_MCEUSB=m
-CONFIG_IR_REDRAT3=m
-CONFIG_IR_STREAMZAP=m
-CONFIG_RC_LOOPBACK=m
-CONFIG_MEDIA_ATTACH=y
-CONFIG_MEDIA_TUNER=m
-CONFIG_MEDIA_TUNER_CUSTOMISE=y
-
-#
-# Customize TV tuners
-#
-CONFIG_MEDIA_TUNER_SIMPLE=m
-CONFIG_MEDIA_TUNER_TDA8290=m
-CONFIG_MEDIA_TUNER_TDA827X=m
-CONFIG_MEDIA_TUNER_TDA18271=m
-CONFIG_MEDIA_TUNER_TDA9887=m
-CONFIG_MEDIA_TUNER_TEA5761=m
-CONFIG_MEDIA_TUNER_TEA5767=m
-CONFIG_MEDIA_TUNER_MT20XX=m
-CONFIG_MEDIA_TUNER_MT2060=m
-CONFIG_MEDIA_TUNER_MT2266=m
-CONFIG_MEDIA_TUNER_MT2131=m
-CONFIG_MEDIA_TUNER_QT1010=m
-CONFIG_MEDIA_TUNER_XC2028=m
-CONFIG_MEDIA_TUNER_XC5000=m
-CONFIG_MEDIA_TUNER_XC4000=m
-CONFIG_MEDIA_TUNER_MXL5005S=m
-CONFIG_MEDIA_TUNER_MXL5007T=m
-CONFIG_MEDIA_TUNER_MC44S803=m
-CONFIG_MEDIA_TUNER_MAX2165=m
-CONFIG_MEDIA_TUNER_TDA18218=m
-CONFIG_MEDIA_TUNER_TDA18212=m
-CONFIG_VIDEO_V4L2=m
-CONFIG_VIDEOBUF_GEN=m
-CONFIG_VIDEOBUF_VMALLOC=m
-CONFIG_VIDEOBUF_DVB=m
-CONFIG_VIDEO_TVEEPROM=m
-CONFIG_VIDEO_TUNER=m
-CONFIG_VIDEOBUF2_CORE=m
-CONFIG_VIDEOBUF2_MEMOPS=m
-CONFIG_VIDEOBUF2_VMALLOC=m
-CONFIG_VIDEO_CAPTURE_DRIVERS=y
-# CONFIG_VIDEO_ADV_DEBUG is not set
-# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
-# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
-CONFIG_VIDEO_IR_I2C=m
-
-#
-# Encoders, decoders, sensors and other helper chips
-#
-
-#
-# Audio decoders, processors and mixers
-#
-# CONFIG_VIDEO_TVAUDIO is not set
-# CONFIG_VIDEO_TDA7432 is not set
-# CONFIG_VIDEO_TDA9840 is not set
-# CONFIG_VIDEO_TEA6415C is not set
-# CONFIG_VIDEO_TEA6420 is not set
-CONFIG_VIDEO_MSP3400=m
-# CONFIG_VIDEO_CS5345 is not set
-CONFIG_VIDEO_CS53L32A=m
-# CONFIG_VIDEO_TLV320AIC23B is not set
-CONFIG_VIDEO_WM8775=m
-# CONFIG_VIDEO_WM8739 is not set
-# CONFIG_VIDEO_VP27SMPX is not set
-
-#
-# RDS decoders
-#
-# CONFIG_VIDEO_SAA6588 is not set
-
-#
-# Video decoders
-#
-# CONFIG_VIDEO_ADV7180 is not set
-# CONFIG_VIDEO_BT819 is not set
-# CONFIG_VIDEO_BT856 is not set
-# CONFIG_VIDEO_BT866 is not set
-# CONFIG_VIDEO_KS0127 is not set
-# CONFIG_VIDEO_SAA7110 is not set
-CONFIG_VIDEO_SAA711X=m
-# CONFIG_VIDEO_SAA7191 is not set
-# CONFIG_VIDEO_TVP514X is not set
-# CONFIG_VIDEO_TVP5150 is not set
-# CONFIG_VIDEO_TVP7002 is not set
-# CONFIG_VIDEO_VPX3220 is not set
-
-#
-# Video and audio decoders
-#
-# CONFIG_VIDEO_SAA717X is not set
-CONFIG_VIDEO_CX25840=m
-
-#
-# MPEG video encoders
-#
-CONFIG_VIDEO_CX2341X=m
-
-#
-# Video encoders
-#
-# CONFIG_VIDEO_SAA7127 is not set
-# CONFIG_VIDEO_SAA7185 is not set
-# CONFIG_VIDEO_ADV7170 is not set
-# CONFIG_VIDEO_ADV7175 is not set
-# CONFIG_VIDEO_ADV7343 is not set
-# CONFIG_VIDEO_AK881X is not set
-
-#
-# Camera sensor devices
-#
-# CONFIG_VIDEO_OV7670 is not set
-# CONFIG_VIDEO_MT9V011 is not set
-# CONFIG_VIDEO_TCM825X is not set
-# CONFIG_VIDEO_SR030PC30 is not set
-
-#
-# Flash devices
-#
-
-#
-# Video improvement chips
-#
-# CONFIG_VIDEO_UPD64031A is not set
-# CONFIG_VIDEO_UPD64083 is not set
-
-#
-# Miscelaneous helper chips
-#
-# CONFIG_VIDEO_THS7303 is not set
-# CONFIG_VIDEO_M52790 is not set
-# CONFIG_VIDEO_VIVI is not set
-# CONFIG_VIDEO_CPIA2 is not set
-# CONFIG_VIDEO_AU0828 is not set
-# CONFIG_SOC_CAMERA is not set
-CONFIG_V4L_USB_DRIVERS=y
-CONFIG_USB_VIDEO_CLASS=m
-CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
-CONFIG_USB_GSPCA=m
-CONFIG_USB_M5602=m
-CONFIG_USB_STV06XX=m
-CONFIG_USB_GL860=m
-CONFIG_USB_GSPCA_BENQ=m
-CONFIG_USB_GSPCA_CONEX=m
-CONFIG_USB_GSPCA_CPIA1=m
-CONFIG_USB_GSPCA_ETOMS=m
-CONFIG_USB_GSPCA_FINEPIX=m
-CONFIG_USB_GSPCA_JEILINJ=m
-CONFIG_USB_GSPCA_KINECT=m
-CONFIG_USB_GSPCA_KONICA=m
-CONFIG_USB_GSPCA_MARS=m
-CONFIG_USB_GSPCA_MR97310A=m
-CONFIG_USB_GSPCA_NW80X=m
-CONFIG_USB_GSPCA_OV519=m
-CONFIG_USB_GSPCA_OV534=m
-CONFIG_USB_GSPCA_OV534_9=m
-CONFIG_USB_GSPCA_PAC207=m
-CONFIG_USB_GSPCA_PAC7302=m
-CONFIG_USB_GSPCA_PAC7311=m
-CONFIG_USB_GSPCA_SE401=m
-CONFIG_USB_GSPCA_SN9C2028=m
-CONFIG_USB_GSPCA_SN9C20X=m
-CONFIG_USB_GSPCA_SONIXB=m
-CONFIG_USB_GSPCA_SONIXJ=m
-CONFIG_USB_GSPCA_SPCA500=m
-CONFIG_USB_GSPCA_SPCA501=m
-CONFIG_USB_GSPCA_SPCA505=m
-CONFIG_USB_GSPCA_SPCA506=m
-CONFIG_USB_GSPCA_SPCA508=m
-CONFIG_USB_GSPCA_SPCA561=m
-CONFIG_USB_GSPCA_SPCA1528=m
-CONFIG_USB_GSPCA_SQ905=m
-CONFIG_USB_GSPCA_SQ905C=m
-CONFIG_USB_GSPCA_SQ930X=m
-CONFIG_USB_GSPCA_STK014=m
-CONFIG_USB_GSPCA_STV0680=m
-CONFIG_USB_GSPCA_SUNPLUS=m
-CONFIG_USB_GSPCA_T613=m
-# CONFIG_USB_GSPCA_TOPRO is not set
-CONFIG_USB_GSPCA_TV8532=m
-CONFIG_USB_GSPCA_VC032X=m
-CONFIG_USB_GSPCA_VICAM=m
-CONFIG_USB_GSPCA_XIRLINK_CIT=m
-CONFIG_USB_GSPCA_ZC3XX=m
-CONFIG_VIDEO_PVRUSB2=m
-CONFIG_VIDEO_PVRUSB2_SYSFS=y
-CONFIG_VIDEO_PVRUSB2_DVB=y
-# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
-CONFIG_VIDEO_HDPVR=m
-CONFIG_VIDEO_EM28XX=m
-CONFIG_VIDEO_EM28XX_ALSA=m
-CONFIG_VIDEO_EM28XX_DVB=m
-CONFIG_VIDEO_EM28XX_RC=y
-CONFIG_VIDEO_TLG2300=m
-CONFIG_VIDEO_CX231XX=m
-CONFIG_VIDEO_CX231XX_RC=y
-CONFIG_VIDEO_CX231XX_ALSA=m
-CONFIG_VIDEO_CX231XX_DVB=m
-# CONFIG_VIDEO_TM6000 is not set
-CONFIG_VIDEO_USBVISION=m
-CONFIG_USB_ET61X251=m
-CONFIG_USB_SN9C102=m
-CONFIG_USB_PWC=m
-# CONFIG_USB_PWC_DEBUG is not set
-CONFIG_USB_PWC_INPUT_EVDEV=y
-CONFIG_USB_ZR364XX=m
-CONFIG_USB_STKWEBCAM=m
-CONFIG_USB_S2255=m
-# CONFIG_V4L_MEM2MEM_DRIVERS is not set
-CONFIG_RADIO_ADAPTERS=y
-# CONFIG_I2C_SI4713 is not set
-# CONFIG_RADIO_SI4713 is not set
-CONFIG_USB_DSBR=m
-CONFIG_RADIO_SI470X=y
-CONFIG_USB_SI470X=m
-# CONFIG_I2C_SI470X is not set
-CONFIG_USB_MR800=m
-# CONFIG_RADIO_TEA5764 is not set
-# CONFIG_RADIO_SAA7706H is not set
-# CONFIG_RADIO_TEF6862 is not set
-# CONFIG_RADIO_WL1273 is not set
-
-#
-# Texas Instruments WL128x FM driver (ST based)
-#
-CONFIG_DVB_MAX_ADAPTERS=8
-# CONFIG_DVB_DYNAMIC_MINORS is not set
-CONFIG_DVB_CAPTURE_DRIVERS=y
-# CONFIG_TTPCI_EEPROM is not set
-
-#
-# Supported USB Adapters
-#
-CONFIG_DVB_USB=m
-# CONFIG_DVB_USB_DEBUG is not set
-CONFIG_DVB_USB_A800=m
-CONFIG_DVB_USB_DIBUSB_MB=m
-# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
-CONFIG_DVB_USB_DIBUSB_MC=m
-CONFIG_DVB_USB_DIB0700=m
-CONFIG_DVB_USB_UMT_010=m
-CONFIG_DVB_USB_CXUSB=m
-CONFIG_DVB_USB_M920X=m
-CONFIG_DVB_USB_GL861=m
-CONFIG_DVB_USB_AU6610=m
-CONFIG_DVB_USB_DIGITV=m
-CONFIG_DVB_USB_VP7045=m
-CONFIG_DVB_USB_VP702X=m
-CONFIG_DVB_USB_GP8PSK=m
-CONFIG_DVB_USB_NOVA_T_USB2=m
-CONFIG_DVB_USB_TTUSB2=m
-CONFIG_DVB_USB_DTT200U=m
-CONFIG_DVB_USB_OPERA1=m
-CONFIG_DVB_USB_AF9005=m
-CONFIG_DVB_USB_AF9005_REMOTE=m
-# CONFIG_DVB_USB_PCTV452E is not set
-CONFIG_DVB_USB_DW2102=m
-CONFIG_DVB_USB_CINERGY_T2=m
-CONFIG_DVB_USB_ANYSEE=m
-CONFIG_DVB_USB_DTV5100=m
-CONFIG_DVB_USB_AF9015=m
-CONFIG_DVB_USB_CE6230=m
-CONFIG_DVB_USB_FRIIO=m
-CONFIG_DVB_USB_EC168=m
-CONFIG_DVB_USB_AZ6027=m
-CONFIG_DVB_USB_LME2510=m
-CONFIG_DVB_USB_TECHNISAT_USB2=m
-# CONFIG_DVB_USB_IT913X is not set
-# CONFIG_DVB_USB_MXL111SF is not set
-CONFIG_SMS_SIANO_MDTV=m
-
-#
-# Siano module components
-#
-CONFIG_SMS_USB_DRV=m
-# CONFIG_SMS_SDIO_DRV is not set
-
-#
-# Supported FlexCopII (B2C2) Adapters
-#
-CONFIG_DVB_B2C2_FLEXCOP=m
-CONFIG_DVB_B2C2_FLEXCOP_USB=m
-# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set
-
-#
-# Supported DVB Frontends
-#
-CONFIG_DVB_FE_CUSTOMISE=y
-
-#
-# Customise DVB Frontends
-#
-
-#
-# Multistandard (satellite) frontends
-#
-CONFIG_DVB_STB0899=m
-CONFIG_DVB_STB6100=m
-CONFIG_DVB_STV090x=m
-CONFIG_DVB_STV6110x=m
-
-#
-# Multistandard (cable + terrestrial) frontends
-#
-CONFIG_DVB_DRXK=m
-CONFIG_DVB_TDA18271C2DD=m
-
-#
-# DVB-S (satellite) frontends
-#
-CONFIG_DVB_CX24110=m
-CONFIG_DVB_CX24123=m
-CONFIG_DVB_MT312=m
-CONFIG_DVB_ZL10036=m
-CONFIG_DVB_ZL10039=m
-CONFIG_DVB_S5H1420=m
-CONFIG_DVB_STV0288=m
-CONFIG_DVB_STB6000=m
-CONFIG_DVB_STV0299=m
-CONFIG_DVB_STV6110=m
-CONFIG_DVB_STV0900=m
-CONFIG_DVB_TDA8083=m
-CONFIG_DVB_TDA10086=m
-CONFIG_DVB_TDA8261=m
-CONFIG_DVB_VES1X93=m
-CONFIG_DVB_TUNER_ITD1000=m
-CONFIG_DVB_TUNER_CX24113=m
-CONFIG_DVB_TDA826X=m
-CONFIG_DVB_TUA6100=m
-CONFIG_DVB_CX24116=m
-CONFIG_DVB_SI21XX=m
-CONFIG_DVB_DS3000=m
-CONFIG_DVB_MB86A16=m
-CONFIG_DVB_TDA10071=m
-
-#
-# DVB-T (terrestrial) frontends
-#
-CONFIG_DVB_SP8870=m
-CONFIG_DVB_SP887X=m
-CONFIG_DVB_CX22700=m
-CONFIG_DVB_CX22702=m
-CONFIG_DVB_S5H1432=m
-CONFIG_DVB_DRXD=m
-CONFIG_DVB_L64781=m
-CONFIG_DVB_TDA1004X=m
-CONFIG_DVB_NXT6000=m
-CONFIG_DVB_MT352=m
-CONFIG_DVB_ZL10353=m
-CONFIG_DVB_DIB3000MB=m
-CONFIG_DVB_DIB3000MC=m
-CONFIG_DVB_DIB7000M=m
-CONFIG_DVB_DIB7000P=m
-CONFIG_DVB_DIB9000=m
-CONFIG_DVB_TDA10048=m
-CONFIG_DVB_AF9013=m
-CONFIG_DVB_EC100=m
-CONFIG_DVB_STV0367=m
-CONFIG_DVB_CXD2820R=m
+# CONFIG_MEDIA_CAMERA_SUPPORT is not set
+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
+# CONFIG_MEDIA_RADIO_SUPPORT is not set
+# CONFIG_MEDIA_RC_SUPPORT is not set
#
-# DVB-C (cable) frontends
-#
-CONFIG_DVB_VES1820=m
-CONFIG_DVB_TDA10021=m
-CONFIG_DVB_TDA10023=m
-CONFIG_DVB_STV0297=m
-
-#
-# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
-#
-CONFIG_DVB_NXT200X=m
-CONFIG_DVB_OR51211=m
-CONFIG_DVB_OR51132=m
-CONFIG_DVB_BCM3510=m
-CONFIG_DVB_LGDT330X=m
-CONFIG_DVB_LGDT3305=m
-CONFIG_DVB_S5H1409=m
-CONFIG_DVB_AU8522=m
-CONFIG_DVB_S5H1411=m
-
-#
-# ISDB-T (terrestrial) frontends
-#
-CONFIG_DVB_S921=m
-CONFIG_DVB_DIB8000=m
-CONFIG_DVB_MB86A20S=m
-
-#
-# Digital terrestrial only tuners/PLL
-#
-CONFIG_DVB_PLL=m
-CONFIG_DVB_TUNER_DIB0070=m
-CONFIG_DVB_TUNER_DIB0090=m
-
+# Media drivers
#
-# SEC control devices for DVB-S
-#
-CONFIG_DVB_LNBP21=m
-CONFIG_DVB_LNBP22=m
-CONFIG_DVB_ISL6405=m
-CONFIG_DVB_ISL6421=m
-CONFIG_DVB_ISL6423=m
-CONFIG_DVB_A8293=m
-CONFIG_DVB_LGS8GL5=m
-CONFIG_DVB_LGS8GXX=m
-CONFIG_DVB_ATBM8830=m
-CONFIG_DVB_TDA665x=m
-CONFIG_DVB_IX2505V=m
-CONFIG_DVB_IT913X_FE=m
-
-#
-# Tools to develop new frontends
-#
-# CONFIG_DVB_DUMMY_FE is not set
#
# Graphics support
@@ -2144,6 +1827,8 @@ CONFIG_FB_BCM2708=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_BROADSHEET is not set
+# CONFIG_FB_AUO_K190X is not set
+# CONFIG_EXYNOS_VIDEO is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=m
# CONFIG_LCD_L4F00242T03 is not set
@@ -2159,11 +1844,7 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=m
CONFIG_BACKLIGHT_GENERIC=m
# CONFIG_BACKLIGHT_ADP8860 is not set
# CONFIG_BACKLIGHT_ADP8870 is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_BACKLIGHT_LP855X is not set
#
# Console display driver support
@@ -2201,6 +1882,7 @@ CONFIG_SND_SUPPORT_OLD_API=y
CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
CONFIG_SND_RAWMIDI_SEQ=m
# CONFIG_SND_OPL3_LIB_SEQ is not set
# CONFIG_SND_OPL4_LIB_SEQ is not set
@@ -2226,16 +1908,15 @@ CONFIG_SND_USB_CAIAQ=m
CONFIG_SND_USB_6FIRE=m
# CONFIG_SND_SOC is not set
CONFIG_SOUND_PRIME=m
-CONFIG_HID_SUPPORT=y
-CONFIG_HID=y
-# CONFIG_HIDRAW is not set
#
-# USB Input Devices
+# HID support
#
-CONFIG_USB_HID=y
-CONFIG_HID_PID=y
-CONFIG_USB_HIDDEV=y
+CONFIG_HID=y
+# CONFIG_HID_BATTERY_STRENGTH is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+CONFIG_HID_GENERIC=y
#
# Special HID drivers
@@ -2244,6 +1925,7 @@ CONFIG_HID_A4TECH=m
CONFIG_HID_ACRUX=m
# CONFIG_HID_ACRUX_FF is not set
CONFIG_HID_APPLE=m
+# CONFIG_HID_AUREAL is not set
CONFIG_HID_BELKIN=m
CONFIG_HID_CHERRY=m
CONFIG_HID_CHICONY=m
@@ -2264,6 +1946,7 @@ CONFIG_HID_GYRATION=m
CONFIG_HID_TWINHAN=m
CONFIG_HID_KENSINGTON=m
CONFIG_HID_LCPOWER=m
+# CONFIG_HID_LENOVO_TPKBD is not set
CONFIG_HID_LOGITECH=m
CONFIG_HID_LOGITECH_DJ=m
# CONFIG_LOGITECH_FF is not set
@@ -2285,14 +1968,8 @@ CONFIG_HID_PICOLCD=m
# CONFIG_HID_PICOLCD_LCD is not set
# CONFIG_HID_PICOLCD_LEDS is not set
# CONFIG_HID_PRIMAX is not set
-CONFIG_HID_QUANTA=m
CONFIG_HID_ROCCAT=m
-CONFIG_HID_ROCCAT_COMMON=m
-# CONFIG_HID_ROCCAT_ARVO is not set
-# CONFIG_HID_ROCCAT_KONE is not set
-# CONFIG_HID_ROCCAT_KONEPLUS is not set
-# CONFIG_HID_ROCCAT_KOVAPLUS is not set
-# CONFIG_HID_ROCCAT_PYRA is not set
+# CONFIG_HID_SAITEK is not set
CONFIG_HID_SAMSUNG=m
CONFIG_HID_SONY=m
CONFIG_HID_SPEEDLINK=m
@@ -2301,21 +1978,29 @@ CONFIG_HID_GREENASIA=m
# CONFIG_GREENASIA_FF is not set
CONFIG_HID_SMARTJOYPLUS=m
# CONFIG_SMARTJOYPLUS_FF is not set
+# CONFIG_HID_TIVO is not set
CONFIG_HID_TOPSEED=m
CONFIG_HID_THRUSTMASTER=m
# CONFIG_THRUSTMASTER_FF is not set
CONFIG_HID_WACOM=m
-# CONFIG_HID_WACOM_POWER_SUPPLY is not set
CONFIG_HID_WIIMOTE=m
+CONFIG_HID_WIIMOTE_EXT=y
CONFIG_HID_ZEROPLUS=m
# CONFIG_ZEROPLUS_FF is not set
CONFIG_HID_ZYDACRON=m
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_ARCH_HAS_HCD=y
+
+#
+# USB HID support
+#
+CONFIG_USB_HID=y
+CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=y
# CONFIG_USB_ARCH_HAS_OHCI is not set
# CONFIG_USB_ARCH_HAS_EHCI is not set
# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
@@ -2323,14 +2008,10 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
#
# Miscellaneous USB options
#
-# CONFIG_USB_DEVICEFS is not set
-CONFIG_USB_DEVICE_CLASS=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
-# CONFIG_USB_DWC3 is not set
CONFIG_USB_MON=m
-# CONFIG_USB_WUSB is not set
# CONFIG_USB_WUSB_CBAF is not set
#
@@ -2344,8 +2025,9 @@ CONFIG_USB_MON=m
# CONFIG_USB_U132_HCD is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
-# CONFIG_USB_HWA_HCD is not set
CONFIG_USB_DWCOTG=y
+# CONFIG_USB_HCD_SSB is not set
+# CONFIG_USB_CHIPIDEA is not set
#
# USB Device Class drivers
@@ -2408,6 +2090,7 @@ CONFIG_USB_SERIAL_IPAQ=m
CONFIG_USB_SERIAL_IR=m
CONFIG_USB_SERIAL_EDGEPORT=m
CONFIG_USB_SERIAL_EDGEPORT_TI=m
+# CONFIG_USB_SERIAL_F81232 is not set
CONFIG_USB_SERIAL_GARMIN=m
CONFIG_USB_SERIAL_IPW=m
CONFIG_USB_SERIAL_IUU=m
@@ -2428,6 +2111,7 @@ CONFIG_USB_SERIAL_KEYSPAN=m
CONFIG_USB_SERIAL_KLSI=m
CONFIG_USB_SERIAL_KOBIL_SCT=m
CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_METRO is not set
CONFIG_USB_SERIAL_MOS7720=m
CONFIG_USB_SERIAL_MOS7840=m
CONFIG_USB_SERIAL_MOTOROLA=m
@@ -2453,6 +2137,7 @@ CONFIG_USB_SERIAL_OPTICON=m
CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m
CONFIG_USB_SERIAL_ZIO=m
CONFIG_USB_SERIAL_SSU100=m
+CONFIG_USB_SERIAL_QT2=m
CONFIG_USB_SERIAL_DEBUG=m
#
@@ -2477,6 +2162,11 @@ CONFIG_USB_IOWARRIOR=m
CONFIG_USB_TEST=m
CONFIG_USB_ISIGHTFW=m
CONFIG_USB_YUREX=m
+
+#
+# USB Physical Layer drivers
+#
+# CONFIG_USB_ISP1301 is not set
# CONFIG_USB_GADGET is not set
#
@@ -2510,35 +2200,39 @@ CONFIG_MMC_SDHCI_PLTFM=y
# CONFIG_MMC_SDHCI_PXAV2 is not set
CONFIG_MMC_SDHCI_BCM2708=y
CONFIG_MMC_SDHCI_BCM2708_DMA=y
-# CONFIG_MMC_BCM2708 is not set
# CONFIG_MMC_SPI is not set
# CONFIG_MMC_DW is not set
# CONFIG_MMC_VUB300 is not set
# CONFIG_MMC_USHC is not set
# CONFIG_MEMSTICK is not set
CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_CLASS=m
#
# LED drivers
#
# CONFIG_LEDS_LM3530 is not set
# CONFIG_LEDS_PCA9532 is not set
-CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO=m
# CONFIG_LEDS_LP3944 is not set
# CONFIG_LEDS_LP5521 is not set
# CONFIG_LEDS_LP5523 is not set
# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_PCA9633 is not set
# CONFIG_LEDS_DAC124S085 is not set
# CONFIG_LEDS_BD2802 is not set
# CONFIG_LEDS_LT3593 is not set
-# CONFIG_LEDS_RENESAS_TPU is not set
+# CONFIG_LEDS_TCA6507 is not set
+# CONFIG_LEDS_LM3556 is not set
+# CONFIG_LEDS_OT200 is not set
+# CONFIG_LEDS_BLINKM is not set
CONFIG_LEDS_TRIGGERS=y
#
# LED Triggers
#
CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_ONESHOT=m
CONFIG_LEDS_TRIGGER_HEARTBEAT=m
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
# CONFIG_LEDS_TRIGGER_GPIO is not set
@@ -2547,7 +2241,9 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
#
# iptables trigger is under Netfilter config (LED target)
#
+CONFIG_LEDS_TRIGGER_TRANSIENT=m
# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
@@ -2633,25 +2329,24 @@ CONFIG_UIO_PDRV_GENIRQ=m
#
# CONFIG_VIRTIO_BALLOON is not set
# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
CONFIG_STAGING=y
# CONFIG_USBIP_CORE is not set
CONFIG_W35UND=m
CONFIG_PRISM2_USB=m
# CONFIG_ECHO is not set
# CONFIG_ASUS_OLED is not set
+# CONFIG_RTLLIB is not set
CONFIG_R8712U=m
# CONFIG_RTS5139 is not set
# CONFIG_TRANZPORT is not set
-# CONFIG_POHMELFS is not set
# CONFIG_LINE6_USB is not set
# CONFIG_USB_SERIAL_QUATECH2 is not set
-# CONFIG_USB_SERIAL_QUATECH_USB2 is not set
# CONFIG_VT6656 is not set
-# CONFIG_IIO is not set
-CONFIG_XVMALLOC=y
-CONFIG_ZRAM=m
-# CONFIG_ZRAM_DEBUG is not set
-# CONFIG_FB_SM7XX is not set
+# CONFIG_ZSMALLOC is not set
# CONFIG_USB_ENESTORAGE is not set
# CONFIG_BCM_WIMAX is not set
# CONFIG_FT1000 is not set
@@ -2663,18 +2358,41 @@ CONFIG_ZRAM=m
# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
# CONFIG_STAGING_MEDIA is not set
+
+#
+# Android
+#
+# CONFIG_ANDROID is not set
+# CONFIG_PHONE is not set
+# CONFIG_USB_WPAN_HCD is not set
+# CONFIG_IPACK_BUS is not set
+# CONFIG_WIMAX_GDM72XX is not set
+# CONFIG_CSR_WIFI is not set
CONFIG_CLKDEV_LOOKUP=y
#
# Hardware Spinlock drivers
#
# CONFIG_IOMMU_SUPPORT is not set
+
+#
+# Remoteproc drivers (EXPERIMENTAL)
+#
+
+#
+# Rpmsg drivers (EXPERIMENTAL)
+#
# CONFIG_VIRT_DRIVERS is not set
# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
+# CONFIG_IIO is not set
+# CONFIG_PWM is not set
#
# File systems
#
+CONFIG_DCACHE_WORD_ACCESS=y
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
CONFIG_EXT4_FS=y
@@ -2703,7 +2421,6 @@ CONFIG_XFS_POSIX_ACL=y
CONFIG_XFS_RT=y
# CONFIG_XFS_DEBUG is not set
CONFIG_GFS2_FS=m
-# CONFIG_GFS2_FS_LOCKING_DLM is not set
CONFIG_OCFS2_FS=m
CONFIG_OCFS2_FS_O2CB=m
CONFIG_OCFS2_FS_STATS=y
@@ -2711,6 +2428,7 @@ CONFIG_OCFS2_DEBUG_MASKLOG=y
# CONFIG_OCFS2_DEBUG_FS is not set
CONFIG_BTRFS_FS=m
CONFIG_BTRFS_FS_POSIX_ACL=y
+# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
CONFIG_NILFS2_FS=m
CONFIG_FS_POSIX_ACL=y
CONFIG_EXPORTFS=y
@@ -2801,32 +2519,36 @@ CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_PSTORE is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
+CONFIG_NFS_V2=y
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
+# CONFIG_NFS_SWAP is not set
# CONFIG_NFS_V4_1 is not set
CONFIG_ROOT_NFS=y
CONFIG_NFS_FSCACHE=y
# CONFIG_NFS_USE_LEGACY_DNS is not set
CONFIG_NFS_USE_KERNEL_DNS=y
-# CONFIG_NFS_USE_NEW_IDMAPPER is not set
CONFIG_NFSD=m
CONFIG_NFSD_V2_ACL=y
CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
+# CONFIG_NFSD_FAULT_INJECTION is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_ACL_SUPPORT=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_DEBUG is not set
# CONFIG_CEPH_FS is not set
CONFIG_CIFS=m
# CONFIG_CIFS_STATS is not set
@@ -2844,28 +2566,6 @@ CONFIG_CIFS_POSIX=y
CONFIG_9P_FS=m
# CONFIG_9P_FSCACHE is not set
CONFIG_9P_FS_POSIX_ACL=y
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-CONFIG_MAC_PARTITION=y
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-CONFIG_EFI_PARTITION=y
-# CONFIG_SYSV68_PARTITION is not set
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="utf8"
CONFIG_NLS_CODEPAGE_437=y
@@ -2905,6 +2605,17 @@ CONFIG_NLS_ISO8859_14=m
CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
+# CONFIG_NLS_MAC_ROMAN is not set
+# CONFIG_NLS_MAC_CELTIC is not set
+# CONFIG_NLS_MAC_CENTEURO is not set
+# CONFIG_NLS_MAC_CROATIAN is not set
+# CONFIG_NLS_MAC_CYRILLIC is not set
+# CONFIG_NLS_MAC_GAELIC is not set
+# CONFIG_NLS_MAC_GREEK is not set
+# CONFIG_NLS_MAC_ICELAND is not set
+# CONFIG_NLS_MAC_INUIT is not set
+# CONFIG_NLS_MAC_ROMANIAN is not set
+# CONFIG_NLS_MAC_TURKISH is not set
CONFIG_NLS_UTF8=m
# CONFIG_DLM is not set
@@ -2918,6 +2629,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_READABLE_ASM is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
@@ -2926,6 +2638,8 @@ CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
# CONFIG_LOCKUP_DETECTOR is not set
# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
@@ -2962,14 +2676,15 @@ CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_CREDENTIALS is not set
CONFIG_BOOT_PRINTK_DELAY=y
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_TRACE is not set
# CONFIG_KPROBES_SANITY_TEST is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_LKDTM is not set
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
# CONFIG_FAULT_INJECTION is not set
CONFIG_LATENCYTOP=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
# CONFIG_DEBUG_PAGEALLOC is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
@@ -2991,6 +2706,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_STACK_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_KPROBE_EVENT is not set
+# CONFIG_PROBE_EVENTS is not set
# CONFIG_RING_BUFFER_BENCHMARK is not set
# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_DMA_API_DEBUG is not set
@@ -3010,6 +2726,7 @@ CONFIG_ARM_UNWIND=y
# CONFIG_DEBUG_LL is not set
# CONFIG_OC_ETM is not set
# CONFIG_ARM_KPROBES_TEST is not set
+# CONFIG_PID_IN_CONTEXTIDR is not set
#
# Security options
@@ -3138,12 +2855,21 @@ CONFIG_CRYPTO_DEFLATE=m
#
CONFIG_RAID6_PQ=m
CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
CONFIG_CRC_CCITT=m
CONFIG_CRC16=y
# CONFIG_CRC_T10DIF is not set
CONFIG_CRC_ITU_T=y
CONFIG_CRC32=y
-CONFIG_CRC7=m
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=y
# CONFIG_CRC8 is not set
CONFIG_AUDIT_GENERIC=y
@@ -3167,8 +2893,11 @@ CONFIG_TEXTSEARCH_FSM=m
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_DQL=y
CONFIG_NLATTR=y
CONFIG_GENERIC_ATOMIC64=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
CONFIG_LRU_CACHE=m
CONFIG_AVERAGE=y
# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
diff --git a/patches/linux-3.2.27/0038-net-usb-smsc95xx-fix-mtu.patch b/patches/linux-3.2.27/0038-net-usb-smsc95xx-fix-mtu.patch
deleted file mode 100644
index 10b592f..0000000
--- a/patches/linux-3.2.27/0038-net-usb-smsc95xx-fix-mtu.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From: Stephane Fillod <fillods@users.sf.net>
-Date: Fri, 20 Apr 2012 09:39:23 +0000
-Subject: [PATCH] net: usb: smsc95xx: fix mtu
-
-Make smsc95xx recalculate the hard_mtu after adjusting the
-hard_header_len.
-
-Without this, usbnet adjusts the MTU down to 1488 bytes, and the host is
-unable to receive standard 1500-byte frames from the device.
-
-Inspired by same fix on cdc_eem 78fb72f7936c01d5b426c03a691eca082b03f2b9.
-
-Tested on ARM/Beagle.
-
-Signed-off-by: Stephane Fillod <fillods@users.sf.net>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/usb/smsc95xx.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
-index da34dc8..5d2fec2 100644
---- a/drivers/net/usb/smsc95xx.c
-+++ b/drivers/net/usb/smsc95xx.c
-@@ -1072,6 +1072,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
- dev->net->ethtool_ops = &smsc95xx_ethtool_ops;
- dev->net->flags |= IFF_MULTICAST;
- dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM;
-+ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
- return 0;
- }
-
diff --git a/patches/linux-3.2.27/0057-mmc-use-really-long-write-timeout-to-deal-with-crapp.patch b/patches/linux-3.2.27/0057-mmc-use-really-long-write-timeout-to-deal-with-crapp.patch
deleted file mode 100644
index 475ba64..0000000
--- a/patches/linux-3.2.27/0057-mmc-use-really-long-write-timeout-to-deal-with-crapp.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From: Paul Walmsley <paul@pwsan.com>
-Date: Mon, 12 Mar 2012 10:58:00 -0600
-Subject: [PATCH] mmc: use really long write timeout to deal with crappy cards
-
-mmc: use really long write timeout to deal with crappy cards
-
-Several people have noticed that crappy SD cards take much longer to
-complete multiple block writes than the 300ms that Linux specifies.
-Try to work around this by using a three second write timeout instead.
-
-This is a generalized version of a patch from Chase Maupin
-<Chase.Maupin@ti.com>, whose patch description said:
-
-* With certain SD cards timeouts like the following have been seen
- due to an improper calculation of the dto value:
- mmcblk0: error -110 transferring data, sector 4126233, nr 8,
- card status 0xc00
-* By removing the dto calculation and setting the timeout value
- to the maximum specified by the SD card specification part A2
- section 2.2.15 these timeouts can be avoided.
-* This change has been used by beagleboard users as well as the
- Texas Instruments SDK without a negative impact.
-* There are multiple discussion threads about this but the most
- relevant ones are:
- * http://talk.maemo.org/showthread.php?p=1000707#post1000707
- * http://www.mail-archive.com/linux-omap@vger.kernel.org/msg42213.html
-* Original proposal for this fix was done by Sukumar Ghoral of
- Texas Instruments
-* Tested using a Texas Instruments AM335x EVM
-
-Signed-off-by: Paul Walmsley <paul@pwsan.com>
-Tested-by: Tony Lindgren <tony@atomide.com>
-Signed-off-by: Chris Ball <cjb@laptop.org>
----
- drivers/mmc/core/core.c | 10 +++++++---
- 1 file changed, 7 insertions(+), 3 deletions(-)
-
-diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
-index 411a994..ad08933 100644
---- a/drivers/mmc/core/core.c
-+++ b/drivers/mmc/core/core.c
-@@ -514,10 +514,14 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
-
- if (data->flags & MMC_DATA_WRITE)
- /*
-- * The limit is really 250 ms, but that is
-- * insufficient for some crappy cards.
-+ * The MMC spec "It is strongly recommended
-+ * for hosts to implement more than 500ms
-+ * timeout value even if the card indicates
-+ * the 250ms maximum busy length." Even the
-+ * previous value of 300ms is known to be
-+ * insufficient for some cards.
- */
-- limit_us = 300000;
-+ limit_us = 3000000;
- else
- limit_us = 100000;
-
diff --git a/patches/linux-3.2.27/0144-Fix-for-KALLSYMS_EXTRA_PASS-requirement.-Thanks-asb-.patch b/patches/linux-3.2.27/0144-Fix-for-KALLSYMS_EXTRA_PASS-requirement.-Thanks-asb-.patch
deleted file mode 100644
index ac7066a..0000000
--- a/patches/linux-3.2.27/0144-Fix-for-KALLSYMS_EXTRA_PASS-requirement.-Thanks-asb-.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From: popcornmix <popcornmix@gmail.com>
-Date: Tue, 11 Sep 2012 00:58:31 +0100
-Subject: [PATCH] Fix for KALLSYMS_EXTRA_PASS requirement. Thanks asb for
- finding this.
-
----
- arch/arm/kernel/vmlinux.lds.S | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
-index 20b3041..e952a30 100644
---- a/arch/arm/kernel/vmlinux.lds.S
-+++ b/arch/arm/kernel/vmlinux.lds.S
-@@ -174,7 +174,9 @@ SECTIONS
- }
- #endif
-
-+#ifdef CONFIG_SMP
- PERCPU_SECTION(32)
-+#endif
-
- #ifdef CONFIG_XIP_KERNEL
- __data_loc = ALIGN(4); /* location in binary */
diff --git a/patches/linux-3.2.27/0201-Release-raspberrypi-20120915.patch b/patches/linux-3.2.27/0201-Release-raspberrypi-20120915.patch
deleted file mode 100644
index abfb916..0000000
--- a/patches/linux-3.2.27/0201-Release-raspberrypi-20120915.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Jan Luebbe <jluebbe@debian.org>
-Date: Sat, 15 Sep 2012 21:39:27 +0200
-Subject: [PATCH] Release raspberrypi/20120915
-
-Signed-off-by: Jan Luebbe <jluebbe@debian.org>
----
- Makefile | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/Makefile b/Makefile
-index bdf851f..18f2efc 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1,7 +1,7 @@
- VERSION = 3
- PATCHLEVEL = 2
- SUBLEVEL = 27
--EXTRAVERSION =
-+EXTRAVERSION =-20120915
- NAME = Saber-toothed Squirrel
-
- # *DOCUMENTATION*
diff --git a/patches/linux-3.2.27/series b/patches/linux-3.2.27/series
deleted file mode 100644
index 38ccd68..0000000
--- a/patches/linux-3.2.27/series
+++ /dev/null
@@ -1,157 +0,0 @@
-# umpf-base: v3.2.27
-# umpf-name: raspberrypi
-# umpf-version: raspberrypi/20120915
-# umpf-topic: rpi-3.2.27
-# umpf-hashinfo: ce4ab6222b47270b1597ce3cd7c0a354346d348d
-# umpf-topic-range: 8524c7870680e93cb3d8f1d3f90f927c3c0686b6..97fce38cde710b9e4d6c7a17a484deacfc3d25b6
-0001-Add-dwc_otg-driver.patch
-0002-Main-bcm2708-linux-port.patch
-0003-bcm2708-watchdog-driver.patch
-0004-bcm2708-framebuffer-driver.patch
-0005-bcm2708-vchiq-driver.patch
-0006-Allow-mac-address-to-be-set-in-smsc95xx.patch
-0007-Fix-headers-for-vchiq-vcos-to-be-GPLv2.patch
-0008-Fix-some-issues-reported.-Lower-case-module-paramete.patch
-0009-Build-anything-reasonable-as-a-module.-Thanks-to-asb.patch
-0010-Add-config-option-to-enable-L2-cache.patch
-0011-Fix-bug-where-vchiq-fails-when-L2-enabled.patch
-0012-Add-devtmpfs-for-archlinux-and-emergency-and-debug-c.patch
-0013-Fix-32bpp-framebuffer-by-adding-alpha-bits.patch
-0014-Enable-L2-cache-is-now-the-default.-Invert-sense-of-.patch
-0015-Allow-24bpp-for-framebuffer.patch
-0016-Disable-debug-code-in-dwc_otg-driver-unless-CONFIG_U.patch
-0017-Enable-high-resolution-timers.patch
-0018-Fix-for-mmc-timeouts-when-erasing-multiple-blocks.patch
-0019-Fix-problem-with-dma-that-could-corrupt-sdcard-espec.patch
-0020-Update-to-match-latest-vc-side-vchiq.-Allows-vchiq-c.patch
-0021-First-pass-at-alsa-sound-driver.-Some-functionality-.patch
-0022-Cast-to-avoid-warning.patch
-0023-Add-new-ioctl-to-match-latest-vc-side-code.patch
-0024-Enable-sound-kernel-modules.-Tidy-formatting.-Fix-ct.patch
-0025-Add-missing-header-file-update-for-vc_mem-iocts.patch
-0026-Remove-most-of-the-alsa-debug-messages.patch
-0027-add-temporary-workaround-for-fbset-crashes.patch
-0028-Fix-harmless-base-size-typo.patch
-0029-Replace-if-1-sections-by-local-configuration-defines.patch
-0030-Don-t-send-data-block-when-emitting-silence.patch
-0031-Fix-hopefully-for-DWC_MEMCPY-kernel-panics.-Thanks-t.patch
-0032-Build-modules-needed-for-USB-booting-into-kernel.patch
-0033-Whitespace-tidy.-Thanks-Roger.patch
-0034-Update-vchiq-to-match-GPU-version.-Should-still-be-c.patch
-0035-added-support-for-TT-in-the-USB-driver.-Thanks-Naren.patch
-0036-Swap-Red-and-Blue-over-in-32bpp-framebuffer-mode.patch
-0037-Update-emergency-config-to-match-latest-debug-one.patch
-0038-net-usb-smsc95xx-fix-mtu.patch
-0039-Use-dwc_alloc_atomic.-Thanks-bootc.patch
-0040-possible-fix-for-sdcard-missing-status.-Thank-naren.patch
-0041-Fix-BUG-in-bcm2708_fb_set_par-doesn-t-work-if-the-co.patch
-0042-Fix-for-DWC-OTG-HCD-URB-Dequeue-has-NULL-URB-panic.-.patch
-0043-Fix-for-bug-in-mbox_read.-Thanks-lp0.patch
-0044-Add-__VCCOREVER__-to-makefile.patch
-0045-Change-PHYS_OFFSET-to-PLAT_PHYS_OFFSET.patch
-0046-sdcard-patch-improvements-from-naren.patch
-0047-Invert-sense-of-sdcard-access-trigger-OK-LED-so-it-i.patch
-0048-Added-power-off-message-to-allow-kexec-to-work.-Than.patch
-0049-remove-unwanted-file.patch
-0050-Enable-PREEMPT-and-SCHED_AUTOGROUP.patch
-0051-Added-support-for-USB-webcams.patch
-0052-Enable-ipv6-due-to-popular-demand.patch
-0053-Fix-regression-in-debug-kernel-config-options.patch
-0054-bcm2835-ctl-fix-alsamixer-control.patch
-0055-bcm2835-ctl-limit-maximal-volume-to-4db.patch
-0056-Add-iptables-and-devtmpfs_mount-to-non-cutdown-confi.patch
-0057-mmc-use-really-long-write-timeout-to-deal-with-crapp.patch
-0058-sdhci-bcm2708-speed-up-DMA-sync.patch
-0059-sdhci-bcm2708-remove-custom-clock-handling.patch
-0060-sdhci-bcm2708-add-additional-quirks.patch
-0061-sdhci-bcm2708-add-allow_highspeed-parameter.patch
-0062-sdhci-bcm2708-assume-50-MHz-eMMC-clock.patch
-0063-Allow-emmc-clock-to-be-specified-as-command-line-par.patch
-0064-sdhci-bcm2708-raise-DMA-sync-timeout.patch
-0065-Fix-bool-int-error.patch
-0066-Fix-bool-int-error-part-2.patch
-0067-More-config-options-for-iptables-device-mapper-PPP_M.patch
-0068-Explicitly-set-usb-host-channels-to-8-as-in-the-spec.patch
-0069-Add-hfs-hfsplus-modules.patch
-0070-Remove-silence-method-and-use-atomic-flags-for-kmall.patch
-0071-Fix-unintended-line-swap-that-cause-cause-memory-lea.patch
-0072-Use-ndelay-rather-than-udelay.-Thanks-lb.patch
-0073-Add-NFSD.-Add-some-dvb-options.-Add-CONFIG_LOCALVERS.patch
-0074-Fixed-issue-with-some-keyboards-giving-too-much-data.patch
-0075-Add-802.1q-vlan-module.patch
-0076-Add-interrupt-support-to-gpio-driver.-Thanks-Mrkva.patch
-0077-Add-a-pm_power_off-function-that-resets-us-and-indic.patch
-0078-Store-palette-info-where-GPU-can-see-it-so-8bpp-mode.patch
-0079-Avoid-blanking-console-when-not-in-palettised-mode.patch
-0080-Add-mechanism-to-reduce-the-number-of-SOF-interrupts.patch
-0081-Updating-dwc_otg-driver-to-fix-issue-releasing-pcm-s.patch
-0082-Backport-of-Chris-Boot-s-i2c-and-spi-drivers.patch
-0083-forgotten-files.patch
-0084-Enable-I2C-and-SPI-modules-in-full-config.patch
-0085-Possible-fix-for-failure-to-boot-with-compressed-ker.patch
-0086-Another-try-at-fixing-compressed-kernel-booting.patch
-0087-Add-missing-UART0_CLOCK-from-last-commit.patch
-0088-Change-to-add-SCSI-tape-support-as-loadable-modules-.patch
-0089-Add-temporary-fix-for-hang-when-quitting-X.patch
-0090-Better-fix-for-quitting-X-hang.-Interrupted-mailbox-.patch
-0091-Add-sync_after_dma-module-parameter.patch
-0092-Add-SPI_SPI_DEV-module.patch
-0093-Fix-var.width-var.height.-They-actually-mean-display.patch
-0094-The-TIMER_PERIOD-should-be-calculated-using-the-time.patch
-0095-update-bcmrpi_defconfig-with-various-user-requests.patch
-0096-Possible-fix-for-USB-packets-going-missing.-Thank-gs.patch
-0097-Revert-Possible-fix-for-USB-packets-going-missing.-T.patch
-0098-dwc_common_port-remove-unused-cruft-with-onerous-dep.patch
-0099-arm-remove-divdi3-it-s-not-necessary-at-all.patch
-0100-Remove-some-patch-backup-files.patch
-0101-mach-bcm2708-fix-mach-debug-macro.S-so-that-early-pr.patch
-0102-sound-arm-bcm2835.c-add-linux-module.h-include.patch
-0103-vcos-add-linux-kernel.h-include.patch
-0104-bcm2708-update-for-3.2-kernel.patch
-0105-bcm2708-use-a-constant-SC_MULT-SC_SHIFT.patch
-0106-Sync-with-bootc-s-file.patch
-0107-sdhci-bcm2708-use-extension-FIFO-to-buffer-DMA-trans.patch
-0108-sdhci-bcm2708-use-multiblock-type-transfers-for-sing.patch
-0109-Add-module-parameter-for-missing_status-quirk.-sdhci.patch
-0110-Some-fixed-for-ALSA.-Mute-and-volume-changing-should.patch
-0111-Fix-spinlock-recursion-in-sdhci-bcm2708.c.patch
-0112-Revert-Add-mechanism-to-reduce-the-number-of-SOF-int.patch
-0113-Enable-CONFIG_CRYPTO_XTS.patch
-0114-Update-Synopsys-USB-OTG-driver-to-v2.94a-and-disable.patch
-0115-Merged-in-microframe-scheduler-currently-disabled.-E.patch
-0116-Make-microframe-schedule-patch-a-little-closer-to-de.patch
-0117-Remove-remove-documentation-from-the-source-tree.patch
-0118-Fix-for-broken-GPIO-with-3.2-kernel.patch
-0119-Revert-Disable-IRQs-in-dwc_otg_hcd_qh_free-because-D.patch
-0120-Regenerate-defconfigs-for-udpated-kernel-verision.patch
-0121-Another-fix-for-10-second-hang-on-closing-sound-driv.patch
-0122-amba-pl011-Don-t-send-a-character-during-startup.patch
-0123-Revert-Regenerate-defconfigs-for-udpated-kernel-veri.patch
-0124-Regenerate-defconfigs-for-updated-kernel-verision-tr.patch
-0125-Read-memory-size-for-vc_mem-through-mailbox-property.patch
-0126-Revert-amba-pl011-Don-t-send-a-character-during-star.patch
-0127-Update-to-dwc_otg-3.00.-Seems-to-be-a-very-minor-upd.patch
-0128-enabling-the-realtime-clock-1-wire-chip-DS1307-and-1.patch
-0129-Switch-of-tracing-options-in-kernel.-Costs-20-in-ipe.patch
-0130-Turn-on-microframe_schedule-by-default.-Can-still-be.patch
-0131-Add-low-latency-mode-to-sdcard-driver.-Enable-with-s.patch
-0132-Fix-build-for-non-preempt-case.-Fix-warning.patch
-0133-Add-config-options-to-allow-iotop-to-run.patch
-0134-Fix-for-vmalloc-failure-with-modprobe-and-cutdown-ke.patch
-0135-Enable-low-latency-mode-by-default-in-sdcard-driver..patch
-0136-Add-FIQ-patch-to-dwc_otg-driver.-Enable-with-dwc_otg.patch
-0137-Fix-typo.patch
-0138-Add-non-mainline-source-for-rtl8188cu-wireless-drive.patch
-0139-Add-verious-user-config-requests.patch
-0140-Don-t-believe-KDIR-is-required-when-building-as-part.patch
-0141-Avoid-dynamic-memory-allocation-for-channel-lock-in-.patch
-0142-Add-cpufreq-driver.patch
-0143-Tidy-up-debug-messages.patch
-0144-Fix-for-KALLSYMS_EXTRA_PASS-requirement.-Thanks-asb-.patch
-0145-Enable-fiq-fix-by-default.-Add-NAK-holdoff-scheme.-E.patch
-0146-Added-hwmon-thermal-driver-for-reporting-core-temper.patch
-0147-Add-config-options-for-thermal-sensor-L2TP-RT2800USB.patch
-# umpf-release: raspberrypi/20120915
-# umpf-topic-range: 97fce38cde710b9e4d6c7a17a484deacfc3d25b6..9fd2c1aa3e6e8a6b43ebbd6fce020dce02efb9b5
-0201-Release-raspberrypi-20120915.patch
-# umpf-end
diff --git a/patches/linux-3.2.27/0001-Add-dwc_otg-driver.patch b/patches/linux-3.6.7/0001-Add-dwc_otg-driver.patch
index 35996ed..5bd8795 100644
--- a/patches/linux-3.2.27/0001-Add-dwc_otg-driver.patch
+++ b/patches/linux-3.6.7/0001-Add-dwc_otg-driver.patch
@@ -6,7 +6,7 @@ Signed-off-by: popcornmix <popcornmix@gmail.com>
---
drivers/usb/Makefile | 1 +
drivers/usb/core/generic.c | 1 +
- drivers/usb/core/hub.c | 61 +-
+ drivers/usb/core/hub.c | 58 +-
drivers/usb/core/message.c | 79 +
drivers/usb/core/otg_whitelist.h | 172 +-
drivers/usb/gadget/Kconfig | 28 +
@@ -345,7 +345,7 @@ Signed-off-by: popcornmix <popcornmix@gmail.com>
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 +
- 341 files changed, 124761 insertions(+), 69 deletions(-)
+ 341 files changed, 124758 insertions(+), 69 deletions(-)
create mode 100644 drivers/usb/host/dwc_common_port/Makefile
create mode 100644 drivers/usb/host/dwc_common_port/Makefile.linux
create mode 100644 drivers/usb/host/dwc_common_port/doc/doxygen.cfg
@@ -680,10 +680,10 @@ Signed-off-by: popcornmix <popcornmix@gmail.com>
create mode 100644 drivers/usb/host/dwc_otg/test/test_sysfs.pl
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
-index 75eca76..a6b7e41 100644
+index f5ed3d7..15cde5c 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
-@@ -23,6 +23,7 @@ obj-$(CONFIG_USB_U132_HCD) += host/
+@@ -25,6 +25,7 @@ obj-$(CONFIG_USB_U132_HCD) += host/
obj-$(CONFIG_USB_R8A66597_HCD) += host/
obj-$(CONFIG_USB_HWA_HCD) += host/
obj-$(CONFIG_USB_ISP1760_HCD) += host/
@@ -704,10 +704,10 @@ index 69ecd3c..0431b4e 100644
return i;
}
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
-index 52340cc..e00d65f 100644
+index fe7faf0..a3d4646 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
-@@ -24,7 +24,6 @@
+@@ -25,7 +25,6 @@
#include <linux/kthread.h>
#include <linux/mutex.h>
#include <linux/freezer.h>
@@ -715,24 +715,7 @@ index 52340cc..e00d65f 100644
#include <asm/uaccess.h>
#include <asm/byteorder.h>
-@@ -1076,6 +1075,8 @@ static int hub_configure(struct usb_hub *hub,
- INIT_WORK(&hub->tt.clear_work, hub_tt_work);
- switch (hdev->descriptor.bDeviceProtocol) {
- case 0:
-+ dev_dbg(hub_dev, "TT with no hub-specific protocol - "
-+ "no TT\n");
- break;
- case 1:
- dev_dbg(hub_dev, "Single TT\n");
-@@ -1092,6 +1093,7 @@ static int hub_configure(struct usb_hub *hub,
- hub->tt.hub = hdev;
- break;
- case 3:
-+ dev_dbg(hub_dev, "USB 3.0 hub - no TT\n");
- /* USB 3.0 hubs don't have a TT */
- break;
- default:
-@@ -1721,6 +1723,12 @@ static inline void announce_device(struct usb_device *udev) { }
+@@ -1973,6 +1972,12 @@ static inline void announce_device(struct usb_device *udev) { }
#endif
#ifdef CONFIG_USB_OTG
@@ -745,7 +728,7 @@ index 52340cc..e00d65f 100644
#include "otg_whitelist.h"
#endif
-@@ -1775,9 +1783,15 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
+@@ -2027,9 +2032,15 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
dev_info(&udev->dev,
"can't set HNP mode: %d\n",
err);
@@ -762,7 +745,7 @@ index 52340cc..e00d65f 100644
}
}
-@@ -1786,12 +1800,27 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
+@@ -2038,12 +2049,27 @@ static int usb_enumerate_device_otg(struct usb_device *udev)
/* Maybe it can talk to us, though we can't talk to it.
* (Includes HNP test device.)
*/
@@ -793,7 +776,7 @@ index 52340cc..e00d65f 100644
goto fail;
}
fail:
-@@ -1898,14 +1927,6 @@ int usb_new_device(struct usb_device *udev)
+@@ -2185,14 +2211,6 @@ int usb_new_device(struct usb_device *udev)
/* Tell the world! */
announce_device(udev);
@@ -806,9 +789,9 @@ index 52340cc..e00d65f 100644
- strlen(udev->manufacturer));
-
device_enable_async_suspend(&udev->dev);
- /* Register the device. The device driver is responsible
- * for configuring the device and invoking the add-device
-@@ -2442,9 +2463,9 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
+
+ /*
+@@ -2813,9 +2831,9 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
status = 0;
} else {
/* device has up to 10 msec to fully suspend */
@@ -820,7 +803,7 @@ index 52340cc..e00d65f 100644
usb_set_device_state(udev, USB_STATE_SUSPENDED);
msleep(10);
}
-@@ -2994,7 +3015,9 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
+@@ -3819,7 +3837,9 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
buf->bMaxPacketSize0 = 0;
r = usb_control_msg(udev, usb_rcvaddr0pipe(),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
@@ -831,7 +814,7 @@ index 52340cc..e00d65f 100644
buf, GET_DESCRIPTOR_BUFSIZE,
initial_descriptor_timeout);
switch (buf->bMaxPacketSize0) {
-@@ -3440,8 +3463,10 @@ loop:
+@@ -4271,8 +4291,10 @@ loop:
release_devnum(udev);
hub_free_dev(udev);
usb_put_dev(udev);
@@ -845,10 +828,10 @@ index 52340cc..e00d65f 100644
if (hub->hdev->parent ||
!hcd->driver->port_handed_over ||
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
-index ef116a5..113b44e 100644
+index 0ab7da2..84e6595 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
-@@ -1838,6 +1838,85 @@ free_interfaces:
+@@ -1877,6 +1877,85 @@ free_interfaces:
if (cp->string == NULL &&
!(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
cp->string = usb_cache_string(dev, cp->desc.iConfiguration);
@@ -932,8 +915,8 @@ index ef116a5..113b44e 100644
+ }
+#endif /* DWC_HS_ELECT_TST */
- /* Now that all the interfaces are set up, register them
- * to trigger binding of drivers to interfaces. probe()
+ /* Now that the interfaces are installed, re-enable LPM. */
+ usb_unlocked_enable_lpm(dev);
diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h
index e8cdce5..3a0da17 100644
--- a/drivers/usb/core/otg_whitelist.h
@@ -1155,11 +1138,11 @@ index e8cdce5..3a0da17 100644
}
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
-index 23a4473..c50eebf 100644
+index 51ab5fd..9f5c8dc 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
-@@ -552,6 +552,34 @@ config USB_GADGET_SUPERSPEED
- depends on USB_GADGET
+@@ -505,6 +505,34 @@ config USB_GADGET_SUPERSPEED
+ bool
depends on USB_GADGET_DUALSPEED
+config USB_GADGET_SNPS_DWC_OTG
@@ -1194,7 +1177,7 @@ index 23a4473..c50eebf 100644
# USB Gadget Drivers
#
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
-index db2d607..5090ae6 100644
+index a896d73..18ae481 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -573,8 +573,37 @@ config_desc = {
@@ -1266,7 +1249,7 @@ index db2d607..5090ae6 100644
break;
/* One config, two speeds */
-@@ -2640,6 +2685,9 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
+@@ -2650,6 +2695,9 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
fsg_set_halt(fsg, fsg->bulk_out);
halt_bulk_in_endpoint(fsg);
}
@@ -1276,7 +1259,7 @@ index db2d607..5090ae6 100644
return -EINVAL;
}
-@@ -2991,7 +3039,8 @@ static void handle_exception(struct fsg_dev *fsg)
+@@ -3011,7 +3059,8 @@ static void handle_exception(struct fsg_dev *fsg)
* bulk endpoint, clear the halt now. (The SuperH UDC
* requires this.) */
if (test_and_clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags))
@@ -1286,7 +1269,7 @@ index db2d607..5090ae6 100644
if (transport_is_bbb()) {
if (fsg->ep0_req_tag == exception_req_tag)
-@@ -3065,6 +3114,9 @@ static int fsg_main_thread(void *fsg_)
+@@ -3085,6 +3134,9 @@ static int fsg_main_thread(void *fsg_)
* that expects a __user pointer and it will work okay. */
set_fs(get_ds());
@@ -1296,7 +1279,7 @@ index db2d607..5090ae6 100644
/* The main loop */
while (fsg->state != FSG_STATE_TERMINATED) {
if (exception_in_progress(fsg) || signal_pending(current)) {
-@@ -3212,6 +3264,13 @@ static int __init check_parameters(struct fsg_dev *fsg)
+@@ -3232,6 +3284,13 @@ static int __init check_parameters(struct fsg_dev *fsg)
gcnum = usb_gadget_controller_number(fsg->gadget);
if (gcnum >= 0)
mod_data.release = 0x0300 + gcnum;
@@ -1310,7 +1293,7 @@ index db2d607..5090ae6 100644
else {
WARNING(fsg, "controller '%s' not recognized\n",
fsg->gadget->name);
-@@ -3473,6 +3532,13 @@ static int __init fsg_bind(struct usb_gadget *gadget)
+@@ -3493,6 +3552,13 @@ static int __init fsg_bind(struct usb_gadget *gadget)
rc = -ENOMEM;
@@ -1325,10 +1308,10 @@ index db2d607..5090ae6 100644
fsg->ep0req = req = usb_ep_alloc_request(fsg->ep0, GFP_KERNEL);
if (!req)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
-index 060e0e2..c03ee48 100644
+index 075d2ec..b257ac2 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
-@@ -556,6 +556,19 @@ config USB_HWA_HCD
+@@ -610,6 +610,19 @@ config USB_HWA_HCD
To compile this driver a module, choose M here: the module
will be called "hwa-hc".
@@ -1349,10 +1332,10 @@ index 060e0e2..c03ee48 100644
tristate "i.MX21 HCD support"
depends on USB && ARM && ARCH_MXC
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
-index 7ca290f..802dda6 100644
+index 9e0a89c..f767684 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
-@@ -33,6 +33,8 @@ obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o
+@@ -37,6 +37,8 @@ obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o
obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o
obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o
@@ -47794,7 +47777,7 @@ index 0000000..11bddbc
+</html>
diff --git a/drivers/usb/host/dwc_otg/doc/html/dwc__otg__hcd__if_8h.html b/drivers/usb/host/dwc_otg/doc/html/dwc__otg__hcd__if_8h.html
new file mode 100644
-index 0000000..3bb51aa1
+index 0000000..3bb51aa
--- /dev/null
+++ b/drivers/usb/host/dwc_otg/doc/html/dwc__otg__hcd__if_8h.html
@@ -0,0 +1,1381 @@
@@ -73456,7 +73439,7 @@ index 0000000..b6be1be
+</html>
diff --git a/drivers/usb/host/dwc_otg/doc/html/functions_vars_0x71.html b/drivers/usb/host/dwc_otg/doc/html/functions_vars_0x71.html
new file mode 100644
-index 0000000..65a9066f
+index 0000000..65a9066
--- /dev/null
+++ b/drivers/usb/host/dwc_otg/doc/html/functions_vars_0x71.html
@@ -0,0 +1,71 @@
diff --git a/patches/linux-3.2.27/0002-Main-bcm2708-linux-port.patch b/patches/linux-3.6.7/0002-Main-bcm2708-linux-port.patch
index 4f3a7cd..778dff6 100644
--- a/patches/linux-3.2.27/0002-Main-bcm2708-linux-port.patch
+++ b/patches/linux-3.6.7/0002-Main-bcm2708-linux-port.patch
@@ -6,7 +6,7 @@ Signed-off-by: popcornmix <popcornmix@gmail.com>
---
arch/arm/Kconfig | 14 +
arch/arm/Makefile | 1 +
- arch/arm/boot/compressed/Makefile | 8 +-
+ arch/arm/boot/compressed/Makefile | 7 +-
arch/arm/boot/compressed/divdi3.c | 338 +++++
arch/arm/boot/compressed/longlong.h | 151 ++
arch/arm/configs/bcmrpi_cutdown_defconfig | 1558 ++++++++++++++++++++
@@ -59,10 +59,10 @@ Signed-off-by: popcornmix <popcornmix@gmail.com>
drivers/mmc/host/bcm2708_mci.c | 889 +++++++++++
drivers/mmc/host/bcm2708_mci.h | 101 ++
drivers/mmc/host/sdhci-bcm2708.c | 1461 ++++++++++++++++++
- drivers/mmc/host/sdhci.c | 284 ++--
+ drivers/mmc/host/sdhci.c | 290 ++--
drivers/mmc/host/sdhci.h | 42 +
include/linux/mmc/sdhci.h | 2 +
- 58 files changed, 10184 insertions(+), 93 deletions(-)
+ 58 files changed, 10189 insertions(+), 93 deletions(-)
create mode 100644 arch/arm/boot/compressed/divdi3.c
create mode 100644 arch/arm/boot/compressed/longlong.h
create mode 100644 arch/arm/configs/bcmrpi_cutdown_defconfig
@@ -109,10 +109,10 @@ Signed-off-by: popcornmix <popcornmix@gmail.com>
create mode 100644 drivers/mmc/host/sdhci-bcm2708.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index 987c72d..39b3d55 100644
+index 48c19d4..fd48798 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
-@@ -955,6 +955,19 @@ config PLAT_SPEAR
+@@ -998,6 +998,19 @@ config PLAT_SPEAR
help
Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).
@@ -132,7 +132,7 @@ index 987c72d..39b3d55 100644
config ARCH_VT8500
bool "VIA/WonderMedia 85xx"
select CPU_ARM926T
-@@ -1098,6 +1111,7 @@ source "arch/arm/plat-versatile/Kconfig"
+@@ -1132,6 +1145,7 @@ source "arch/arm/plat-versatile/Kconfig"
source "arch/arm/mach-vt8500/Kconfig"
source "arch/arm/mach-w90x900/Kconfig"
@@ -141,7 +141,7 @@ index 987c72d..39b3d55 100644
# Definitions to make life easier
config ARCH_ACORN
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
-index dfcf3b0..1b18ede 100644
+index a051dfb..179a2e5 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -198,6 +198,7 @@ machine-$(CONFIG_MACH_SPEAR310) := spear3xx
@@ -153,10 +153,10 @@ index dfcf3b0..1b18ede 100644
# Platform directory name. This list is sorted alphanumerically
# by CONFIG_* macro name.
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
-index 21f56ff..02d4943 100644
+index bb26756..08bc871 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
-@@ -145,11 +145,17 @@ LDFLAGS_vmlinux += -X
+@@ -149,7 +149,7 @@ LDFLAGS_vmlinux += -X
LDFLAGS_vmlinux += -T
# For __aeabi_uidivmod
@@ -165,16 +165,18 @@ index 21f56ff..02d4943 100644
$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
$(call cmd,shipped)
+@@ -158,6 +158,11 @@ $(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
+ ashldi3 = $(obj)/ashldi3.o
+ $(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S
++
+$(obj)/longlong.h: $(srctree)/arch/$(SRCARCH)/lib/longlong.h FORCE
+ $(call cmd,shipped)
+
+$(obj)/divdi3.c: $(srctree)/arch/$(SRCARCH)/lib/divdi3.c $(obj)/longlong.h FORCE
-+ $(call cmd,shipped)
-+
+ $(call cmd,shipped)
+
# We need to prevent any GOTOFF relocs being used with references
- # to symbols in the .bss section since we cannot relocate them
- # independently from the rest at run time. This can be achieved by
diff --git a/arch/arm/boot/compressed/divdi3.c b/arch/arm/boot/compressed/divdi3.c
new file mode 100644
index 0000000..0848d21
@@ -2241,10 +2243,10 @@ index 0000000..4862854
+# CONFIG_AVERAGE is not set
+# CONFIG_CORDIC is not set
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
-index 5b0bce6..9a93886 100644
+index 60d3b73..7b2fa74 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
-@@ -46,6 +46,8 @@ extern void __aeabi_lmul(void);
+@@ -45,6 +45,8 @@ extern void __aeabi_lmul(void);
extern void __aeabi_uidiv(void);
extern void __aeabi_uidivmod(void);
extern void __aeabi_ulcmp(void);
@@ -2253,7 +2255,7 @@ index 5b0bce6..9a93886 100644
extern void fpundefinstr(void);
-@@ -131,6 +133,8 @@ EXPORT_SYMBOL(__aeabi_lmul);
+@@ -125,6 +127,8 @@ EXPORT_SYMBOL(__aeabi_lmul);
EXPORT_SYMBOL(__aeabi_uidiv);
EXPORT_SYMBOL(__aeabi_uidivmod);
EXPORT_SYMBOL(__aeabi_ulcmp);
@@ -2263,15 +2265,15 @@ index 5b0bce6..9a93886 100644
/* bitops */
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
-index cf73a7f..e917b9e 100644
+index af72969..26d01af 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -13,7 +13,8 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
- testchangebit.o testclearbit.o testsetbit.o \
ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
ucmpdi2.o lib1funcs.o div64.o \
-- io-readsb.o io-writesb.o io-readsl.o io-writesl.o
-+ io-readsb.o io-writesb.o io-readsl.o io-writesl.o \
+ io-readsb.o io-writesb.o io-readsl.o io-writesl.o \
+- call_with_stack.o
++ call_with_stack.o \
+ divdi3.o
mmu-y := clear_user.o copy_page.o getuser.o putuser.o
@@ -7883,10 +7885,10 @@ index 0000000..b7d1e14
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:bcm-mbox");
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
-index 67f75a0..2c9ec3c 100644
+index 101b968..a93a41e 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
-@@ -390,7 +390,7 @@ config CPU_PJ4
+@@ -354,7 +354,7 @@ config CPU_PJ4
# ARMv6
config CPU_V6
@@ -7896,10 +7898,10 @@ index 67f75a0..2c9ec3c 100644
select CPU_ABRT_EV6
select CPU_PABRT_V6
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
-index c335c76..118b667 100644
+index 9107231..87d2468 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
-@@ -855,9 +855,11 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+@@ -856,9 +856,11 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
case 0x08000000: /* ldm or stm, or thumb-2 32bit instruction */
if (thumb2_32b)
handler = do_alignment_t32_to_handler(&instr, regs, &offset);
@@ -7914,10 +7916,10 @@ index c335c76..118b667 100644
default:
goto bad;
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
-index d061d2f..436dc2c 100644
+index 86b8b48..dc86b85 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
-@@ -70,10 +70,19 @@ ENTRY(cpu_v6_reset)
+@@ -73,10 +73,19 @@ ENDPROC(cpu_v6_reset)
*
* IRQs are already disabled.
*/
@@ -7941,7 +7943,7 @@ index d061d2f..436dc2c 100644
ENTRY(cpu_v6_dcache_clean_area)
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
-index cf444b0..f8feea6 100644
+index aa131b3..5f7bde5 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -229,6 +229,27 @@ config MMC_SDHCI_S3C_DMA
@@ -7972,7 +7974,7 @@ index cf444b0..f8feea6 100644
config MMC_OMAP
tristate "TI OMAP Multimedia Card Interface support"
depends on ARCH_OMAP
-@@ -296,6 +317,14 @@ config MMC_ATMELMCI
+@@ -299,6 +320,14 @@ config MMC_ATMELMCI
If unsure, say N.
endchoice
@@ -7988,7 +7990,7 @@ index cf444b0..f8feea6 100644
config MMC_ATMELMCI_DMA
bool "Atmel MCI DMA support"
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
-index b4b83f3..eeb683c 100644
+index 8922b06..79fe195 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o
@@ -8006,7 +8008,7 @@ index b4b83f3..eeb683c 100644
+obj-$(CONFIG_MMC_BCM2708) += bcm2708_mci.o
obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o
obj-$(CONFIG_MMC_DW) += dw_mmc.o
- obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o
+ obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o
diff --git a/drivers/mmc/host/bcm2708_mci.c b/drivers/mmc/host/bcm2708_mci.c
new file mode 100644
index 0000000..3c7de96
@@ -10477,18 +10479,18 @@ index 0000000..2dd6bed
+MODULE_ALIAS("platform:"DRIVER_NAME);
+
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
-index 6ce32a7..aeda16a 100644
+index b1facf9..e206890 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
-@@ -27,6 +27,7 @@
-
+@@ -28,6 +28,7 @@
#include <linux/mmc/mmc.h>
#include <linux/mmc/host.h>
+ #include <linux/mmc/card.h>
+#include <linux/mmc/sd.h>
#include "sdhci.h"
-@@ -296,7 +297,7 @@ static void sdhci_read_block_pio(struct sdhci_host *host)
+@@ -313,7 +314,7 @@ static void sdhci_read_block_pio(struct sdhci_host *host)
u32 uninitialized_var(scratch);
u8 *buf;
@@ -10497,7 +10499,7 @@ index 6ce32a7..aeda16a 100644
blksize = host->data->blksz;
chunk = 0;
-@@ -341,7 +342,7 @@ static void sdhci_write_block_pio(struct sdhci_host *host)
+@@ -358,7 +359,7 @@ static void sdhci_write_block_pio(struct sdhci_host *host)
u32 scratch;
u8 *buf;
@@ -10506,7 +10508,7 @@ index 6ce32a7..aeda16a 100644
blksize = host->data->blksz;
chunk = 0;
-@@ -380,19 +381,28 @@ static void sdhci_write_block_pio(struct sdhci_host *host)
+@@ -397,19 +398,28 @@ static void sdhci_write_block_pio(struct sdhci_host *host)
local_irq_restore(flags);
}
@@ -10538,7 +10540,7 @@ index 6ce32a7..aeda16a 100644
/*
* Some controllers (JMicron JMB38x) mess up the buffer bits
-@@ -403,7 +413,7 @@ static void sdhci_transfer_pio(struct sdhci_host *host)
+@@ -420,7 +430,7 @@ static void sdhci_transfer_pio(struct sdhci_host *host)
(host->data->blocks == 1))
mask = ~0;
@@ -10547,7 +10549,7 @@ index 6ce32a7..aeda16a 100644
if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY)
udelay(100);
-@@ -415,9 +425,11 @@ static void sdhci_transfer_pio(struct sdhci_host *host)
+@@ -432,9 +442,11 @@ static void sdhci_transfer_pio(struct sdhci_host *host)
host->blocks--;
if (host->blocks == 0)
break;
@@ -10560,7 +10562,7 @@ index 6ce32a7..aeda16a 100644
}
static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags)
-@@ -690,7 +702,9 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host)
+@@ -707,7 +719,9 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host)
u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL;
u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
@@ -10571,7 +10573,7 @@ index 6ce32a7..aeda16a 100644
sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
else
sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
-@@ -722,44 +736,25 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
+@@ -739,44 +753,25 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
host->data_early = 0;
host->data->bytes_xfered = 0;
@@ -10624,7 +10626,7 @@ index 6ce32a7..aeda16a 100644
int broken, i;
struct scatterlist *sg;
-@@ -818,7 +813,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
+@@ -835,7 +830,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
*/
WARN_ON(1);
host->flags &= ~SDHCI_REQ_USE_DMA;
@@ -10634,7 +10636,7 @@ index 6ce32a7..aeda16a 100644
WARN_ON(sg_cnt != 1);
sdhci_writel(host, sg_dma_address(data->sg),
SDHCI_DMA_ADDRESS);
-@@ -834,11 +830,13 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
+@@ -851,11 +847,13 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
if (host->version >= SDHCI_SPEC_200) {
ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
ctrl &= ~SDHCI_CTRL_DMA_MASK;
@@ -10653,7 +10655,7 @@ index 6ce32a7..aeda16a 100644
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
}
-@@ -890,7 +888,8 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host,
+@@ -907,7 +905,8 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host,
if (data->flags & MMC_DATA_READ)
mode |= SDHCI_TRNS_READ;
@@ -10663,7 +10665,7 @@ index 6ce32a7..aeda16a 100644
mode |= SDHCI_TRNS_DMA;
sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
-@@ -906,13 +905,16 @@ static void sdhci_finish_data(struct sdhci_host *host)
+@@ -923,13 +922,16 @@ static void sdhci_finish_data(struct sdhci_host *host)
host->data = NULL;
if (host->flags & SDHCI_REQ_USE_DMA) {
@@ -10684,7 +10686,7 @@ index 6ce32a7..aeda16a 100644
}
/*
-@@ -965,6 +967,12 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
+@@ -982,6 +984,12 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY))
mask |= SDHCI_DATA_INHIBIT;
@@ -10697,7 +10699,7 @@ index 6ce32a7..aeda16a 100644
/* We shouldn't wait for data inihibit for stop commands, even
though they might use busy signaling */
if (host->mrq->data && (cmd == host->mrq->data->stop))
-@@ -982,10 +990,16 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
+@@ -999,10 +1007,16 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
timeout--;
mdelay(1);
}
@@ -10714,8 +10716,8 @@ index 6ce32a7..aeda16a 100644
sdhci_prepare_data(host, cmd);
-@@ -1218,6 +1232,35 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
- mdelay(10);
+@@ -1248,6 +1262,35 @@ static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
+ return power;
}
+/* Power on or off the circuitary supporting the register set */
@@ -10750,15 +10752,15 @@ index 6ce32a7..aeda16a 100644
/*****************************************************************************\
* *
* MMC callbacks *
-@@ -1298,6 +1341,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
- {
+@@ -1337,6 +1380,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
unsigned long flags;
+ int vdd_bit = -1;
u8 ctrl;
+ int rc;
spin_lock_irqsave(&host->lock, flags);
-@@ -1356,7 +1400,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
+@@ -1405,7 +1449,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
else
ctrl &= ~SDHCI_CTRL_HISPD;
@@ -10767,8 +10769,8 @@ index 6ce32a7..aeda16a 100644
u16 clk, ctrl_2;
unsigned int clock;
-@@ -1364,7 +1408,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
- if ((ios->timing == MMC_TIMING_UHS_SDR50) ||
+@@ -1414,7 +1458,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
+ (ios->timing == MMC_TIMING_UHS_SDR50) ||
(ios->timing == MMC_TIMING_UHS_SDR104) ||
(ios->timing == MMC_TIMING_UHS_DDR50) ||
- (ios->timing == MMC_TIMING_UHS_SDR25))
@@ -10777,8 +10779,8 @@ index 6ce32a7..aeda16a 100644
ctrl |= SDHCI_CTRL_HISPD;
ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-@@ -1445,6 +1490,12 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
- out:
+@@ -1496,6 +1541,12 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
+
mmiowb();
spin_unlock_irqrestore(&host->lock, flags);
+
@@ -10790,7 +10792,7 @@ index 6ce32a7..aeda16a 100644
}
static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
-@@ -1888,6 +1939,8 @@ static const struct mmc_host_ops sdhci_ops = {
+@@ -1961,6 +2012,8 @@ static const struct mmc_host_ops sdhci_ops = {
.start_signal_voltage_switch = sdhci_start_signal_voltage_switch,
.execute_tuning = sdhci_execute_tuning,
.enable_preset_value = sdhci_enable_preset_value,
@@ -10799,7 +10801,7 @@ index 6ce32a7..aeda16a 100644
};
/*****************************************************************************\
-@@ -2000,7 +2053,7 @@ static void sdhci_timeout_timer(unsigned long data)
+@@ -2073,7 +2126,7 @@ static void sdhci_timeout_timer(unsigned long data)
if (host->mrq) {
pr_err("%s: Timeout waiting for hardware "
@@ -10808,7 +10810,7 @@ index 6ce32a7..aeda16a 100644
sdhci_dumpregs(host);
if (host->data) {
-@@ -2045,10 +2098,13 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
+@@ -2118,10 +2171,13 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
BUG_ON(intmask == 0);
if (!host->cmd) {
@@ -10826,7 +10828,7 @@ index 6ce32a7..aeda16a 100644
return;
}
-@@ -2118,6 +2174,19 @@ static void sdhci_show_adma_error(struct sdhci_host *host)
+@@ -2191,6 +2247,19 @@ static void sdhci_show_adma_error(struct sdhci_host *host)
static void sdhci_show_adma_error(struct sdhci_host *host) { }
#endif
@@ -10845,8 +10847,8 @@ index 6ce32a7..aeda16a 100644
+
static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
{
- BUG_ON(intmask == 0);
-@@ -2144,34 +2213,57 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
+ u32 command;
+@@ -2219,34 +2288,57 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
return;
}
}
@@ -10919,7 +10921,7 @@ index 6ce32a7..aeda16a 100644
/*
* We currently don't do anything fancy with DMA
-@@ -2200,18 +2292,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
+@@ -2275,18 +2367,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS);
}
@@ -10940,7 +10942,7 @@ index 6ce32a7..aeda16a 100644
}
}
-@@ -2266,6 +2348,22 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
+@@ -2342,6 +2424,22 @@ again:
tasklet_schedule(&host->card_tasklet);
}
@@ -10963,7 +10965,7 @@ index 6ce32a7..aeda16a 100644
if (intmask & SDHCI_INT_CMD_MASK) {
sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
SDHCI_INT_STATUS);
-@@ -2280,7 +2378,13 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
+@@ -2356,7 +2454,13 @@ again:
intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK);
@@ -10978,17 +10980,23 @@ index 6ce32a7..aeda16a 100644
if (intmask & SDHCI_INT_BUS_POWER) {
pr_err("%s: Card is consuming too much power!\n",
-@@ -2363,7 +2467,8 @@ int sdhci_resume_host(struct sdhci_host *host)
- return ret;
- }
+@@ -2445,7 +2549,14 @@ int sdhci_resume_host(struct sdhci_host *host)
+ {
+ int ret;
- if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
++ if (host->vmmc) {
++ int ret = regulator_enable(host->vmmc);
++ if (ret)
++ return ret;
++ }
++
+ if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA |
+ SDHCI_USE_PLATDMA)) {
if (host->ops->enable_dma)
host->ops->enable_dma(host);
}
-@@ -2570,14 +2675,16 @@ int sdhci_add_host(struct sdhci_host *host)
+@@ -2663,14 +2774,16 @@ int sdhci_add_host(struct sdhci_host *host)
host->flags &= ~SDHCI_USE_ADMA;
}
@@ -11007,7 +11015,7 @@ index 6ce32a7..aeda16a 100644
}
}
}
-@@ -2688,7 +2795,7 @@ int sdhci_add_host(struct sdhci_host *host)
+@@ -2781,7 +2894,7 @@ int sdhci_add_host(struct sdhci_host *host)
/* Auto-CMD23 stuff only works in ADMA or PIO. */
if ((host->version >= SDHCI_SPEC_300) &&
((host->flags & SDHCI_USE_ADMA) ||
@@ -11016,8 +11024,8 @@ index 6ce32a7..aeda16a 100644
host->flags |= SDHCI_AUTO_CMD23;
DBG("%s: Auto-CMD23 available\n", mmc_hostname(mmc));
} else {
-@@ -2821,6 +2928,12 @@ int sdhci_add_host(struct sdhci_host *host)
- mmc->caps |= MMC_CAP_MAX_CURRENT_200;
+@@ -2933,6 +3046,12 @@ int sdhci_add_host(struct sdhci_host *host)
+ SDHCI_MAX_CURRENT_MULTIPLIER;
}
+ if(host->ops->voltage_broken) {
@@ -11029,7 +11037,7 @@ index 6ce32a7..aeda16a 100644
mmc->ocr_avail = ocr_avail;
mmc->ocr_avail_sdio = ocr_avail;
if (host->ocr_avail_sdio)
-@@ -2953,6 +3066,7 @@ int sdhci_add_host(struct sdhci_host *host)
+@@ -3063,6 +3182,7 @@ int sdhci_add_host(struct sdhci_host *host)
pr_info("%s: SDHCI controller on %s [%s] using %s\n",
mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)),
@@ -11038,10 +11046,10 @@ index 6ce32a7..aeda16a 100644
(host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO");
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
-index a04d4d0..4cc7b4b 100644
+index 97653ea..aad9454 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
-@@ -273,6 +273,25 @@ struct sdhci_ops {
+@@ -275,6 +275,25 @@ struct sdhci_ops {
void (*platform_reset_enter)(struct sdhci_host *host, u8 mask);
void (*platform_reset_exit)(struct sdhci_host *host, u8 mask);
int (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
@@ -11065,9 +11073,9 @@ index a04d4d0..4cc7b4b 100644
+ unsigned int (*missing_status)(struct sdhci_host *host);
+
void (*hw_reset)(struct sdhci_host *host);
- };
-
-@@ -379,6 +398,29 @@ extern int sdhci_resume_host(struct sdhci_host *host);
+ void (*platform_suspend)(struct sdhci_host *host);
+ void (*platform_resume)(struct sdhci_host *host);
+@@ -383,6 +402,29 @@ extern int sdhci_resume_host(struct sdhci_host *host);
extern void sdhci_enable_irq_wakeups(struct sdhci_host *host);
#endif
@@ -11098,18 +11106,18 @@ index a04d4d0..4cc7b4b 100644
extern int sdhci_runtime_suspend_host(struct sdhci_host *host);
extern int sdhci_runtime_resume_host(struct sdhci_host *host);
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
-index e4b6935..99b7eef 100644
+index ac83b10..2c83a35 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
-@@ -121,6 +121,7 @@ struct sdhci_host {
- #define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */
- #define SDHCI_PV_ENABLED (1<<8) /* Preset value enabled */
+@@ -123,6 +123,7 @@ struct sdhci_host {
#define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */
-+#define SDHCI_USE_PLATDMA (1<<10) /* Host uses 3rd party DMA */
+ #define SDHCI_HS200_NEEDS_TUNING (1<<10) /* HS200 needs tuning */
+ #define SDHCI_USING_RETUNING_TIMER (1<<11) /* Host is using a retuning timer for the card */
++#define SDHCI_USE_PLATDMA (1<<12) /* Host uses 3rd party DMA */
unsigned int version; /* SDHCI spec. version */
-@@ -135,6 +136,7 @@ struct sdhci_host {
+@@ -137,6 +138,7 @@ struct sdhci_host {
struct mmc_request *mrq; /* Current request */
struct mmc_command *cmd; /* Current command */
diff --git a/patches/linux-3.2.27/0003-bcm2708-watchdog-driver.patch b/patches/linux-3.6.7/0003-bcm2708-watchdog-driver.patch
index d68717b..b537702 100644
--- a/patches/linux-3.2.27/0003-bcm2708-watchdog-driver.patch
+++ b/patches/linux-3.6.7/0003-bcm2708-watchdog-driver.patch
@@ -4,17 +4,17 @@ Subject: [PATCH] bcm2708 watchdog driver
Signed-off-by: popcornmix <popcornmix@gmail.com>
---
- drivers/watchdog/Kconfig | 6 +
- drivers/watchdog/Makefile | 1 +
- drivers/watchdog/bcm2708_wdog.c | 385 +++++++++++++++++++++++++++++++++++++++
+ drivers/watchdog/Kconfig | 6 +
+ drivers/watchdog/Makefile | 1 +
+ drivers/watchdog/bcm2708_wdog.c | 385 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 392 insertions(+)
create mode 100644 drivers/watchdog/bcm2708_wdog.c
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
-index 79fd606..bd76a65 100644
+index 53d7571..1c89388 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
-@@ -343,6 +343,12 @@ config IMX2_WDT
+@@ -352,6 +352,12 @@ config IMX2_WDT
To compile this driver as a module, choose M here: the
module will be called imx2_wdt.
@@ -28,10 +28,10 @@ index 79fd606..bd76a65 100644
config AT32AP700X_WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
-index fe893e9..897ab01 100644
+index 572b39b..d6d8fb7 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
-@@ -53,6 +53,7 @@ obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o
+@@ -52,6 +52,7 @@ obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o
obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
diff --git a/patches/linux-3.2.27/0004-bcm2708-framebuffer-driver.patch b/patches/linux-3.6.7/0004-bcm2708-framebuffer-driver.patch
index d45f379..f3ebda7 100644
--- a/patches/linux-3.2.27/0004-bcm2708-framebuffer-driver.patch
+++ b/patches/linux-3.6.7/0004-bcm2708-framebuffer-driver.patch
@@ -12,7 +12,7 @@ Signed-off-by: popcornmix <popcornmix@gmail.com>
create mode 100644 drivers/video/bcm2708_fb.c
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
-index d83e967..a488cd7 100644
+index 0217f74..7b96e5f 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -312,6 +312,20 @@ config FB_PM2_FIFO_DISCONNECT
@@ -37,10 +37,10 @@ index d83e967..a488cd7 100644
tristate "ARM PrimeCell PL110 support"
depends on FB && ARM && ARM_AMBA
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
-index 9b9d8ff..6e9e8e9 100644
+index ee8dafb..3a7c1f5 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
-@@ -96,6 +96,7 @@ obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o
+@@ -99,6 +99,7 @@ obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o
obj-$(CONFIG_FB_PVR2) += pvr2fb.o
obj-$(CONFIG_FB_VOODOO1) += sstfb.o
obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
diff --git a/patches/linux-3.2.27/0005-bcm2708-vchiq-driver.patch b/patches/linux-3.6.7/0005-bcm2708-vchiq-driver.patch
index 86411f7..08016e9 100644
--- a/patches/linux-3.2.27/0005-bcm2708-vchiq-driver.patch
+++ b/patches/linux-3.6.7/0005-bcm2708-vchiq-driver.patch
@@ -4,8 +4,8 @@ Subject: [PATCH] bcm2708 vchiq driver
Signed-off-by: popcornmix <popcornmix@gmail.com>
---
- drivers/misc/Kconfig | 1 +
- drivers/misc/Makefile | 1 +
+ drivers/misc/Kconfig | 2 +
+ drivers/misc/Makefile | 2 +
drivers/misc/vc04_services/Kconfig | 7 +
drivers/misc/vc04_services/Makefile | 19 +
.../misc/vc04_services/interface/vchi/vchi_mh.h | 19 +
@@ -78,7 +78,7 @@ Signed-off-by: popcornmix <popcornmix@gmail.com>
.../interface/vcos/vcos_thread_attr.h | 73 +
.../misc/vc04_services/interface/vcos/vcos_timer.h | 95 +
.../misc/vc04_services/interface/vcos/vcos_types.h | 197 ++
- 74 files changed, 15998 insertions(+)
+ 74 files changed, 16000 insertions(+)
create mode 100644 drivers/misc/vc04_services/Kconfig
create mode 100644 drivers/misc/vc04_services/Makefile
create mode 100644 drivers/misc/vc04_services/interface/vchi/vchi_mh.h
@@ -153,25 +153,26 @@ Signed-off-by: popcornmix <popcornmix@gmail.com>
create mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_types.h
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
-index 5664696..b4679ec 100644
+index 98a442d..f738bf3 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
-@@ -508,5 +508,6 @@ source "drivers/misc/ti-st/Kconfig"
- source "drivers/misc/lis3lv02d/Kconfig"
+@@ -517,4 +517,6 @@ source "drivers/misc/lis3lv02d/Kconfig"
source "drivers/misc/carma/Kconfig"
source "drivers/misc/altera-stapl/Kconfig"
+ source "drivers/misc/mei/Kconfig"
+source "drivers/misc/vc04_services/Kconfig"
-
- endif # MISC_DEVICES
+ endmenu
++
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
-index b26495a..a06b534 100644
+index b88df7a..aeeb47e 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
-@@ -48,3 +48,4 @@ obj-y += lis3lv02d/
- obj-y += carma/
+@@ -50,3 +50,5 @@ obj-y += carma/
obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
+ obj-$(CONFIG_INTEL_MEI) += mei/
+obj-y += vc04_services/
++
diff --git a/drivers/misc/vc04_services/Kconfig b/drivers/misc/vc04_services/Kconfig
new file mode 100644
index 0000000..d97a1e2
@@ -12654,7 +12655,7 @@ index 0000000..e3f0840
+
diff --git a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel_misc.c b/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel_misc.c
new file mode 100644
-index 0000000..4d934c3
+index 0000000..4d934c38
--- /dev/null
+++ b/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel_misc.c
@@ -0,0 +1,113 @@
diff --git a/patches/linux-3.2.27/0006-Allow-mac-address-to-be-set-in-smsc95xx.patch b/patches/linux-3.6.7/0006-Allow-mac-address-to-be-set-in-smsc95xx.patch
index 10fd255..2db0750 100644
--- a/patches/linux-3.2.27/0006-Allow-mac-address-to-be-set-in-smsc95xx.patch
+++ b/patches/linux-3.6.7/0006-Allow-mac-address-to-be-set-in-smsc95xx.patch
@@ -4,11 +4,11 @@ Subject: [PATCH] Allow mac address to be set in smsc95xx
Signed-off-by: popcornmix <popcornmix@gmail.com>
---
- drivers/net/usb/smsc95xx.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
+ drivers/net/usb/smsc95xx.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
-index 55b3218..da34dc8 100644
+index d45e539..e00ae5d 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -46,6 +46,7 @@
@@ -19,7 +19,7 @@ index 55b3218..da34dc8 100644
struct smsc95xx_priv {
u32 mac_cr;
-@@ -63,6 +64,10 @@ static int turbo_mode = true;
+@@ -63,6 +64,10 @@ static bool turbo_mode = true;
module_param(turbo_mode, bool, 0644);
MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
@@ -30,7 +30,7 @@ index 55b3218..da34dc8 100644
static int smsc95xx_read_reg(struct usbnet *dev, u32 index, u32 *data)
{
u32 *buf = kmalloc(4, GFP_KERNEL);
-@@ -600,8 +605,59 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+@@ -633,8 +638,59 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
}
diff --git a/patches/linux-3.2.27/0007-Fix-headers-for-vchiq-vcos-to-be-GPLv2.patch b/patches/linux-3.6.7/0007-Fix-headers-for-vchiq-vcos-to-be-GPLv2.patch
index 87b53e3..f38c111 100644
--- a/patches/linux-3.2.27/0007-Fix-headers-for-vchiq-vcos-to-be-GPLv2.patch
+++ b/patches/linux-3.6.7/0007-Fix-headers-for-vchiq-vcos-to-be-GPLv2.patch
@@ -4,50 +4,50 @@ Subject: [PATCH] Fix headers for vchiq/vcos to be GPLv2
Signed-off-by: Dom Cobley <dc4@broadcom.com>
---
- .../misc/vc04_services/interface/vchi/vchi_mh.h | 26 +++++++++++++-------
- .../interface/vcos/generic/vcos_common.h | 25 +++++++++++++------
- .../vcos/generic/vcos_generic_blockpool.h | 25 +++++++++++++------
- .../vcos/generic/vcos_generic_event_flags.c | 22 ++++++++++++++---
- .../vcos/generic/vcos_generic_event_flags.h | 22 ++++++++++++++---
- .../vcos/generic/vcos_generic_named_sem.h | 25 +++++++++++++------
- .../vcos/generic/vcos_generic_quickslow_mutex.h | 25 +++++++++++++------
- .../vcos/generic/vcos_generic_reentrant_mtx.h | 25 +++++++++++++------
- .../interface/vcos/generic/vcos_generic_tls.h | 25 +++++++++++++------
- .../vcos/generic/vcos_joinable_thread_from_plain.h | 24 +++++++++++++-----
- .../interface/vcos/generic/vcos_latch_from_sem.h | 25 +++++++++++++------
- .../interface/vcos/generic/vcos_logcat.c | 25 +++++++++++++------
- .../interface/vcos/generic/vcos_mem_from_malloc.c | 25 +++++++++++++------
- .../interface/vcos/generic/vcos_mem_from_malloc.h | 25 +++++++++++++------
- .../vcos/generic/vcos_mutexes_are_reentrant.h | 25 +++++++++++++------
- .../interface/vcos/generic/vcos_thread_reaper.h | 25 +++++++++++++------
- .../interface/vcos/linuxkernel/stdint.h | 22 ++++++++++++++---
- .../interface/vcos/linuxkernel/vcos_linuxkernel.c | 25 +++++++++++++------
- .../vcos/linuxkernel/vcos_linuxkernel_misc.c | 2 --
- .../interface/vcos/linuxkernel/vcos_platform.h | 25 +++++++++++++------
- .../vcos/linuxkernel/vcos_platform_types.h | 25 +++++++++++++------
- drivers/misc/vc04_services/interface/vcos/vcos.h | 25 +++++++++++++------
- .../vc04_services/interface/vcos/vcos_assert.h | 25 +++++++++++++------
- .../interface/vcos/vcos_atomic_flags.h | 25 +++++++++++++------
- .../vc04_services/interface/vcos/vcos_build_info.h | 18 ++++++++++++++
- .../misc/vc04_services/interface/vcos/vcos_ctype.h | 25 +++++++++++++------
- .../misc/vc04_services/interface/vcos/vcos_dlfcn.h | 25 +++++++++++++------
- .../misc/vc04_services/interface/vcos/vcos_event.h | 25 +++++++++++++------
- .../interface/vcos/vcos_event_flags.h | 25 +++++++++++++------
- .../misc/vc04_services/interface/vcos/vcos_init.h | 25 +++++++++++++------
- .../vc04_services/interface/vcos/vcos_logging.h | 25 +++++++++++++------
- .../interface/vcos/vcos_lowlevel_thread.h | 25 +++++++++++++------
- .../misc/vc04_services/interface/vcos/vcos_mem.h | 25 +++++++++++++------
- .../vc04_services/interface/vcos/vcos_msgqueue.h | 25 +++++++++++++------
- .../misc/vc04_services/interface/vcos/vcos_mutex.h | 25 +++++++++++++------
- .../misc/vc04_services/interface/vcos/vcos_once.h | 25 +++++++++++++------
- .../vc04_services/interface/vcos/vcos_semaphore.h | 25 +++++++++++++------
- .../vc04_services/interface/vcos/vcos_stdbool.h | 17 +++++++++++++
- .../vc04_services/interface/vcos/vcos_stdint.h | 24 ++++++++++++------
- .../vc04_services/interface/vcos/vcos_string.h | 25 +++++++++++++------
- .../vc04_services/interface/vcos/vcos_thread.h | 25 +++++++++++++------
- .../interface/vcos/vcos_thread_attr.h | 22 ++++++++++++++---
- .../misc/vc04_services/interface/vcos/vcos_timer.h | 25 +++++++++++++------
- .../misc/vc04_services/interface/vcos/vcos_types.h | 22 ++++++++++++++---
+ .../misc/vc04_services/interface/vchi/vchi_mh.h | 26 ++++++++++++++--------
+ .../interface/vcos/generic/vcos_common.h | 25 +++++++++++++++------
+ .../vcos/generic/vcos_generic_blockpool.h | 25 +++++++++++++++------
+ .../vcos/generic/vcos_generic_event_flags.c | 22 ++++++++++++++----
+ .../vcos/generic/vcos_generic_event_flags.h | 22 ++++++++++++++----
+ .../vcos/generic/vcos_generic_named_sem.h | 25 +++++++++++++++------
+ .../vcos/generic/vcos_generic_quickslow_mutex.h | 25 +++++++++++++++------
+ .../vcos/generic/vcos_generic_reentrant_mtx.h | 25 +++++++++++++++------
+ .../interface/vcos/generic/vcos_generic_tls.h | 25 +++++++++++++++------
+ .../vcos/generic/vcos_joinable_thread_from_plain.h | 24 +++++++++++++++-----
+ .../interface/vcos/generic/vcos_latch_from_sem.h | 25 +++++++++++++++------
+ .../interface/vcos/generic/vcos_logcat.c | 25 +++++++++++++++------
+ .../interface/vcos/generic/vcos_mem_from_malloc.c | 25 +++++++++++++++------
+ .../interface/vcos/generic/vcos_mem_from_malloc.h | 25 +++++++++++++++------
+ .../vcos/generic/vcos_mutexes_are_reentrant.h | 25 +++++++++++++++------
+ .../interface/vcos/generic/vcos_thread_reaper.h | 25 +++++++++++++++------
+ .../interface/vcos/linuxkernel/stdint.h | 22 ++++++++++++++----
+ .../interface/vcos/linuxkernel/vcos_linuxkernel.c | 25 +++++++++++++++------
+ .../vcos/linuxkernel/vcos_linuxkernel_misc.c | 2 --
+ .../interface/vcos/linuxkernel/vcos_platform.h | 25 +++++++++++++++------
+ .../vcos/linuxkernel/vcos_platform_types.h | 25 +++++++++++++++------
+ drivers/misc/vc04_services/interface/vcos/vcos.h | 25 +++++++++++++++------
+ .../vc04_services/interface/vcos/vcos_assert.h | 25 +++++++++++++++------
+ .../interface/vcos/vcos_atomic_flags.h | 25 +++++++++++++++------
+ .../vc04_services/interface/vcos/vcos_build_info.h | 18 +++++++++++++++
+ .../misc/vc04_services/interface/vcos/vcos_ctype.h | 25 +++++++++++++++------
+ .../misc/vc04_services/interface/vcos/vcos_dlfcn.h | 25 +++++++++++++++------
+ .../misc/vc04_services/interface/vcos/vcos_event.h | 25 +++++++++++++++------
+ .../interface/vcos/vcos_event_flags.h | 25 +++++++++++++++------
+ .../misc/vc04_services/interface/vcos/vcos_init.h | 25 +++++++++++++++------
+ .../vc04_services/interface/vcos/vcos_logging.h | 25 +++++++++++++++------
+ .../interface/vcos/vcos_lowlevel_thread.h | 25 +++++++++++++++------
+ .../misc/vc04_services/interface/vcos/vcos_mem.h | 25 +++++++++++++++------
+ .../vc04_services/interface/vcos/vcos_msgqueue.h | 25 +++++++++++++++------
+ .../misc/vc04_services/interface/vcos/vcos_mutex.h | 25 +++++++++++++++------
+ .../misc/vc04_services/interface/vcos/vcos_once.h | 25 +++++++++++++++------
+ .../vc04_services/interface/vcos/vcos_semaphore.h | 25 +++++++++++++++------
+ .../vc04_services/interface/vcos/vcos_stdbool.h | 17 ++++++++++++++
+ .../vc04_services/interface/vcos/vcos_stdint.h | 24 ++++++++++++++------
+ .../vc04_services/interface/vcos/vcos_string.h | 25 +++++++++++++++------
+ .../vc04_services/interface/vcos/vcos_thread.h | 25 +++++++++++++++------
+ .../interface/vcos/vcos_thread_attr.h | 22 ++++++++++++++----
+ .../misc/vc04_services/interface/vcos/vcos_timer.h | 25 +++++++++++++++------
+ .../misc/vc04_services/interface/vcos/vcos_types.h | 22 ++++++++++++++----
44 files changed, 771 insertions(+), 275 deletions(-)
diff --git a/drivers/misc/vc04_services/interface/vchi/vchi_mh.h b/drivers/misc/vc04_services/interface/vchi/vchi_mh.h
@@ -653,7 +653,7 @@ index 154f4a1..0385540 100644
=============================================================================*/
diff --git a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel_misc.c b/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel_misc.c
-index 4d934c3..4a9cedf 100644
+index 4d934c38..4a9cedf 100644
--- a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel_misc.c
+++ b/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel_misc.c
@@ -1,5 +1,3 @@
diff --git a/patches/linux-3.2.27/0008-Fix-some-issues-reported.-Lower-case-module-paramete.patch b/patches/linux-3.6.7/0008-Fix-some-issues-reported.-Lower-case-module-paramete.patch
index 1b6d25b..62a9aa4 100644
--- a/patches/linux-3.2.27/0008-Fix-some-issues-reported.-Lower-case-module-paramete.patch
+++ b/patches/linux-3.6.7/0008-Fix-some-issues-reported.-Lower-case-module-paramete.patch
@@ -5,9 +5,9 @@ Subject: [PATCH] Fix some issues reported. Lower case module parameters for
Signed-off-by: Dom Cobley <dc4@broadcom.com>
---
- arch/arm/mach-bcm2708/bcm2708.c | 569 +++++++++++++++++++--------------------
- drivers/usb/gadget/Kconfig | 14 -
- drivers/video/bcm2708_fb.c | 425 +++++++++++++++--------------
+ arch/arm/mach-bcm2708/bcm2708.c | 569 +++++++++++++++++++---------------------
+ drivers/usb/gadget/Kconfig | 14 -
+ drivers/video/bcm2708_fb.c | 425 ++++++++++++++++--------------
3 files changed, 497 insertions(+), 511 deletions(-)
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
@@ -823,10 +823,10 @@ index 5012f3f..d9dc628 100644
+ bcm2708_init, MACHINE_END module_param(boardrev, uint, 0644);
+module_param(serial, uint, 0644);
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
-index c50eebf..b7935b2 100644
+index 9f5c8dc..ddb753b 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
-@@ -566,20 +566,6 @@ config USB_DWC_OTG_LPM
+@@ -519,20 +519,6 @@ config USB_DWC_OTG_LPM
help
Enables LPM support.
diff --git a/patches/linux-3.2.27/0009-Build-anything-reasonable-as-a-module.-Thanks-to-asb.patch b/patches/linux-3.6.7/0009-Build-anything-reasonable-as-a-module.-Thanks-to-asb.patch
index 9c338c6..9c338c6 100644
--- a/patches/linux-3.2.27/0009-Build-anything-reasonable-as-a-module.-Thanks-to-asb.patch
+++ b/patches/linux-3.6.7/0009-Build-anything-reasonable-as-a-module.-Thanks-to-asb.patch
diff --git a/patches/linux-3.2.27/0010-Add-config-option-to-enable-L2-cache.patch b/patches/linux-3.6.7/0010-Add-config-option-to-enable-L2-cache.patch
index 586e507..256685d 100644
--- a/patches/linux-3.2.27/0010-Add-config-option-to-enable-L2-cache.patch
+++ b/patches/linux-3.6.7/0010-Add-config-option-to-enable-L2-cache.patch
@@ -4,8 +4,8 @@ Subject: [PATCH] Add config option to enable L2 cache
Signed-off-by: Dom Cobley <dc4@broadcom.com>
---
- arch/arm/mach-bcm2708/Kconfig | 7 +++++++
- arch/arm/mach-bcm2708/include/mach/memory.h | 7 ++++++-
+ arch/arm/mach-bcm2708/Kconfig | 7 +++++++
+ arch/arm/mach-bcm2708/include/mach/memory.h | 7 ++++++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig
diff --git a/patches/linux-3.2.27/0011-Fix-bug-where-vchiq-fails-when-L2-enabled.patch b/patches/linux-3.6.7/0011-Fix-bug-where-vchiq-fails-when-L2-enabled.patch
index 2ca673c..cb2633d 100644
--- a/patches/linux-3.2.27/0011-Fix-bug-where-vchiq-fails-when-L2-enabled.patch
+++ b/patches/linux-3.6.7/0011-Fix-bug-where-vchiq-fails-when-L2-enabled.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] Fix bug where vchiq fails when L2 enabled
Signed-off-by: Dom Cobley <dc4@broadcom.com>
---
- drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 2 +-
+ drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
diff --git a/patches/linux-3.2.27/0012-Add-devtmpfs-for-archlinux-and-emergency-and-debug-c.patch b/patches/linux-3.6.7/0012-Add-devtmpfs-for-archlinux-and-emergency-and-debug-c.patch
index 1c59a49..f20f0f5 100644
--- a/patches/linux-3.2.27/0012-Add-devtmpfs-for-archlinux-and-emergency-and-debug-c.patch
+++ b/patches/linux-3.6.7/0012-Add-devtmpfs-for-archlinux-and-emergency-and-debug-c.patch
@@ -3,9 +3,9 @@ Date: Wed, 7 Mar 2012 23:19:08 +0000
Subject: [PATCH] Add devtmpfs for archlinux, and emergency and debug config
---
- arch/arm/configs/bcmrpi_cutdown_defconfig | 2 +-
- arch/arm/configs/bcmrpi_defconfig | 509 +++++++++++++++++++++++++++
- arch/arm/configs/bcmrpi_emergency_defconfig | 475 +++++++++++++++++++++++++
+ arch/arm/configs/bcmrpi_cutdown_defconfig | 2 +-
+ arch/arm/configs/bcmrpi_defconfig | 509 ++++++++++++++++++++++++++++
+ arch/arm/configs/bcmrpi_emergency_defconfig | 475 ++++++++++++++++++++++++++
3 files changed, 985 insertions(+), 1 deletion(-)
create mode 100644 arch/arm/configs/bcmrpi_defconfig
create mode 100644 arch/arm/configs/bcmrpi_emergency_defconfig
diff --git a/patches/linux-3.2.27/0013-Fix-32bpp-framebuffer-by-adding-alpha-bits.patch b/patches/linux-3.6.7/0013-Fix-32bpp-framebuffer-by-adding-alpha-bits.patch
index a56eb05..a8a0dee 100644
--- a/patches/linux-3.2.27/0013-Fix-32bpp-framebuffer-by-adding-alpha-bits.patch
+++ b/patches/linux-3.6.7/0013-Fix-32bpp-framebuffer-by-adding-alpha-bits.patch
@@ -3,7 +3,7 @@ Date: Wed, 7 Mar 2012 23:21:01 +0000
Subject: [PATCH] Fix 32bpp framebuffer by adding alpha bits
---
- drivers/video/bcm2708_fb.c | 65 ++++++++++++++++++--------------------------
+ drivers/video/bcm2708_fb.c | 65 +++++++++++++++++++---------------------------
1 file changed, 26 insertions(+), 39 deletions(-)
diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
diff --git a/patches/linux-3.2.27/0014-Enable-L2-cache-is-now-the-default.-Invert-sense-of-.patch b/patches/linux-3.6.7/0014-Enable-L2-cache-is-now-the-default.-Invert-sense-of-.patch
index b6a67f6..597feb1 100644
--- a/patches/linux-3.2.27/0014-Enable-L2-cache-is-now-the-default.-Invert-sense-of-.patch
+++ b/patches/linux-3.6.7/0014-Enable-L2-cache-is-now-the-default.-Invert-sense-of-.patch
@@ -3,8 +3,8 @@ Date: Wed, 7 Mar 2012 23:22:59 +0000
Subject: [PATCH] Enable L2 cache is now the default. Invert sense of L2 flags
---
- arch/arm/mach-bcm2708/Kconfig | 6 +++---
- arch/arm/mach-bcm2708/include/mach/memory.h | 6 +++---
+ arch/arm/mach-bcm2708/Kconfig | 6 +++---
+ arch/arm/mach-bcm2708/include/mach/memory.h | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig
diff --git a/patches/linux-3.2.27/0015-Allow-24bpp-for-framebuffer.patch b/patches/linux-3.6.7/0015-Allow-24bpp-for-framebuffer.patch
index 3198cc9..ed3cdb3 100644
--- a/patches/linux-3.2.27/0015-Allow-24bpp-for-framebuffer.patch
+++ b/patches/linux-3.6.7/0015-Allow-24bpp-for-framebuffer.patch
@@ -3,7 +3,7 @@ Date: Wed, 14 Mar 2012 23:26:14 +0000
Subject: [PATCH] Allow 24bpp for framebuffer
---
- drivers/video/bcm2708_fb.c | 5 +++++
+ drivers/video/bcm2708_fb.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
diff --git a/patches/linux-3.2.27/0016-Disable-debug-code-in-dwc_otg-driver-unless-CONFIG_U.patch b/patches/linux-3.6.7/0016-Disable-debug-code-in-dwc_otg-driver-unless-CONFIG_U.patch
index e745dee..072f2e6 100644
--- a/patches/linux-3.2.27/0016-Disable-debug-code-in-dwc_otg-driver-unless-CONFIG_U.patch
+++ b/patches/linux-3.6.7/0016-Disable-debug-code-in-dwc_otg-driver-unless-CONFIG_U.patch
@@ -4,9 +4,9 @@ Subject: [PATCH] Disable debug code in dwc_otg driver unless CONFIG_USB_DEBUG
is set
---
- drivers/usb/host/dwc_common_port/Makefile | 2 ++
- drivers/usb/host/dwc_common_port/dwc_os.h | 1 +
- drivers/usb/host/dwc_otg/Makefile | 4 +++-
+ drivers/usb/host/dwc_common_port/Makefile | 2 ++
+ drivers/usb/host/dwc_common_port/dwc_os.h | 1 +
+ drivers/usb/host/dwc_otg/Makefile | 4 +++-
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/dwc_common_port/Makefile b/drivers/usb/host/dwc_common_port/Makefile
diff --git a/patches/linux-3.2.27/0017-Enable-high-resolution-timers.patch b/patches/linux-3.6.7/0017-Enable-high-resolution-timers.patch
index 0a95995..087cd48 100644
--- a/patches/linux-3.2.27/0017-Enable-high-resolution-timers.patch
+++ b/patches/linux-3.6.7/0017-Enable-high-resolution-timers.patch
@@ -3,9 +3,9 @@ Date: Sat, 17 Mar 2012 23:23:01 +0000
Subject: [PATCH] Enable high resolution timers
---
- arch/arm/configs/bcmrpi_cutdown_defconfig | 1 +
- arch/arm/configs/bcmrpi_defconfig | 1 +
- arch/arm/mach-bcm2708/bcm2708.c | 49 +++++++++++++++++++++--------
+ arch/arm/configs/bcmrpi_cutdown_defconfig | 1 +
+ arch/arm/configs/bcmrpi_defconfig | 1 +
+ arch/arm/mach-bcm2708/bcm2708.c | 49 +++++++++++++++++++++++--------
3 files changed, 38 insertions(+), 13 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_cutdown_defconfig b/arch/arm/configs/bcmrpi_cutdown_defconfig
diff --git a/patches/linux-3.2.27/0018-Fix-for-mmc-timeouts-when-erasing-multiple-blocks.patch b/patches/linux-3.6.7/0018-Fix-for-mmc-timeouts-when-erasing-multiple-blocks.patch
index a97c8cf..c87441b 100644
--- a/patches/linux-3.2.27/0018-Fix-for-mmc-timeouts-when-erasing-multiple-blocks.patch
+++ b/patches/linux-3.6.7/0018-Fix-for-mmc-timeouts-when-erasing-multiple-blocks.patch
@@ -3,8 +3,8 @@ Date: Sat, 17 Mar 2012 23:28:22 +0000
Subject: [PATCH] Fix for mmc timeouts when erasing multiple blocks
---
- arch/arm/mach-bcm2708/power.c | 10 ++--
- drivers/mmc/host/sdhci-bcm2708.c | 97 +++++++++++++++++++++++++++++++++++---
+ arch/arm/mach-bcm2708/power.c | 10 +++--
+ drivers/mmc/host/sdhci-bcm2708.c | 97 +++++++++++++++++++++++++++++++++++++---
2 files changed, 97 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mach-bcm2708/power.c b/arch/arm/mach-bcm2708/power.c
diff --git a/patches/linux-3.2.27/0019-Fix-problem-with-dma-that-could-corrupt-sdcard-espec.patch b/patches/linux-3.6.7/0019-Fix-problem-with-dma-that-could-corrupt-sdcard-espec.patch
index 800e6c7..46b5149 100644
--- a/patches/linux-3.2.27/0019-Fix-problem-with-dma-that-could-corrupt-sdcard-espec.patch
+++ b/patches/linux-3.6.7/0019-Fix-problem-with-dma-that-could-corrupt-sdcard-espec.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] Fix problem with dma that could corrupt sdcard, especially
when L2 enabled
---
- drivers/mmc/host/sdhci-bcm2708.c | 6 ++++--
+ drivers/mmc/host/sdhci-bcm2708.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0020-Update-to-match-latest-vc-side-vchiq.-Allows-vchiq-c.patch b/patches/linux-3.6.7/0020-Update-to-match-latest-vc-side-vchiq.-Allows-vchiq-c.patch
index 79303de..03a7398 100644
--- a/patches/linux-3.2.27/0020-Update-to-match-latest-vc-side-vchiq.-Allows-vchiq-c.patch
+++ b/patches/linux-3.6.7/0020-Update-to-match-latest-vc-side-vchiq.-Allows-vchiq-c.patch
@@ -4,21 +4,21 @@ Subject: [PATCH] Update to match latest vc side vchiq. Allows vchiq calls
from kernel.
---
- drivers/misc/vc04_services/Makefile | 4 +-
- .../interface/vchi/connections/connection.h | 309 ++++++++++
- .../interface/vchi/message_drivers/message.h | 186 ++++++
- drivers/misc/vc04_services/interface/vchi/vchi.h | 347 +++++++++++
- .../misc/vc04_services/interface/vchi/vchi_cfg.h | 214 +++++++
- .../interface/vchi/vchi_cfg_internal.h | 56 ++
- .../vc04_services/interface/vchi/vchi_common.h | 152 +++++
- .../interface/vchiq_arm/vchiq_2835_arm.c | 73 ++-
- .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 618 +++++++++++++++++++-
- .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 80 +++
- .../vc04_services/interface/vchiq_arm/vchiq_core.c | 216 +++++--
- .../vc04_services/interface/vchiq_arm/vchiq_core.h | 59 +-
- .../vc04_services/interface/vchiq_arm/vchiq_if.h | 19 +-
- .../vc04_services/interface/vchiq_arm/vchiq_lib.c | 118 +++-
- .../vc04_services/interface/vchiq_arm/vchiq_shim.c | 37 +-
+ drivers/misc/vc04_services/Makefile | 4 +-
+ .../interface/vchi/connections/connection.h | 309 +++++++++++
+ .../interface/vchi/message_drivers/message.h | 186 +++++++
+ drivers/misc/vc04_services/interface/vchi/vchi.h | 347 ++++++++++++
+ .../misc/vc04_services/interface/vchi/vchi_cfg.h | 214 +++++++
+ .../interface/vchi/vchi_cfg_internal.h | 56 ++
+ .../vc04_services/interface/vchi/vchi_common.h | 152 +++++
+ .../interface/vchiq_arm/vchiq_2835_arm.c | 73 ++-
+ .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 618 ++++++++++++++++++++-
+ .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 80 +++
+ .../vc04_services/interface/vchiq_arm/vchiq_core.c | 216 +++++--
+ .../vc04_services/interface/vchiq_arm/vchiq_core.h | 59 +-
+ .../vc04_services/interface/vchiq_arm/vchiq_if.h | 19 +-
+ .../vc04_services/interface/vchiq_arm/vchiq_lib.c | 118 +++-
+ .../vc04_services/interface/vchiq_arm/vchiq_shim.c | 37 +-
15 files changed, 2370 insertions(+), 118 deletions(-)
create mode 100644 drivers/misc/vc04_services/interface/vchi/connections/connection.h
create mode 100644 drivers/misc/vc04_services/interface/vchi/message_drivers/message.h
diff --git a/patches/linux-3.2.27/0021-First-pass-at-alsa-sound-driver.-Some-functionality-.patch b/patches/linux-3.6.7/0021-First-pass-at-alsa-sound-driver.-Some-functionality-.patch
index 2e64178..78b6dce 100644
--- a/patches/linux-3.2.27/0021-First-pass-at-alsa-sound-driver.-Some-functionality-.patch
+++ b/patches/linux-3.6.7/0021-First-pass-at-alsa-sound-driver.-Some-functionality-.patch
@@ -4,15 +4,15 @@ Subject: [PATCH] First pass at alsa sound driver. Some functionality, but
also some underruns
---
- arch/arm/mach-bcm2708/bcm2708.c | 12 +
- sound/arm/Kconfig | 7 +
- sound/arm/Makefile | 6 +
- sound/arm/bcm2835-ctl.c | 168 +++++++
- sound/arm/bcm2835-pcm.c | 391 ++++++++++++++++
- sound/arm/bcm2835-vchiq.c | 863 ++++++++++++++++++++++++++++++++++++
- sound/arm/bcm2835.c | 426 ++++++++++++++++++
- sound/arm/bcm2835.h | 239 ++++++++++
- sound/arm/vc_vchi_audioserv_defs.h | 128 ++++++
+ arch/arm/mach-bcm2708/bcm2708.c | 12 +
+ sound/arm/Kconfig | 7 +
+ sound/arm/Makefile | 6 +
+ sound/arm/bcm2835-ctl.c | 168 ++++++++
+ sound/arm/bcm2835-pcm.c | 391 +++++++++++++++++
+ sound/arm/bcm2835-vchiq.c | 863 +++++++++++++++++++++++++++++++++++++
+ sound/arm/bcm2835.c | 426 ++++++++++++++++++
+ sound/arm/bcm2835.h | 239 ++++++++++
+ sound/arm/vc_vchi_audioserv_defs.h | 128 ++++++
9 files changed, 2240 insertions(+)
create mode 100755 sound/arm/bcm2835-ctl.c
create mode 100755 sound/arm/bcm2835-pcm.c
diff --git a/patches/linux-3.2.27/0022-Cast-to-avoid-warning.patch b/patches/linux-3.6.7/0022-Cast-to-avoid-warning.patch
index 1923c15..0aca4f5 100644
--- a/patches/linux-3.2.27/0022-Cast-to-avoid-warning.patch
+++ b/patches/linux-3.6.7/0022-Cast-to-avoid-warning.patch
@@ -3,7 +3,7 @@ Date: Mon, 26 Mar 2012 22:18:37 +0100
Subject: [PATCH] Cast to avoid warning
---
- drivers/video/bcm2708_fb.c | 4 ++--
+ drivers/video/bcm2708_fb.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
diff --git a/patches/linux-3.2.27/0023-Add-new-ioctl-to-match-latest-vc-side-code.patch b/patches/linux-3.6.7/0023-Add-new-ioctl-to-match-latest-vc-side-code.patch
index bf6cb4b..4f29eb2 100644
--- a/patches/linux-3.2.27/0023-Add-new-ioctl-to-match-latest-vc-side-code.patch
+++ b/patches/linux-3.6.7/0023-Add-new-ioctl-to-match-latest-vc-side-code.patch
@@ -3,7 +3,7 @@ Date: Mon, 26 Mar 2012 22:19:16 +0100
Subject: [PATCH] Add new ioctl to match latest vc side code
---
- arch/arm/mach-bcm2708/vc_mem.c | 55 ++++++++++++++++++++--------------------
+ arch/arm/mach-bcm2708/vc_mem.c | 55 +++++++++++++++++++++---------------------
1 file changed, 27 insertions(+), 28 deletions(-)
diff --git a/arch/arm/mach-bcm2708/vc_mem.c b/arch/arm/mach-bcm2708/vc_mem.c
diff --git a/patches/linux-3.2.27/0024-Enable-sound-kernel-modules.-Tidy-formatting.-Fix-ct.patch b/patches/linux-3.6.7/0024-Enable-sound-kernel-modules.-Tidy-formatting.-Fix-ct.patch
index 6c11312..b4ae6fe 100644
--- a/patches/linux-3.2.27/0024-Enable-sound-kernel-modules.-Tidy-formatting.-Fix-ct.patch
+++ b/patches/linux-3.6.7/0024-Enable-sound-kernel-modules.-Tidy-formatting.-Fix-ct.patch
@@ -4,14 +4,14 @@ Subject: [PATCH] Enable sound kernel modules. Tidy formatting. Fix ctl dest
setting
---
- arch/arm/configs/bcmrpi_cutdown_defconfig | 20 ++
- arch/arm/configs/bcmrpi_defconfig | 20 ++
- sound/arm/bcm2835-ctl.c | 120 +++----
- sound/arm/bcm2835-pcm.c | 215 +++++++-----
- sound/arm/bcm2835-vchiq.c | 525 +++++++++++++----------------
- sound/arm/bcm2835.c | 223 ++++++------
- sound/arm/bcm2835.h | 113 ++++---
- sound/arm/vc_vchi_audioserv_defs.h | 116 +++----
+ arch/arm/configs/bcmrpi_cutdown_defconfig | 20 ++
+ arch/arm/configs/bcmrpi_defconfig | 20 ++
+ sound/arm/bcm2835-ctl.c | 120 +++----
+ sound/arm/bcm2835-pcm.c | 215 ++++++------
+ sound/arm/bcm2835-vchiq.c | 525 ++++++++++++++----------------
+ sound/arm/bcm2835.c | 223 +++++++------
+ sound/arm/bcm2835.h | 113 +++----
+ sound/arm/vc_vchi_audioserv_defs.h | 116 +++----
8 files changed, 682 insertions(+), 670 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_cutdown_defconfig b/arch/arm/configs/bcmrpi_cutdown_defconfig
diff --git a/patches/linux-3.2.27/0025-Add-missing-header-file-update-for-vc_mem-iocts.patch b/patches/linux-3.6.7/0025-Add-missing-header-file-update-for-vc_mem-iocts.patch
index 7a7e674..0533e73 100644
--- a/patches/linux-3.2.27/0025-Add-missing-header-file-update-for-vc_mem-iocts.patch
+++ b/patches/linux-3.6.7/0025-Add-missing-header-file-update-for-vc_mem-iocts.patch
@@ -3,7 +3,7 @@ Date: Thu, 29 Mar 2012 21:09:45 +0100
Subject: [PATCH] Add missing header file update for vc_mem iocts
---
- arch/arm/mach-bcm2708/include/mach/vc_mem.h | 1 +
+ arch/arm/mach-bcm2708/include/mach/vc_mem.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-bcm2708/include/mach/vc_mem.h b/arch/arm/mach-bcm2708/include/mach/vc_mem.h
diff --git a/patches/linux-3.2.27/0026-Remove-most-of-the-alsa-debug-messages.patch b/patches/linux-3.6.7/0026-Remove-most-of-the-alsa-debug-messages.patch
index 24deb4e..8553229 100644
--- a/patches/linux-3.2.27/0026-Remove-most-of-the-alsa-debug-messages.patch
+++ b/patches/linux-3.6.7/0026-Remove-most-of-the-alsa-debug-messages.patch
@@ -3,9 +3,9 @@ Date: Tue, 3 Apr 2012 18:18:10 +0100
Subject: [PATCH] Remove most of the alsa debug messages
---
- sound/arm/bcm2835-pcm.c | 60 ++++++++++++++++++++++-----------------------
- sound/arm/bcm2835-vchiq.c | 3 +--
- sound/arm/bcm2835.h | 2 +-
+ sound/arm/bcm2835-pcm.c | 60 +++++++++++++++++++++++------------------------
+ sound/arm/bcm2835-vchiq.c | 3 +--
+ sound/arm/bcm2835.h | 2 +-
3 files changed, 32 insertions(+), 33 deletions(-)
diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c
diff --git a/patches/linux-3.2.27/0027-add-temporary-workaround-for-fbset-crashes.patch b/patches/linux-3.6.7/0027-add-temporary-workaround-for-fbset-crashes.patch
index 99e3e3b..66a028b 100644
--- a/patches/linux-3.2.27/0027-add-temporary-workaround-for-fbset-crashes.patch
+++ b/patches/linux-3.6.7/0027-add-temporary-workaround-for-fbset-crashes.patch
@@ -3,7 +3,7 @@ Date: Thu, 12 Apr 2012 12:16:31 +0100
Subject: [PATCH] add temporary workaround for fbset crashes
---
- drivers/video/bcm2708_fb.c | 2 ++
+ drivers/video/bcm2708_fb.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
diff --git a/patches/linux-3.2.27/0028-Fix-harmless-base-size-typo.patch b/patches/linux-3.6.7/0028-Fix-harmless-base-size-typo.patch
index 0f4cc49..f4c7bc8 100644
--- a/patches/linux-3.2.27/0028-Fix-harmless-base-size-typo.patch
+++ b/patches/linux-3.6.7/0028-Fix-harmless-base-size-typo.patch
@@ -3,7 +3,7 @@ Date: Mon, 16 Apr 2012 12:55:39 +0100
Subject: [PATCH] Fix harmless base/size typo
---
- arch/arm/mach-bcm2708/vc_mem.c | 8 ++++----
+ arch/arm/mach-bcm2708/vc_mem.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-bcm2708/vc_mem.c b/arch/arm/mach-bcm2708/vc_mem.c
diff --git a/patches/linux-3.2.27/0029-Replace-if-1-sections-by-local-configuration-defines.patch b/patches/linux-3.6.7/0029-Replace-if-1-sections-by-local-configuration-defines.patch
index e61c493..f61d393 100644
--- a/patches/linux-3.2.27/0029-Replace-if-1-sections-by-local-configuration-defines.patch
+++ b/patches/linux-3.6.7/0029-Replace-if-1-sections-by-local-configuration-defines.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] Replace #if 1 sections by local configuration #defines
(tidy)
---
- drivers/mmc/host/sdhci-bcm2708.c | 21 ++++++++++++++-------
+ drivers/mmc/host/sdhci-bcm2708.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0030-Don-t-send-data-block-when-emitting-silence.patch b/patches/linux-3.6.7/0030-Don-t-send-data-block-when-emitting-silence.patch
index 5c8032b..614831e 100644
--- a/patches/linux-3.2.27/0030-Don-t-send-data-block-when-emitting-silence.patch
+++ b/patches/linux-3.6.7/0030-Don-t-send-data-block-when-emitting-silence.patch
@@ -3,7 +3,7 @@ Date: Tue, 17 Apr 2012 00:33:10 +0100
Subject: [PATCH] Don't send data block when emitting silence
---
- sound/arm/bcm2835-vchiq.c | 31 ++++++++++++++++++-------------
+ sound/arm/bcm2835-vchiq.c | 31 ++++++++++++++++++-------------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/sound/arm/bcm2835-vchiq.c b/sound/arm/bcm2835-vchiq.c
diff --git a/patches/linux-3.2.27/0031-Fix-hopefully-for-DWC_MEMCPY-kernel-panics.-Thanks-t.patch b/patches/linux-3.6.7/0031-Fix-hopefully-for-DWC_MEMCPY-kernel-panics.-Thanks-t.patch
index ff9a759..a95cafd 100644
--- a/patches/linux-3.2.27/0031-Fix-hopefully-for-DWC_MEMCPY-kernel-panics.-Thanks-t.patch
+++ b/patches/linux-3.6.7/0031-Fix-hopefully-for-DWC_MEMCPY-kernel-panics.-Thanks-t.patch
@@ -4,8 +4,8 @@ Subject: [PATCH] Fix (hopefully) for DWC_MEMCPY kernel panics. Thanks to
Naren Sankar for finding this
---
- drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 4 ++++
- drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 3 +++
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 4 ++++
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 3 +++
2 files changed, 7 insertions(+)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
diff --git a/patches/linux-3.2.27/0032-Build-modules-needed-for-USB-booting-into-kernel.patch b/patches/linux-3.6.7/0032-Build-modules-needed-for-USB-booting-into-kernel.patch
index 242f78d..7b57066 100644
--- a/patches/linux-3.2.27/0032-Build-modules-needed-for-USB-booting-into-kernel.patch
+++ b/patches/linux-3.6.7/0032-Build-modules-needed-for-USB-booting-into-kernel.patch
@@ -3,8 +3,8 @@ Date: Fri, 27 Apr 2012 00:31:37 +0100
Subject: [PATCH] Build modules needed for USB booting into kernel
---
- arch/arm/configs/bcmrpi_cutdown_defconfig | 4 ++--
- arch/arm/configs/bcmrpi_defconfig | 4 ++--
+ arch/arm/configs/bcmrpi_cutdown_defconfig | 4 ++--
+ arch/arm/configs/bcmrpi_defconfig | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_cutdown_defconfig b/arch/arm/configs/bcmrpi_cutdown_defconfig
diff --git a/patches/linux-3.2.27/0033-Whitespace-tidy.-Thanks-Roger.patch b/patches/linux-3.6.7/0033-Whitespace-tidy.-Thanks-Roger.patch
index acca562..db8329c 100644
--- a/patches/linux-3.2.27/0033-Whitespace-tidy.-Thanks-Roger.patch
+++ b/patches/linux-3.6.7/0033-Whitespace-tidy.-Thanks-Roger.patch
@@ -3,7 +3,7 @@ Date: Fri, 27 Apr 2012 00:33:27 +0100
Subject: [PATCH] Whitespace tidy. Thanks Roger
---
- arch/arm/mach-bcm2708/bcm2708.c | 151 +++++++++++++++++----------------------
+ arch/arm/mach-bcm2708/bcm2708.c | 151 ++++++++++++++++++----------------------
1 file changed, 67 insertions(+), 84 deletions(-)
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
diff --git a/patches/linux-3.2.27/0034-Update-vchiq-to-match-GPU-version.-Should-still-be-c.patch b/patches/linux-3.6.7/0034-Update-vchiq-to-match-GPU-version.-Should-still-be-c.patch
index 8c9a9da..90a51a8 100644
--- a/patches/linux-3.2.27/0034-Update-vchiq-to-match-GPU-version.-Should-still-be-c.patch
+++ b/patches/linux-3.6.7/0034-Update-vchiq-to-match-GPU-version.-Should-still-be-c.patch
@@ -4,10 +4,10 @@ Subject: [PATCH] Update vchiq to match GPU version. Should still be
compatible
---
- .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 19 ++++++++++-----
- .../vc04_services/interface/vchiq_arm/vchiq_core.c | 25 ++++++++++++++++----
- .../vc04_services/interface/vchiq_arm/vchiq_core.h | 3 ++-
- .../interface/vchiq_arm/vchiq_ioctl.h | 16 ++++++-------
+ .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 19 ++++++++++------
+ .../vc04_services/interface/vchiq_arm/vchiq_core.c | 25 ++++++++++++++++++----
+ .../vc04_services/interface/vchiq_arm/vchiq_core.h | 3 ++-
+ .../interface/vchiq_arm/vchiq_ioctl.h | 16 +++++++-------
4 files changed, 44 insertions(+), 19 deletions(-)
diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
diff --git a/patches/linux-3.2.27/0035-added-support-for-TT-in-the-USB-driver.-Thanks-Naren.patch b/patches/linux-3.6.7/0035-added-support-for-TT-in-the-USB-driver.-Thanks-Naren.patch
index 60b554a..da119ea 100644
--- a/patches/linux-3.2.27/0035-added-support-for-TT-in-the-USB-driver.-Thanks-Naren.patch
+++ b/patches/linux-3.6.7/0035-added-support-for-TT-in-the-USB-driver.-Thanks-Naren.patch
@@ -3,16 +3,16 @@ Date: Mon, 30 Apr 2012 14:45:52 +0100
Subject: [PATCH] added support for TT in the USB driver. Thanks Naren
---
- drivers/usb/gadget/Kconfig | 8 --------
- drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 3 +++
+ drivers/usb/gadget/Kconfig | 8 --------
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 3 +++
2 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
-index b7935b2..12d27d2 100644
+index ddb753b..8e78a1c 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
-@@ -552,14 +552,6 @@ config USB_GADGET_SUPERSPEED
- depends on USB_GADGET
+@@ -505,14 +505,6 @@ config USB_GADGET_SUPERSPEED
+ bool
depends on USB_GADGET_DUALSPEED
-config USB_GADGET_SNPS_DWC_OTG
diff --git a/patches/linux-3.2.27/0036-Swap-Red-and-Blue-over-in-32bpp-framebuffer-mode.patch b/patches/linux-3.6.7/0036-Swap-Red-and-Blue-over-in-32bpp-framebuffer-mode.patch
index df42087..a3a891a 100644
--- a/patches/linux-3.2.27/0036-Swap-Red-and-Blue-over-in-32bpp-framebuffer-mode.patch
+++ b/patches/linux-3.6.7/0036-Swap-Red-and-Blue-over-in-32bpp-framebuffer-mode.patch
@@ -3,7 +3,7 @@ Date: Wed, 2 May 2012 22:13:14 +0100
Subject: [PATCH] Swap Red and Blue over in 32bpp framebuffer mode
---
- drivers/video/bcm2708_fb.c | 16 ++++++++++++----
+ drivers/video/bcm2708_fb.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
diff --git a/patches/linux-3.2.27/0037-Update-emergency-config-to-match-latest-debug-one.patch b/patches/linux-3.6.7/0037-Update-emergency-config-to-match-latest-debug-one.patch
index 4222958..93bf5aa 100644
--- a/patches/linux-3.2.27/0037-Update-emergency-config-to-match-latest-debug-one.patch
+++ b/patches/linux-3.6.7/0037-Update-emergency-config-to-match-latest-debug-one.patch
@@ -3,7 +3,7 @@ Date: Sun, 6 May 2012 16:58:07 +0100
Subject: [PATCH] Update emergency config to match latest debug one
---
- arch/arm/configs/bcmrpi_emergency_defconfig | 75 +++++++++++++++++++++++----
+ arch/arm/configs/bcmrpi_emergency_defconfig | 75 +++++++++++++++++++++++++----
1 file changed, 66 insertions(+), 9 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_emergency_defconfig b/arch/arm/configs/bcmrpi_emergency_defconfig
diff --git a/patches/linux-3.2.27/0039-Use-dwc_alloc_atomic.-Thanks-bootc.patch b/patches/linux-3.6.7/0038-Use-dwc_alloc_atomic.-Thanks-bootc.patch
index 0f9b5da..6fce20b 100644
--- a/patches/linux-3.2.27/0039-Use-dwc_alloc_atomic.-Thanks-bootc.patch
+++ b/patches/linux-3.6.7/0038-Use-dwc_alloc_atomic.-Thanks-bootc.patch
@@ -3,7 +3,7 @@ Date: Tue, 8 May 2012 23:09:44 +0100
Subject: [PATCH] Use dwc_alloc_atomic. Thanks bootc
---
- drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 4 ++--
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.h b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
diff --git a/patches/linux-3.2.27/0040-possible-fix-for-sdcard-missing-status.-Thank-naren.patch b/patches/linux-3.6.7/0039-possible-fix-for-sdcard-missing-status.-Thank-naren.patch
index de1bd8b..80ed865 100644
--- a/patches/linux-3.2.27/0040-possible-fix-for-sdcard-missing-status.-Thank-naren.patch
+++ b/patches/linux-3.6.7/0039-possible-fix-for-sdcard-missing-status.-Thank-naren.patch
@@ -3,7 +3,7 @@ Date: Tue, 8 May 2012 23:12:13 +0100
Subject: [PATCH] possible fix for sdcard missing status. Thank naren
---
- drivers/mmc/host/sdhci-bcm2708.c | 9 +++++++++
+ drivers/mmc/host/sdhci-bcm2708.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0041-Fix-BUG-in-bcm2708_fb_set_par-doesn-t-work-if-the-co.patch b/patches/linux-3.6.7/0040-Fix-BUG-in-bcm2708_fb_set_par-doesn-t-work-if-the-co.patch
index f627c4a..09460a4 100644
--- a/patches/linux-3.2.27/0041-Fix-BUG-in-bcm2708_fb_set_par-doesn-t-work-if-the-co.patch
+++ b/patches/linux-3.6.7/0040-Fix-BUG-in-bcm2708_fb_set_par-doesn-t-work-if-the-co.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] Fix BUG() in bcm2708_fb_set_par doesn't work if the console
is currently locked. Thanks lp0
---
- drivers/video/bcm2708_fb.c | 8 +++++++-
+ drivers/video/bcm2708_fb.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
diff --git a/patches/linux-3.2.27/0042-Fix-for-DWC-OTG-HCD-URB-Dequeue-has-NULL-URB-panic.-.patch b/patches/linux-3.6.7/0041-Fix-for-DWC-OTG-HCD-URB-Dequeue-has-NULL-URB-panic.-.patch
index 0a4afb4..f48afc8 100644
--- a/patches/linux-3.2.27/0042-Fix-for-DWC-OTG-HCD-URB-Dequeue-has-NULL-URB-panic.-.patch
+++ b/patches/linux-3.6.7/0041-Fix-for-DWC-OTG-HCD-URB-Dequeue-has-NULL-URB-panic.-.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] Fix for DWC OTG HCD URB Dequeue has NULL URB panic. Thanks
Naren
---
- drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 8 +++++---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
diff --git a/patches/linux-3.2.27/0043-Fix-for-bug-in-mbox_read.-Thanks-lp0.patch b/patches/linux-3.6.7/0042-Fix-for-bug-in-mbox_read.-Thanks-lp0.patch
index ea825d4..4a7e3c3 100644
--- a/patches/linux-3.2.27/0043-Fix-for-bug-in-mbox_read.-Thanks-lp0.patch
+++ b/patches/linux-3.6.7/0042-Fix-for-bug-in-mbox_read.-Thanks-lp0.patch
@@ -3,9 +3,9 @@ Date: Wed, 16 May 2012 14:15:12 +0100
Subject: [PATCH] Fix for bug in mbox_read. Thanks lp0
---
- arch/arm/mach-bcm2708/power.c | 2 --
- arch/arm/mach-bcm2708/vcio.c | 3 +--
- drivers/video/bcm2708_fb.c | 4 +---
+ arch/arm/mach-bcm2708/power.c | 2 --
+ arch/arm/mach-bcm2708/vcio.c | 3 +--
+ drivers/video/bcm2708_fb.c | 4 +---
3 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-bcm2708/power.c b/arch/arm/mach-bcm2708/power.c
diff --git a/patches/linux-3.2.27/0044-Add-__VCCOREVER__-to-makefile.patch b/patches/linux-3.6.7/0043-Add-__VCCOREVER__-to-makefile.patch
index 7f56091..b5aafda 100644
--- a/patches/linux-3.2.27/0044-Add-__VCCOREVER__-to-makefile.patch
+++ b/patches/linux-3.6.7/0043-Add-__VCCOREVER__-to-makefile.patch
@@ -3,7 +3,7 @@ Date: Wed, 16 May 2012 20:16:43 +0100
Subject: [PATCH] Add __VCCOREVER__ to makefile
---
- sound/arm/Makefile | 2 +-
+ sound/arm/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/arm/Makefile b/sound/arm/Makefile
diff --git a/patches/linux-3.2.27/0045-Change-PHYS_OFFSET-to-PLAT_PHYS_OFFSET.patch b/patches/linux-3.6.7/0044-Change-PHYS_OFFSET-to-PLAT_PHYS_OFFSET.patch
index 939f6e8..e16eac4 100644
--- a/patches/linux-3.2.27/0045-Change-PHYS_OFFSET-to-PLAT_PHYS_OFFSET.patch
+++ b/patches/linux-3.6.7/0044-Change-PHYS_OFFSET-to-PLAT_PHYS_OFFSET.patch
@@ -3,7 +3,7 @@ Date: Thu, 17 May 2012 14:40:44 +0100
Subject: [PATCH] Change PHYS_OFFSET to PLAT_PHYS_OFFSET
---
- arch/arm/mach-bcm2708/include/mach/memory.h | 6 +++---
+ arch/arm/mach-bcm2708/include/mach/memory.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-bcm2708/include/mach/memory.h b/arch/arm/mach-bcm2708/include/mach/memory.h
diff --git a/patches/linux-3.2.27/0046-sdcard-patch-improvements-from-naren.patch b/patches/linux-3.6.7/0045-sdcard-patch-improvements-from-naren.patch
index f891cd5..52ece3b 100644
--- a/patches/linux-3.2.27/0046-sdcard-patch-improvements-from-naren.patch
+++ b/patches/linux-3.6.7/0045-sdcard-patch-improvements-from-naren.patch
@@ -3,7 +3,7 @@ Date: Thu, 17 May 2012 14:44:19 +0100
Subject: [PATCH] sdcard patch improvements from naren
---
- drivers/mmc/host/sdhci-bcm2708.c | 23 +++++++----------------
+ drivers/mmc/host/sdhci-bcm2708.c | 23 +++++++----------------
1 file changed, 7 insertions(+), 16 deletions(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0047-Invert-sense-of-sdcard-access-trigger-OK-LED-so-it-i.patch b/patches/linux-3.6.7/0046-Invert-sense-of-sdcard-access-trigger-OK-LED-so-it-i.patch
index eaaa816..6cc0664 100644
--- a/patches/linux-3.2.27/0047-Invert-sense-of-sdcard-access-trigger-OK-LED-so-it-i.patch
+++ b/patches/linux-3.6.7/0046-Invert-sense-of-sdcard-access-trigger-OK-LED-so-it-i.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] Invert sense of sdcard access trigger (OK LED), so it is on
when accessing
---
- arch/arm/mach-bcm2708/bcm2708.c | 2 +-
+ arch/arm/mach-bcm2708/bcm2708.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
diff --git a/patches/linux-3.2.27/0048-Added-power-off-message-to-allow-kexec-to-work.-Than.patch b/patches/linux-3.6.7/0047-Added-power-off-message-to-allow-kexec-to-work.-Than.patch
index 4bb150f..4277a9b 100644
--- a/patches/linux-3.2.27/0048-Added-power-off-message-to-allow-kexec-to-work.-Than.patch
+++ b/patches/linux-3.6.7/0047-Added-power-off-message-to-allow-kexec-to-work.-Than.patch
@@ -3,8 +3,8 @@ Date: Sat, 26 May 2012 16:40:51 +0100
Subject: [PATCH] Added power off message to allow kexec to work. Thanks lp0
---
- arch/arm/mach-bcm2708/power.c | 1 +
- arch/arm/mach-bcm2708/power.c.rej | 10 ++++++++++
+ arch/arm/mach-bcm2708/power.c | 1 +
+ arch/arm/mach-bcm2708/power.c.rej | 10 ++++++++++
2 files changed, 11 insertions(+)
create mode 100644 arch/arm/mach-bcm2708/power.c.rej
diff --git a/patches/linux-3.2.27/0049-remove-unwanted-file.patch b/patches/linux-3.6.7/0048-remove-unwanted-file.patch
index 605acb5..b2fc796 100644
--- a/patches/linux-3.2.27/0049-remove-unwanted-file.patch
+++ b/patches/linux-3.6.7/0048-remove-unwanted-file.patch
@@ -3,7 +3,7 @@ Date: Sun, 27 May 2012 19:24:35 +0100
Subject: [PATCH] remove unwanted file
---
- arch/arm/mach-bcm2708/power.c.rej | 10 ----------
+ arch/arm/mach-bcm2708/power.c.rej | 10 ----------
1 file changed, 10 deletions(-)
delete mode 100644 arch/arm/mach-bcm2708/power.c.rej
diff --git a/patches/linux-3.2.27/0050-Enable-PREEMPT-and-SCHED_AUTOGROUP.patch b/patches/linux-3.6.7/0049-Enable-PREEMPT-and-SCHED_AUTOGROUP.patch
index 74870ff..02c5dd7 100644
--- a/patches/linux-3.2.27/0050-Enable-PREEMPT-and-SCHED_AUTOGROUP.patch
+++ b/patches/linux-3.6.7/0049-Enable-PREEMPT-and-SCHED_AUTOGROUP.patch
@@ -3,8 +3,8 @@ Date: Tue, 29 May 2012 00:04:15 +0100
Subject: [PATCH] Enable PREEMPT and SCHED_AUTOGROUP
---
- arch/arm/configs/bcmrpi_cutdown_defconfig | 4 ++++
- arch/arm/configs/bcmrpi_defconfig | 2 ++
+ arch/arm/configs/bcmrpi_cutdown_defconfig | 4 ++++
+ arch/arm/configs/bcmrpi_defconfig | 2 ++
2 files changed, 6 insertions(+)
diff --git a/arch/arm/configs/bcmrpi_cutdown_defconfig b/arch/arm/configs/bcmrpi_cutdown_defconfig
diff --git a/patches/linux-3.2.27/0051-Added-support-for-USB-webcams.patch b/patches/linux-3.6.7/0050-Added-support-for-USB-webcams.patch
index fe1303c..0e39e19 100644
--- a/patches/linux-3.2.27/0051-Added-support-for-USB-webcams.patch
+++ b/patches/linux-3.6.7/0050-Added-support-for-USB-webcams.patch
@@ -3,8 +3,8 @@ Date: Wed, 30 May 2012 11:57:52 +0100
Subject: [PATCH] Added support for USB webcams
---
- arch/arm/configs/bcmrpi_cutdown_defconfig | 52 ++++++++++++++++++++++
- arch/arm/configs/bcmrpi_defconfig | 69 +++++++++++++++++++++++------
+ arch/arm/configs/bcmrpi_cutdown_defconfig | 52 +++++++++++++++++++++++
+ arch/arm/configs/bcmrpi_defconfig | 69 +++++++++++++++++++++++++------
2 files changed, 108 insertions(+), 13 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_cutdown_defconfig b/arch/arm/configs/bcmrpi_cutdown_defconfig
diff --git a/patches/linux-3.2.27/0052-Enable-ipv6-due-to-popular-demand.patch b/patches/linux-3.6.7/0051-Enable-ipv6-due-to-popular-demand.patch
index 2d64159..223f3d7 100644
--- a/patches/linux-3.2.27/0052-Enable-ipv6-due-to-popular-demand.patch
+++ b/patches/linux-3.6.7/0051-Enable-ipv6-due-to-popular-demand.patch
@@ -3,8 +3,8 @@ Date: Wed, 30 May 2012 21:54:02 +0100
Subject: [PATCH] Enable ipv6 due to popular demand
---
- arch/arm/configs/bcmrpi_cutdown_defconfig | 2 +-
- arch/arm/configs/bcmrpi_defconfig | 2 +-
+ arch/arm/configs/bcmrpi_cutdown_defconfig | 2 +-
+ arch/arm/configs/bcmrpi_defconfig | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_cutdown_defconfig b/arch/arm/configs/bcmrpi_cutdown_defconfig
diff --git a/patches/linux-3.2.27/0053-Fix-regression-in-debug-kernel-config-options.patch b/patches/linux-3.6.7/0052-Fix-regression-in-debug-kernel-config-options.patch
index 9dcadf8..027e98c 100644
--- a/patches/linux-3.2.27/0053-Fix-regression-in-debug-kernel-config-options.patch
+++ b/patches/linux-3.6.7/0052-Fix-regression-in-debug-kernel-config-options.patch
@@ -3,7 +3,7 @@ Date: Thu, 31 May 2012 13:01:16 +0100
Subject: [PATCH] Fix regression in debug kernel config options
---
- arch/arm/configs/bcmrpi_defconfig | 19 ++++++++++++++-----
+ arch/arm/configs/bcmrpi_defconfig | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
diff --git a/patches/linux-3.2.27/0054-bcm2835-ctl-fix-alsamixer-control.patch b/patches/linux-3.6.7/0053-bcm2835-ctl-fix-alsamixer-control.patch
index 39d6594..726a5da 100644
--- a/patches/linux-3.2.27/0054-bcm2835-ctl-fix-alsamixer-control.patch
+++ b/patches/linux-3.6.7/0053-bcm2835-ctl-fix-alsamixer-control.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] bcm2835-ctl: fix alsamixer control.
alsamixer read the volume for the screen controller so we had to
scale the chipvol back to db for reading.
---
- sound/arm/bcm2835-ctl.c | 22 ++++++++++++++++------
+ sound/arm/bcm2835-ctl.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c
diff --git a/patches/linux-3.2.27/0055-bcm2835-ctl-limit-maximal-volume-to-4db.patch b/patches/linux-3.6.7/0054-bcm2835-ctl-limit-maximal-volume-to-4db.patch
index 2879063..87d7d17 100644
--- a/patches/linux-3.2.27/0055-bcm2835-ctl-limit-maximal-volume-to-4db.patch
+++ b/patches/linux-3.6.7/0054-bcm2835-ctl-limit-maximal-volume-to-4db.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] bcm2835-ctl: limit maximal volume to 4db.
it makes no sense to set 23.04db as maximum volume since around 3db it start to cliping. So with 4db the alsamixer is much better to control. (86% is 0db)
---
- sound/arm/bcm2835-ctl.c | 2 +-
+ sound/arm/bcm2835-ctl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c
diff --git a/patches/linux-3.2.27/0056-Add-iptables-and-devtmpfs_mount-to-non-cutdown-confi.patch b/patches/linux-3.6.7/0055-Add-iptables-and-devtmpfs_mount-to-non-cutdown-confi.patch
index dabca56..2f3dd68 100644
--- a/patches/linux-3.2.27/0056-Add-iptables-and-devtmpfs_mount-to-non-cutdown-confi.patch
+++ b/patches/linux-3.6.7/0055-Add-iptables-and-devtmpfs_mount-to-non-cutdown-confi.patch
@@ -4,8 +4,8 @@ Subject: [PATCH] Add iptables and devtmpfs_mount to non-cutdown config. This
will become default kernel
---
- arch/arm/configs/bcmrpi_cutdown_defconfig | 1 +
- arch/arm/configs/bcmrpi_defconfig | 147 ++++++++++++++++++++++++++++-
+ arch/arm/configs/bcmrpi_cutdown_defconfig | 1 +
+ arch/arm/configs/bcmrpi_defconfig | 147 +++++++++++++++++++++++++++++-
2 files changed, 144 insertions(+), 4 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_cutdown_defconfig b/arch/arm/configs/bcmrpi_cutdown_defconfig
diff --git a/patches/linux-3.2.27/0058-sdhci-bcm2708-speed-up-DMA-sync.patch b/patches/linux-3.6.7/0056-sdhci-bcm2708-speed-up-DMA-sync.patch
index 943e482..a529cd4 100644
--- a/patches/linux-3.2.27/0058-sdhci-bcm2708-speed-up-DMA-sync.patch
+++ b/patches/linux-3.6.7/0056-sdhci-bcm2708-speed-up-DMA-sync.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] sdhci-bcm2708: speed up DMA sync
Experiments show that it doesn't really take that long to sync, so we
can reduce the poll interval slightly. Might improve performance a bit.
---
- drivers/mmc/host/sdhci-bcm2708.c | 2 +-
+ drivers/mmc/host/sdhci-bcm2708.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0059-sdhci-bcm2708-remove-custom-clock-handling.patch b/patches/linux-3.6.7/0057-sdhci-bcm2708-remove-custom-clock-handling.patch
index 645fecf..efe862f 100644
--- a/patches/linux-3.2.27/0059-sdhci-bcm2708-remove-custom-clock-handling.patch
+++ b/patches/linux-3.6.7/0057-sdhci-bcm2708-remove-custom-clock-handling.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] sdhci-bcm2708: remove custom clock handling
The custom clock handling code is redundant and buggy. The MMC/SDHCI
subsystem does a better job than it, so remove it for good.
---
- drivers/mmc/host/sdhci-bcm2708.c | 65 +-------------------------------------
+ drivers/mmc/host/sdhci-bcm2708.c | 65 +---------------------------------------
1 file changed, 1 insertion(+), 64 deletions(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0060-sdhci-bcm2708-add-additional-quirks.patch b/patches/linux-3.6.7/0058-sdhci-bcm2708-add-additional-quirks.patch
index b4c9503..54e1ef8 100644
--- a/patches/linux-3.2.27/0060-sdhci-bcm2708-add-additional-quirks.patch
+++ b/patches/linux-3.6.7/0058-sdhci-bcm2708-add-additional-quirks.patch
@@ -8,7 +8,7 @@ zero, so add SDHCI_QUIRK_MISSING_CAPS. Apparently
SDHCI_QUIRK_NO_HISPD_BIT is needed for many cards to work correctly in
high-speed mode, so add it as well.
---
- drivers/mmc/host/sdhci-bcm2708.c | 4 +++-
+ drivers/mmc/host/sdhci-bcm2708.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0061-sdhci-bcm2708-add-allow_highspeed-parameter.patch b/patches/linux-3.6.7/0059-sdhci-bcm2708-add-allow_highspeed-parameter.patch
index 3446214..f101260 100644
--- a/patches/linux-3.2.27/0061-sdhci-bcm2708-add-allow_highspeed-parameter.patch
+++ b/patches/linux-3.6.7/0059-sdhci-bcm2708-add-allow_highspeed-parameter.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] sdhci-bcm2708: add allow_highspeed parameter
Add a parameter to disable high-speed mode for the few cards that
still might have problems. High-speed mode is enabled by default.
---
- drivers/mmc/host/sdhci-bcm2708.c | 9 ++++++++-
+ drivers/mmc/host/sdhci-bcm2708.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0062-sdhci-bcm2708-assume-50-MHz-eMMC-clock.patch b/patches/linux-3.6.7/0060-sdhci-bcm2708-assume-50-MHz-eMMC-clock.patch
index 75c24b8..f19e29f 100644
--- a/patches/linux-3.2.27/0062-sdhci-bcm2708-assume-50-MHz-eMMC-clock.patch
+++ b/patches/linux-3.6.7/0060-sdhci-bcm2708-assume-50-MHz-eMMC-clock.patch
@@ -6,7 +6,7 @@ Subject: [PATCH] sdhci-bcm2708: assume 50 MHz eMMC clock
MHz (default mode) or 50 MHz (high speed mode). 50 MHz are perfect to
drive the SD interface at ideal frequencies.
---
- drivers/mmc/host/sdhci-bcm2708.c | 2 +-
+ drivers/mmc/host/sdhci-bcm2708.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0063-Allow-emmc-clock-to-be-specified-as-command-line-par.patch b/patches/linux-3.6.7/0061-Allow-emmc-clock-to-be-specified-as-command-line-par.patch
index a1fc66d..16ff96b 100644
--- a/patches/linux-3.2.27/0063-Allow-emmc-clock-to-be-specified-as-command-line-par.patch
+++ b/patches/linux-3.6.7/0061-Allow-emmc-clock-to-be-specified-as-command-line-par.patch
@@ -3,7 +3,7 @@ Date: Sat, 16 Jun 2012 22:31:55 +0100
Subject: [PATCH] Allow emmc clock to be specified as command line parameter
---
- drivers/mmc/host/sdhci-bcm2708.c | 6 +++++-
+ drivers/mmc/host/sdhci-bcm2708.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0064-sdhci-bcm2708-raise-DMA-sync-timeout.patch b/patches/linux-3.6.7/0062-sdhci-bcm2708-raise-DMA-sync-timeout.patch
index 617eeca..f5cfca6 100644
--- a/patches/linux-3.2.27/0064-sdhci-bcm2708-raise-DMA-sync-timeout.patch
+++ b/patches/linux-3.6.7/0062-sdhci-bcm2708-raise-DMA-sync-timeout.patch
@@ -10,7 +10,7 @@ cards require crazy long timeouts (3s), but as we're busy-waiting,
and shouldn't delay for such a long time, let's hope 150ms will be
enough for most cards.
---
- drivers/mmc/host/sdhci-bcm2708.c | 2 +-
+ drivers/mmc/host/sdhci-bcm2708.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0065-Fix-bool-int-error.patch b/patches/linux-3.6.7/0063-Fix-bool-int-error.patch
index e911b1f..1bbeaba 100644
--- a/patches/linux-3.2.27/0065-Fix-bool-int-error.patch
+++ b/patches/linux-3.6.7/0063-Fix-bool-int-error.patch
@@ -3,7 +3,7 @@ Date: Sat, 16 Jun 2012 23:26:28 +0100
Subject: [PATCH] Fix bool/int error
---
- drivers/mmc/host/sdhci-bcm2708.c | 2 +-
+ drivers/mmc/host/sdhci-bcm2708.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0066-Fix-bool-int-error-part-2.patch b/patches/linux-3.6.7/0064-Fix-bool-int-error-part-2.patch
index 85dc47c..d56c1b2 100644
--- a/patches/linux-3.2.27/0066-Fix-bool-int-error-part-2.patch
+++ b/patches/linux-3.6.7/0064-Fix-bool-int-error-part-2.patch
@@ -3,11 +3,11 @@ Date: Sat, 16 Jun 2012 23:46:08 +0100
Subject: [PATCH] Fix bool/int error, part 2
---
- drivers/mmc/host/sdhci-bcm2708.c | 2 +-
+ drivers/mmc/host/sdhci-bcm2708.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
-index eedd724..13abbc92 100644
+index eedd724..13abbc9 100644
--- a/drivers/mmc/host/sdhci-bcm2708.c
+++ b/drivers/mmc/host/sdhci-bcm2708.c
@@ -136,7 +136,7 @@ static inline unsigned long int since_ns(hptime_t t)
diff --git a/patches/linux-3.2.27/0067-More-config-options-for-iptables-device-mapper-PPP_M.patch b/patches/linux-3.6.7/0065-More-config-options-for-iptables-device-mapper-PPP_M.patch
index 1327a7d..4b8f871 100644
--- a/patches/linux-3.2.27/0067-More-config-options-for-iptables-device-mapper-PPP_M.patch
+++ b/patches/linux-3.6.7/0065-More-config-options-for-iptables-device-mapper-PPP_M.patch
@@ -3,7 +3,7 @@ Date: Sat, 16 Jun 2012 23:49:52 +0100
Subject: [PATCH] More config options for iptables, device mapper, PPP_MPPE
---
- arch/arm/configs/bcmrpi_defconfig | 38 +++++++++++++++++++++++++++++++++++--
+ arch/arm/configs/bcmrpi_defconfig | 38 ++++++++++++++++++++++++++++++++++++--
1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
diff --git a/patches/linux-3.2.27/0068-Explicitly-set-usb-host-channels-to-8-as-in-the-spec.patch b/patches/linux-3.6.7/0066-Explicitly-set-usb-host-channels-to-8-as-in-the-spec.patch
index 3dfabde..d9317dc 100644
--- a/patches/linux-3.2.27/0068-Explicitly-set-usb-host-channels-to-8-as-in-the-spec.patch
+++ b/patches/linux-3.6.7/0066-Explicitly-set-usb-host-channels-to-8-as-in-the-spec.patch
@@ -3,7 +3,7 @@ Date: Sun, 17 Jun 2012 00:14:54 +0100
Subject: [PATCH] Explicitly set usb host channels to 8, as in the spec
---
- drivers/usb/host/dwc_otg/dwc_otg_core_if.h | 3 ++-
+ drivers/usb/host/dwc_otg/dwc_otg_core_if.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_core_if.h b/drivers/usb/host/dwc_otg/dwc_otg_core_if.h
diff --git a/patches/linux-3.2.27/0069-Add-hfs-hfsplus-modules.patch b/patches/linux-3.6.7/0067-Add-hfs-hfsplus-modules.patch
index d823749..a12d2c6 100644
--- a/patches/linux-3.2.27/0069-Add-hfs-hfsplus-modules.patch
+++ b/patches/linux-3.6.7/0067-Add-hfs-hfsplus-modules.patch
@@ -3,7 +3,7 @@ Date: Sun, 17 Jun 2012 15:52:33 +0100
Subject: [PATCH] Add hfs/hfsplus modules
---
- arch/arm/configs/bcmrpi_defconfig | 3 ++-
+ arch/arm/configs/bcmrpi_defconfig | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
diff --git a/patches/linux-3.2.27/0070-Remove-silence-method-and-use-atomic-flags-for-kmall.patch b/patches/linux-3.6.7/0068-Remove-silence-method-and-use-atomic-flags-for-kmall.patch
index 528e71b..4eccfaf 100644
--- a/patches/linux-3.2.27/0070-Remove-silence-method-and-use-atomic-flags-for-kmall.patch
+++ b/patches/linux-3.6.7/0068-Remove-silence-method-and-use-atomic-flags-for-kmall.patch
@@ -3,8 +3,8 @@ Date: Thu, 21 Jun 2012 01:31:08 +0100
Subject: [PATCH] Remove silence method, and use atomic flags for kmalloc
---
- sound/arm/bcm2835-pcm.c | 24 ------------------------
- sound/arm/bcm2835-vchiq.c | 4 ++--
+ sound/arm/bcm2835-pcm.c | 24 ------------------------
+ sound/arm/bcm2835-vchiq.c | 4 ++--
2 files changed, 2 insertions(+), 26 deletions(-)
diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c
diff --git a/patches/linux-3.2.27/0071-Fix-unintended-line-swap-that-cause-cause-memory-lea.patch b/patches/linux-3.6.7/0069-Fix-unintended-line-swap-that-cause-cause-memory-lea.patch
index 9e2c72c..36411a7 100644
--- a/patches/linux-3.2.27/0071-Fix-unintended-line-swap-that-cause-cause-memory-lea.patch
+++ b/patches/linux-3.6.7/0069-Fix-unintended-line-swap-that-cause-cause-memory-lea.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] Fix unintended line swap that cause cause memory leak in USB
driver
---
- drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 2 +-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
diff --git a/patches/linux-3.2.27/0072-Use-ndelay-rather-than-udelay.-Thanks-lb.patch b/patches/linux-3.6.7/0070-Use-ndelay-rather-than-udelay.-Thanks-lb.patch
index 54e3f34..6d70880 100644
--- a/patches/linux-3.2.27/0072-Use-ndelay-rather-than-udelay.-Thanks-lb.patch
+++ b/patches/linux-3.6.7/0070-Use-ndelay-rather-than-udelay.-Thanks-lb.patch
@@ -3,11 +3,11 @@ Date: Fri, 22 Jun 2012 12:57:42 +0100
Subject: [PATCH] Use ndelay rather than udelay. Thanks lb
---
- drivers/mmc/host/sdhci-bcm2708.c | 8 ++++----
+ drivers/mmc/host/sdhci-bcm2708.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
-index 13abbc92..1d8751c 100644
+index 13abbc9..1d8751c 100644
--- a/drivers/mmc/host/sdhci-bcm2708.c
+++ b/drivers/mmc/host/sdhci-bcm2708.c
@@ -255,14 +255,14 @@ static void sdhci_bcm2708_raw_writel(struct sdhci_host *host, u32 val, int reg)
diff --git a/patches/linux-3.2.27/0073-Add-NFSD.-Add-some-dvb-options.-Add-CONFIG_LOCALVERS.patch b/patches/linux-3.6.7/0071-Add-NFSD.-Add-some-dvb-options.-Add-CONFIG_LOCALVERS.patch
index dc31dd7..18123c3 100644
--- a/patches/linux-3.2.27/0073-Add-NFSD.-Add-some-dvb-options.-Add-CONFIG_LOCALVERS.patch
+++ b/patches/linux-3.6.7/0071-Add-NFSD.-Add-some-dvb-options.-Add-CONFIG_LOCALVERS.patch
@@ -4,8 +4,8 @@ Subject: [PATCH] Add NFSD. Add some dvb options. Add CONFIG_LOCALVERSION for
cutdown
---
- arch/arm/configs/bcmrpi_cutdown_defconfig | 1 +
- arch/arm/configs/bcmrpi_defconfig | 5 +++++
+ arch/arm/configs/bcmrpi_cutdown_defconfig | 1 +
+ arch/arm/configs/bcmrpi_defconfig | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/arch/arm/configs/bcmrpi_cutdown_defconfig b/arch/arm/configs/bcmrpi_cutdown_defconfig
diff --git a/patches/linux-3.2.27/0074-Fixed-issue-with-some-keyboards-giving-too-much-data.patch b/patches/linux-3.6.7/0072-Fixed-issue-with-some-keyboards-giving-too-much-data.patch
index e467740..9d827c2 100644
--- a/patches/linux-3.2.27/0074-Fixed-issue-with-some-keyboards-giving-too-much-data.patch
+++ b/patches/linux-3.6.7/0072-Fixed-issue-with-some-keyboards-giving-too-much-data.patch
@@ -7,9 +7,9 @@ Subject: [PATCH] Fixed issue with some keyboards giving too much data
Naren.
---
- drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 4 ++--
- drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 6 +++---
- drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 13 ++++++++++---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 4 ++--
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 6 +++---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 13 ++++++++++---
3 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c
diff --git a/patches/linux-3.2.27/0075-Add-802.1q-vlan-module.patch b/patches/linux-3.6.7/0073-Add-802.1q-vlan-module.patch
index 0d6f7cb..375a778 100644
--- a/patches/linux-3.2.27/0075-Add-802.1q-vlan-module.patch
+++ b/patches/linux-3.6.7/0073-Add-802.1q-vlan-module.patch
@@ -3,7 +3,7 @@ Date: Sat, 30 Jun 2012 11:40:33 +0100
Subject: [PATCH] Add 802.1q vlan module
---
- arch/arm/configs/bcmrpi_defconfig | 2 ++
+ arch/arm/configs/bcmrpi_defconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
diff --git a/patches/linux-3.2.27/0076-Add-interrupt-support-to-gpio-driver.-Thanks-Mrkva.patch b/patches/linux-3.6.7/0074-Add-interrupt-support-to-gpio-driver.-Thanks-Mrkva.patch
index 0f09a1f..8ea98b3 100644
--- a/patches/linux-3.2.27/0076-Add-interrupt-support-to-gpio-driver.-Thanks-Mrkva.patch
+++ b/patches/linux-3.6.7/0074-Add-interrupt-support-to-gpio-driver.-Thanks-Mrkva.patch
@@ -3,9 +3,9 @@ Date: Sat, 30 Jun 2012 11:47:45 +0100
Subject: [PATCH] Add interrupt support to gpio driver. Thanks Mrkva
---
- arch/arm/mach-bcm2708/bcm2708_gpio.c | 264 +++++++++++++++--------------
- arch/arm/mach-bcm2708/include/mach/gpio.h | 17 +-
- arch/arm/mach-bcm2708/include/mach/irqs.h | 8 +-
+ arch/arm/mach-bcm2708/bcm2708_gpio.c | 264 ++++++++++++++++--------------
+ arch/arm/mach-bcm2708/include/mach/gpio.h | 17 +-
+ arch/arm/mach-bcm2708/include/mach/irqs.h | 8 +-
3 files changed, 154 insertions(+), 135 deletions(-)
diff --git a/arch/arm/mach-bcm2708/bcm2708_gpio.c b/arch/arm/mach-bcm2708/bcm2708_gpio.c
diff --git a/patches/linux-3.2.27/0077-Add-a-pm_power_off-function-that-resets-us-and-indic.patch b/patches/linux-3.6.7/0075-Add-a-pm_power_off-function-that-resets-us-and-indic.patch
index bc47f89..d5b7964 100644
--- a/patches/linux-3.2.27/0077-Add-a-pm_power_off-function-that-resets-us-and-indic.patch
+++ b/patches/linux-3.6.7/0075-Add-a-pm_power_off-function-that-resets-us-and-indic.patch
@@ -5,8 +5,8 @@ Subject: [PATCH] Add a pm_power_off function that resets us, and indicates to
'off' state
---
- arch/arm/mach-bcm2708/bcm2708.c | 14 ++++++++++++++
- arch/arm/mach-bcm2708/include/mach/platform.h | 16 +++++++++++++---
+ arch/arm/mach-bcm2708/bcm2708.c | 14 ++++++++++++++
+ arch/arm/mach-bcm2708/include/mach/platform.h | 16 +++++++++++++---
2 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
diff --git a/patches/linux-3.2.27/0078-Store-palette-info-where-GPU-can-see-it-so-8bpp-mode.patch b/patches/linux-3.6.7/0076-Store-palette-info-where-GPU-can-see-it-so-8bpp-mode.patch
index 665bcd1..53679b9 100644
--- a/patches/linux-3.2.27/0078-Store-palette-info-where-GPU-can-see-it-so-8bpp-mode.patch
+++ b/patches/linux-3.6.7/0076-Store-palette-info-where-GPU-can-see-it-so-8bpp-mode.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] Store palette info where GPU can see it, so 8bpp modes can
work. Requires updated start.elf to work properly
---
- drivers/video/bcm2708_fb.c | 14 ++++++++++++++
+ drivers/video/bcm2708_fb.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
diff --git a/patches/linux-3.2.27/0079-Avoid-blanking-console-when-not-in-palettised-mode.patch b/patches/linux-3.6.7/0077-Avoid-blanking-console-when-not-in-palettised-mode.patch
index 46b56e9..dbf2312 100644
--- a/patches/linux-3.2.27/0079-Avoid-blanking-console-when-not-in-palettised-mode.patch
+++ b/patches/linux-3.6.7/0077-Avoid-blanking-console-when-not-in-palettised-mode.patch
@@ -3,7 +3,7 @@ Date: Mon, 2 Jul 2012 20:34:38 +0100
Subject: [PATCH] Avoid blanking console when not in palettised mode
---
- drivers/video/bcm2708_fb.c | 24 ++++++++++++------------
+ drivers/video/bcm2708_fb.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
diff --git a/patches/linux-3.2.27/0080-Add-mechanism-to-reduce-the-number-of-SOF-interrupts.patch b/patches/linux-3.6.7/0078-Add-mechanism-to-reduce-the-number-of-SOF-interrupts.patch
index 88cd06d..ee99a33 100644
--- a/patches/linux-3.2.27/0080-Add-mechanism-to-reduce-the-number-of-SOF-interrupts.patch
+++ b/patches/linux-3.6.7/0078-Add-mechanism-to-reduce-the-number-of-SOF-interrupts.patch
@@ -5,13 +5,13 @@ Subject: [PATCH] Add mechanism to reduce the number of SOF interrupts in
/proc/dwc_sof/SOF_reduction
---
- .../usb/host/dwc_common_port/dwc_common_linux.c | 2 +-
- drivers/usb/host/dwc_otg/Makefile | 7 +-
- drivers/usb/host/dwc_otg/dwc_otg_driver.c | 149 ++++++++++++++++++++
- drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 56 ++++++++
- drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 9 ++
- drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 103 +++++++++++++-
- drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 19 +++
+ .../usb/host/dwc_common_port/dwc_common_linux.c | 2 +-
+ drivers/usb/host/dwc_otg/Makefile | 7 +-
+ drivers/usb/host/dwc_otg/dwc_otg_driver.c | 149 +++++++++++++++++++++
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 56 ++++++++
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 9 ++
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 103 +++++++++++++-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 19 +++
7 files changed, 338 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/host/dwc_common_port/dwc_common_linux.c b/drivers/usb/host/dwc_common_port/dwc_common_linux.c
diff --git a/patches/linux-3.2.27/0081-Updating-dwc_otg-driver-to-fix-issue-releasing-pcm-s.patch b/patches/linux-3.6.7/0079-Updating-dwc_otg-driver-to-fix-issue-releasing-pcm-s.patch
index a16efe9..f1cc6d7 100644
--- a/patches/linux-3.2.27/0081-Updating-dwc_otg-driver-to-fix-issue-releasing-pcm-s.patch
+++ b/patches/linux-3.6.7/0079-Updating-dwc_otg-driver-to-fix-issue-releasing-pcm-s.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] Updating dwc_otg driver to fix issue releasing pcm stream
see: https://github.com/raspberrypi/firmware/issues/51
---
- drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 20 ++++++++++++++++++--
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
diff --git a/patches/linux-3.2.27/0082-Backport-of-Chris-Boot-s-i2c-and-spi-drivers.patch b/patches/linux-3.6.7/0080-Backport-of-Chris-Boot-s-i2c-and-spi-drivers.patch
index c823510..88419ce 100644
--- a/patches/linux-3.2.27/0082-Backport-of-Chris-Boot-s-i2c-and-spi-drivers.patch
+++ b/patches/linux-3.6.7/0080-Backport-of-Chris-Boot-s-i2c-and-spi-drivers.patch
@@ -3,13 +3,13 @@ Date: Sun, 8 Jul 2012 20:57:25 +0100
Subject: [PATCH] Backport of Chris Boot's i2c and spi drivers.
---
- arch/arm/configs/bcmrpi_cutdown_defconfig | 9 +++
- arch/arm/mach-bcm2708/bcm2708.c | 95 ++++++++++++++++++++++++-
- arch/arm/mach-bcm2708/include/mach/platform.h | 3 +
- drivers/i2c/busses/Kconfig | 8 +++
- drivers/i2c/busses/Makefile | 1 +
- drivers/spi/Kconfig | 8 +++
- drivers/spi/Makefile | 1 +
+ arch/arm/configs/bcmrpi_cutdown_defconfig | 9 +++
+ arch/arm/mach-bcm2708/bcm2708.c | 95 ++++++++++++++++++++++++++-
+ arch/arm/mach-bcm2708/include/mach/platform.h | 3 +
+ drivers/i2c/busses/Kconfig | 8 +++
+ drivers/i2c/busses/Makefile | 1 +
+ drivers/spi/Kconfig | 8 +++
+ drivers/spi/Makefile | 1 +
7 files changed, 123 insertions(+), 2 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_cutdown_defconfig b/arch/arm/configs/bcmrpi_cutdown_defconfig
@@ -196,10 +196,10 @@ index 5afa0a7..3085af1 100644
#define MCORE_BASE (BCM2708_PERI_BASE + 0x0000) /* Fake frame buffer device (actually the multicore sync block*/
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
-index a3afac4..cbc62ff 100644
+index 970a161..99cb85b 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
-@@ -308,6 +308,14 @@ config I2C_AU1550
+@@ -314,6 +314,14 @@ config I2C_AU1550
This driver can also be built as a module. If so, the module
will be called i2c-au1550.
@@ -215,7 +215,7 @@ index a3afac4..cbc62ff 100644
tristate "Blackfin TWI I2C support"
depends on BLACKFIN
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
-index fba6da6..4022671 100644
+index 37c4182..d8ff8f9 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o
@@ -227,7 +227,7 @@ index fba6da6..4022671 100644
obj-$(CONFIG_I2C_CPM) += i2c-cpm.o
obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
-index 7587796..4153631 100644
+index 5f84b55..ec934d9 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -74,6 +74,14 @@ config SPI_ATMEL
@@ -242,18 +242,18 @@ index 7587796..4153631 100644
+ driver is not compatible with the "Universal SPI Master" or the SPI slave
+ device.
+
- config SPI_BFIN
+ config SPI_BFIN5XX
tristate "SPI controller driver for ADI Blackfin5xx"
depends on BLACKFIN
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
-index 61c3261..2ff2985 100644
+index 3920dcf..1905862 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
-@@ -14,6 +14,7 @@ obj-$(CONFIG_SPI_ALTERA) += spi-altera.o
- obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o
- obj-$(CONFIG_SPI_ATH79) += spi-ath79.o
+@@ -16,6 +16,7 @@ obj-$(CONFIG_SPI_ATH79) += spi-ath79.o
obj-$(CONFIG_SPI_AU1550) += spi-au1550.o
+ obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o
+ obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o
+obj-$(CONFIG_SPI_BCM2708) += spi-bcm2708.o
- obj-$(CONFIG_SPI_BFIN) += spi-bfin5xx.o
obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o
obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o
+ obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o
diff --git a/patches/linux-3.2.27/0083-forgotten-files.patch b/patches/linux-3.6.7/0081-forgotten-files.patch
index a9ad1ca..80a8699 100644
--- a/patches/linux-3.2.27/0083-forgotten-files.patch
+++ b/patches/linux-3.6.7/0081-forgotten-files.patch
@@ -3,8 +3,8 @@ Date: Sun, 8 Jul 2012 21:39:42 +0100
Subject: [PATCH] forgotten files....
---
- drivers/i2c/busses/i2c-bcm2708.c | 396 +++++++++++++++++++++++++
- drivers/spi/spi-bcm2708.c | 594 ++++++++++++++++++++++++++++++++++++++
+ drivers/i2c/busses/i2c-bcm2708.c | 396 ++++++++++++++++++++++++++
+ drivers/spi/spi-bcm2708.c | 594 +++++++++++++++++++++++++++++++++++++++
2 files changed, 990 insertions(+)
create mode 100644 drivers/i2c/busses/i2c-bcm2708.c
create mode 100644 drivers/spi/spi-bcm2708.c
diff --git a/patches/linux-3.2.27/0084-Enable-I2C-and-SPI-modules-in-full-config.patch b/patches/linux-3.6.7/0082-Enable-I2C-and-SPI-modules-in-full-config.patch
index 5b7a2e4..ce4c3ff 100644
--- a/patches/linux-3.2.27/0084-Enable-I2C-and-SPI-modules-in-full-config.patch
+++ b/patches/linux-3.6.7/0082-Enable-I2C-and-SPI-modules-in-full-config.patch
@@ -3,8 +3,8 @@ Date: Mon, 9 Jul 2012 12:19:26 +0100
Subject: [PATCH] Enable I2C and SPI modules in full config
---
- arch/arm/configs/bcmrpi_cutdown_defconfig | 9 ---------
- arch/arm/configs/bcmrpi_defconfig | 5 +++++
+ arch/arm/configs/bcmrpi_cutdown_defconfig | 9 ---------
+ arch/arm/configs/bcmrpi_defconfig | 5 +++++
2 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_cutdown_defconfig b/arch/arm/configs/bcmrpi_cutdown_defconfig
diff --git a/patches/linux-3.2.27/0085-Possible-fix-for-failure-to-boot-with-compressed-ker.patch b/patches/linux-3.6.7/0083-Possible-fix-for-failure-to-boot-with-compressed-ker.patch
index 901fdbe..9a10c35 100644
--- a/patches/linux-3.2.27/0085-Possible-fix-for-failure-to-boot-with-compressed-ker.patch
+++ b/patches/linux-3.6.7/0083-Possible-fix-for-failure-to-boot-with-compressed-ker.patch
@@ -3,7 +3,7 @@ Date: Tue, 10 Jul 2012 00:14:48 +0100
Subject: [PATCH] Possible fix for failure to boot with compressed kernels
---
- arch/arm/mach-bcm2708/include/mach/uncompress.h | 7 ++++++-
+ arch/arm/mach-bcm2708/include/mach/uncompress.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-bcm2708/include/mach/uncompress.h b/arch/arm/mach-bcm2708/include/mach/uncompress.h
diff --git a/patches/linux-3.2.27/0086-Another-try-at-fixing-compressed-kernel-booting.patch b/patches/linux-3.6.7/0084-Another-try-at-fixing-compressed-kernel-booting.patch
index 686e1b3..1ab0414 100644
--- a/patches/linux-3.2.27/0086-Another-try-at-fixing-compressed-kernel-booting.patch
+++ b/patches/linux-3.6.7/0084-Another-try-at-fixing-compressed-kernel-booting.patch
@@ -3,7 +3,7 @@ Date: Wed, 11 Jul 2012 00:29:52 +0100
Subject: [PATCH] Another try at fixing compressed kernel booting
---
- arch/arm/mach-bcm2708/include/mach/uncompress.h | 41 ++++++++++++++++++++---
+ arch/arm/mach-bcm2708/include/mach/uncompress.h | 41 ++++++++++++++++++++++---
1 file changed, 36 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-bcm2708/include/mach/uncompress.h b/arch/arm/mach-bcm2708/include/mach/uncompress.h
diff --git a/patches/linux-3.2.27/0087-Add-missing-UART0_CLOCK-from-last-commit.patch b/patches/linux-3.6.7/0085-Add-missing-UART0_CLOCK-from-last-commit.patch
index 8859a44..6f824fa 100644
--- a/patches/linux-3.2.27/0087-Add-missing-UART0_CLOCK-from-last-commit.patch
+++ b/patches/linux-3.6.7/0085-Add-missing-UART0_CLOCK-from-last-commit.patch
@@ -3,8 +3,8 @@ Date: Wed, 11 Jul 2012 13:55:11 +0100
Subject: [PATCH] Add missing UART0_CLOCK from last commit
---
- arch/arm/mach-bcm2708/bcm2708.c | 2 +-
- arch/arm/mach-bcm2708/include/mach/platform.h | 2 +-
+ arch/arm/mach-bcm2708/bcm2708.c | 2 +-
+ arch/arm/mach-bcm2708/include/mach/platform.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
diff --git a/patches/linux-3.2.27/0088-Change-to-add-SCSI-tape-support-as-loadable-modules-.patch b/patches/linux-3.6.7/0086-Change-to-add-SCSI-tape-support-as-loadable-modules-.patch
index e3c7f36..23c04cd 100644
--- a/patches/linux-3.2.27/0088-Change-to-add-SCSI-tape-support-as-loadable-modules-.patch
+++ b/patches/linux-3.6.7/0086-Change-to-add-SCSI-tape-support-as-loadable-modules-.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Change to add SCSI tape support as loadable modules to
CONFIG_CHR_DEV_ST=m CONFIG_CHR_DEV_OSST=m
---
- arch/arm/configs/bcmrpi_defconfig | 2 ++
+ arch/arm/configs/bcmrpi_defconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
diff --git a/patches/linux-3.2.27/0089-Add-temporary-fix-for-hang-when-quitting-X.patch b/patches/linux-3.6.7/0087-Add-temporary-fix-for-hang-when-quitting-X.patch
index 63cb898..773e91d 100644
--- a/patches/linux-3.2.27/0089-Add-temporary-fix-for-hang-when-quitting-X.patch
+++ b/patches/linux-3.6.7/0087-Add-temporary-fix-for-hang-when-quitting-X.patch
@@ -3,7 +3,7 @@ Date: Fri, 13 Jul 2012 18:34:18 +0100
Subject: [PATCH] Add temporary fix for hang when quitting X
---
- drivers/video/bcm2708_fb.c | 5 ++++-
+ drivers/video/bcm2708_fb.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
diff --git a/patches/linux-3.2.27/0090-Better-fix-for-quitting-X-hang.-Interrupted-mailbox-.patch b/patches/linux-3.6.7/0088-Better-fix-for-quitting-X-hang.-Interrupted-mailbox-.patch
index 707332f..2fd6bd6 100644
--- a/patches/linux-3.2.27/0090-Better-fix-for-quitting-X-hang.-Interrupted-mailbox-.patch
+++ b/patches/linux-3.6.7/0088-Better-fix-for-quitting-X-hang.-Interrupted-mailbox-.patch
@@ -5,8 +5,8 @@ Subject: [PATCH] Better fix for quitting X hang. Interrupted mailbox reads
down_interruptable is not a safe call.
---
- arch/arm/mach-bcm2708/vcio.c | 12 ++++--------
- drivers/video/bcm2708_fb.c | 3 ---
+ arch/arm/mach-bcm2708/vcio.c | 12 ++++--------
+ drivers/video/bcm2708_fb.c | 3 ---
2 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c
diff --git a/patches/linux-3.2.27/0091-Add-sync_after_dma-module-parameter.patch b/patches/linux-3.6.7/0089-Add-sync_after_dma-module-parameter.patch
index 4ee72c3..28e3730 100644
--- a/patches/linux-3.2.27/0091-Add-sync_after_dma-module-parameter.patch
+++ b/patches/linux-3.6.7/0089-Add-sync_after_dma-module-parameter.patch
@@ -3,7 +3,7 @@ Date: Tue, 17 Jul 2012 00:48:27 +0100
Subject: [PATCH] Add sync_after_dma module parameter
---
- drivers/mmc/host/sdhci-bcm2708.c | 60 ++++++++++++++++++++------------------
+ drivers/mmc/host/sdhci-bcm2708.c | 60 +++++++++++++++++++++-------------------
1 file changed, 32 insertions(+), 28 deletions(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0092-Add-SPI_SPI_DEV-module.patch b/patches/linux-3.6.7/0090-Add-SPI_SPI_DEV-module.patch
index b15f40e..c60f63a 100644
--- a/patches/linux-3.2.27/0092-Add-SPI_SPI_DEV-module.patch
+++ b/patches/linux-3.6.7/0090-Add-SPI_SPI_DEV-module.patch
@@ -3,7 +3,7 @@ Date: Thu, 19 Jul 2012 16:00:28 +0100
Subject: [PATCH] Add SPI_SPI_DEV module
---
- arch/arm/configs/bcmrpi_defconfig | 1 +
+ arch/arm/configs/bcmrpi_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
diff --git a/patches/linux-3.2.27/0093-Fix-var.width-var.height.-They-actually-mean-display.patch b/patches/linux-3.6.7/0091-Fix-var.width-var.height.-They-actually-mean-display.patch
index bebe2f5..66d10ae 100644
--- a/patches/linux-3.2.27/0093-Fix-var.width-var.height.-They-actually-mean-display.patch
+++ b/patches/linux-3.6.7/0091-Fix-var.width-var.height.-They-actually-mean-display.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] Fix var.width/var.height. They actually mean display size.
See #65
---
- drivers/video/bcm2708_fb.c | 4 ++--
+ drivers/video/bcm2708_fb.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
diff --git a/patches/linux-3.2.27/0094-The-TIMER_PERIOD-should-be-calculated-using-the-time.patch b/patches/linux-3.6.7/0092-The-TIMER_PERIOD-should-be-calculated-using-the-time.patch
index 68f1d96..835ecec 100644
--- a/patches/linux-3.2.27/0094-The-TIMER_PERIOD-should-be-calculated-using-the-time.patch
+++ b/patches/linux-3.6.7/0092-The-TIMER_PERIOD-should-be-calculated-using-the-time.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] The TIMER_PERIOD should be calculated using the timer
interrupt frequency.
---
- arch/arm/mach-bcm2708/bcm2708.c | 2 +-
+ arch/arm/mach-bcm2708/bcm2708.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
diff --git a/patches/linux-3.2.27/0095-update-bcmrpi_defconfig-with-various-user-requests.patch b/patches/linux-3.6.7/0093-update-bcmrpi_defconfig-with-various-user-requests.patch
index 5b26d44..0fec7de 100644
--- a/patches/linux-3.2.27/0095-update-bcmrpi_defconfig-with-various-user-requests.patch
+++ b/patches/linux-3.6.7/0093-update-bcmrpi_defconfig-with-various-user-requests.patch
@@ -3,7 +3,7 @@ Date: Wed, 25 Jul 2012 21:39:52 +0100
Subject: [PATCH] update bcmrpi_defconfig with various user requests
---
- arch/arm/configs/bcmrpi_defconfig | 120 +++++++++++++++++++++++++++++++++++++
+ arch/arm/configs/bcmrpi_defconfig | 120 ++++++++++++++++++++++++++++++++++++++
1 file changed, 120 insertions(+)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
diff --git a/patches/linux-3.2.27/0096-Possible-fix-for-USB-packets-going-missing.-Thank-gs.patch b/patches/linux-3.6.7/0094-Possible-fix-for-USB-packets-going-missing.-Thank-gs.patch
index 3b2a42d..b474871 100644
--- a/patches/linux-3.2.27/0096-Possible-fix-for-USB-packets-going-missing.-Thank-gs.patch
+++ b/patches/linux-3.6.7/0094-Possible-fix-for-USB-packets-going-missing.-Thank-gs.patch
@@ -3,7 +3,7 @@ Date: Fri, 27 Jul 2012 10:32:03 +0100
Subject: [PATCH] Possible fix for USB packets going missing. Thank gsh
---
- drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 21 +++++++++++++++------
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
diff --git a/patches/linux-3.2.27/0097-Revert-Possible-fix-for-USB-packets-going-missing.-T.patch b/patches/linux-3.6.7/0095-Revert-Possible-fix-for-USB-packets-going-missing.-T.patch
index 4c14ef9..39fea4d 100644
--- a/patches/linux-3.2.27/0097-Revert-Possible-fix-for-USB-packets-going-missing.-T.patch
+++ b/patches/linux-3.6.7/0095-Revert-Possible-fix-for-USB-packets-going-missing.-T.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Revert "Possible fix for USB packets going missing. Thank
This reverts commit 7e7695894e9e86490558b92af0d8bebdfaadcfed.
---
- drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 21 ++++++---------------
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 21 ++++++---------------
1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
diff --git a/patches/linux-3.2.27/0098-dwc_common_port-remove-unused-cruft-with-onerous-dep.patch b/patches/linux-3.6.7/0096-dwc_common_port-remove-unused-cruft-with-onerous-dep.patch
index 497fafb..9d167fe 100644
--- a/patches/linux-3.2.27/0098-dwc_common_port-remove-unused-cruft-with-onerous-dep.patch
+++ b/patches/linux-3.6.7/0096-dwc_common_port-remove-unused-cruft-with-onerous-dep.patch
@@ -9,14 +9,14 @@ this dead code.
Signed-off-by: Chris Boot <bootc@bootc.net>
---
- drivers/usb/host/dwc_common_port/Makefile | 4 +-
- .../usb/host/dwc_common_port/dwc_common_linux.c | 109 ----
- drivers/usb/host/dwc_common_port/dwc_crypto.c | 306 ----------
- drivers/usb/host/dwc_common_port/dwc_crypto.h | 103 ----
- drivers/usb/host/dwc_common_port/dwc_dh.c | 286 ---------
- drivers/usb/host/dwc_common_port/dwc_dh.h | 98 ---
- drivers/usb/host/dwc_common_port/dwc_modpow.c | 622 --------------------
- drivers/usb/host/dwc_common_port/dwc_modpow.h | 26 -
+ drivers/usb/host/dwc_common_port/Makefile | 4 +-
+ .../usb/host/dwc_common_port/dwc_common_linux.c | 109 ----
+ drivers/usb/host/dwc_common_port/dwc_crypto.c | 306 ----------
+ drivers/usb/host/dwc_common_port/dwc_crypto.h | 103 ----
+ drivers/usb/host/dwc_common_port/dwc_dh.c | 286 ----------
+ drivers/usb/host/dwc_common_port/dwc_dh.h | 98 ----
+ drivers/usb/host/dwc_common_port/dwc_modpow.c | 622 ---------------------
+ drivers/usb/host/dwc_common_port/dwc_modpow.h | 26 -
8 files changed, 2 insertions(+), 1552 deletions(-)
delete mode 100644 drivers/usb/host/dwc_common_port/dwc_crypto.c
delete mode 100644 drivers/usb/host/dwc_common_port/dwc_crypto.h
diff --git a/patches/linux-3.2.27/0099-arm-remove-divdi3-it-s-not-necessary-at-all.patch b/patches/linux-3.6.7/0097-arm-remove-divdi3-it-s-not-necessary-at-all.patch
index 6fc1026..c8c6830 100644
--- a/patches/linux-3.2.27/0099-arm-remove-divdi3-it-s-not-necessary-at-all.patch
+++ b/patches/linux-3.6.7/0097-arm-remove-divdi3-it-s-not-necessary-at-all.patch
@@ -8,25 +8,25 @@ longer required at all.
Signed-off-by: Chris Boot <bootc@bootc.net>
---
- arch/arm/boot/compressed/Makefile | 8 +-
- arch/arm/boot/compressed/divdi3.c | 338 -----------------------------------
- arch/arm/boot/compressed/longlong.h | 151 ----------------
- arch/arm/kernel/armksyms.c | 4 -
- arch/arm/lib/Makefile | 3 +-
- arch/arm/lib/divdi3.c | 338 -----------------------------------
- arch/arm/lib/lib1funcs.S | 27 ---
- arch/arm/lib/longlong.h | 151 ----------------
- 8 files changed, 2 insertions(+), 1018 deletions(-)
+ arch/arm/boot/compressed/Makefile | 7 +-
+ arch/arm/boot/compressed/divdi3.c | 338 ------------------------------------
+ arch/arm/boot/compressed/longlong.h | 151 ----------------
+ arch/arm/kernel/armksyms.c | 4 -
+ arch/arm/lib/Makefile | 6 +-
+ arch/arm/lib/divdi3.c | 338 ------------------------------------
+ arch/arm/lib/lib1funcs.S | 27 ---
+ arch/arm/lib/longlong.h | 151 ----------------
+ 8 files changed, 4 insertions(+), 1018 deletions(-)
delete mode 100644 arch/arm/boot/compressed/divdi3.c
delete mode 100644 arch/arm/boot/compressed/longlong.h
delete mode 100644 arch/arm/lib/divdi3.c
delete mode 100644 arch/arm/lib/longlong.h
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
-index 02d4943..21f56ff 100644
+index 08bc871..bb26756 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
-@@ -145,17 +145,11 @@ LDFLAGS_vmlinux += -X
+@@ -149,7 +149,7 @@ LDFLAGS_vmlinux += -X
LDFLAGS_vmlinux += -T
# For __aeabi_uidivmod
@@ -35,16 +35,18 @@ index 02d4943..21f56ff 100644
$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
$(call cmd,shipped)
+@@ -158,11 +158,6 @@ $(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
+ ashldi3 = $(obj)/ashldi3.o
+ $(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S
+-
-$(obj)/longlong.h: $(srctree)/arch/$(SRCARCH)/lib/longlong.h FORCE
- $(call cmd,shipped)
-
-$(obj)/divdi3.c: $(srctree)/arch/$(SRCARCH)/lib/divdi3.c $(obj)/longlong.h FORCE
-- $(call cmd,shipped)
--
+ $(call cmd,shipped)
+
# We need to prevent any GOTOFF relocs being used with references
- # to symbols in the .bss section since we cannot relocate them
- # independently from the rest at run time. This can be achieved by
diff --git a/arch/arm/boot/compressed/divdi3.c b/arch/arm/boot/compressed/divdi3.c
deleted file mode 100644
index 0848d21..0000000
@@ -547,10 +549,10 @@ index 38e0dcc..0000000
-#define UDIV_NEEDS_NORMALIZATION 1
-#define udiv_qrnnd __udiv_qrnnd_c
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
-index 9a93886..5b0bce6 100644
+index 7b2fa74..60d3b73 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
-@@ -46,8 +46,6 @@ extern void __aeabi_lmul(void);
+@@ -45,8 +45,6 @@ extern void __aeabi_lmul(void);
extern void __aeabi_uidiv(void);
extern void __aeabi_uidivmod(void);
extern void __aeabi_ulcmp(void);
@@ -559,7 +561,7 @@ index 9a93886..5b0bce6 100644
extern void fpundefinstr(void);
-@@ -133,8 +131,6 @@ EXPORT_SYMBOL(__aeabi_lmul);
+@@ -127,8 +125,6 @@ EXPORT_SYMBOL(__aeabi_lmul);
EXPORT_SYMBOL(__aeabi_uidiv);
EXPORT_SYMBOL(__aeabi_uidivmod);
EXPORT_SYMBOL(__aeabi_ulcmp);
@@ -569,16 +571,25 @@ index 9a93886..5b0bce6 100644
/* bitops */
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
-index e917b9e..cf73a7f 100644
+index 26d01af..0ade0ac 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
-@@ -13,8 +13,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
+@@ -6,15 +6,15 @@
+
+ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
+ csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
+- delay.o delay-loop.o findbit.o memchr.o memcpy.o \
++ delay.o findbit.o memchr.o memcpy.o \
+ memmove.o memset.o memzero.o setbit.o \
++ strncpy_from_user.o strnlen_user.o \
+ strchr.o strrchr.o \
testchangebit.o testclearbit.o testsetbit.o \
ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
ucmpdi2.o lib1funcs.o div64.o \
-- io-readsb.o io-writesb.o io-readsl.o io-writesl.o \
+ io-readsb.o io-writesb.o io-readsl.o io-writesl.o \
+- call_with_stack.o \
- divdi3.o
-+ io-readsb.o io-writesb.o io-readsl.o io-writesl.o
++ call_with_stack.o
mmu-y := clear_user.o copy_page.o getuser.o putuser.o
diff --git a/patches/linux-3.2.27/0100-Remove-some-patch-backup-files.patch b/patches/linux-3.6.7/0098-Remove-some-patch-backup-files.patch
index 73545dd..85f5c2d 100644
--- a/patches/linux-3.2.27/0100-Remove-some-patch-backup-files.patch
+++ b/patches/linux-3.6.7/0098-Remove-some-patch-backup-files.patch
@@ -4,8 +4,8 @@ Subject: [PATCH] Remove some patch backup files
Signed-off-by: Chris Boot <bootc@bootc.net>
---
- arch/arm/mach-bcm2708/include/mach/irqs.h.orig | 185 -----------------
- arch/arm/mach-bcm2708/include/mach/platform.h.orig | 210 --------------------
+ arch/arm/mach-bcm2708/include/mach/irqs.h.orig | 185 ------------------
+ arch/arm/mach-bcm2708/include/mach/platform.h.orig | 210 ---------------------
2 files changed, 395 deletions(-)
delete mode 100644 arch/arm/mach-bcm2708/include/mach/irqs.h.orig
delete mode 100644 arch/arm/mach-bcm2708/include/mach/platform.h.orig
diff --git a/patches/linux-3.2.27/0101-mach-bcm2708-fix-mach-debug-macro.S-so-that-early-pr.patch b/patches/linux-3.6.7/0099-mach-bcm2708-fix-mach-debug-macro.S-so-that-early-pr.patch
index 6a18eb7..54a14bd 100644
--- a/patches/linux-3.2.27/0101-mach-bcm2708-fix-mach-debug-macro.S-so-that-early-pr.patch
+++ b/patches/linux-3.6.7/0099-mach-bcm2708-fix-mach-debug-macro.S-so-that-early-pr.patch
@@ -13,7 +13,7 @@ access the UART.
Signed-off-by: Chris Boot <bootc@bootc.net>
---
- arch/arm/mach-bcm2708/include/mach/debug-macro.S | 12 +++++-------
+ arch/arm/mach-bcm2708/include/mach/debug-macro.S | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-bcm2708/include/mach/debug-macro.S b/arch/arm/mach-bcm2708/include/mach/debug-macro.S
diff --git a/patches/linux-3.2.27/0102-sound-arm-bcm2835.c-add-linux-module.h-include.patch b/patches/linux-3.6.7/0100-sound-arm-bcm2835.c-add-linux-module.h-include.patch
index f87b66c..648cd96 100644
--- a/patches/linux-3.2.27/0102-sound-arm-bcm2835.c-add-linux-module.h-include.patch
+++ b/patches/linux-3.6.7/0100-sound-arm-bcm2835.c-add-linux-module.h-include.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] sound/arm/bcm2835.c: add linux/module.h include
Signed-off-by: Chris Boot <bootc@bootc.net>
---
- sound/arm/bcm2835.c | 1 +
+ sound/arm/bcm2835.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/arm/bcm2835.c b/sound/arm/bcm2835.c
diff --git a/patches/linux-3.2.27/0103-vcos-add-linux-kernel.h-include.patch b/patches/linux-3.6.7/0101-vcos-add-linux-kernel.h-include.patch
index 92d6915..722adb3 100644
--- a/patches/linux-3.2.27/0103-vcos-add-linux-kernel.h-include.patch
+++ b/patches/linux-3.6.7/0101-vcos-add-linux-kernel.h-include.patch
@@ -3,7 +3,7 @@ Date: Tue, 8 May 2012 14:50:35 +0100
Subject: [PATCH] vcos: add linux/kernel.h include
---
- .../vc04_services/interface/vcos/linuxkernel/vcos_platform_types.h | 1 +
+ .../misc/vc04_services/interface/vcos/linuxkernel/vcos_platform_types.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_platform_types.h b/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_platform_types.h
diff --git a/patches/linux-3.2.27/0104-bcm2708-update-for-3.2-kernel.patch b/patches/linux-3.6.7/0102-bcm2708-update-for-3.2-kernel.patch
index 562fbda..7df89fb 100644
--- a/patches/linux-3.2.27/0104-bcm2708-update-for-3.2-kernel.patch
+++ b/patches/linux-3.6.7/0102-bcm2708-update-for-3.2-kernel.patch
@@ -9,18 +9,18 @@ Conflicts:
arch/arm/Kconfig.debug
arch/arm/mach-bcm2708/include/mach/memory.h
---
- arch/arm/Kconfig | 2 ++
- arch/arm/Kconfig.debug | 8 ++++++++
- arch/arm/mach-bcm2708/bcm2708.c | 23 +++++++++++++++-------
- arch/arm/mach-bcm2708/include/mach/debug-macro.S | 2 +-
- arch/arm/mach-bcm2708/include/mach/memory.h | 6 +++---
+ arch/arm/Kconfig | 2 ++
+ arch/arm/Kconfig.debug | 8 ++++++++
+ arch/arm/mach-bcm2708/bcm2708.c | 23 ++++++++++++++++-------
+ arch/arm/mach-bcm2708/include/mach/debug-macro.S | 2 +-
+ arch/arm/mach-bcm2708/include/mach/memory.h | 6 +++---
5 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index 39b3d55..98ea27e 100644
+index fd48798..fd49001 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
-@@ -960,6 +960,8 @@ config ARCH_BCM2708
+@@ -1003,6 +1003,8 @@ config ARCH_BCM2708
select CPU_V6
select ARM_AMBA
select HAVE_CLK
@@ -30,12 +30,12 @@ index 39b3d55..98ea27e 100644
select GENERIC_CLOCKEVENTS
select ARM_ERRATA_411920
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
-index c5213e7..5e58b8f 100644
+index e968a52..c33604c 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
-@@ -247,6 +247,14 @@ choice
- their output to the standard serial port on the RealView
- PB1176 platform.
+@@ -371,6 +371,14 @@ choice
+ For more details about semihosting, please see
+ chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd.
+ config DEBUG_BCM2708_UART0
+ bool "Broadcom BCM2708 UART0 (PL011)"
diff --git a/patches/linux-3.2.27/0105-bcm2708-use-a-constant-SC_MULT-SC_SHIFT.patch b/patches/linux-3.6.7/0103-bcm2708-use-a-constant-SC_MULT-SC_SHIFT.patch
index de36e09..e6fb65f 100644
--- a/patches/linux-3.2.27/0105-bcm2708-use-a-constant-SC_MULT-SC_SHIFT.patch
+++ b/patches/linux-3.6.7/0103-bcm2708-use-a-constant-SC_MULT-SC_SHIFT.patch
@@ -12,7 +12,7 @@ So use the constant values much like arch/arm/mach-tegra/timer.c does.
Signed-off-by: Chris Boot <bootc@bootc.net>
---
- arch/arm/mach-bcm2708/bcm2708.c | 14 ++++++++++----
+ arch/arm/mach-bcm2708/bcm2708.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
diff --git a/patches/linux-3.2.27/0106-Sync-with-bootc-s-file.patch b/patches/linux-3.6.7/0104-Sync-with-bootc-s-file.patch
index fe81121..8d6b243 100644
--- a/patches/linux-3.2.27/0106-Sync-with-bootc-s-file.patch
+++ b/patches/linux-3.6.7/0104-Sync-with-bootc-s-file.patch
@@ -3,7 +3,7 @@ Date: Tue, 31 Jul 2012 16:42:03 +0100
Subject: [PATCH] Sync with bootc's file
---
- arch/arm/mach-bcm2708/power.c | 10 +++++-----
+ arch/arm/mach-bcm2708/power.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-bcm2708/power.c b/arch/arm/mach-bcm2708/power.c
diff --git a/patches/linux-3.2.27/0107-sdhci-bcm2708-use-extension-FIFO-to-buffer-DMA-trans.patch b/patches/linux-3.6.7/0105-sdhci-bcm2708-use-extension-FIFO-to-buffer-DMA-trans.patch
index 40fde47..4ae61d8 100644
--- a/patches/linux-3.2.27/0107-sdhci-bcm2708-use-extension-FIFO-to-buffer-DMA-trans.patch
+++ b/patches/linux-3.6.7/0105-sdhci-bcm2708-use-extension-FIFO-to-buffer-DMA-trans.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] sdhci-bcm2708: use extension FIFO to buffer DMA transfers
The additional FIFO might speed up transfers in some cases.
---
- drivers/mmc/host/sdhci-bcm2708.c | 10 ++++++++++
+ drivers/mmc/host/sdhci-bcm2708.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0108-sdhci-bcm2708-use-multiblock-type-transfers-for-sing.patch b/patches/linux-3.6.7/0106-sdhci-bcm2708-use-multiblock-type-transfers-for-sing.patch
index af6628c..ea16c1e 100644
--- a/patches/linux-3.2.27/0108-sdhci-bcm2708-use-multiblock-type-transfers-for-sing.patch
+++ b/patches/linux-3.6.7/0106-sdhci-bcm2708-use-multiblock-type-transfers-for-sing.patch
@@ -8,16 +8,16 @@ and writes (data loss in some cases!). Just don't do single block
transfers anymore, and treat them like multiblock transfers. This
adds a quirk for this and uses it.
---
- drivers/mmc/card/block.c | 2 +-
- drivers/mmc/host/sdhci-bcm2708.c | 3 +++
- include/linux/mmc/host.h | 1 +
+ drivers/mmc/card/block.c | 2 +-
+ drivers/mmc/host/sdhci-bcm2708.c | 3 +++
+ include/linux/mmc/host.h | 1 +
3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
-index 34416d4..13cde4a 100644
+index 172a768..538cec6 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
-@@ -1075,7 +1075,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
+@@ -1135,7 +1135,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
brq->data.blocks = 1;
}
@@ -41,14 +41,14 @@ index 882ae42..ad44fbe 100644
ret = sdhci_add_host(host);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
-index deb6282..e97b341 100644
+index f578a71..3824f2d 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
-@@ -242,6 +242,7 @@ struct mmc_host {
- #define MMC_CAP2_CACHE_CTRL (1 << 1) /* Allow cache control */
- #define MMC_CAP2_POWEROFF_NOTIFY (1 << 2) /* Notify poweroff supported */
- #define MMC_CAP2_NO_MULTI_READ (1 << 3) /* Multiblock reads don't work */
-+#define MMC_CAP2_FORCE_MULTIBLOCK (1 << 4) /* Always use multiblock transfers */
+@@ -257,6 +257,7 @@ struct mmc_host {
+ #define MMC_CAP2_HC_ERASE_SZ (1 << 9) /* High-capacity erase size */
+ #define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10) /* Card-detect signal active high */
+ #define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11) /* Write-protect signal active high */
++#define MMC_CAP2_FORCE_MULTIBLOCK (1 << 12) /* Always use multiblock transfers */
mmc_pm_flag_t pm_caps; /* supported pm features */
unsigned int power_notify_type;
diff --git a/patches/linux-3.2.27/0109-Add-module-parameter-for-missing_status-quirk.-sdhci.patch b/patches/linux-3.6.7/0107-Add-module-parameter-for-missing_status-quirk.-sdhci.patch
index 04b5d33..c6727c8 100644
--- a/patches/linux-3.2.27/0109-Add-module-parameter-for-missing_status-quirk.-sdhci.patch
+++ b/patches/linux-3.6.7/0107-Add-module-parameter-for-missing_status-quirk.-sdhci.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Add module parameter for missing_status quirk.
latency
---
- drivers/mmc/host/sdhci-bcm2708.c | 7 ++++++-
+ drivers/mmc/host/sdhci-bcm2708.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0110-Some-fixed-for-ALSA.-Mute-and-volume-changing-should.patch b/patches/linux-3.6.7/0108-Some-fixed-for-ALSA.-Mute-and-volume-changing-should.patch
index feddc4a..a8a6419 100644
--- a/patches/linux-3.2.27/0110-Some-fixed-for-ALSA.-Mute-and-volume-changing-should.patch
+++ b/patches/linux-3.6.7/0108-Some-fixed-for-ALSA.-Mute-and-volume-changing-should.patch
@@ -4,10 +4,10 @@ Subject: [PATCH] Some fixed for ALSA. Mute and volume changing should be
improved
---
- sound/arm/bcm2835-ctl.c | 76 +++++++++++++++++-----------
- sound/arm/bcm2835-pcm.c | 24 ++++++---
- sound/arm/bcm2835-vchiq.c | 34 +++++++++----
- sound/arm/bcm2835.h | 123 +++++++--------------------------------------
+ sound/arm/bcm2835-ctl.c | 76 +++++++++++++++++-----------
+ sound/arm/bcm2835-pcm.c | 24 ++++++---
+ sound/arm/bcm2835-vchiq.c | 34 +++++++++----
+ sound/arm/bcm2835.h | 123 +++++++---------------------------------------
4 files changed, 106 insertions(+), 151 deletions(-)
diff --git a/sound/arm/bcm2835-ctl.c b/sound/arm/bcm2835-ctl.c
diff --git a/patches/linux-3.2.27/0111-Fix-spinlock-recursion-in-sdhci-bcm2708.c.patch b/patches/linux-3.6.7/0109-Fix-spinlock-recursion-in-sdhci-bcm2708.c.patch
index 5f719b1..5bf0927 100644
--- a/patches/linux-3.2.27/0111-Fix-spinlock-recursion-in-sdhci-bcm2708.c.patch
+++ b/patches/linux-3.6.7/0109-Fix-spinlock-recursion-in-sdhci-bcm2708.c.patch
@@ -3,7 +3,7 @@ Date: Sun, 5 Aug 2012 10:42:12 -0400
Subject: [PATCH] Fix spinlock recursion in sdhci-bcm2708.c
---
- drivers/mmc/host/sdhci-bcm2708.c | 10 +++++-----
+ drivers/mmc/host/sdhci-bcm2708.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0112-Revert-Add-mechanism-to-reduce-the-number-of-SOF-int.patch b/patches/linux-3.6.7/0110-Revert-Add-mechanism-to-reduce-the-number-of-SOF-int.patch
index 5221b6d..ce8b2c0 100644
--- a/patches/linux-3.2.27/0112-Revert-Add-mechanism-to-reduce-the-number-of-SOF-int.patch
+++ b/patches/linux-3.6.7/0110-Revert-Add-mechanism-to-reduce-the-number-of-SOF-int.patch
@@ -6,13 +6,13 @@ Subject: [PATCH] Revert "Add mechanism to reduce the number of SOF interrupts
This reverts commit 85b7821857dd0b9cabab59d47f08eabed74679a3.
---
- .../usb/host/dwc_common_port/dwc_common_linux.c | 2 +-
- drivers/usb/host/dwc_otg/Makefile | 7 +-
- drivers/usb/host/dwc_otg/dwc_otg_driver.c | 149 --------------------
- drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 56 --------
- drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 9 --
- drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 103 +-------------
- drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 19 ---
+ .../usb/host/dwc_common_port/dwc_common_linux.c | 2 +-
+ drivers/usb/host/dwc_otg/Makefile | 7 +-
+ drivers/usb/host/dwc_otg/dwc_otg_driver.c | 149 ---------------------
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 56 --------
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 9 --
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 103 +-------------
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 19 ---
7 files changed, 7 insertions(+), 338 deletions(-)
diff --git a/drivers/usb/host/dwc_common_port/dwc_common_linux.c b/drivers/usb/host/dwc_common_port/dwc_common_linux.c
diff --git a/patches/linux-3.2.27/0113-Enable-CONFIG_CRYPTO_XTS.patch b/patches/linux-3.6.7/0111-Enable-CONFIG_CRYPTO_XTS.patch
index 7a97524..2566d3b 100644
--- a/patches/linux-3.2.27/0113-Enable-CONFIG_CRYPTO_XTS.patch
+++ b/patches/linux-3.6.7/0111-Enable-CONFIG_CRYPTO_XTS.patch
@@ -3,7 +3,7 @@ Date: Mon, 13 Aug 2012 20:16:58 +0100
Subject: [PATCH] Enable CONFIG_CRYPTO_XTS
---
- arch/arm/configs/bcmrpi_defconfig | 1 +
+ arch/arm/configs/bcmrpi_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
diff --git a/patches/linux-3.2.27/0114-Update-Synopsys-USB-OTG-driver-to-v2.94a-and-disable.patch b/patches/linux-3.6.7/0112-Update-Synopsys-USB-OTG-driver-to-v2.94a-and-disable.patch
index c554d52..2829e17 100644
--- a/patches/linux-3.2.27/0114-Update-Synopsys-USB-OTG-driver-to-v2.94a-and-disable.patch
+++ b/patches/linux-3.6.7/0112-Update-Synopsys-USB-OTG-driver-to-v2.94a-and-disable.patch
@@ -4,363 +4,363 @@ Subject: [PATCH] Update Synopsys USB OTG driver to v2.94a and disable
CRYPTOLIB
---
- drivers/usb/host/dwc_common_port/Makefile | 38 +-
- drivers/usb/host/dwc_common_port/Makefile.fbsd | 17 +
- drivers/usb/host/dwc_common_port/Makefile.linux | 39 +-
- drivers/usb/host/dwc_common_port/changes.txt | 174 +
- .../html/dir_c13d72e45af28cdc461a5f284d3d36fc.html | 81 -
- .../usb/host/dwc_common_port/doc/html/dirs.html | 22 -
- .../usb/host/dwc_common_port/doc/html/doxygen.css | 358 -
- .../host/dwc_common_port/doc/html/dwc__cc_8h.html | 709 --
- .../dwc_common_port/doc/html/dwc__crypto_8c.html | 435 -
- .../dwc_common_port/doc/html/dwc__crypto_8h.html | 618 --
- .../host/dwc_common_port/doc/html/dwc__dh_8h.html | 166 -
- .../dwc_common_port/doc/html/dwc__list_8h.html | 1844 ----
- .../dwc_common_port/doc/html/dwc__modpow_8h.html | 48 -
- .../dwc_common_port/doc/html/dwc__notifier_8h.html | 306 -
- .../host/dwc_common_port/doc/html/dwc__os_8h.html | 3090 ------
- .../usb/host/dwc_common_port/doc/html/files.html | 34 -
- .../usb/host/dwc_common_port/doc/html/globals.html | 163 -
- .../dwc_common_port/doc/html/globals_defs.html | 41 -
- .../dwc_common_port/doc/html/globals_func.html | 153 -
- .../dwc_common_port/doc/html/globals_type.html | 41 -
- .../usb/host/dwc_common_port/doc/html/index.html | 8 -
- .../usb/host/dwc_common_port/doc/html/main.html | 45 -
- .../usb/host/dwc_common_port/doc/html/pages.html | 23 -
- drivers/usb/host/dwc_common_port/doc/html/tabs.css | 102 -
- .../usb/host/dwc_common_port/doc/html/todo.html | 23 -
- .../usb/host/dwc_common_port/doc/html/tree.html | 90 -
- drivers/usb/host/dwc_common_port/dwc_cc.c | 116 +-
- drivers/usb/host/dwc_common_port/dwc_cc.h | 42 +-
- drivers/usb/host/dwc_common_port/dwc_common_fbsd.c | 1308 +++
- .../usb/host/dwc_common_port/dwc_common_linux.c | 1343 ++-
- 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 | 274 +-
- drivers/usb/host/dwc_common_port/dwc_mem.c | 191 +-
- 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 | 155 +-
- drivers/usb/host/dwc_common_port/dwc_notifier.h | 22 +-
- drivers/usb/host/dwc_common_port/dwc_os.h | 627 +-
- drivers/usb/host/dwc_common_port/usb.h | 308 +-
- drivers/usb/host/dwc_otg/Makefile | 40 +-
- drivers/usb/host/dwc_otg/doc/doxygen.cfg | 2 +-
- drivers/usb/host/dwc_otg/doc/html/annotated.html | 51 +-
- drivers/usb/host/dwc_otg/doc/html/doxygen.css | 143 +-
- drivers/usb/host/dwc_otg/doc/html/doxygen.png | Bin 0 -> 1281 bytes
- .../dwc_otg/doc/html/dummy__audio_8c-source.html | 1550 ---
- .../doc/html/dwc__cfi__common_8h-source.html | 196 +-
- .../host/dwc_otg/doc/html/dwc__cfi__common_8h.html | 102 +-
- .../dwc_otg/doc/html/dwc__otg__adp_8c-source.html | 769 ++
- .../host/dwc_otg/doc/html/dwc__otg__adp_8c.html | 482 +
- .../dwc_otg/doc/html/dwc__otg__adp_8h-source.html | 80 +
- .../host/dwc_otg/doc/html/dwc__otg__adp_8h.html | 308 +
- .../dwc_otg/doc/html/dwc__otg__attr_8c-source.html | 1741 +--
- .../host/dwc_otg/doc/html/dwc__otg__attr_8c.html | 714 +-
- .../dwc_otg/doc/html/dwc__otg__attr_8h-source.html | 183 +-
- .../host/dwc_otg/doc/html/dwc__otg__attr_8h.html | 82 +-
- .../dwc_otg/doc/html/dwc__otg__cfi_8c-source.html | 3419 +++---
- .../host/dwc_otg/doc/html/dwc__otg__cfi_8c.html | 24 +-
- .../dwc_otg/doc/html/dwc__otg__cfi_8h-source.html | 570 +-
- .../host/dwc_otg/doc/html/dwc__otg__cfi_8h.html | 336 +-
- .../dwc_otg/doc/html/dwc__otg__cil_8c-source.html |11466 +++++++++++---------
- .../host/dwc_otg/doc/html/dwc__otg__cil_8c.html | 4356 ++++----
- .../dwc_otg/doc/html/dwc__otg__cil_8h-source.html | 1601 +--
- .../host/dwc_otg/doc/html/dwc__otg__cil_8h.html | 2770 +++--
- .../doc/html/dwc__otg__cil__intr_8c-source.html | 2023 ++--
- .../dwc_otg/doc/html/dwc__otg__cil__intr_8c.html | 820 +-
- .../doc/html/dwc__otg__core__if_8h-source.html | 746 +-
- .../dwc_otg/doc/html/dwc__otg__core__if_8h.html | 2414 +++--
- .../dwc_otg/doc/html/dwc__otg__dbg_8h-source.html | 172 +-
- .../host/dwc_otg/doc/html/dwc__otg__dbg_8h.html | 126 +-
- .../doc/html/dwc__otg__driver_8c-source.html | 2204 ++--
- .../host/dwc_otg/doc/html/dwc__otg__driver_8c.html | 883 +-
- .../doc/html/dwc__otg__driver_8h-source.html | 178 +-
- .../host/dwc_otg/doc/html/dwc__otg__driver_8h.html | 31 +-
- .../dwc_otg/doc/html/dwc__otg__hcd_8c-source.html | 6146 ++++++-----
- .../host/dwc_otg/doc/html/dwc__otg__hcd_8c.html | 2417 +++--
- .../dwc_otg/doc/html/dwc__otg__hcd_8h-source.html | 1017 +-
- .../host/dwc_otg/doc/html/dwc__otg__hcd_8h.html | 1718 +--
- .../doc/html/dwc__otg__hcd__ddma_8c-source.html | 2128 ++--
- .../dwc_otg/doc/html/dwc__otg__hcd__ddma_8c.html | 357 +-
- .../doc/html/dwc__otg__hcd__if_8h-source.html | 367 +-
- .../dwc_otg/doc/html/dwc__otg__hcd__if_8h.html | 1798 +--
- .../doc/html/dwc__otg__hcd__intr_8c-source.html | 3778 +++----
- .../dwc_otg/doc/html/dwc__otg__hcd__intr_8c.html | 1754 +--
- .../doc/html/dwc__otg__hcd__linux_8c-source.html | 1501 +--
- .../dwc_otg/doc/html/dwc__otg__hcd__linux_8c.html | 680 +-
- .../doc/html/dwc__otg__hcd__queue_8c-source.html | 1229 ++-
- .../dwc_otg/doc/html/dwc__otg__hcd__queue_8c.html | 850 +-
- .../doc/html/dwc__otg__os__dep_8h-source.html | 102 +
- .../dwc_otg/doc/html/dwc__otg__os__dep_8h.html | 59 +
- .../dwc_otg/doc/html/dwc__otg__pcd_8c-source.html | 4273 ++++----
- .../host/dwc_otg/doc/html/dwc__otg__pcd_8c.html | 1757 +--
- .../dwc_otg/doc/html/dwc__otg__pcd_8h-source.html | 344 +-
- .../host/dwc_otg/doc/html/dwc__otg__pcd_8h.html | 293 +-
- .../doc/html/dwc__otg__pcd__if_8h-source.html | 336 +-
- .../dwc_otg/doc/html/dwc__otg__pcd__if_8h.html | 1328 ++-
- .../doc/html/dwc__otg__pcd__intr_8c-source.html | 7951 +++++++-------
- .../dwc_otg/doc/html/dwc__otg__pcd__intr_8c.html | 2234 ++--
- .../doc/html/dwc__otg__pcd__linux_8c-source.html | 2103 ++--
- .../dwc_otg/doc/html/dwc__otg__pcd__linux_8c.html | 1008 +-
- .../dwc_otg/doc/html/dwc__otg__regs_8h-source.html | 2624 ++---
- .../host/dwc_otg/doc/html/dwc__otg__regs_8h.html | 2161 ++--
- drivers/usb/host/dwc_otg/doc/html/files.html | 28 +-
- drivers/usb/host/dwc_otg/doc/html/ftv2blank.png | Bin 0 -> 174 bytes
- drivers/usb/host/dwc_otg/doc/html/ftv2doc.png | Bin 0 -> 255 bytes
- .../usb/host/dwc_otg/doc/html/ftv2folderclosed.png | Bin 0 -> 259 bytes
- .../usb/host/dwc_otg/doc/html/ftv2folderopen.png | Bin 0 -> 261 bytes
- drivers/usb/host/dwc_otg/doc/html/ftv2lastnode.png | Bin 0 -> 233 bytes
- drivers/usb/host/dwc_otg/doc/html/ftv2link.png | Bin 0 -> 358 bytes
- .../usb/host/dwc_otg/doc/html/ftv2mlastnode.png | Bin 0 -> 160 bytes
- drivers/usb/host/dwc_otg/doc/html/ftv2mnode.png | Bin 0 -> 194 bytes
- drivers/usb/host/dwc_otg/doc/html/ftv2node.png | Bin 0 -> 235 bytes
- .../usb/host/dwc_otg/doc/html/ftv2plastnode.png | Bin 0 -> 165 bytes
- drivers/usb/host/dwc_otg/doc/html/ftv2pnode.png | Bin 0 -> 200 bytes
- drivers/usb/host/dwc_otg/doc/html/ftv2vertline.png | Bin 0 -> 229 bytes
- drivers/usb/host/dwc_otg/doc/html/functions.html | 653 +-
- .../usb/host/dwc_otg/doc/html/functions_0x62.html | 99 -
- .../usb/host/dwc_otg/doc/html/functions_0x63.html | 110 -
- .../usb/host/dwc_otg/doc/html/functions_0x64.html | 158 -
- .../usb/host/dwc_otg/doc/html/functions_0x65.html | 109 -
- .../usb/host/dwc_otg/doc/html/functions_0x66.html | 81 -
- .../usb/host/dwc_otg/doc/html/functions_0x67.html | 95 -
- .../usb/host/dwc_otg/doc/html/functions_0x68.html | 119 -
- .../usb/host/dwc_otg/doc/html/functions_0x69.html | 121 -
- .../usb/host/dwc_otg/doc/html/functions_0x6c.html | 74 -
- .../usb/host/dwc_otg/doc/html/functions_0x6d.html | 79 -
- .../usb/host/dwc_otg/doc/html/functions_0x6e.html | 99 -
- .../usb/host/dwc_otg/doc/html/functions_0x6f.html | 101 -
- .../usb/host/dwc_otg/doc/html/functions_0x70.html | 144 -
- .../usb/host/dwc_otg/doc/html/functions_0x71.html | 71 -
- .../usb/host/dwc_otg/doc/html/functions_0x72.html | 141 -
- .../usb/host/dwc_otg/doc/html/functions_0x73.html | 128 -
- .../usb/host/dwc_otg/doc/html/functions_0x74.html | 88 -
- .../usb/host/dwc_otg/doc/html/functions_0x75.html | 78 -
- .../usb/host/dwc_otg/doc/html/functions_0x76.html | 65 -
- .../usb/host/dwc_otg/doc/html/functions_0x77.html | 79 -
- .../usb/host/dwc_otg/doc/html/functions_0x78.html | 77 -
- .../usb/host/dwc_otg/doc/html/functions_func.html | 32 +-
- .../usb/host/dwc_otg/doc/html/functions_vars.html | 650 +-
- .../host/dwc_otg/doc/html/functions_vars_0x62.html | 99 -
- .../host/dwc_otg/doc/html/functions_vars_0x63.html | 110 -
- .../host/dwc_otg/doc/html/functions_vars_0x64.html | 157 -
- .../host/dwc_otg/doc/html/functions_vars_0x65.html | 109 -
- .../host/dwc_otg/doc/html/functions_vars_0x66.html | 81 -
- .../host/dwc_otg/doc/html/functions_vars_0x67.html | 95 -
- .../host/dwc_otg/doc/html/functions_vars_0x68.html | 119 -
- .../host/dwc_otg/doc/html/functions_vars_0x69.html | 121 -
- .../host/dwc_otg/doc/html/functions_vars_0x6c.html | 74 -
- .../host/dwc_otg/doc/html/functions_vars_0x6d.html | 79 -
- .../host/dwc_otg/doc/html/functions_vars_0x6e.html | 99 -
- .../host/dwc_otg/doc/html/functions_vars_0x6f.html | 101 -
- .../host/dwc_otg/doc/html/functions_vars_0x70.html | 144 -
- .../host/dwc_otg/doc/html/functions_vars_0x71.html | 71 -
- .../host/dwc_otg/doc/html/functions_vars_0x72.html | 141 -
- .../host/dwc_otg/doc/html/functions_vars_0x73.html | 128 -
- .../host/dwc_otg/doc/html/functions_vars_0x74.html | 88 -
- .../host/dwc_otg/doc/html/functions_vars_0x75.html | 78 -
- .../host/dwc_otg/doc/html/functions_vars_0x76.html | 65 -
- .../host/dwc_otg/doc/html/functions_vars_0x77.html | 79 -
- .../host/dwc_otg/doc/html/functions_vars_0x78.html | 77 -
- drivers/usb/host/dwc_otg/doc/html/globals.html | 747 +-
- .../usb/host/dwc_otg/doc/html/globals_0x61.html | 76 -
- .../usb/host/dwc_otg/doc/html/globals_0x62.html | 83 -
- .../usb/host/dwc_otg/doc/html/globals_0x63.html | 100 -
- .../usb/host/dwc_otg/doc/html/globals_0x64.html | 686 --
- .../usb/host/dwc_otg/doc/html/globals_0x65.html | 78 -
- .../usb/host/dwc_otg/doc/html/globals_0x66.html | 87 -
- .../usb/host/dwc_otg/doc/html/globals_0x67.html | 93 -
- .../usb/host/dwc_otg/doc/html/globals_0x68.html | 129 -
- .../usb/host/dwc_otg/doc/html/globals_0x69.html | 76 -
- .../usb/host/dwc_otg/doc/html/globals_0x6b.html | 69 -
- .../usb/host/dwc_otg/doc/html/globals_0x6d.html | 84 -
- .../usb/host/dwc_otg/doc/html/globals_0x6e.html | 68 -
- .../usb/host/dwc_otg/doc/html/globals_0x6f.html | 73 -
- .../usb/host/dwc_otg/doc/html/globals_0x70.html | 84 -
- .../usb/host/dwc_otg/doc/html/globals_0x71.html | 70 -
- .../usb/host/dwc_otg/doc/html/globals_0x72.html | 94 -
- .../usb/host/dwc_otg/doc/html/globals_0x73.html | 85 -
- .../usb/host/dwc_otg/doc/html/globals_0x74.html | 68 -
- .../usb/host/dwc_otg/doc/html/globals_0x75.html | 80 -
- .../usb/host/dwc_otg/doc/html/globals_0x76.html | 75 -
- .../usb/host/dwc_otg/doc/html/globals_0x77.html | 74 -
- .../usb/host/dwc_otg/doc/html/globals_defs.html | 137 +-
- .../host/dwc_otg/doc/html/globals_defs_0x61.html | 64 -
- .../host/dwc_otg/doc/html/globals_defs_0x62.html | 71 -
- .../host/dwc_otg/doc/html/globals_defs_0x63.html | 74 -
- .../host/dwc_otg/doc/html/globals_defs_0x64.html | 241 -
- .../host/dwc_otg/doc/html/globals_defs_0x66.html | 71 -
- .../host/dwc_otg/doc/html/globals_defs_0x67.html | 62 -
- .../host/dwc_otg/doc/html/globals_defs_0x68.html | 63 -
- .../host/dwc_otg/doc/html/globals_defs_0x69.html | 62 -
- .../host/dwc_otg/doc/html/globals_defs_0x6d.html | 76 -
- .../host/dwc_otg/doc/html/globals_defs_0x6e.html | 62 -
- .../host/dwc_otg/doc/html/globals_defs_0x6f.html | 67 -
- .../host/dwc_otg/doc/html/globals_defs_0x72.html | 66 -
- .../host/dwc_otg/doc/html/globals_defs_0x73.html | 63 -
- .../host/dwc_otg/doc/html/globals_defs_0x75.html | 64 -
- .../host/dwc_otg/doc/html/globals_defs_0x76.html | 68 -
- .../usb/host/dwc_otg/doc/html/globals_enum.html | 45 +-
- .../usb/host/dwc_otg/doc/html/globals_eval.html | 44 +-
- .../usb/host/dwc_otg/doc/html/globals_func.html | 575 +-
- .../host/dwc_otg/doc/html/globals_func_0x61.html | 70 -
- .../host/dwc_otg/doc/html/globals_func_0x62.html | 68 -
- .../host/dwc_otg/doc/html/globals_func_0x63.html | 77 -
- .../host/dwc_otg/doc/html/globals_func_0x64.html | 427 -
- .../host/dwc_otg/doc/html/globals_func_0x65.html | 73 -
- .../host/dwc_otg/doc/html/globals_func_0x66.html | 72 -
- .../host/dwc_otg/doc/html/globals_func_0x67.html | 78 -
- .../host/dwc_otg/doc/html/globals_func_0x68.html | 101 -
- .../host/dwc_otg/doc/html/globals_func_0x69.html | 71 -
- .../host/dwc_otg/doc/html/globals_func_0x6b.html | 66 -
- .../host/dwc_otg/doc/html/globals_func_0x6d.html | 66 -
- .../host/dwc_otg/doc/html/globals_func_0x70.html | 78 -
- .../host/dwc_otg/doc/html/globals_func_0x71.html | 67 -
- .../host/dwc_otg/doc/html/globals_func_0x72.html | 80 -
- .../host/dwc_otg/doc/html/globals_func_0x73.html | 77 -
- .../host/dwc_otg/doc/html/globals_func_0x75.html | 73 -
- .../host/dwc_otg/doc/html/globals_func_0x76.html | 65 -
- .../host/dwc_otg/doc/html/globals_func_0x77.html | 70 -
- .../usb/host/dwc_otg/doc/html/globals_type.html | 257 +-
- .../usb/host/dwc_otg/doc/html/globals_vars.html | 122 +-
- .../dwc_otg/doc/html/linux module attributes.html | 33 +-
- drivers/usb/host/dwc_otg/doc/html/main.html | 15 +-
- .../host/dwc_otg/doc/html/module parameters.html | 72 +-
- drivers/usb/host/dwc_otg/doc/html/pages.html | 15 +-
- .../html/struct__ddma__align__buffer__setup.html | 32 +-
- .../html/struct__ddma__concat__buffer__setup.html | 32 +-
- .../struct__ddma__concat__buffer__setup__hdr.html | 36 +-
- .../doc/html/struct__ddma__sg__buffer__setup.html | 44 +-
- .../doc/html/struct__rx__fifo__size__setup.html | 28 +-
- .../doc/html/struct__tx__fifo__size__setup.html | 32 +-
- .../doc/html/structcfi__all__features__header.html | 68 +-
- .../dwc_otg/doc/html/structcfi__dma__buff.html | 41 -
- .../usb/host/dwc_otg/doc/html/structcfi__ep.html | 60 +-
- .../doc/html/structcfi__feature__desc__header.html | 42 +-
- .../usb/host/dwc_otg/doc/html/structcfi__ops.html | 44 +-
- .../host/dwc_otg/doc/html/structcfi__string.html | 30 +-
- .../doc/html/structcfi__usb__ctrlrequest.html | 50 +-
- .../usb/host/dwc_otg/doc/html/structcfiobject.html | 62 -
- .../usb/host/dwc_otg/doc/html/structdwc__ep.html | 251 +-
- .../usb/host/dwc_otg/doc/html/structdwc__hc.html | 566 +-
- .../doc/html/structdwc__otg__cil__callbacks.html | 54 +-
- .../html/structdwc__otg__core__global__regs.html | 786 +-
- .../dwc_otg/doc/html/structdwc__otg__core__if.html | 319 +-
- .../doc/html/structdwc__otg__core__params.html | 1032 +-
- .../doc/html/structdwc__otg__dev__dma__desc.html | 32 +-
- .../html/structdwc__otg__dev__global__regs.html | 600 +-
- .../dwc_otg/doc/html/structdwc__otg__dev__if.html | 150 +-
- .../html/structdwc__otg__dev__in__ep__regs.html | 280 +-
- .../html/structdwc__otg__dev__out__ep__regs.html | 284 +-
- .../dwc_otg/doc/html/structdwc__otg__device.html | 77 +-
- .../structdwc__otg__driver__module__params.html | 146 -
- .../dwc_otg/doc/html/structdwc__otg__hc__regs.html | 252 +-
- .../host/dwc_otg/doc/html/structdwc__otg__hcd.html | 666 +-
- .../html/structdwc__otg__hcd__function__ops.html | 53 -
- .../structdwc__otg__hcd__iso__packet__desc.html | 47 -
- .../doc/html/structdwc__otg__hcd__pipe__info.html | 50 -
- .../dwc_otg/doc/html/structdwc__otg__hcd__urb.html | 80 -
- .../doc/html/structdwc__otg__host__dma__desc.html | 32 +-
- .../html/structdwc__otg__host__global__regs.html | 280 +-
- .../dwc_otg/doc/html/structdwc__otg__host__if.html | 48 +-
- .../host/dwc_otg/doc/html/structdwc__otg__pcd.html | 180 +-
- .../dwc_otg/doc/html/structdwc__otg__pcd__ep.html | 64 +-
- .../html/structdwc__otg__pcd__function__ops.html | 68 +-
- .../doc/html/structdwc__otg__pcd__request.html | 57 +-
- .../host/dwc_otg/doc/html/structdwc__otg__qh.html | 318 +-
- .../host/dwc_otg/doc/html/structdwc__otg__qtd.html | 198 +-
- .../dwc_otg/doc/html/structgadget__wrapper.html | 53 -
- .../dwc_otg/doc/html/structiso__pkt__info.html | 36 +-
- .../doc/html/structwrapper__priv__data.html | 38 -
- .../usb/host/dwc_otg/doc/html/structzero__dev.html | 56 -
- drivers/usb/host/dwc_otg/doc/html/tabs.css | 102 -
- drivers/usb/host/dwc_otg/doc/html/todo.html | 233 +-
- drivers/usb/host/dwc_otg/doc/html/tree.html | 145 +-
- .../host/dwc_otg/doc/html/unionadpctl__data.html | 440 +
- .../host/dwc_otg/doc/html/uniondaint__data.html | 102 +-
- .../usb/host/dwc_otg/doc/html/uniondcfg__data.html | 55 +-
- .../usb/host/dwc_otg/doc/html/uniondctl__data.html | 67 +-
- .../host/dwc_otg/doc/html/uniondepctl__data.html | 155 +-
- .../host/dwc_otg/doc/html/uniondeptsiz0__data.html | 44 +-
- .../host/dwc_otg/doc/html/uniondeptsiz__data.html | 40 +-
- .../dwc_otg/doc/html/uniondev__dma__desc__sts.html | 95 +-
- .../doc/html/uniondevice__grxsts__data.html | 44 +-
- .../host/dwc_otg/doc/html/uniondiepint__data.html | 62 +-
- .../host/dwc_otg/doc/html/uniondoepint__data.html | 64 +-
- .../usb/host/dwc_otg/doc/html/uniondsts__data.html | 44 +-
- .../host/dwc_otg/doc/html/uniondthrctl__data.html | 211 +-
- .../host/dwc_otg/doc/html/uniondtknq1__data.html | 74 +-
- .../host/dwc_otg/doc/html/uniondtxfsts__data.html | 36 +-
- ...otg__hcd_1_1dwc__otg__hcd__internal__flags.html | 48 +-
- .../host/dwc_otg/doc/html/unionfifosize__data.html | 36 +-
- .../host/dwc_otg/doc/html/uniongahbcfg__data.html | 54 +-
- .../dwc_otg/doc/html/uniongdfifocfg__data.html | 45 +
- .../host/dwc_otg/doc/html/unionggpio__data.html | 44 +
- .../host/dwc_otg/doc/html/uniongi2cctl__data.html | 54 +-
- .../host/dwc_otg/doc/html/uniongintmsk__data.html | 96 +-
- .../host/dwc_otg/doc/html/uniongintsts__data.html | 96 +-
- .../host/dwc_otg/doc/html/unionglpmctl__data.html | 453 +-
- .../host/dwc_otg/doc/html/uniongnptxsts__data.html | 80 +-
- .../host/dwc_otg/doc/html/uniongotgctl__data.html | 76 +-
- .../host/dwc_otg/doc/html/uniongotgint__data.html | 55 +-
- .../host/dwc_otg/doc/html/uniongpvndctl__data.html | 60 +
- .../host/dwc_otg/doc/html/uniongpwrdn__data.html | 114 +
- .../host/dwc_otg/doc/html/uniongrstctl__data.html | 315 +-
- .../host/dwc_otg/doc/html/uniongsnpsid__data.html | 42 +
- .../usb/host/dwc_otg/doc/html/unionguid__data.html | 42 +
- .../host/dwc_otg/doc/html/uniongusbcfg__data.html | 86 +-
- .../host/dwc_otg/doc/html/unionhaint__data.html | 72 +-
- .../host/dwc_otg/doc/html/unionhaintmsk__data.html | 72 +-
- .../host/dwc_otg/doc/html/unionhcchar__data.html | 116 +-
- .../host/dwc_otg/doc/html/unionhcdma__data.html | 68 +-
- .../usb/host/dwc_otg/doc/html/unionhcfg__data.html | 57 +-
- .../host/dwc_otg/doc/html/unionhcint__data.html | 62 +-
- .../host/dwc_otg/doc/html/unionhcintmsk__data.html | 62 +-
- .../host/dwc_otg/doc/html/unionhcsplt__data.html | 63 -
- .../host/dwc_otg/doc/html/unionhctsiz__data.html | 86 +-
- .../usb/host/dwc_otg/doc/html/unionhfir__data.html | 38 +-
- .../host/dwc_otg/doc/html/unionhfnum__data.html | 36 +-
- .../doc/html/unionhost__dma__desc__sts.html | 100 +-
- .../dwc_otg/doc/html/unionhost__grxsts__data.html | 42 +-
- .../host/dwc_otg/doc/html/unionhprt0__data.html | 62 +-
- .../host/dwc_otg/doc/html/unionhptxsts__data.html | 62 -
- .../host/dwc_otg/doc/html/unionhwcfg1__data.html | 64 +-
- .../host/dwc_otg/doc/html/unionhwcfg2__data.html | 62 +-
- .../host/dwc_otg/doc/html/unionhwcfg3__data.html | 56 +-
- .../host/dwc_otg/doc/html/unionhwcfg4__data.html | 64 +-
- .../host/dwc_otg/doc/html/unionpcgcctl__data.html | 74 +-
- 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 | 526 +-
- drivers/usb/host/dwc_otg/dwc_otg_attr.h | 25 +-
- drivers/usb/host/dwc_otg/dwc_otg_cfi.c | 112 +-
- drivers/usb/host/dwc_otg/dwc_otg_cfi.h | 29 +-
- drivers/usb/host/dwc_otg/dwc_otg_cil.c | 3275 ++++--
- drivers/usb/host/dwc_otg/dwc_otg_cil.h | 524 +-
- drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 1027 +-
- drivers/usb/host/dwc_otg/dwc_otg_core_if.h | 79 +-
- drivers/usb/host/dwc_otg/dwc_otg_dbg.h | 3 +
- drivers/usb/host/dwc_otg/dwc_otg_driver.c | 526 +-
- drivers/usb/host/dwc_otg/dwc_otg_driver.h | 31 +-
- drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 1293 +--
- drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 95 +-
- drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 780 +-
- drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h | 35 +-
- drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 419 +-
- drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 312 +-
- drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 143 +-
- drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 185 +
- drivers/usb/host/dwc_otg/dwc_otg_pcd.c | 1157 +-
- drivers/usb/host/dwc_otg/dwc_otg_pcd.h | 70 +-
- drivers/usb/host/dwc_otg/dwc_otg_pcd_if.h | 43 +-
- drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c | 1600 ++-
- drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c | 341 +-
- drivers/usb/host/dwc_otg/dwc_otg_regs.h | 916 +-
+ drivers/usb/host/dwc_common_port/Makefile | 38 +-
+ drivers/usb/host/dwc_common_port/Makefile.fbsd | 17 +
+ drivers/usb/host/dwc_common_port/Makefile.linux | 39 +-
+ drivers/usb/host/dwc_common_port/changes.txt | 174 +
+ .../html/dir_c13d72e45af28cdc461a5f284d3d36fc.html | 81 -
+ .../usb/host/dwc_common_port/doc/html/dirs.html | 22 -
+ .../usb/host/dwc_common_port/doc/html/doxygen.css | 358 -
+ .../host/dwc_common_port/doc/html/dwc__cc_8h.html | 709 --
+ .../dwc_common_port/doc/html/dwc__crypto_8c.html | 435 -
+ .../dwc_common_port/doc/html/dwc__crypto_8h.html | 618 -
+ .../host/dwc_common_port/doc/html/dwc__dh_8h.html | 166 -
+ .../dwc_common_port/doc/html/dwc__list_8h.html | 1844 ---
+ .../dwc_common_port/doc/html/dwc__modpow_8h.html | 48 -
+ .../dwc_common_port/doc/html/dwc__notifier_8h.html | 306 -
+ .../host/dwc_common_port/doc/html/dwc__os_8h.html | 3090 -----
+ .../usb/host/dwc_common_port/doc/html/files.html | 34 -
+ .../usb/host/dwc_common_port/doc/html/globals.html | 163 -
+ .../dwc_common_port/doc/html/globals_defs.html | 41 -
+ .../dwc_common_port/doc/html/globals_func.html | 153 -
+ .../dwc_common_port/doc/html/globals_type.html | 41 -
+ .../usb/host/dwc_common_port/doc/html/index.html | 8 -
+ .../usb/host/dwc_common_port/doc/html/main.html | 45 -
+ .../usb/host/dwc_common_port/doc/html/pages.html | 23 -
+ drivers/usb/host/dwc_common_port/doc/html/tabs.css | 102 -
+ .../usb/host/dwc_common_port/doc/html/todo.html | 23 -
+ .../usb/host/dwc_common_port/doc/html/tree.html | 90 -
+ drivers/usb/host/dwc_common_port/dwc_cc.c | 116 +-
+ drivers/usb/host/dwc_common_port/dwc_cc.h | 42 +-
+ drivers/usb/host/dwc_common_port/dwc_common_fbsd.c | 1308 +++
+ .../usb/host/dwc_common_port/dwc_common_linux.c | 1343 ++-
+ 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 | 274 +-
+ drivers/usb/host/dwc_common_port/dwc_mem.c | 191 +-
+ 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 | 155 +-
+ drivers/usb/host/dwc_common_port/dwc_notifier.h | 22 +-
+ drivers/usb/host/dwc_common_port/dwc_os.h | 627 +-
+ drivers/usb/host/dwc_common_port/usb.h | 308 +-
+ drivers/usb/host/dwc_otg/Makefile | 40 +-
+ drivers/usb/host/dwc_otg/doc/doxygen.cfg | 2 +-
+ drivers/usb/host/dwc_otg/doc/html/annotated.html | 51 +-
+ drivers/usb/host/dwc_otg/doc/html/doxygen.css | 143 +-
+ drivers/usb/host/dwc_otg/doc/html/doxygen.png | Bin 0 -> 1281 bytes
+ .../dwc_otg/doc/html/dummy__audio_8c-source.html | 1550 ---
+ .../doc/html/dwc__cfi__common_8h-source.html | 196 +-
+ .../host/dwc_otg/doc/html/dwc__cfi__common_8h.html | 102 +-
+ .../dwc_otg/doc/html/dwc__otg__adp_8c-source.html | 769 ++
+ .../host/dwc_otg/doc/html/dwc__otg__adp_8c.html | 482 +
+ .../dwc_otg/doc/html/dwc__otg__adp_8h-source.html | 80 +
+ .../host/dwc_otg/doc/html/dwc__otg__adp_8h.html | 308 +
+ .../dwc_otg/doc/html/dwc__otg__attr_8c-source.html | 1741 +--
+ .../host/dwc_otg/doc/html/dwc__otg__attr_8c.html | 714 +-
+ .../dwc_otg/doc/html/dwc__otg__attr_8h-source.html | 183 +-
+ .../host/dwc_otg/doc/html/dwc__otg__attr_8h.html | 82 +-
+ .../dwc_otg/doc/html/dwc__otg__cfi_8c-source.html | 3419 +++---
+ .../host/dwc_otg/doc/html/dwc__otg__cfi_8c.html | 24 +-
+ .../dwc_otg/doc/html/dwc__otg__cfi_8h-source.html | 570 +-
+ .../host/dwc_otg/doc/html/dwc__otg__cfi_8h.html | 336 +-
+ .../dwc_otg/doc/html/dwc__otg__cil_8c-source.html | 11466 +++++++++++--------
+ .../host/dwc_otg/doc/html/dwc__otg__cil_8c.html | 4356 ++++---
+ .../dwc_otg/doc/html/dwc__otg__cil_8h-source.html | 1601 +--
+ .../host/dwc_otg/doc/html/dwc__otg__cil_8h.html | 2770 +++--
+ .../doc/html/dwc__otg__cil__intr_8c-source.html | 2023 ++--
+ .../dwc_otg/doc/html/dwc__otg__cil__intr_8c.html | 820 +-
+ .../doc/html/dwc__otg__core__if_8h-source.html | 746 +-
+ .../dwc_otg/doc/html/dwc__otg__core__if_8h.html | 2414 ++--
+ .../dwc_otg/doc/html/dwc__otg__dbg_8h-source.html | 172 +-
+ .../host/dwc_otg/doc/html/dwc__otg__dbg_8h.html | 126 +-
+ .../doc/html/dwc__otg__driver_8c-source.html | 2204 ++--
+ .../host/dwc_otg/doc/html/dwc__otg__driver_8c.html | 883 +-
+ .../doc/html/dwc__otg__driver_8h-source.html | 178 +-
+ .../host/dwc_otg/doc/html/dwc__otg__driver_8h.html | 31 +-
+ .../dwc_otg/doc/html/dwc__otg__hcd_8c-source.html | 6146 +++++-----
+ .../host/dwc_otg/doc/html/dwc__otg__hcd_8c.html | 2417 ++--
+ .../dwc_otg/doc/html/dwc__otg__hcd_8h-source.html | 1017 +-
+ .../host/dwc_otg/doc/html/dwc__otg__hcd_8h.html | 1718 +--
+ .../doc/html/dwc__otg__hcd__ddma_8c-source.html | 2128 ++--
+ .../dwc_otg/doc/html/dwc__otg__hcd__ddma_8c.html | 357 +-
+ .../doc/html/dwc__otg__hcd__if_8h-source.html | 367 +-
+ .../dwc_otg/doc/html/dwc__otg__hcd__if_8h.html | 1798 +--
+ .../doc/html/dwc__otg__hcd__intr_8c-source.html | 3778 +++---
+ .../dwc_otg/doc/html/dwc__otg__hcd__intr_8c.html | 1754 +--
+ .../doc/html/dwc__otg__hcd__linux_8c-source.html | 1501 +--
+ .../dwc_otg/doc/html/dwc__otg__hcd__linux_8c.html | 680 +-
+ .../doc/html/dwc__otg__hcd__queue_8c-source.html | 1229 +-
+ .../dwc_otg/doc/html/dwc__otg__hcd__queue_8c.html | 850 +-
+ .../doc/html/dwc__otg__os__dep_8h-source.html | 102 +
+ .../dwc_otg/doc/html/dwc__otg__os__dep_8h.html | 59 +
+ .../dwc_otg/doc/html/dwc__otg__pcd_8c-source.html | 4273 ++++---
+ .../host/dwc_otg/doc/html/dwc__otg__pcd_8c.html | 1757 +--
+ .../dwc_otg/doc/html/dwc__otg__pcd_8h-source.html | 344 +-
+ .../host/dwc_otg/doc/html/dwc__otg__pcd_8h.html | 293 +-
+ .../doc/html/dwc__otg__pcd__if_8h-source.html | 336 +-
+ .../dwc_otg/doc/html/dwc__otg__pcd__if_8h.html | 1328 ++-
+ .../doc/html/dwc__otg__pcd__intr_8c-source.html | 7951 +++++++------
+ .../dwc_otg/doc/html/dwc__otg__pcd__intr_8c.html | 2234 ++--
+ .../doc/html/dwc__otg__pcd__linux_8c-source.html | 2103 ++--
+ .../dwc_otg/doc/html/dwc__otg__pcd__linux_8c.html | 1008 +-
+ .../dwc_otg/doc/html/dwc__otg__regs_8h-source.html | 2624 +++--
+ .../host/dwc_otg/doc/html/dwc__otg__regs_8h.html | 2161 ++--
+ drivers/usb/host/dwc_otg/doc/html/files.html | 28 +-
+ drivers/usb/host/dwc_otg/doc/html/ftv2blank.png | Bin 0 -> 174 bytes
+ drivers/usb/host/dwc_otg/doc/html/ftv2doc.png | Bin 0 -> 255 bytes
+ .../usb/host/dwc_otg/doc/html/ftv2folderclosed.png | Bin 0 -> 259 bytes
+ .../usb/host/dwc_otg/doc/html/ftv2folderopen.png | Bin 0 -> 261 bytes
+ drivers/usb/host/dwc_otg/doc/html/ftv2lastnode.png | Bin 0 -> 233 bytes
+ drivers/usb/host/dwc_otg/doc/html/ftv2link.png | Bin 0 -> 358 bytes
+ .../usb/host/dwc_otg/doc/html/ftv2mlastnode.png | Bin 0 -> 160 bytes
+ drivers/usb/host/dwc_otg/doc/html/ftv2mnode.png | Bin 0 -> 194 bytes
+ drivers/usb/host/dwc_otg/doc/html/ftv2node.png | Bin 0 -> 235 bytes
+ .../usb/host/dwc_otg/doc/html/ftv2plastnode.png | Bin 0 -> 165 bytes
+ drivers/usb/host/dwc_otg/doc/html/ftv2pnode.png | Bin 0 -> 200 bytes
+ drivers/usb/host/dwc_otg/doc/html/ftv2vertline.png | Bin 0 -> 229 bytes
+ drivers/usb/host/dwc_otg/doc/html/functions.html | 653 +-
+ .../usb/host/dwc_otg/doc/html/functions_0x62.html | 99 -
+ .../usb/host/dwc_otg/doc/html/functions_0x63.html | 110 -
+ .../usb/host/dwc_otg/doc/html/functions_0x64.html | 158 -
+ .../usb/host/dwc_otg/doc/html/functions_0x65.html | 109 -
+ .../usb/host/dwc_otg/doc/html/functions_0x66.html | 81 -
+ .../usb/host/dwc_otg/doc/html/functions_0x67.html | 95 -
+ .../usb/host/dwc_otg/doc/html/functions_0x68.html | 119 -
+ .../usb/host/dwc_otg/doc/html/functions_0x69.html | 121 -
+ .../usb/host/dwc_otg/doc/html/functions_0x6c.html | 74 -
+ .../usb/host/dwc_otg/doc/html/functions_0x6d.html | 79 -
+ .../usb/host/dwc_otg/doc/html/functions_0x6e.html | 99 -
+ .../usb/host/dwc_otg/doc/html/functions_0x6f.html | 101 -
+ .../usb/host/dwc_otg/doc/html/functions_0x70.html | 144 -
+ .../usb/host/dwc_otg/doc/html/functions_0x71.html | 71 -
+ .../usb/host/dwc_otg/doc/html/functions_0x72.html | 141 -
+ .../usb/host/dwc_otg/doc/html/functions_0x73.html | 128 -
+ .../usb/host/dwc_otg/doc/html/functions_0x74.html | 88 -
+ .../usb/host/dwc_otg/doc/html/functions_0x75.html | 78 -
+ .../usb/host/dwc_otg/doc/html/functions_0x76.html | 65 -
+ .../usb/host/dwc_otg/doc/html/functions_0x77.html | 79 -
+ .../usb/host/dwc_otg/doc/html/functions_0x78.html | 77 -
+ .../usb/host/dwc_otg/doc/html/functions_func.html | 32 +-
+ .../usb/host/dwc_otg/doc/html/functions_vars.html | 650 +-
+ .../host/dwc_otg/doc/html/functions_vars_0x62.html | 99 -
+ .../host/dwc_otg/doc/html/functions_vars_0x63.html | 110 -
+ .../host/dwc_otg/doc/html/functions_vars_0x64.html | 157 -
+ .../host/dwc_otg/doc/html/functions_vars_0x65.html | 109 -
+ .../host/dwc_otg/doc/html/functions_vars_0x66.html | 81 -
+ .../host/dwc_otg/doc/html/functions_vars_0x67.html | 95 -
+ .../host/dwc_otg/doc/html/functions_vars_0x68.html | 119 -
+ .../host/dwc_otg/doc/html/functions_vars_0x69.html | 121 -
+ .../host/dwc_otg/doc/html/functions_vars_0x6c.html | 74 -
+ .../host/dwc_otg/doc/html/functions_vars_0x6d.html | 79 -
+ .../host/dwc_otg/doc/html/functions_vars_0x6e.html | 99 -
+ .../host/dwc_otg/doc/html/functions_vars_0x6f.html | 101 -
+ .../host/dwc_otg/doc/html/functions_vars_0x70.html | 144 -
+ .../host/dwc_otg/doc/html/functions_vars_0x71.html | 71 -
+ .../host/dwc_otg/doc/html/functions_vars_0x72.html | 141 -
+ .../host/dwc_otg/doc/html/functions_vars_0x73.html | 128 -
+ .../host/dwc_otg/doc/html/functions_vars_0x74.html | 88 -
+ .../host/dwc_otg/doc/html/functions_vars_0x75.html | 78 -
+ .../host/dwc_otg/doc/html/functions_vars_0x76.html | 65 -
+ .../host/dwc_otg/doc/html/functions_vars_0x77.html | 79 -
+ .../host/dwc_otg/doc/html/functions_vars_0x78.html | 77 -
+ drivers/usb/host/dwc_otg/doc/html/globals.html | 747 +-
+ .../usb/host/dwc_otg/doc/html/globals_0x61.html | 76 -
+ .../usb/host/dwc_otg/doc/html/globals_0x62.html | 83 -
+ .../usb/host/dwc_otg/doc/html/globals_0x63.html | 100 -
+ .../usb/host/dwc_otg/doc/html/globals_0x64.html | 686 --
+ .../usb/host/dwc_otg/doc/html/globals_0x65.html | 78 -
+ .../usb/host/dwc_otg/doc/html/globals_0x66.html | 87 -
+ .../usb/host/dwc_otg/doc/html/globals_0x67.html | 93 -
+ .../usb/host/dwc_otg/doc/html/globals_0x68.html | 129 -
+ .../usb/host/dwc_otg/doc/html/globals_0x69.html | 76 -
+ .../usb/host/dwc_otg/doc/html/globals_0x6b.html | 69 -
+ .../usb/host/dwc_otg/doc/html/globals_0x6d.html | 84 -
+ .../usb/host/dwc_otg/doc/html/globals_0x6e.html | 68 -
+ .../usb/host/dwc_otg/doc/html/globals_0x6f.html | 73 -
+ .../usb/host/dwc_otg/doc/html/globals_0x70.html | 84 -
+ .../usb/host/dwc_otg/doc/html/globals_0x71.html | 70 -
+ .../usb/host/dwc_otg/doc/html/globals_0x72.html | 94 -
+ .../usb/host/dwc_otg/doc/html/globals_0x73.html | 85 -
+ .../usb/host/dwc_otg/doc/html/globals_0x74.html | 68 -
+ .../usb/host/dwc_otg/doc/html/globals_0x75.html | 80 -
+ .../usb/host/dwc_otg/doc/html/globals_0x76.html | 75 -
+ .../usb/host/dwc_otg/doc/html/globals_0x77.html | 74 -
+ .../usb/host/dwc_otg/doc/html/globals_defs.html | 137 +-
+ .../host/dwc_otg/doc/html/globals_defs_0x61.html | 64 -
+ .../host/dwc_otg/doc/html/globals_defs_0x62.html | 71 -
+ .../host/dwc_otg/doc/html/globals_defs_0x63.html | 74 -
+ .../host/dwc_otg/doc/html/globals_defs_0x64.html | 241 -
+ .../host/dwc_otg/doc/html/globals_defs_0x66.html | 71 -
+ .../host/dwc_otg/doc/html/globals_defs_0x67.html | 62 -
+ .../host/dwc_otg/doc/html/globals_defs_0x68.html | 63 -
+ .../host/dwc_otg/doc/html/globals_defs_0x69.html | 62 -
+ .../host/dwc_otg/doc/html/globals_defs_0x6d.html | 76 -
+ .../host/dwc_otg/doc/html/globals_defs_0x6e.html | 62 -
+ .../host/dwc_otg/doc/html/globals_defs_0x6f.html | 67 -
+ .../host/dwc_otg/doc/html/globals_defs_0x72.html | 66 -
+ .../host/dwc_otg/doc/html/globals_defs_0x73.html | 63 -
+ .../host/dwc_otg/doc/html/globals_defs_0x75.html | 64 -
+ .../host/dwc_otg/doc/html/globals_defs_0x76.html | 68 -
+ .../usb/host/dwc_otg/doc/html/globals_enum.html | 45 +-
+ .../usb/host/dwc_otg/doc/html/globals_eval.html | 44 +-
+ .../usb/host/dwc_otg/doc/html/globals_func.html | 575 +-
+ .../host/dwc_otg/doc/html/globals_func_0x61.html | 70 -
+ .../host/dwc_otg/doc/html/globals_func_0x62.html | 68 -
+ .../host/dwc_otg/doc/html/globals_func_0x63.html | 77 -
+ .../host/dwc_otg/doc/html/globals_func_0x64.html | 427 -
+ .../host/dwc_otg/doc/html/globals_func_0x65.html | 73 -
+ .../host/dwc_otg/doc/html/globals_func_0x66.html | 72 -
+ .../host/dwc_otg/doc/html/globals_func_0x67.html | 78 -
+ .../host/dwc_otg/doc/html/globals_func_0x68.html | 101 -
+ .../host/dwc_otg/doc/html/globals_func_0x69.html | 71 -
+ .../host/dwc_otg/doc/html/globals_func_0x6b.html | 66 -
+ .../host/dwc_otg/doc/html/globals_func_0x6d.html | 66 -
+ .../host/dwc_otg/doc/html/globals_func_0x70.html | 78 -
+ .../host/dwc_otg/doc/html/globals_func_0x71.html | 67 -
+ .../host/dwc_otg/doc/html/globals_func_0x72.html | 80 -
+ .../host/dwc_otg/doc/html/globals_func_0x73.html | 77 -
+ .../host/dwc_otg/doc/html/globals_func_0x75.html | 73 -
+ .../host/dwc_otg/doc/html/globals_func_0x76.html | 65 -
+ .../host/dwc_otg/doc/html/globals_func_0x77.html | 70 -
+ .../usb/host/dwc_otg/doc/html/globals_type.html | 257 +-
+ .../usb/host/dwc_otg/doc/html/globals_vars.html | 122 +-
+ .../dwc_otg/doc/html/linux module attributes.html | 33 +-
+ drivers/usb/host/dwc_otg/doc/html/main.html | 15 +-
+ .../host/dwc_otg/doc/html/module parameters.html | 72 +-
+ drivers/usb/host/dwc_otg/doc/html/pages.html | 15 +-
+ .../html/struct__ddma__align__buffer__setup.html | 32 +-
+ .../html/struct__ddma__concat__buffer__setup.html | 32 +-
+ .../struct__ddma__concat__buffer__setup__hdr.html | 36 +-
+ .../doc/html/struct__ddma__sg__buffer__setup.html | 44 +-
+ .../doc/html/struct__rx__fifo__size__setup.html | 28 +-
+ .../doc/html/struct__tx__fifo__size__setup.html | 32 +-
+ .../doc/html/structcfi__all__features__header.html | 68 +-
+ .../dwc_otg/doc/html/structcfi__dma__buff.html | 41 -
+ .../usb/host/dwc_otg/doc/html/structcfi__ep.html | 60 +-
+ .../doc/html/structcfi__feature__desc__header.html | 42 +-
+ .../usb/host/dwc_otg/doc/html/structcfi__ops.html | 44 +-
+ .../host/dwc_otg/doc/html/structcfi__string.html | 30 +-
+ .../doc/html/structcfi__usb__ctrlrequest.html | 50 +-
+ .../usb/host/dwc_otg/doc/html/structcfiobject.html | 62 -
+ .../usb/host/dwc_otg/doc/html/structdwc__ep.html | 251 +-
+ .../usb/host/dwc_otg/doc/html/structdwc__hc.html | 566 +-
+ .../doc/html/structdwc__otg__cil__callbacks.html | 54 +-
+ .../html/structdwc__otg__core__global__regs.html | 786 +-
+ .../dwc_otg/doc/html/structdwc__otg__core__if.html | 319 +-
+ .../doc/html/structdwc__otg__core__params.html | 1032 +-
+ .../doc/html/structdwc__otg__dev__dma__desc.html | 32 +-
+ .../html/structdwc__otg__dev__global__regs.html | 600 +-
+ .../dwc_otg/doc/html/structdwc__otg__dev__if.html | 150 +-
+ .../html/structdwc__otg__dev__in__ep__regs.html | 280 +-
+ .../html/structdwc__otg__dev__out__ep__regs.html | 284 +-
+ .../dwc_otg/doc/html/structdwc__otg__device.html | 77 +-
+ .../structdwc__otg__driver__module__params.html | 146 -
+ .../dwc_otg/doc/html/structdwc__otg__hc__regs.html | 252 +-
+ .../host/dwc_otg/doc/html/structdwc__otg__hcd.html | 666 +-
+ .../html/structdwc__otg__hcd__function__ops.html | 53 -
+ .../structdwc__otg__hcd__iso__packet__desc.html | 47 -
+ .../doc/html/structdwc__otg__hcd__pipe__info.html | 50 -
+ .../dwc_otg/doc/html/structdwc__otg__hcd__urb.html | 80 -
+ .../doc/html/structdwc__otg__host__dma__desc.html | 32 +-
+ .../html/structdwc__otg__host__global__regs.html | 280 +-
+ .../dwc_otg/doc/html/structdwc__otg__host__if.html | 48 +-
+ .../host/dwc_otg/doc/html/structdwc__otg__pcd.html | 180 +-
+ .../dwc_otg/doc/html/structdwc__otg__pcd__ep.html | 64 +-
+ .../html/structdwc__otg__pcd__function__ops.html | 68 +-
+ .../doc/html/structdwc__otg__pcd__request.html | 57 +-
+ .../host/dwc_otg/doc/html/structdwc__otg__qh.html | 318 +-
+ .../host/dwc_otg/doc/html/structdwc__otg__qtd.html | 198 +-
+ .../dwc_otg/doc/html/structgadget__wrapper.html | 53 -
+ .../dwc_otg/doc/html/structiso__pkt__info.html | 36 +-
+ .../doc/html/structwrapper__priv__data.html | 38 -
+ .../usb/host/dwc_otg/doc/html/structzero__dev.html | 56 -
+ drivers/usb/host/dwc_otg/doc/html/tabs.css | 102 -
+ drivers/usb/host/dwc_otg/doc/html/todo.html | 233 +-
+ drivers/usb/host/dwc_otg/doc/html/tree.html | 145 +-
+ .../host/dwc_otg/doc/html/unionadpctl__data.html | 440 +
+ .../host/dwc_otg/doc/html/uniondaint__data.html | 102 +-
+ .../usb/host/dwc_otg/doc/html/uniondcfg__data.html | 55 +-
+ .../usb/host/dwc_otg/doc/html/uniondctl__data.html | 67 +-
+ .../host/dwc_otg/doc/html/uniondepctl__data.html | 155 +-
+ .../host/dwc_otg/doc/html/uniondeptsiz0__data.html | 44 +-
+ .../host/dwc_otg/doc/html/uniondeptsiz__data.html | 40 +-
+ .../dwc_otg/doc/html/uniondev__dma__desc__sts.html | 95 +-
+ .../doc/html/uniondevice__grxsts__data.html | 44 +-
+ .../host/dwc_otg/doc/html/uniondiepint__data.html | 62 +-
+ .../host/dwc_otg/doc/html/uniondoepint__data.html | 64 +-
+ .../usb/host/dwc_otg/doc/html/uniondsts__data.html | 44 +-
+ .../host/dwc_otg/doc/html/uniondthrctl__data.html | 211 +-
+ .../host/dwc_otg/doc/html/uniondtknq1__data.html | 74 +-
+ .../host/dwc_otg/doc/html/uniondtxfsts__data.html | 36 +-
+ ...otg__hcd_1_1dwc__otg__hcd__internal__flags.html | 48 +-
+ .../host/dwc_otg/doc/html/unionfifosize__data.html | 36 +-
+ .../host/dwc_otg/doc/html/uniongahbcfg__data.html | 54 +-
+ .../dwc_otg/doc/html/uniongdfifocfg__data.html | 45 +
+ .../host/dwc_otg/doc/html/unionggpio__data.html | 44 +
+ .../host/dwc_otg/doc/html/uniongi2cctl__data.html | 54 +-
+ .../host/dwc_otg/doc/html/uniongintmsk__data.html | 96 +-
+ .../host/dwc_otg/doc/html/uniongintsts__data.html | 96 +-
+ .../host/dwc_otg/doc/html/unionglpmctl__data.html | 453 +-
+ .../host/dwc_otg/doc/html/uniongnptxsts__data.html | 80 +-
+ .../host/dwc_otg/doc/html/uniongotgctl__data.html | 76 +-
+ .../host/dwc_otg/doc/html/uniongotgint__data.html | 55 +-
+ .../host/dwc_otg/doc/html/uniongpvndctl__data.html | 60 +
+ .../host/dwc_otg/doc/html/uniongpwrdn__data.html | 114 +
+ .../host/dwc_otg/doc/html/uniongrstctl__data.html | 315 +-
+ .../host/dwc_otg/doc/html/uniongsnpsid__data.html | 42 +
+ .../usb/host/dwc_otg/doc/html/unionguid__data.html | 42 +
+ .../host/dwc_otg/doc/html/uniongusbcfg__data.html | 86 +-
+ .../host/dwc_otg/doc/html/unionhaint__data.html | 72 +-
+ .../host/dwc_otg/doc/html/unionhaintmsk__data.html | 72 +-
+ .../host/dwc_otg/doc/html/unionhcchar__data.html | 116 +-
+ .../host/dwc_otg/doc/html/unionhcdma__data.html | 68 +-
+ .../usb/host/dwc_otg/doc/html/unionhcfg__data.html | 57 +-
+ .../host/dwc_otg/doc/html/unionhcint__data.html | 62 +-
+ .../host/dwc_otg/doc/html/unionhcintmsk__data.html | 62 +-
+ .../host/dwc_otg/doc/html/unionhcsplt__data.html | 63 -
+ .../host/dwc_otg/doc/html/unionhctsiz__data.html | 86 +-
+ .../usb/host/dwc_otg/doc/html/unionhfir__data.html | 38 +-
+ .../host/dwc_otg/doc/html/unionhfnum__data.html | 36 +-
+ .../doc/html/unionhost__dma__desc__sts.html | 100 +-
+ .../dwc_otg/doc/html/unionhost__grxsts__data.html | 42 +-
+ .../host/dwc_otg/doc/html/unionhprt0__data.html | 62 +-
+ .../host/dwc_otg/doc/html/unionhptxsts__data.html | 62 -
+ .../host/dwc_otg/doc/html/unionhwcfg1__data.html | 64 +-
+ .../host/dwc_otg/doc/html/unionhwcfg2__data.html | 62 +-
+ .../host/dwc_otg/doc/html/unionhwcfg3__data.html | 56 +-
+ .../host/dwc_otg/doc/html/unionhwcfg4__data.html | 64 +-
+ .../host/dwc_otg/doc/html/unionpcgcctl__data.html | 74 +-
+ 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 | 526 +-
+ drivers/usb/host/dwc_otg/dwc_otg_attr.h | 25 +-
+ drivers/usb/host/dwc_otg/dwc_otg_cfi.c | 112 +-
+ drivers/usb/host/dwc_otg/dwc_otg_cfi.h | 29 +-
+ drivers/usb/host/dwc_otg/dwc_otg_cil.c | 3275 ++++--
+ drivers/usb/host/dwc_otg/dwc_otg_cil.h | 524 +-
+ drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 1027 +-
+ drivers/usb/host/dwc_otg/dwc_otg_core_if.h | 79 +-
+ drivers/usb/host/dwc_otg/dwc_otg_dbg.h | 3 +
+ drivers/usb/host/dwc_otg/dwc_otg_driver.c | 526 +-
+ drivers/usb/host/dwc_otg/dwc_otg_driver.h | 31 +-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 1293 ++-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 95 +-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 780 +-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h | 35 +-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 419 +-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 312 +-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 143 +-
+ drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 185 +
+ drivers/usb/host/dwc_otg/dwc_otg_pcd.c | 1157 +-
+ drivers/usb/host/dwc_otg/dwc_otg_pcd.h | 70 +-
+ drivers/usb/host/dwc_otg/dwc_otg_pcd_if.h | 43 +-
+ drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c | 1600 ++-
+ drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c | 341 +-
+ drivers/usb/host/dwc_otg/dwc_otg_regs.h | 916 +-
357 files changed, 77086 insertions(+), 71826 deletions(-)
mode change 100644 => 100755 drivers/usb/host/dwc_common_port/Makefile
create mode 100755 drivers/usb/host/dwc_common_port/Makefile.fbsd
@@ -730,7 +730,7 @@ Subject: [PATCH] Update Synopsys USB OTG driver to v2.94a and disable
diff --git a/drivers/usb/host/dwc_common_port/Makefile b/drivers/usb/host/dwc_common_port/Makefile
old mode 100644
new mode 100755
-index b593b08..203c7eaa
+index b593b08..203c7ea
--- a/drivers/usb/host/dwc_common_port/Makefile
+++ b/drivers/usb/host/dwc_common_port/Makefile
@@ -4,21 +4,25 @@
@@ -79026,7 +79026,7 @@ index 11bddbc..a2f865b
diff --git a/drivers/usb/host/dwc_otg/doc/html/dwc__otg__hcd__if_8h.html b/drivers/usb/host/dwc_otg/doc/html/dwc__otg__hcd__if_8h.html
old mode 100644
new mode 100755
-index 3bb51aa1..bfdf80a
+index 3bb51aa..bfdf80a
--- a/drivers/usb/host/dwc_otg/doc/html/dwc__otg__hcd__if_8h.html
+++ b/drivers/usb/host/dwc_otg/doc/html/dwc__otg__hcd__if_8h.html
@@ -2,163 +2,157 @@
@@ -88857,7 +88857,7 @@ index cf20761..3f3fd86
diff --git a/drivers/usb/host/dwc_otg/doc/html/dwc__otg__hcd__linux_8c.html b/drivers/usb/host/dwc_otg/doc/html/dwc__otg__hcd__linux_8c.html
old mode 100644
new mode 100755
-index e88d971..6fa75f6d
+index e88d971..6fa75f6
--- a/drivers/usb/host/dwc_otg/doc/html/dwc__otg__hcd__linux_8c.html
+++ b/drivers/usb/host/dwc_otg/doc/html/dwc__otg__hcd__linux_8c.html
@@ -2,21 +2,9 @@
@@ -126367,7 +126367,7 @@ index b6be1be..0000000
-</html>
diff --git a/drivers/usb/host/dwc_otg/doc/html/functions_vars_0x71.html b/drivers/usb/host/dwc_otg/doc/html/functions_vars_0x71.html
deleted file mode 100644
-index 65a9066f..0000000
+index 65a9066..0000000
--- a/drivers/usb/host/dwc_otg/doc/html/functions_vars_0x71.html
+++ /dev/null
@@ -1,71 +0,0 @@
diff --git a/patches/linux-3.2.27/0115-Merged-in-microframe-scheduler-currently-disabled.-E.patch b/patches/linux-3.6.7/0113-Merged-in-microframe-scheduler-currently-disabled.-E.patch
index 82430e9..921b30a 100644
--- a/patches/linux-3.2.27/0115-Merged-in-microframe-scheduler-currently-disabled.-E.patch
+++ b/patches/linux-3.6.7/0113-Merged-in-microframe-scheduler-currently-disabled.-E.patch
@@ -4,12 +4,12 @@ Subject: [PATCH] Merged in microframe scheduler, currently disabled. Enable
with dwc_otg.microframe_schedule=1
---
- drivers/usb/host/dwc_otg/dwc_otg_driver.c | 4 +
- drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 69 +++++++-
- drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 25 ++-
- drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 21 ++-
- drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 36 ++--
- drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 232 ++++++++++++++++++++++++--
+ drivers/usb/host/dwc_otg/dwc_otg_driver.c | 4 +
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 69 +++++++-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 25 ++-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 21 ++-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 36 +++--
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 232 ++++++++++++++++++++++++---
6 files changed, 346 insertions(+), 41 deletions(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.c b/drivers/usb/host/dwc_otg/dwc_otg_driver.c
diff --git a/patches/linux-3.2.27/0116-Make-microframe-schedule-patch-a-little-closer-to-de.patch b/patches/linux-3.6.7/0114-Make-microframe-schedule-patch-a-little-closer-to-de.patch
index d7b3a00..c206501 100644
--- a/patches/linux-3.2.27/0116-Make-microframe-schedule-patch-a-little-closer-to-de.patch
+++ b/patches/linux-3.6.7/0114-Make-microframe-schedule-patch-a-little-closer-to-de.patch
@@ -4,11 +4,11 @@ Subject: [PATCH] Make microframe schedule patch a little closer to denx
version. Remove vestiges of HW2937_WORKAROUND
---
- drivers/usb/host/dwc_otg/dwc_otg_cil.c | 1 -
- drivers/usb/host/dwc_otg/dwc_otg_cil.h | 2 --
- drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 3 ++-
- drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 18 ------------------
- drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 22 +++++++++++-----------
+ drivers/usb/host/dwc_otg/dwc_otg_cil.c | 1 -
+ drivers/usb/host/dwc_otg/dwc_otg_cil.h | 2 --
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 3 ++-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 18 ------------------
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 22 +++++++++++-----------
5 files changed, 13 insertions(+), 33 deletions(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_cil.c b/drivers/usb/host/dwc_otg/dwc_otg_cil.c
diff --git a/patches/linux-3.2.27/0117-Remove-remove-documentation-from-the-source-tree.patch b/patches/linux-3.6.7/0115-Remove-remove-documentation-from-the-source-tree.patch
index cd99131..bdc59ed 100644
--- a/patches/linux-3.2.27/0117-Remove-remove-documentation-from-the-source-tree.patch
+++ b/patches/linux-3.6.7/0115-Remove-remove-documentation-from-the-source-tree.patch
@@ -42215,7 +42215,7 @@ index 3f3fd86..0000000
-</html>
diff --git a/drivers/usb/host/dwc_otg/doc/html/dwc__otg__hcd__linux_8c.html b/drivers/usb/host/dwc_otg/doc/html/dwc__otg__hcd__linux_8c.html
deleted file mode 100755
-index 6fa75f6d..0000000
+index 6fa75f6..0000000
--- a/drivers/usb/host/dwc_otg/doc/html/dwc__otg__hcd__linux_8c.html
+++ /dev/null
@@ -1,604 +0,0 @@
diff --git a/patches/linux-3.2.27/0118-Fix-for-broken-GPIO-with-3.2-kernel.patch b/patches/linux-3.6.7/0116-Fix-for-broken-GPIO-with-3.2-kernel.patch
index f4909a1..c6271db 100644
--- a/patches/linux-3.2.27/0118-Fix-for-broken-GPIO-with-3.2-kernel.patch
+++ b/patches/linux-3.6.7/0116-Fix-for-broken-GPIO-with-3.2-kernel.patch
@@ -3,8 +3,8 @@ Date: Sun, 19 Aug 2012 20:56:11 +0100
Subject: [PATCH] Fix for broken GPIO with 3.2 kernel
---
- arch/arm/mach-bcm2708/bcm2708_gpio.c | 8 ++++----
- arch/arm/mach-bcm2708/include/mach/gpio.h | 5 ++++-
+ arch/arm/mach-bcm2708/bcm2708_gpio.c | 8 ++++----
+ arch/arm/mach-bcm2708/include/mach/gpio.h | 5 ++++-
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-bcm2708/bcm2708_gpio.c b/arch/arm/mach-bcm2708/bcm2708_gpio.c
diff --git a/patches/linux-3.2.27/0119-Revert-Disable-IRQs-in-dwc_otg_hcd_qh_free-because-D.patch b/patches/linux-3.6.7/0117-Revert-Disable-IRQs-in-dwc_otg_hcd_qh_free-because-D.patch
index e549f75..ce9c7db 100644
--- a/patches/linux-3.2.27/0119-Revert-Disable-IRQs-in-dwc_otg_hcd_qh_free-because-D.patch
+++ b/patches/linux-3.6.7/0117-Revert-Disable-IRQs-in-dwc_otg_hcd_qh_free-because-D.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] Revert "Disable IRQs in dwc_otg_hcd_qh_free" because
DWC_DMA_FREE should be called with enabled IRQs.
---
- drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 5 ++---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
diff --git a/patches/linux-3.2.27/0120-Regenerate-defconfigs-for-udpated-kernel-verision.patch b/patches/linux-3.6.7/0118-Regenerate-defconfigs-for-udpated-kernel-verision.patch
index 6b5db41..ce3957d 100644
--- a/patches/linux-3.2.27/0120-Regenerate-defconfigs-for-udpated-kernel-verision.patch
+++ b/patches/linux-3.6.7/0118-Regenerate-defconfigs-for-udpated-kernel-verision.patch
@@ -3,8 +3,8 @@ Date: Tue, 21 Aug 2012 10:40:36 +0100
Subject: [PATCH] Regenerate defconfigs for udpated kernel verision
---
- arch/arm/configs/bcmrpi_cutdown_defconfig | 74 +++--
- arch/arm/configs/bcmrpi_defconfig | 438 +++--------------------------
+ arch/arm/configs/bcmrpi_cutdown_defconfig | 74 +++--
+ arch/arm/configs/bcmrpi_defconfig | 438 +++---------------------------
2 files changed, 79 insertions(+), 433 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_cutdown_defconfig b/arch/arm/configs/bcmrpi_cutdown_defconfig
diff --git a/patches/linux-3.2.27/0121-Another-fix-for-10-second-hang-on-closing-sound-driv.patch b/patches/linux-3.6.7/0119-Another-fix-for-10-second-hang-on-closing-sound-driv.patch
index c8248cd..d7790e6 100644
--- a/patches/linux-3.2.27/0121-Another-fix-for-10-second-hang-on-closing-sound-driv.patch
+++ b/patches/linux-3.6.7/0119-Another-fix-for-10-second-hang-on-closing-sound-driv.patch
@@ -3,8 +3,8 @@ Date: Tue, 21 Aug 2012 12:25:47 +0100
Subject: [PATCH] Another fix for 10 second hang on closing sound driver
---
- sound/arm/bcm2835-pcm.c | 2 +-
- sound/arm/bcm2835.h | 2 +-
+ sound/arm/bcm2835-pcm.c | 2 +-
+ sound/arm/bcm2835.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c
diff --git a/patches/linux-3.2.27/0122-amba-pl011-Don-t-send-a-character-during-startup.patch b/patches/linux-3.6.7/0120-amba-pl011-Don-t-send-a-character-during-startup.patch
index a5ab46b..d8e922a 100644
--- a/patches/linux-3.2.27/0122-amba-pl011-Don-t-send-a-character-during-startup.patch
+++ b/patches/linux-3.6.7/0120-amba-pl011-Don-t-send-a-character-during-startup.patch
@@ -10,14 +10,14 @@ which isn't appropriate either.
Signed-off-by: Simon Arlott <sa.me.uk>
---
- drivers/tty/serial/amba-pl011.c | 6 ++++++
+ drivers/tty/serial/amba-pl011.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
-index 6da8cf8..1b60985 100644
+index 762f5fd..a8698b2 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
-@@ -1394,6 +1394,11 @@ static int pl011_startup(struct uart_port *port)
+@@ -1351,6 +1351,11 @@ static int pl011_startup(struct uart_port *port)
writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS);
/*
@@ -29,11 +29,11 @@ index 6da8cf8..1b60985 100644
* Provoke TX FIFO interrupt into asserting.
*/
cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE;
-@@ -1414,6 +1419,7 @@ static int pl011_startup(struct uart_port *port)
+@@ -1371,6 +1376,7 @@ static int pl011_startup(struct uart_port *port)
writew(0, uap->port.membase + UART01x_DR);
while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY)
barrier();
+#endif
- cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
- writew(cr, uap->port.membase + UART011_CR);
+ /* restore RTS and DTR */
+ cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR);
diff --git a/patches/linux-3.2.27/0123-Revert-Regenerate-defconfigs-for-udpated-kernel-veri.patch b/patches/linux-3.6.7/0121-Revert-Regenerate-defconfigs-for-udpated-kernel-veri.patch
index 0bc5de9..1b54d67 100644
--- a/patches/linux-3.2.27/0123-Revert-Regenerate-defconfigs-for-udpated-kernel-veri.patch
+++ b/patches/linux-3.6.7/0121-Revert-Regenerate-defconfigs-for-udpated-kernel-veri.patch
@@ -4,8 +4,8 @@ Subject: [PATCH] Revert "Regenerate defconfigs for udpated kernel verision"
This reverts commit d47734bbc53386d08c6a5a6a5bc4219e881cc778.
---
- arch/arm/configs/bcmrpi_cutdown_defconfig | 74 ++---
- arch/arm/configs/bcmrpi_defconfig | 438 ++++++++++++++++++++++++++---
+ arch/arm/configs/bcmrpi_cutdown_defconfig | 74 ++---
+ arch/arm/configs/bcmrpi_defconfig | 438 +++++++++++++++++++++++++++---
2 files changed, 433 insertions(+), 79 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_cutdown_defconfig b/arch/arm/configs/bcmrpi_cutdown_defconfig
diff --git a/patches/linux-3.2.27/0124-Regenerate-defconfigs-for-updated-kernel-verision-tr.patch b/patches/linux-3.6.7/0122-Regenerate-defconfigs-for-updated-kernel-verision-tr.patch
index ec2a530..9b34995 100644
--- a/patches/linux-3.2.27/0124-Regenerate-defconfigs-for-updated-kernel-verision-tr.patch
+++ b/patches/linux-3.6.7/0122-Regenerate-defconfigs-for-updated-kernel-verision-tr.patch
@@ -3,8 +3,8 @@ Date: Tue, 21 Aug 2012 13:10:02 +0100
Subject: [PATCH] Regenerate defconfigs for updated kernel verision, try 2
---
- arch/arm/configs/bcmrpi_cutdown_defconfig | 74 ++++++++++++-------------
- arch/arm/configs/bcmrpi_defconfig | 85 +++++++++++++----------------
+ arch/arm/configs/bcmrpi_cutdown_defconfig | 74 +++++++++++++--------------
+ arch/arm/configs/bcmrpi_defconfig | 85 ++++++++++++++-----------------
2 files changed, 73 insertions(+), 86 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_cutdown_defconfig b/arch/arm/configs/bcmrpi_cutdown_defconfig
diff --git a/patches/linux-3.2.27/0125-Read-memory-size-for-vc_mem-through-mailbox-property.patch b/patches/linux-3.6.7/0123-Read-memory-size-for-vc_mem-through-mailbox-property.patch
index 74ee6f2..a012c3b 100644
--- a/patches/linux-3.2.27/0125-Read-memory-size-for-vc_mem-through-mailbox-property.patch
+++ b/patches/linux-3.6.7/0123-Read-memory-size-for-vc_mem-through-mailbox-property.patch
@@ -3,9 +3,9 @@ Date: Tue, 21 Aug 2012 18:49:44 +0100
Subject: [PATCH] Read memory size for vc_mem through mailbox property channel
---
- arch/arm/mach-bcm2708/include/mach/vcio.h | 3 +-
- arch/arm/mach-bcm2708/include/mach/vmalloc.h | 2 +-
- arch/arm/mach-bcm2708/vc_mem.c | 82 ++++++++++++++++++++------
+ arch/arm/mach-bcm2708/include/mach/vcio.h | 3 +-
+ arch/arm/mach-bcm2708/include/mach/vmalloc.h | 2 +-
+ arch/arm/mach-bcm2708/vc_mem.c | 82 +++++++++++++++++++++-------
3 files changed, 66 insertions(+), 21 deletions(-)
diff --git a/arch/arm/mach-bcm2708/include/mach/vcio.h b/arch/arm/mach-bcm2708/include/mach/vcio.h
diff --git a/patches/linux-3.2.27/0126-Revert-amba-pl011-Don-t-send-a-character-during-star.patch b/patches/linux-3.6.7/0124-Revert-amba-pl011-Don-t-send-a-character-during-star.patch
index 71a5f84..b53d461 100644
--- a/patches/linux-3.2.27/0126-Revert-amba-pl011-Don-t-send-a-character-during-star.patch
+++ b/patches/linux-3.6.7/0124-Revert-amba-pl011-Don-t-send-a-character-during-star.patch
@@ -4,14 +4,14 @@ Subject: [PATCH] Revert "amba-pl011: Don't send a character during startup"
This reverts commit 4a0a5565a02b84d1061bc3dccc5384b4b6829851.
---
- drivers/tty/serial/amba-pl011.c | 6 ------
+ drivers/tty/serial/amba-pl011.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
-index 1b60985..6da8cf8 100644
+index a8698b2..762f5fd 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
-@@ -1394,11 +1394,6 @@ static int pl011_startup(struct uart_port *port)
+@@ -1351,11 +1351,6 @@ static int pl011_startup(struct uart_port *port)
writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS);
/*
@@ -23,11 +23,11 @@ index 1b60985..6da8cf8 100644
* Provoke TX FIFO interrupt into asserting.
*/
cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE;
-@@ -1419,7 +1414,6 @@ static int pl011_startup(struct uart_port *port)
+@@ -1376,7 +1371,6 @@ static int pl011_startup(struct uart_port *port)
writew(0, uap->port.membase + UART01x_DR);
while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY)
barrier();
-#endif
- cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
- writew(cr, uap->port.membase + UART011_CR);
+ /* restore RTS and DTR */
+ cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR);
diff --git a/patches/linux-3.2.27/0127-Update-to-dwc_otg-3.00.-Seems-to-be-a-very-minor-upd.patch b/patches/linux-3.6.7/0125-Update-to-dwc_otg-3.00.-Seems-to-be-a-very-minor-upd.patch
index a3bfdb8..97ff7be 100644
--- a/patches/linux-3.2.27/0127-Update-to-dwc_otg-3.00.-Seems-to-be-a-very-minor-upd.patch
+++ b/patches/linux-3.6.7/0125-Update-to-dwc_otg-3.00.-Seems-to-be-a-very-minor-upd.patch
@@ -4,17 +4,17 @@ Subject: [PATCH] Update to dwc_otg 3.00. Seems to be a very minor update
(mostly adding support for a newer version of hardware)
---
- drivers/usb/host/dwc_otg/doc/doxygen.cfg | 2 +-
- drivers/usb/host/dwc_otg/dwc_otg_cil.c | 341 ++++++++++-------
- drivers/usb/host/dwc_otg/dwc_otg_cil.h | 15 +-
- drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 204 +++++++++-
- drivers/usb/host/dwc_otg/dwc_otg_core_if.h | 6 +-
- drivers/usb/host/dwc_otg/dwc_otg_driver.c | 15 +-
- drivers/usb/host/dwc_otg/dwc_otg_pcd.c | 216 +++++------
- drivers/usb/host/dwc_otg/dwc_otg_pcd.h | 10 +-
- drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c | 520 +++++++++++++++++++++-----
- drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c | 13 +-
- drivers/usb/host/dwc_otg/dwc_otg_regs.h | 19 +-
+ drivers/usb/host/dwc_otg/doc/doxygen.cfg | 2 +-
+ drivers/usb/host/dwc_otg/dwc_otg_cil.c | 341 +++++++++++-------
+ drivers/usb/host/dwc_otg/dwc_otg_cil.h | 15 +-
+ drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 204 ++++++++++-
+ drivers/usb/host/dwc_otg/dwc_otg_core_if.h | 6 +-
+ drivers/usb/host/dwc_otg/dwc_otg_driver.c | 15 +-
+ drivers/usb/host/dwc_otg/dwc_otg_pcd.c | 216 +++++------
+ drivers/usb/host/dwc_otg/dwc_otg_pcd.h | 10 +-
+ drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c | 520 ++++++++++++++++++++++-----
+ drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c | 13 +-
+ drivers/usb/host/dwc_otg/dwc_otg_regs.h | 19 +-
11 files changed, 979 insertions(+), 382 deletions(-)
mode change 100755 => 100644 drivers/usb/host/dwc_common_port/Makefile
mode change 100755 => 100644 drivers/usb/host/dwc_common_port/Makefile.fbsd
diff --git a/patches/linux-3.2.27/0128-enabling-the-realtime-clock-1-wire-chip-DS1307-and-1.patch b/patches/linux-3.6.7/0126-enabling-the-realtime-clock-1-wire-chip-DS1307-and-1.patch
index d1c54f7..6fbd0d0 100644
--- a/patches/linux-3.2.27/0128-enabling-the-realtime-clock-1-wire-chip-DS1307-and-1.patch
+++ b/patches/linux-3.6.7/0126-enabling-the-realtime-clock-1-wire-chip-DS1307-and-1.patch
@@ -4,8 +4,8 @@ Subject: [PATCH] enabling the realtime clock 1-wire chip DS1307 and 1-wire on
GPIO4 (as a module)
---
- arch/arm/configs/bcmrpi_defconfig | 2 ++
- arch/arm/mach-bcm2708/bcm2708.c | 20 ++++++++++++++++++++
+ arch/arm/configs/bcmrpi_defconfig | 2 ++
+ arch/arm/mach-bcm2708/bcm2708.c | 20 ++++++++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
diff --git a/patches/linux-3.2.27/0129-Switch-of-tracing-options-in-kernel.-Costs-20-in-ipe.patch b/patches/linux-3.6.7/0127-Switch-of-tracing-options-in-kernel.-Costs-20-in-ipe.patch
index 1624658..59546e0 100644
--- a/patches/linux-3.2.27/0129-Switch-of-tracing-options-in-kernel.-Costs-20-in-ipe.patch
+++ b/patches/linux-3.6.7/0127-Switch-of-tracing-options-in-kernel.-Costs-20-in-ipe.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] Switch of tracing options in kernel. Costs 20% in iperf
speed, and 10% in xbmc framerate
---
- arch/arm/configs/bcmrpi_defconfig | 10 +++-------
+ arch/arm/configs/bcmrpi_defconfig | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
diff --git a/patches/linux-3.2.27/0130-Turn-on-microframe_schedule-by-default.-Can-still-be.patch b/patches/linux-3.6.7/0128-Turn-on-microframe_schedule-by-default.-Can-still-be.patch
index 921c840..8e8cfd4 100644
--- a/patches/linux-3.2.27/0130-Turn-on-microframe_schedule-by-default.-Can-still-be.patch
+++ b/patches/linux-3.6.7/0128-Turn-on-microframe_schedule-by-default.-Can-still-be.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] Turn on microframe_schedule by default. Can still be
disabled on command line
---
- drivers/usb/host/dwc_otg/dwc_otg_driver.c | 2 +-
+ drivers/usb/host/dwc_otg/dwc_otg_driver.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.c b/drivers/usb/host/dwc_otg/dwc_otg_driver.c
diff --git a/patches/linux-3.2.27/0131-Add-low-latency-mode-to-sdcard-driver.-Enable-with-s.patch b/patches/linux-3.6.7/0129-Add-low-latency-mode-to-sdcard-driver.-Enable-with-s.patch
index 96c67fc..0d348b0 100644
--- a/patches/linux-3.2.27/0131-Add-low-latency-mode-to-sdcard-driver.-Enable-with-s.patch
+++ b/patches/linux-3.6.7/0129-Add-low-latency-mode-to-sdcard-driver.-Enable-with-s.patch
@@ -4,10 +4,10 @@ Subject: [PATCH] Add low-latency mode to sdcard driver. Enable with
sdhci-bcm2708.enable_llm=1. Thanks ddv2005.
---
- drivers/mmc/host/sdhci-bcm2708.c | 17 +++--
- drivers/mmc/host/sdhci.c | 149 +++++++++++++++++++++++++++++---------
- drivers/mmc/host/sdhci.h | 6 ++
- include/linux/mmc/sdhci.h | 1 +
+ drivers/mmc/host/sdhci-bcm2708.c | 17 +++--
+ drivers/mmc/host/sdhci.c | 149 ++++++++++++++++++++++++++++++---------
+ drivers/mmc/host/sdhci.h | 6 ++
+ include/linux/mmc/sdhci.h | 1 +
4 files changed, 132 insertions(+), 41 deletions(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
@@ -91,10 +91,10 @@ index 349d7ab..d0af30a 100644
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
-index aeda16a..3d786a8 100644
+index e206890..220c08e 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
-@@ -121,6 +121,79 @@ static void sdhci_dumpregs(struct sdhci_host *host)
+@@ -122,6 +122,79 @@ static void sdhci_dumpregs(struct sdhci_host *host)
* Low level functions *
* *
\*****************************************************************************/
@@ -174,7 +174,7 @@ index aeda16a..3d786a8 100644
static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
{
-@@ -207,7 +280,9 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
+@@ -206,7 +279,9 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
return;
}
timeout--;
@@ -184,7 +184,7 @@ index aeda16a..3d786a8 100644
}
if (host->ops->platform_reset_exit)
-@@ -270,7 +345,7 @@ static void sdhci_led_control(struct led_classdev *led,
+@@ -287,7 +362,7 @@ static void sdhci_led_control(struct led_classdev *led,
struct sdhci_host *host = container_of(led, struct sdhci_host, led);
unsigned long flags;
@@ -193,7 +193,7 @@ index aeda16a..3d786a8 100644
if (host->runtime_suspended)
goto out;
-@@ -280,7 +355,7 @@ static void sdhci_led_control(struct led_classdev *led,
+@@ -297,7 +372,7 @@ static void sdhci_led_control(struct led_classdev *led,
else
sdhci_activate_led(host);
out:
@@ -202,7 +202,7 @@ index aeda16a..3d786a8 100644
}
#endif
-@@ -988,7 +1063,9 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
+@@ -1005,7 +1080,9 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
return;
}
timeout--;
@@ -212,7 +212,7 @@ index aeda16a..3d786a8 100644
}
DBG("send cmd %d - wait 0x%X irq 0x%x\n", cmd->opcode, mask,
sdhci_readl(host, SDHCI_INT_STATUS));
-@@ -1164,7 +1241,9 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
+@@ -1192,7 +1269,9 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
return;
}
timeout--;
@@ -222,7 +222,7 @@ index aeda16a..3d786a8 100644
}
clk |= SDHCI_CLOCK_CARD_EN;
-@@ -1277,7 +1356,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
+@@ -1308,7 +1387,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
sdhci_runtime_pm_get(host);
@@ -231,19 +231,19 @@ index aeda16a..3d786a8 100644
WARN_ON(host->mrq != NULL);
-@@ -1319,9 +1398,9 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
- */
- if ((host->flags & SDHCI_NEEDS_RETUNING) &&
- !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) {
-- spin_unlock_irqrestore(&host->lock, flags);
-+ sdhci_spin_unlock_irqrestore(host, flags);
- sdhci_execute_tuning(mmc);
-- spin_lock_irqsave(&host->lock, flags);
-+ sdhci_spin_lock_irqsave(host, &flags);
-
- /* Restore original mmc_request structure */
- host->mrq = mrq;
-@@ -1334,7 +1413,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
+@@ -1356,9 +1435,9 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
+ mmc->card->type == MMC_TYPE_MMC ?
+ MMC_SEND_TUNING_BLOCK_HS200 :
+ MMC_SEND_TUNING_BLOCK;
+- spin_unlock_irqrestore(&host->lock, flags);
++ sdhci_spin_unlock_irqrestore(host, flags);
+ sdhci_execute_tuning(mmc, tuning_opcode);
+- spin_lock_irqsave(&host->lock, flags);
++ sdhci_spin_lock_irqsave(host, &flags);
+
+ /* Restore original mmc_request structure */
+ host->mrq = mrq;
+@@ -1372,7 +1451,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
}
mmiowb();
@@ -252,25 +252,25 @@ index aeda16a..3d786a8 100644
}
static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
-@@ -1343,7 +1422,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
+@@ -1382,7 +1461,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
u8 ctrl;
int rc;
- spin_lock_irqsave(&host->lock, flags);
+ sdhci_spin_lock_irqsave(host, &flags);
- if (host->flags & SDHCI_DEVICE_DEAD)
- goto out;
-@@ -1489,7 +1568,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
+ if (host->flags & SDHCI_DEVICE_DEAD) {
+ spin_unlock_irqrestore(&host->lock, flags);
+@@ -1540,7 +1619,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
+ sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
- out:
mmiowb();
- spin_unlock_irqrestore(&host->lock, flags);
+ sdhci_spin_unlock_irqrestore(host, flags);
if (ios->power_mode == MMC_POWER_OFF) {
do
-@@ -1512,7 +1591,7 @@ static int sdhci_check_ro(struct sdhci_host *host)
+@@ -1563,7 +1642,7 @@ static int sdhci_check_ro(struct sdhci_host *host)
unsigned long flags;
int is_readonly;
@@ -279,7 +279,7 @@ index aeda16a..3d786a8 100644
if (host->flags & SDHCI_DEVICE_DEAD)
is_readonly = 0;
-@@ -1522,7 +1601,7 @@ static int sdhci_check_ro(struct sdhci_host *host)
+@@ -1573,7 +1652,7 @@ static int sdhci_check_ro(struct sdhci_host *host)
is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
& SDHCI_WRITE_PROTECT);
@@ -288,7 +288,7 @@ index aeda16a..3d786a8 100644
/* This quirk needs to be replaced by a callback-function later */
return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ?
-@@ -1595,9 +1674,9 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
+@@ -1646,9 +1725,9 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
struct sdhci_host *host = mmc_priv(mmc);
unsigned long flags;
@@ -300,7 +300,7 @@ index aeda16a..3d786a8 100644
}
static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
-@@ -1900,7 +1979,7 @@ static void sdhci_do_enable_preset_value(struct sdhci_host *host, bool enable)
+@@ -1973,7 +2052,7 @@ static void sdhci_do_enable_preset_value(struct sdhci_host *host, bool enable)
if (host->version < SDHCI_SPEC_300)
return;
@@ -309,7 +309,7 @@ index aeda16a..3d786a8 100644
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-@@ -1918,7 +1997,7 @@ static void sdhci_do_enable_preset_value(struct sdhci_host *host, bool enable)
+@@ -1991,7 +2070,7 @@ static void sdhci_do_enable_preset_value(struct sdhci_host *host, bool enable)
host->flags &= ~SDHCI_PV_ENABLED;
}
@@ -318,7 +318,7 @@ index aeda16a..3d786a8 100644
}
static void sdhci_enable_preset_value(struct mmc_host *mmc, bool enable)
-@@ -1956,7 +2035,7 @@ static void sdhci_tasklet_card(unsigned long param)
+@@ -2029,7 +2108,7 @@ static void sdhci_tasklet_card(unsigned long param)
host = (struct sdhci_host*)param;
@@ -327,7 +327,7 @@ index aeda16a..3d786a8 100644
/* Check host->mrq first in case we are runtime suspended */
if (host->mrq &&
-@@ -1973,7 +2052,7 @@ static void sdhci_tasklet_card(unsigned long param)
+@@ -2046,7 +2125,7 @@ static void sdhci_tasklet_card(unsigned long param)
tasklet_schedule(&host->finish_tasklet);
}
@@ -336,7 +336,7 @@ index aeda16a..3d786a8 100644
mmc_detect_change(host->mmc, msecs_to_jiffies(200));
}
-@@ -1986,14 +2065,14 @@ static void sdhci_tasklet_finish(unsigned long param)
+@@ -2059,14 +2138,14 @@ static void sdhci_tasklet_finish(unsigned long param)
host = (struct sdhci_host*)param;
@@ -353,7 +353,7 @@ index aeda16a..3d786a8 100644
return;
}
-@@ -2036,7 +2115,7 @@ static void sdhci_tasklet_finish(unsigned long param)
+@@ -2109,7 +2188,7 @@ static void sdhci_tasklet_finish(unsigned long param)
#endif
mmiowb();
@@ -362,7 +362,7 @@ index aeda16a..3d786a8 100644
mmc_request_done(host->mmc, mrq);
sdhci_runtime_pm_put(host);
-@@ -2049,7 +2128,7 @@ static void sdhci_timeout_timer(unsigned long data)
+@@ -2122,7 +2201,7 @@ static void sdhci_timeout_timer(unsigned long data)
host = (struct sdhci_host*)data;
@@ -371,7 +371,7 @@ index aeda16a..3d786a8 100644
if (host->mrq) {
pr_err("%s: Timeout waiting for hardware "
-@@ -2070,7 +2149,7 @@ static void sdhci_timeout_timer(unsigned long data)
+@@ -2143,7 +2222,7 @@ static void sdhci_timeout_timer(unsigned long data)
}
mmiowb();
@@ -380,7 +380,7 @@ index aeda16a..3d786a8 100644
}
static void sdhci_tuning_timer(unsigned long data)
-@@ -2080,11 +2159,11 @@ static void sdhci_tuning_timer(unsigned long data)
+@@ -2153,11 +2232,11 @@ static void sdhci_tuning_timer(unsigned long data)
host = (struct sdhci_host *)data;
@@ -394,9 +394,9 @@ index aeda16a..3d786a8 100644
}
/*****************************************************************************\
-@@ -2304,10 +2383,10 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
- u32 intmask;
- int cardint = 0;
+@@ -2379,10 +2458,10 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
+ u32 intmask, unexpected = 0;
+ int cardint = 0, max_loops = 16;
- spin_lock(&host->lock);
+ sdhci_spin_lock(host);
@@ -407,16 +407,16 @@ index aeda16a..3d786a8 100644
pr_warning("%s: got irq while runtime suspended\n",
mmc_hostname(host->mmc));
return IRQ_HANDLED;
-@@ -2411,7 +2490,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
-
- mmiowb();
+@@ -2486,7 +2565,7 @@ again:
+ if (intmask && --max_loops)
+ goto again;
out:
- spin_unlock(&host->lock);
+ sdhci_spin_unlock(host);
- /*
- * We have to delay this as it calls back into the driver.
-@@ -2531,15 +2610,15 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
+ if (unexpected) {
+ pr_err("%s: Unexpected interrupt 0x%08x.\n",
+@@ -2629,15 +2708,15 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
host->flags &= ~SDHCI_NEEDS_RETUNING;
}
@@ -436,8 +436,8 @@ index aeda16a..3d786a8 100644
return ret;
}
-@@ -2571,7 +2650,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
- (host->tuning_mode == SDHCI_TUNING_MODE_1))
+@@ -2668,7 +2747,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
+ if (host->flags & SDHCI_USING_RETUNING_TIMER)
host->flags |= SDHCI_NEEDS_RETUNING;
- spin_lock_irqsave(&host->lock, flags);
@@ -445,7 +445,7 @@ index aeda16a..3d786a8 100644
host->runtime_suspended = false;
-@@ -2582,7 +2661,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
+@@ -2679,7 +2758,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host)
/* Enable Card Detection */
sdhci_enable_card_detection(host);
@@ -454,16 +454,16 @@ index aeda16a..3d786a8 100644
return ret;
}
-@@ -3028,7 +3107,7 @@ int sdhci_add_host(struct sdhci_host *host)
+@@ -3146,7 +3225,7 @@ int sdhci_add_host(struct sdhci_host *host)
host->tuning_timer.function = sdhci_tuning_timer;
}
- ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
+ ret = request_irq(host->irq, sdhci_irq, 0,//IRQF_SHARED,
mmc_hostname(mmc), host);
- if (ret)
- goto untasklet;
-@@ -3093,7 +3172,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
+ if (ret) {
+ pr_err("%s: Failed to request IRQ %d: %d\n",
+@@ -3209,7 +3288,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
unsigned long flags;
if (dead) {
@@ -472,7 +472,7 @@ index aeda16a..3d786a8 100644
host->flags |= SDHCI_DEVICE_DEAD;
-@@ -3105,7 +3184,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
+@@ -3221,7 +3300,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
tasklet_schedule(&host->finish_tasklet);
}
@@ -482,10 +482,10 @@ index aeda16a..3d786a8 100644
sdhci_disable_card_detection(host);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
-index 4cc7b4b..c08882b 100644
+index aad9454..5503909 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
-@@ -426,4 +426,10 @@ extern int sdhci_runtime_suspend_host(struct sdhci_host *host);
+@@ -430,4 +430,10 @@ extern int sdhci_runtime_suspend_host(struct sdhci_host *host);
extern int sdhci_runtime_resume_host(struct sdhci_host *host);
#endif
@@ -497,11 +497,11 @@ index 4cc7b4b..c08882b 100644
+
#endif /* __SDHCI_HW_H */
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
-index 99b7eef..d307033 100644
+index 2c83a35..7afc5cd 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -93,6 +93,7 @@ struct sdhci_host {
- #define SDHCI_QUIRK2_OWN_CARD_DETECTION (1<<0)
+ #define SDHCI_QUIRK2_HOST_OFF_CARD_ON (1<<0)
int irq; /* Device IRQ */
+ int second_irq; /* Additional IRQ to disable/enable in low-latency mode */
diff --git a/patches/linux-3.2.27/0132-Fix-build-for-non-preempt-case.-Fix-warning.patch b/patches/linux-3.6.7/0130-Fix-build-for-non-preempt-case.-Fix-warning.patch
index db46c65..55e5dd7 100644
--- a/patches/linux-3.2.27/0132-Fix-build-for-non-preempt-case.-Fix-warning.patch
+++ b/patches/linux-3.6.7/0130-Fix-build-for-non-preempt-case.-Fix-warning.patch
@@ -3,8 +3,8 @@ Date: Tue, 28 Aug 2012 17:40:49 +0100
Subject: [PATCH] Fix build for non-preempt case. Fix warning
---
- drivers/mmc/host/sdhci-bcm2708.c | 4 ++--
- drivers/mmc/host/sdhci.c | 12 ++++++++++++
+ drivers/mmc/host/sdhci-bcm2708.c | 4 ++--
+ drivers/mmc/host/sdhci.c | 12 ++++++++++++
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
@@ -30,10 +30,10 @@ index d0af30a..d0acde7 100644
BUG_ON(NULL == host);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
-index 3d786a8..0562295 100644
+index 220c08e..4500ef7 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
-@@ -126,6 +126,7 @@ static int sdhci_locked=0;
+@@ -127,6 +127,7 @@ static int sdhci_locked=0;
void sdhci_spin_lock(struct sdhci_host *host)
{
spin_lock(&host->lock);
@@ -41,7 +41,7 @@ index 3d786a8..0562295 100644
if(enable_llm)
{
disable_irq_nosync(host->irq);
-@@ -133,10 +134,12 @@ void sdhci_spin_lock(struct sdhci_host *host)
+@@ -134,10 +135,12 @@ void sdhci_spin_lock(struct sdhci_host *host)
disable_irq_nosync(host->second_irq);
local_irq_enable();
}
@@ -54,7 +54,7 @@ index 3d786a8..0562295 100644
if(enable_llm)
{
local_irq_disable();
-@@ -144,11 +147,13 @@ void sdhci_spin_unlock(struct sdhci_host *host)
+@@ -145,11 +148,13 @@ void sdhci_spin_unlock(struct sdhci_host *host)
if(host->second_irq)
enable_irq(host->second_irq);
}
@@ -68,7 +68,7 @@ index 3d786a8..0562295 100644
if(enable_llm)
{
while(sdhci_locked)
-@@ -162,11 +167,13 @@ void sdhci_spin_lock_irqsave(struct sdhci_host *host,unsigned long *flags)
+@@ -163,11 +168,13 @@ void sdhci_spin_lock_irqsave(struct sdhci_host *host,unsigned long *flags)
local_irq_enable();
}
else
@@ -82,7 +82,7 @@ index 3d786a8..0562295 100644
if(enable_llm)
{
local_irq_disable();
-@@ -174,25 +181,30 @@ void sdhci_spin_unlock_irqrestore(struct sdhci_host *host,unsigned long flags)
+@@ -175,25 +182,30 @@ void sdhci_spin_unlock_irqrestore(struct sdhci_host *host,unsigned long flags)
if(host->second_irq)
enable_irq(host->second_irq);
}
diff --git a/patches/linux-3.2.27/0133-Add-config-options-to-allow-iotop-to-run.patch b/patches/linux-3.6.7/0131-Add-config-options-to-allow-iotop-to-run.patch
index 779e197..7d814fc 100644
--- a/patches/linux-3.2.27/0133-Add-config-options-to-allow-iotop-to-run.patch
+++ b/patches/linux-3.6.7/0131-Add-config-options-to-allow-iotop-to-run.patch
@@ -3,7 +3,7 @@ Date: Wed, 29 Aug 2012 21:46:25 +0100
Subject: [PATCH] Add config options to allow iotop to run
---
- arch/arm/configs/bcmrpi_defconfig | 4 ++++
+ arch/arm/configs/bcmrpi_defconfig | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
diff --git a/patches/linux-3.2.27/0134-Fix-for-vmalloc-failure-with-modprobe-and-cutdown-ke.patch b/patches/linux-3.6.7/0132-Fix-for-vmalloc-failure-with-modprobe-and-cutdown-ke.patch
index c7608ae..afa6c07 100644
--- a/patches/linux-3.2.27/0134-Fix-for-vmalloc-failure-with-modprobe-and-cutdown-ke.patch
+++ b/patches/linux-3.6.7/0132-Fix-for-vmalloc-failure-with-modprobe-and-cutdown-ke.patch
@@ -3,14 +3,14 @@ Date: Wed, 29 Aug 2012 21:54:01 +0100
Subject: [PATCH] Fix for vmalloc failure with modprobe and cutdown kernel
---
- kernel/module.c | 29 ++++++++++++++++-------------
+ kernel/module.c | 29 ++++++++++++++++-------------
1 file changed, 16 insertions(+), 13 deletions(-)
diff --git a/kernel/module.c b/kernel/module.c
-index 6969ef0..0a64968 100644
+index 9ad9ee9..9825f72 100644
--- a/kernel/module.c
+++ b/kernel/module.c
-@@ -2604,20 +2604,23 @@ static int move_module(struct module *mod, struct load_info *info)
+@@ -2675,20 +2675,23 @@ static int move_module(struct module *mod, struct load_info *info)
memset(ptr, 0, mod->core_size);
mod->module_core = ptr;
@@ -46,4 +46,4 @@ index 6969ef0..0a64968 100644
+ else mod->module_init = NULL;
/* Transfer each section which specifies SHF_ALLOC */
- DEBUGP("final section addresses:\n");
+ pr_debug("final section addresses:\n");
diff --git a/patches/linux-3.2.27/0135-Enable-low-latency-mode-by-default-in-sdcard-driver..patch b/patches/linux-3.6.7/0133-Enable-low-latency-mode-by-default-in-sdcard-driver..patch
index 2c1236b..d69ecec 100644
--- a/patches/linux-3.2.27/0135-Enable-low-latency-mode-by-default-in-sdcard-driver..patch
+++ b/patches/linux-3.6.7/0133-Enable-low-latency-mode-by-default-in-sdcard-driver..patch
@@ -4,7 +4,7 @@ Subject: [PATCH] Enable low latency mode by default in sdcard driver. Can be
disabled with sdhci-bcm2708.enable_llm=0
---
- drivers/mmc/host/sdhci-bcm2708.c | 2 +-
+ drivers/mmc/host/sdhci-bcm2708.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
diff --git a/patches/linux-3.2.27/0136-Add-FIQ-patch-to-dwc_otg-driver.-Enable-with-dwc_otg.patch b/patches/linux-3.6.7/0134-Add-FIQ-patch-to-dwc_otg-driver.-Enable-with-dwc_otg.patch
index ec585da..1d6dbf2 100644
--- a/patches/linux-3.2.27/0136-Add-FIQ-patch-to-dwc_otg-driver.-Enable-with-dwc_otg.patch
+++ b/patches/linux-3.6.7/0134-Add-FIQ-patch-to-dwc_otg-driver.-Enable-with-dwc_otg.patch
@@ -5,33 +5,33 @@ Subject: [PATCH] Add FIQ patch to dwc_otg driver. Enable with
performance. Thanks to Gordon and Costas
---
- arch/arm/Kconfig | 3 +-
- arch/arm/include/asm/fiq.h | 1 +
- arch/arm/kernel/fiq.c | 1 +
- arch/arm/kernel/fiqasm.S | 4 +
- arch/arm/mach-bcm2708/armctrl.c | 31 +++--
- arch/arm/mach-bcm2708/bcm2708.c | 29 ++++-
- arch/arm/mach-bcm2708/include/mach/irqs.h | 159 +++++++++++++------------
- arch/arm/mach-bcm2708/include/mach/platform.h | 2 +
- drivers/usb/host/dwc_otg/Makefile | 1 +
- drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 14 ++-
- drivers/usb/host/dwc_otg/dwc_otg_dbg.h | 1 +
- drivers/usb/host/dwc_otg/dwc_otg_driver.c | 37 +++++-
- drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 5 +
- drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 2 +-
- drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h | 5 +
- drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 154 +++++++++++++++++++++---
- drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 45 +++++++
- drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 20 +++-
- drivers/usb/host/dwc_otg/dwc_otg_mphi_fix.c | 113 ++++++++++++++++++
- drivers/usb/host/dwc_otg/dwc_otg_mphi_fix.h | 36 ++++++
- drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 3 +
+ arch/arm/Kconfig | 3 +-
+ arch/arm/include/asm/fiq.h | 1 +
+ arch/arm/kernel/fiq.c | 1 +
+ arch/arm/kernel/fiqasm.S | 4 +
+ arch/arm/mach-bcm2708/armctrl.c | 31 +++--
+ arch/arm/mach-bcm2708/bcm2708.c | 29 ++++-
+ arch/arm/mach-bcm2708/include/mach/irqs.h | 159 +++++++++++++-------------
+ arch/arm/mach-bcm2708/include/mach/platform.h | 2 +
+ drivers/usb/host/dwc_otg/Makefile | 1 +
+ drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 14 ++-
+ drivers/usb/host/dwc_otg/dwc_otg_dbg.h | 1 +
+ drivers/usb/host/dwc_otg/dwc_otg_driver.c | 37 +++++-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 5 +
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 2 +-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h | 5 +
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 154 ++++++++++++++++++++++---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 45 ++++++++
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 20 +++-
+ drivers/usb/host/dwc_otg/dwc_otg_mphi_fix.c | 113 ++++++++++++++++++
+ drivers/usb/host/dwc_otg/dwc_otg_mphi_fix.h | 36 ++++++
+ drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 3 +
21 files changed, 552 insertions(+), 114 deletions(-)
create mode 100755 drivers/usb/host/dwc_otg/dwc_otg_mphi_fix.c
create mode 100755 drivers/usb/host/dwc_otg/dwc_otg_mphi_fix.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index 98ea27e..eecdf50 100644
+index fd49001..111f1b0 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1,4 +1,4 @@
@@ -39,8 +39,8 @@ index 98ea27e..eecdf50 100644
+iconfig ARM
bool
default y
- select HAVE_AOUT
-@@ -967,6 +967,7 @@ config ARCH_BCM2708
+ select ARCH_HAVE_CUSTOM_GPIO_H
+@@ -1010,6 +1010,7 @@ config ARCH_BCM2708
select ARM_ERRATA_411920
select MACH_BCM2708
select VC4
@@ -61,10 +61,10 @@ index d493d0b..f1a131b 100644
static inline void set_fiq_regs(struct pt_regs const *regs)
{
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
-index 4c164ec..3841bde 100644
+index 2adda11..3e71f30 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
-@@ -135,6 +135,7 @@ void disable_fiq(int fiq)
+@@ -137,6 +137,7 @@ void disable_fiq(int fiq)
EXPORT_SYMBOL(set_fiq_handler);
EXPORT_SYMBOL(__set_fiq_regs); /* defined in fiqasm.S */
EXPORT_SYMBOL(__get_fiq_regs); /* defined in fiqasm.S */
diff --git a/patches/linux-3.2.27/0137-Fix-typo.patch b/patches/linux-3.6.7/0135-Fix-typo.patch
index 60efccf..e5f458d 100644
--- a/patches/linux-3.2.27/0137-Fix-typo.patch
+++ b/patches/linux-3.6.7/0135-Fix-typo.patch
@@ -3,11 +3,11 @@ Date: Sat, 1 Sep 2012 00:31:47 +0100
Subject: [PATCH] Fix typo
---
- arch/arm/Kconfig | 2 +-
+ arch/arm/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index eecdf50..5285fbf 100644
+index 111f1b0..4dd71eb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1,4 +1,4 @@
@@ -15,4 +15,4 @@ index eecdf50..5285fbf 100644
+config ARM
bool
default y
- select HAVE_AOUT
+ select ARCH_HAVE_CUSTOM_GPIO_H
diff --git a/patches/linux-3.2.27/0138-Add-non-mainline-source-for-rtl8188cu-wireless-drive.patch b/patches/linux-3.6.7/0136-Add-non-mainline-source-for-rtl8188cu-wireless-drive.patch
index 00a5960..157b87b 100644
--- a/patches/linux-3.2.27/0138-Add-non-mainline-source-for-rtl8188cu-wireless-drive.patch
+++ b/patches/linux-3.6.7/0136-Add-non-mainline-source-for-rtl8188cu-wireless-drive.patch
@@ -4,172 +4,172 @@ Subject: [PATCH] Add non-mainline source for rtl8188cu wireless driver as
this is widely used. Disabled older rtlwifi driver
---
- drivers/net/wireless/Kconfig | 3 +-
- drivers/net/wireless/Makefile | 5 +-
- drivers/net/wireless/rtl8192cu/Kconfig | 6 +
- drivers/net/wireless/rtl8192cu/Makefile | 545 +
- drivers/net/wireless/rtl8192cu/clean | 9 +
- .../net/wireless/rtl8192cu/core/efuse/rtw_efuse.c | 1097 +
- drivers/net/wireless/rtl8192cu/core/rtw_br_ext.c | 1694 ++
- drivers/net/wireless/rtl8192cu/core/rtw_cmd.c | 2573 ++
- drivers/net/wireless/rtl8192cu/core/rtw_debug.c | 662 +
- drivers/net/wireless/rtl8192cu/core/rtw_eeprom.c | 424 +
- .../net/wireless/rtl8192cu/core/rtw_ieee80211.c | 1486 +
- drivers/net/wireless/rtl8192cu/core/rtw_io.c | 490 +
- .../net/wireless/rtl8192cu/core/rtw_ioctl_query.c | 197 +
- .../net/wireless/rtl8192cu/core/rtw_ioctl_rtl.c | 1032 +
- .../net/wireless/rtl8192cu/core/rtw_ioctl_set.c | 1426 +
- drivers/net/wireless/rtl8192cu/core/rtw_iol.c | 266 +
- drivers/net/wireless/rtl8192cu/core/rtw_mlme.c | 3549 +++
- drivers/net/wireless/rtl8192cu/core/rtw_mlme_ext.c |12271 ++++++++
- drivers/net/wireless/rtl8192cu/core/rtw_mp.c | 1318 +
- drivers/net/wireless/rtl8192cu/core/rtw_mp_ioctl.c | 2841 ++
- drivers/net/wireless/rtl8192cu/core/rtw_p2p.c | 3498 +++
- drivers/net/wireless/rtl8192cu/core/rtw_pwrctrl.c | 1227 +
- drivers/net/wireless/rtl8192cu/core/rtw_recv.c | 4597 +++
- drivers/net/wireless/rtl8192cu/core/rtw_rf.c | 96 +
- drivers/net/wireless/rtl8192cu/core/rtw_security.c | 2831 ++
- drivers/net/wireless/rtl8192cu/core/rtw_sta_mgt.c | 720 +
- .../net/wireless/rtl8192cu/core/rtw_wlan_util.c | 1848 ++
- drivers/net/wireless/rtl8192cu/core/rtw_xmit.c | 4277 +++
- drivers/net/wireless/rtl8192cu/hal/hal_init.c | 120 +
- .../wireless/rtl8192cu/hal/rtl8192c/rtl8192c_cmd.c | 1361 +
- .../wireless/rtl8192cu/hal/rtl8192c/rtl8192c_dm.c | 4753 +++
- .../rtl8192cu/hal/rtl8192c/rtl8192c_hal_init.c | 3642 +++
- .../wireless/rtl8192cu/hal/rtl8192c/rtl8192c_mp.c | 1230 +
- .../rtl8192cu/hal/rtl8192c/rtl8192c_phycfg.c | 5583 ++++
- .../rtl8192cu/hal/rtl8192c/rtl8192c_rf6052.c | 1047 +
- .../rtl8192cu/hal/rtl8192c/rtl8192c_rxdesc.c | 767 +
- .../rtl8192cu/hal/rtl8192c/rtl8192c_sreset.c | 293 +
- .../rtl8192cu/hal/rtl8192c/usb/Hal8192CUHWImg.c | 9662 ++++++
- .../hal/rtl8192c/usb/Hal8192CUHWImg_wowlan.c | 2564 ++
- .../rtl8192cu/hal/rtl8192c/usb/rtl8192cu_led.c | 2668 ++
- .../rtl8192cu/hal/rtl8192c/usb/rtl8192cu_recv.c | 380 +
- .../rtl8192cu/hal/rtl8192c/usb/rtl8192cu_xmit.c | 1322 +
- .../rtl8192cu/hal/rtl8192c/usb/usb_halinit.c | 6036 ++++
- .../rtl8192cu/hal/rtl8192c/usb/usb_ops_ce.c | 1208 +
- .../rtl8192cu/hal/rtl8192c/usb/usb_ops_linux.c | 2045 ++
- .../rtl8192cu/hal/rtl8192c/usb/usb_ops_xp.c | 1266 +
- drivers/net/wireless/rtl8192cu/ifcfg-wlan0 | 4 +
- .../wireless/rtl8192cu/include/Hal8192CEHWImg.h | 81 +
- .../wireless/rtl8192cu/include/Hal8192CPhyCfg.h | 451 +
- .../wireless/rtl8192cu/include/Hal8192CPhyReg.h | 1102 +
- .../wireless/rtl8192cu/include/Hal8192CUHWImg.h | 99 +
- .../rtl8192cu/include/Hal8192CUHWImg_wowlan.h | 34 +
- .../wireless/rtl8192cu/include/Hal8192DEHWImg.h | 66 +
- .../rtl8192cu/include/Hal8192DETestHWImg.h | 54 +
- .../wireless/rtl8192cu/include/Hal8192DPhyCfg.h | 528 +
- .../wireless/rtl8192cu/include/Hal8192DPhyReg.h | 1171 +
- .../wireless/rtl8192cu/include/Hal8192DUHWImg.h | 66 +
- .../rtl8192cu/include/Hal8192DUHWImg_wowlan.h | 30 +
- .../rtl8192cu/include/Hal8192DUTestHWImg.h | 54 +
- drivers/net/wireless/rtl8192cu/include/autoconf.h | 285 +
- .../net/wireless/rtl8192cu/include/basic_types.h | 276 +
- .../rtl8192cu/include/byteorder/big_endian.h | 87 +
- .../wireless/rtl8192cu/include/byteorder/generic.h | 209 +
- .../rtl8192cu/include/byteorder/little_endian.h | 89 +
- .../wireless/rtl8192cu/include/byteorder/swab.h | 133 +
- .../wireless/rtl8192cu/include/byteorder/swabb.h | 157 +
- drivers/net/wireless/rtl8192cu/include/circ_buf.h | 27 +
- drivers/net/wireless/rtl8192cu/include/cmd_osdep.h | 36 +
- drivers/net/wireless/rtl8192cu/include/drv_conf.h | 78 +
- drivers/net/wireless/rtl8192cu/include/drv_types.h | 555 +
- .../net/wireless/rtl8192cu/include/drv_types_ce.h | 92 +
- .../wireless/rtl8192cu/include/drv_types_linux.h | 25 +
- .../net/wireless/rtl8192cu/include/drv_types_xp.h | 95 +
- drivers/net/wireless/rtl8192cu/include/ethernet.h | 41 +
- drivers/net/wireless/rtl8192cu/include/farray.h |31480 ++++++++++++++++++++
- drivers/net/wireless/rtl8192cu/include/h2clbk.h | 35 +
- drivers/net/wireless/rtl8192cu/include/hal_init.h | 305 +
- drivers/net/wireless/rtl8192cu/include/ieee80211.h | 1461 +
- .../net/wireless/rtl8192cu/include/ieee80211_ext.h | 477 +
- drivers/net/wireless/rtl8192cu/include/if_ether.h | 112 +
- .../wireless/rtl8192cu/include/ioctl_cfg80211.h | 81 +
- drivers/net/wireless/rtl8192cu/include/ip.h | 138 +
- .../net/wireless/rtl8192cu/include/mlme_osdep.h | 44 +
- .../net/wireless/rtl8192cu/include/mp_custom_oid.h | 353 +
- drivers/net/wireless/rtl8192cu/include/nic_spec.h | 47 +
- .../wireless/rtl8192cu/include/osdep_ce_service.h | 171 +
- .../net/wireless/rtl8192cu/include/osdep_intf.h | 128 +
- .../net/wireless/rtl8192cu/include/osdep_service.h | 830 +
- drivers/net/wireless/rtl8192cu/include/pci_hal.h | 168 +
- drivers/net/wireless/rtl8192cu/include/pci_ops.h | 58 +
- .../net/wireless/rtl8192cu/include/pci_osintf.h | 33 +
- .../net/wireless/rtl8192cu/include/recv_osdep.h | 58 +
- .../net/wireless/rtl8192cu/include/rtl8192c_cmd.h | 153 +
- .../net/wireless/rtl8192cu/include/rtl8192c_dm.h | 616 +
- .../wireless/rtl8192cu/include/rtl8192c_event.h | 29 +
- .../net/wireless/rtl8192cu/include/rtl8192c_hal.h | 887 +
- .../net/wireless/rtl8192cu/include/rtl8192c_led.h | 43 +
- .../net/wireless/rtl8192cu/include/rtl8192c_recv.h | 180 +
- .../net/wireless/rtl8192cu/include/rtl8192c_rf.h | 93 +
- .../net/wireless/rtl8192cu/include/rtl8192c_spec.h | 1899 ++
- .../wireless/rtl8192cu/include/rtl8192c_sreset.h | 54 +
- .../net/wireless/rtl8192cu/include/rtl8192c_xmit.h | 91 +
- .../net/wireless/rtl8192cu/include/rtl8192d_cmd.h | 133 +
- .../net/wireless/rtl8192cu/include/rtl8192d_dm.h | 414 +
- .../net/wireless/rtl8192cu/include/rtl8192d_hal.h | 983 +
- .../net/wireless/rtl8192cu/include/rtl8192d_led.h | 44 +
- .../net/wireless/rtl8192cu/include/rtl8192d_recv.h | 179 +
- .../net/wireless/rtl8192cu/include/rtl8192d_rf.h | 98 +
- .../net/wireless/rtl8192cu/include/rtl8192d_spec.h | 1879 ++
- .../net/wireless/rtl8192cu/include/rtl8192d_xmit.h | 106 +
- .../net/wireless/rtl8192cu/include/rtw_android.h | 80 +
- .../net/wireless/rtl8192cu/include/rtw_br_ext.h | 76 +
- .../net/wireless/rtl8192cu/include/rtw_byteorder.h | 41 +
- drivers/net/wireless/rtl8192cu/include/rtw_cmd.h | 1132 +
- drivers/net/wireless/rtl8192cu/include/rtw_debug.h | 383 +
- .../net/wireless/rtl8192cu/include/rtw_eeprom.h | 153 +
- drivers/net/wireless/rtl8192cu/include/rtw_efuse.h | 123 +
- drivers/net/wireless/rtl8192cu/include/rtw_event.h | 154 +
- drivers/net/wireless/rtl8192cu/include/rtw_ht.h | 51 +
- drivers/net/wireless/rtl8192cu/include/rtw_io.h | 543 +
- drivers/net/wireless/rtl8192cu/include/rtw_ioctl.h | 271 +
- .../wireless/rtl8192cu/include/rtw_ioctl_query.h | 37 +
- .../net/wireless/rtl8192cu/include/rtw_ioctl_rtl.h | 84 +
- .../net/wireless/rtl8192cu/include/rtw_ioctl_set.h | 78 +
- drivers/net/wireless/rtl8192cu/include/rtw_iol.h | 89 +
- drivers/net/wireless/rtl8192cu/include/rtw_led.h | 214 +
- drivers/net/wireless/rtl8192cu/include/rtw_mlme.h | 664 +
- .../net/wireless/rtl8192cu/include/rtw_mlme_ext.h | 878 +
- drivers/net/wireless/rtl8192cu/include/rtw_mp.h | 708 +
- .../net/wireless/rtl8192cu/include/rtw_mp_ioctl.h | 596 +
- .../wireless/rtl8192cu/include/rtw_mp_phy_regdef.h | 1098 +
- drivers/net/wireless/rtl8192cu/include/rtw_p2p.h | 139 +
- .../net/wireless/rtl8192cu/include/rtw_pwrctrl.h | 343 +
- drivers/net/wireless/rtl8192cu/include/rtw_qos.h | 41 +
- drivers/net/wireless/rtl8192cu/include/rtw_recv.h | 711 +
- drivers/net/wireless/rtl8192cu/include/rtw_rf.h | 152 +
- .../net/wireless/rtl8192cu/include/rtw_security.h | 423 +
- .../net/wireless/rtl8192cu/include/rtw_version.h | 1 +
- drivers/net/wireless/rtl8192cu/include/rtw_xmit.h | 668 +
- drivers/net/wireless/rtl8192cu/include/sdio_hal.h | 34 +
- drivers/net/wireless/rtl8192cu/include/sdio_ops.h | 80 +
- .../net/wireless/rtl8192cu/include/sdio_ops_ce.h | 56 +
- .../wireless/rtl8192cu/include/sdio_ops_linux.h | 55 +
- .../net/wireless/rtl8192cu/include/sdio_ops_xp.h | 56 +
- .../net/wireless/rtl8192cu/include/sdio_osintf.h | 48 +
- drivers/net/wireless/rtl8192cu/include/sta_info.h | 353 +
- drivers/net/wireless/rtl8192cu/include/usb_hal.h | 32 +
- drivers/net/wireless/rtl8192cu/include/usb_ops.h | 100 +
- .../net/wireless/rtl8192cu/include/usb_osintf.h | 39 +
- .../wireless/rtl8192cu/include/usb_vendor_req.h | 60 +
- drivers/net/wireless/rtl8192cu/include/wifi.h | 1185 +
- .../net/wireless/rtl8192cu/include/wlan_bssdef.h | 453 +
- .../net/wireless/rtl8192cu/include/xmit_osdep.h | 90 +
- .../rtl8192cu/os_dep/linux/ioctl_cfg80211.c | 4620 +++
- .../wireless/rtl8192cu/os_dep/linux/ioctl_linux.c | 9305 ++++++
- .../wireless/rtl8192cu/os_dep/linux/mlme_linux.c | 740 +
- .../net/wireless/rtl8192cu/os_dep/linux/os_intfs.c | 1542 +
- .../net/wireless/rtl8192cu/os_dep/linux/pci_intf.c | 1889 ++
- .../wireless/rtl8192cu/os_dep/linux/recv_linux.c | 462 +
- .../wireless/rtl8192cu/os_dep/linux/rtw_android.c | 713 +
- .../wireless/rtl8192cu/os_dep/linux/sdio_intf.c | 922 +
- .../net/wireless/rtl8192cu/os_dep/linux/usb_intf.c | 1524 +
- .../wireless/rtl8192cu/os_dep/linux/xmit_linux.c | 367 +
- .../net/wireless/rtl8192cu/os_dep/osdep_service.c | 1555 +
- drivers/net/wireless/rtl8192cu/wlan0dhcp | 16 +
- 165 files changed, 182945 insertions(+), 2 deletions(-)
+ drivers/net/wireless/Kconfig | 3 +-
+ drivers/net/wireless/Makefile | 3 +-
+ drivers/net/wireless/rtl8192cu/Kconfig | 6 +
+ drivers/net/wireless/rtl8192cu/Makefile | 545 +
+ drivers/net/wireless/rtl8192cu/clean | 9 +
+ .../net/wireless/rtl8192cu/core/efuse/rtw_efuse.c | 1097 +
+ drivers/net/wireless/rtl8192cu/core/rtw_br_ext.c | 1694 +
+ drivers/net/wireless/rtl8192cu/core/rtw_cmd.c | 2573 ++
+ drivers/net/wireless/rtl8192cu/core/rtw_debug.c | 662 +
+ drivers/net/wireless/rtl8192cu/core/rtw_eeprom.c | 424 +
+ .../net/wireless/rtl8192cu/core/rtw_ieee80211.c | 1486 +
+ drivers/net/wireless/rtl8192cu/core/rtw_io.c | 490 +
+ .../net/wireless/rtl8192cu/core/rtw_ioctl_query.c | 197 +
+ .../net/wireless/rtl8192cu/core/rtw_ioctl_rtl.c | 1032 +
+ .../net/wireless/rtl8192cu/core/rtw_ioctl_set.c | 1426 +
+ drivers/net/wireless/rtl8192cu/core/rtw_iol.c | 266 +
+ drivers/net/wireless/rtl8192cu/core/rtw_mlme.c | 3549 +++
+ drivers/net/wireless/rtl8192cu/core/rtw_mlme_ext.c | 12271 ++++++++
+ drivers/net/wireless/rtl8192cu/core/rtw_mp.c | 1318 +
+ drivers/net/wireless/rtl8192cu/core/rtw_mp_ioctl.c | 2841 ++
+ drivers/net/wireless/rtl8192cu/core/rtw_p2p.c | 3498 +++
+ drivers/net/wireless/rtl8192cu/core/rtw_pwrctrl.c | 1227 +
+ drivers/net/wireless/rtl8192cu/core/rtw_recv.c | 4597 +++
+ drivers/net/wireless/rtl8192cu/core/rtw_rf.c | 96 +
+ drivers/net/wireless/rtl8192cu/core/rtw_security.c | 2831 ++
+ drivers/net/wireless/rtl8192cu/core/rtw_sta_mgt.c | 720 +
+ .../net/wireless/rtl8192cu/core/rtw_wlan_util.c | 1848 ++
+ drivers/net/wireless/rtl8192cu/core/rtw_xmit.c | 4277 +++
+ drivers/net/wireless/rtl8192cu/hal/hal_init.c | 120 +
+ .../wireless/rtl8192cu/hal/rtl8192c/rtl8192c_cmd.c | 1361 +
+ .../wireless/rtl8192cu/hal/rtl8192c/rtl8192c_dm.c | 4753 +++
+ .../rtl8192cu/hal/rtl8192c/rtl8192c_hal_init.c | 3642 +++
+ .../wireless/rtl8192cu/hal/rtl8192c/rtl8192c_mp.c | 1230 +
+ .../rtl8192cu/hal/rtl8192c/rtl8192c_phycfg.c | 5583 ++++
+ .../rtl8192cu/hal/rtl8192c/rtl8192c_rf6052.c | 1047 +
+ .../rtl8192cu/hal/rtl8192c/rtl8192c_rxdesc.c | 767 +
+ .../rtl8192cu/hal/rtl8192c/rtl8192c_sreset.c | 293 +
+ .../rtl8192cu/hal/rtl8192c/usb/Hal8192CUHWImg.c | 9662 ++++++
+ .../hal/rtl8192c/usb/Hal8192CUHWImg_wowlan.c | 2564 ++
+ .../rtl8192cu/hal/rtl8192c/usb/rtl8192cu_led.c | 2668 ++
+ .../rtl8192cu/hal/rtl8192c/usb/rtl8192cu_recv.c | 380 +
+ .../rtl8192cu/hal/rtl8192c/usb/rtl8192cu_xmit.c | 1322 +
+ .../rtl8192cu/hal/rtl8192c/usb/usb_halinit.c | 6036 ++++
+ .../rtl8192cu/hal/rtl8192c/usb/usb_ops_ce.c | 1208 +
+ .../rtl8192cu/hal/rtl8192c/usb/usb_ops_linux.c | 2045 ++
+ .../rtl8192cu/hal/rtl8192c/usb/usb_ops_xp.c | 1266 +
+ drivers/net/wireless/rtl8192cu/ifcfg-wlan0 | 4 +
+ .../wireless/rtl8192cu/include/Hal8192CEHWImg.h | 81 +
+ .../wireless/rtl8192cu/include/Hal8192CPhyCfg.h | 451 +
+ .../wireless/rtl8192cu/include/Hal8192CPhyReg.h | 1102 +
+ .../wireless/rtl8192cu/include/Hal8192CUHWImg.h | 99 +
+ .../rtl8192cu/include/Hal8192CUHWImg_wowlan.h | 34 +
+ .../wireless/rtl8192cu/include/Hal8192DEHWImg.h | 66 +
+ .../rtl8192cu/include/Hal8192DETestHWImg.h | 54 +
+ .../wireless/rtl8192cu/include/Hal8192DPhyCfg.h | 528 +
+ .../wireless/rtl8192cu/include/Hal8192DPhyReg.h | 1171 +
+ .../wireless/rtl8192cu/include/Hal8192DUHWImg.h | 66 +
+ .../rtl8192cu/include/Hal8192DUHWImg_wowlan.h | 30 +
+ .../rtl8192cu/include/Hal8192DUTestHWImg.h | 54 +
+ drivers/net/wireless/rtl8192cu/include/autoconf.h | 285 +
+ .../net/wireless/rtl8192cu/include/basic_types.h | 276 +
+ .../rtl8192cu/include/byteorder/big_endian.h | 87 +
+ .../wireless/rtl8192cu/include/byteorder/generic.h | 209 +
+ .../rtl8192cu/include/byteorder/little_endian.h | 89 +
+ .../wireless/rtl8192cu/include/byteorder/swab.h | 133 +
+ .../wireless/rtl8192cu/include/byteorder/swabb.h | 157 +
+ drivers/net/wireless/rtl8192cu/include/circ_buf.h | 27 +
+ drivers/net/wireless/rtl8192cu/include/cmd_osdep.h | 36 +
+ drivers/net/wireless/rtl8192cu/include/drv_conf.h | 78 +
+ drivers/net/wireless/rtl8192cu/include/drv_types.h | 555 +
+ .../net/wireless/rtl8192cu/include/drv_types_ce.h | 92 +
+ .../wireless/rtl8192cu/include/drv_types_linux.h | 25 +
+ .../net/wireless/rtl8192cu/include/drv_types_xp.h | 95 +
+ drivers/net/wireless/rtl8192cu/include/ethernet.h | 41 +
+ drivers/net/wireless/rtl8192cu/include/farray.h | 31480 +++++++++++++++++++
+ drivers/net/wireless/rtl8192cu/include/h2clbk.h | 35 +
+ drivers/net/wireless/rtl8192cu/include/hal_init.h | 305 +
+ drivers/net/wireless/rtl8192cu/include/ieee80211.h | 1461 +
+ .../net/wireless/rtl8192cu/include/ieee80211_ext.h | 477 +
+ drivers/net/wireless/rtl8192cu/include/if_ether.h | 112 +
+ .../wireless/rtl8192cu/include/ioctl_cfg80211.h | 81 +
+ drivers/net/wireless/rtl8192cu/include/ip.h | 138 +
+ .../net/wireless/rtl8192cu/include/mlme_osdep.h | 44 +
+ .../net/wireless/rtl8192cu/include/mp_custom_oid.h | 353 +
+ drivers/net/wireless/rtl8192cu/include/nic_spec.h | 47 +
+ .../wireless/rtl8192cu/include/osdep_ce_service.h | 171 +
+ .../net/wireless/rtl8192cu/include/osdep_intf.h | 128 +
+ .../net/wireless/rtl8192cu/include/osdep_service.h | 830 +
+ drivers/net/wireless/rtl8192cu/include/pci_hal.h | 168 +
+ drivers/net/wireless/rtl8192cu/include/pci_ops.h | 58 +
+ .../net/wireless/rtl8192cu/include/pci_osintf.h | 33 +
+ .../net/wireless/rtl8192cu/include/recv_osdep.h | 58 +
+ .../net/wireless/rtl8192cu/include/rtl8192c_cmd.h | 153 +
+ .../net/wireless/rtl8192cu/include/rtl8192c_dm.h | 616 +
+ .../wireless/rtl8192cu/include/rtl8192c_event.h | 29 +
+ .../net/wireless/rtl8192cu/include/rtl8192c_hal.h | 887 +
+ .../net/wireless/rtl8192cu/include/rtl8192c_led.h | 43 +
+ .../net/wireless/rtl8192cu/include/rtl8192c_recv.h | 180 +
+ .../net/wireless/rtl8192cu/include/rtl8192c_rf.h | 93 +
+ .../net/wireless/rtl8192cu/include/rtl8192c_spec.h | 1899 ++
+ .../wireless/rtl8192cu/include/rtl8192c_sreset.h | 54 +
+ .../net/wireless/rtl8192cu/include/rtl8192c_xmit.h | 91 +
+ .../net/wireless/rtl8192cu/include/rtl8192d_cmd.h | 133 +
+ .../net/wireless/rtl8192cu/include/rtl8192d_dm.h | 414 +
+ .../net/wireless/rtl8192cu/include/rtl8192d_hal.h | 983 +
+ .../net/wireless/rtl8192cu/include/rtl8192d_led.h | 44 +
+ .../net/wireless/rtl8192cu/include/rtl8192d_recv.h | 179 +
+ .../net/wireless/rtl8192cu/include/rtl8192d_rf.h | 98 +
+ .../net/wireless/rtl8192cu/include/rtl8192d_spec.h | 1879 ++
+ .../net/wireless/rtl8192cu/include/rtl8192d_xmit.h | 106 +
+ .../net/wireless/rtl8192cu/include/rtw_android.h | 80 +
+ .../net/wireless/rtl8192cu/include/rtw_br_ext.h | 76 +
+ .../net/wireless/rtl8192cu/include/rtw_byteorder.h | 41 +
+ drivers/net/wireless/rtl8192cu/include/rtw_cmd.h | 1132 +
+ drivers/net/wireless/rtl8192cu/include/rtw_debug.h | 383 +
+ .../net/wireless/rtl8192cu/include/rtw_eeprom.h | 153 +
+ drivers/net/wireless/rtl8192cu/include/rtw_efuse.h | 123 +
+ drivers/net/wireless/rtl8192cu/include/rtw_event.h | 154 +
+ drivers/net/wireless/rtl8192cu/include/rtw_ht.h | 51 +
+ drivers/net/wireless/rtl8192cu/include/rtw_io.h | 543 +
+ drivers/net/wireless/rtl8192cu/include/rtw_ioctl.h | 271 +
+ .../wireless/rtl8192cu/include/rtw_ioctl_query.h | 37 +
+ .../net/wireless/rtl8192cu/include/rtw_ioctl_rtl.h | 84 +
+ .../net/wireless/rtl8192cu/include/rtw_ioctl_set.h | 78 +
+ drivers/net/wireless/rtl8192cu/include/rtw_iol.h | 89 +
+ drivers/net/wireless/rtl8192cu/include/rtw_led.h | 214 +
+ drivers/net/wireless/rtl8192cu/include/rtw_mlme.h | 664 +
+ .../net/wireless/rtl8192cu/include/rtw_mlme_ext.h | 878 +
+ drivers/net/wireless/rtl8192cu/include/rtw_mp.h | 708 +
+ .../net/wireless/rtl8192cu/include/rtw_mp_ioctl.h | 596 +
+ .../wireless/rtl8192cu/include/rtw_mp_phy_regdef.h | 1098 +
+ drivers/net/wireless/rtl8192cu/include/rtw_p2p.h | 139 +
+ .../net/wireless/rtl8192cu/include/rtw_pwrctrl.h | 343 +
+ drivers/net/wireless/rtl8192cu/include/rtw_qos.h | 41 +
+ drivers/net/wireless/rtl8192cu/include/rtw_recv.h | 711 +
+ drivers/net/wireless/rtl8192cu/include/rtw_rf.h | 152 +
+ .../net/wireless/rtl8192cu/include/rtw_security.h | 423 +
+ .../net/wireless/rtl8192cu/include/rtw_version.h | 1 +
+ drivers/net/wireless/rtl8192cu/include/rtw_xmit.h | 668 +
+ drivers/net/wireless/rtl8192cu/include/sdio_hal.h | 34 +
+ drivers/net/wireless/rtl8192cu/include/sdio_ops.h | 80 +
+ .../net/wireless/rtl8192cu/include/sdio_ops_ce.h | 56 +
+ .../wireless/rtl8192cu/include/sdio_ops_linux.h | 55 +
+ .../net/wireless/rtl8192cu/include/sdio_ops_xp.h | 56 +
+ .../net/wireless/rtl8192cu/include/sdio_osintf.h | 48 +
+ drivers/net/wireless/rtl8192cu/include/sta_info.h | 353 +
+ drivers/net/wireless/rtl8192cu/include/usb_hal.h | 32 +
+ drivers/net/wireless/rtl8192cu/include/usb_ops.h | 100 +
+ .../net/wireless/rtl8192cu/include/usb_osintf.h | 39 +
+ .../wireless/rtl8192cu/include/usb_vendor_req.h | 60 +
+ drivers/net/wireless/rtl8192cu/include/wifi.h | 1185 +
+ .../net/wireless/rtl8192cu/include/wlan_bssdef.h | 453 +
+ .../net/wireless/rtl8192cu/include/xmit_osdep.h | 90 +
+ .../rtl8192cu/os_dep/linux/ioctl_cfg80211.c | 4620 +++
+ .../wireless/rtl8192cu/os_dep/linux/ioctl_linux.c | 9305 ++++++
+ .../wireless/rtl8192cu/os_dep/linux/mlme_linux.c | 740 +
+ .../net/wireless/rtl8192cu/os_dep/linux/os_intfs.c | 1542 +
+ .../net/wireless/rtl8192cu/os_dep/linux/pci_intf.c | 1889 ++
+ .../wireless/rtl8192cu/os_dep/linux/recv_linux.c | 462 +
+ .../wireless/rtl8192cu/os_dep/linux/rtw_android.c | 713 +
+ .../wireless/rtl8192cu/os_dep/linux/sdio_intf.c | 922 +
+ .../net/wireless/rtl8192cu/os_dep/linux/usb_intf.c | 1524 +
+ .../wireless/rtl8192cu/os_dep/linux/xmit_linux.c | 367 +
+ .../net/wireless/rtl8192cu/os_dep/osdep_service.c | 1555 +
+ drivers/net/wireless/rtl8192cu/wlan0dhcp | 16 +
+ 165 files changed, 182943 insertions(+), 2 deletions(-)
create mode 100755 drivers/net/wireless/rtl8192cu/Kconfig
create mode 100755 drivers/net/wireless/rtl8192cu/Makefile
create mode 100755 drivers/net/wireless/rtl8192cu/clean
@@ -335,24 +335,23 @@ Subject: [PATCH] Add non-mainline source for rtl8188cu wireless driver as
create mode 100755 drivers/net/wireless/rtl8192cu/wlan0dhcp
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
-index abd3b71..f561d69 100644
+index 6deaae1..4b6c43c 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
-@@ -281,10 +281,11 @@ source "drivers/net/wireless/libertas/Kconfig"
+@@ -280,9 +280,10 @@ source "drivers/net/wireless/libertas/Kconfig"
source "drivers/net/wireless/orinoco/Kconfig"
source "drivers/net/wireless/p54/Kconfig"
source "drivers/net/wireless/rt2x00/Kconfig"
-source "drivers/net/wireless/rtlwifi/Kconfig"
+#source "drivers/net/wireless/rtlwifi/Kconfig"
- source "drivers/net/wireless/wl1251/Kconfig"
- source "drivers/net/wireless/wl12xx/Kconfig"
+ source "drivers/net/wireless/ti/Kconfig"
source "drivers/net/wireless/zd1211rw/Kconfig"
source "drivers/net/wireless/mwifiex/Kconfig"
+source "drivers/net/wireless/rtl8192cu/Kconfig"
endif # WLAN
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
-index 0a304b0..a042951 100644
+index 062dfdf..9a124fd 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -24,7 +24,7 @@ obj-$(CONFIG_B43LEGACY) += b43legacy/
@@ -364,13 +363,11 @@ index 0a304b0..a042951 100644
# 16-bit wireless PCMCIA client drivers
obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
-@@ -61,3 +61,6 @@ obj-$(CONFIG_MWIFIEX) += mwifiex/
- obj-$(CONFIG_BRCMFMAC) += brcm80211/
- obj-$(CONFIG_BRCMUMAC) += brcm80211/
- obj-$(CONFIG_BRCMSMAC) += brcm80211/
-+
+@@ -57,3 +57,4 @@ obj-$(CONFIG_MWIFIEX) += mwifiex/
+
+ obj-$(CONFIG_BRCMFMAC) += brcm80211/
+ obj-$(CONFIG_BRCMSMAC) += brcm80211/
+obj-$(CONFIG_RTL8192CU) += rtl8192cu/
-+
diff --git a/drivers/net/wireless/rtl8192cu/Kconfig b/drivers/net/wireless/rtl8192cu/Kconfig
new file mode 100755
index 0000000..bee5ed6
@@ -29521,7 +29518,7 @@ index 0000000..0cdc094
+
diff --git a/drivers/net/wireless/rtl8192cu/core/rtw_mp_ioctl.c b/drivers/net/wireless/rtl8192cu/core/rtw_mp_ioctl.c
new file mode 100755
-index 0000000..a8515680
+index 0000000..a851568
--- /dev/null
+++ b/drivers/net/wireless/rtl8192cu/core/rtw_mp_ioctl.c
@@ -0,0 +1,2841 @@
@@ -151025,7 +151022,7 @@ index 0000000..577af51
+
diff --git a/drivers/net/wireless/rtl8192cu/include/rtw_iol.h b/drivers/net/wireless/rtl8192cu/include/rtw_iol.h
new file mode 100755
-index 0000000..2750eb3e
+index 0000000..2750eb3
--- /dev/null
+++ b/drivers/net/wireless/rtl8192cu/include/rtw_iol.h
@@ -0,0 +1,89 @@
diff --git a/patches/linux-3.2.27/0139-Add-verious-user-config-requests.patch b/patches/linux-3.6.7/0137-Add-verious-user-config-requests.patch
index ea55a33..a6c5dd1 100644
--- a/patches/linux-3.2.27/0139-Add-verious-user-config-requests.patch
+++ b/patches/linux-3.6.7/0137-Add-verious-user-config-requests.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Add verious user config requests. CONFIG_DEVTMPFS_MOUNT,
drbd and IPSEC modules
---
- arch/arm/configs/bcmrpi_defconfig | 32 +++++++++++++++++++++++++-------
+ arch/arm/configs/bcmrpi_defconfig | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
diff --git a/patches/linux-3.2.27/0140-Don-t-believe-KDIR-is-required-when-building-as-part.patch b/patches/linux-3.6.7/0138-Don-t-believe-KDIR-is-required-when-building-as-part.patch
index af4521f..a20e558 100644
--- a/patches/linux-3.2.27/0140-Don-t-believe-KDIR-is-required-when-building-as-part.patch
+++ b/patches/linux-3.6.7/0138-Don-t-believe-KDIR-is-required-when-building-as-part.patch
@@ -4,11 +4,11 @@ Subject: [PATCH] Don't believe KDIR is required when building as part of
kernel
---
- drivers/usb/host/dwc_common_port/Makefile | 6 +++---
+ drivers/usb/host/dwc_common_port/Makefile | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/host/dwc_common_port/Makefile b/drivers/usb/host/dwc_common_port/Makefile
-index 203c7eaa..63e3485 100644
+index 203c7ea..63e3485 100644
--- a/drivers/usb/host/dwc_common_port/Makefile
+++ b/drivers/usb/host/dwc_common_port/Makefile
@@ -30,9 +30,9 @@ endif
diff --git a/patches/linux-3.2.27/0141-Avoid-dynamic-memory-allocation-for-channel-lock-in-.patch b/patches/linux-3.6.7/0139-Avoid-dynamic-memory-allocation-for-channel-lock-in-.patch
index 702671b..8dbf226 100644
--- a/patches/linux-3.2.27/0141-Avoid-dynamic-memory-allocation-for-channel-lock-in-.patch
+++ b/patches/linux-3.6.7/0139-Avoid-dynamic-memory-allocation-for-channel-lock-in-.patch
@@ -4,10 +4,10 @@ Subject: [PATCH] Avoid dynamic memory allocation for channel lock in USB
driver. Thanks ddv2005.
---
- drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 6 +++---
- drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 2 +-
- drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 3 +--
- drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 3 +--
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 6 +++---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 2 +-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 3 +--
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 3 +--
4 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
diff --git a/patches/linux-3.2.27/0142-Add-cpufreq-driver.patch b/patches/linux-3.6.7/0140-Add-cpufreq-driver.patch
index 8e79ba1..df06fac 100644
--- a/patches/linux-3.2.27/0142-Add-cpufreq-driver.patch
+++ b/patches/linux-3.6.7/0140-Add-cpufreq-driver.patch
@@ -3,22 +3,22 @@ Date: Sun, 9 Sep 2012 23:47:03 +0100
Subject: [PATCH] Add cpufreq driver
---
- arch/arm/Kconfig | 1 +
- arch/arm/configs/bcmrpi_defconfig | 6 +
- arch/arm/mach-bcm2708/include/mach/vcio.h | 81 +++++++++-
- arch/arm/mach-bcm2708/vc_mem.c | 47 +++---
- arch/arm/mach-bcm2708/vcio.c | 34 ++++
- drivers/cpufreq/Kconfig.arm | 8 +
- drivers/cpufreq/Makefile | 1 +
- drivers/cpufreq/bcm2835-cpufreq.c | 239 +++++++++++++++++++++++++++++
- 8 files changed, 380 insertions(+), 37 deletions(-)
+ arch/arm/Kconfig | 1 +
+ arch/arm/configs/bcmrpi_defconfig | 6 +
+ arch/arm/mach-bcm2708/include/mach/vcio.h | 81 +++++++++-
+ arch/arm/mach-bcm2708/vc_mem.c | 47 +++---
+ arch/arm/mach-bcm2708/vcio.c | 34 +++++
+ drivers/cpufreq/Kconfig.arm | 9 ++
+ drivers/cpufreq/Makefile | 1 +
+ drivers/cpufreq/bcm2835-cpufreq.c | 239 ++++++++++++++++++++++++++++++
+ 8 files changed, 381 insertions(+), 37 deletions(-)
create mode 100755 drivers/cpufreq/bcm2835-cpufreq.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index 5285fbf..b58af94 100644
+index 4dd71eb..14afaea 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
-@@ -963,6 +963,7 @@ config ARCH_BCM2708
+@@ -1006,6 +1006,7 @@ config ARCH_BCM2708
select HAVE_SCHED_CLOCK
select NEED_MACH_MEMORY_H
select CLKDEV_LOOKUP
@@ -251,13 +251,13 @@ index 3874051..468fdef 100644
* Platform Device for Mailbox
* -------------------------------------------------------------------- */
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
-index 72a0044..c28423d 100644
+index 5961e64..6999dfd 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
-@@ -30,3 +30,11 @@ config ARM_EXYNOS4210_CPUFREQ
- SoC (S5PV310 or S5PC210).
-
- If in doubt, say N.
+@@ -76,3 +76,12 @@ config ARM_EXYNOS5250_CPUFREQ
+ help
+ This adds the CPUFreq driver for Samsung EXYNOS5250
+ SoC.
+
+config ARM_BCM2835_CPUFREQ
+ bool "BCM2835 Driver"
@@ -266,14 +266,15 @@ index 72a0044..c28423d 100644
+ This adds the CPUFreq driver for BCM2835
+
+ If in doubt, say N.
++
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
-index a48bc02..51ebbb3 100644
+index 9531fc2..860ab83 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
-@@ -43,6 +43,7 @@ obj-$(CONFIG_UX500_SOC_DB8500) += db8500-cpufreq.o
- obj-$(CONFIG_ARM_S3C64XX_CPUFREQ) += s3c64xx-cpufreq.o
- obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o
- obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ) += exynos4210-cpufreq.o
+@@ -48,6 +48,7 @@ obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ) += exynos4210-cpufreq.o
+ obj-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ) += exynos4x12-cpufreq.o
+ obj-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o
+ obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
+obj-$(CONFIG_ARM_BCM2835_CPUFREQ) += bcm2835-cpufreq.o
##################################################################################
diff --git a/patches/linux-3.2.27/0143-Tidy-up-debug-messages.patch b/patches/linux-3.6.7/0141-Tidy-up-debug-messages.patch
index 32ab799..aab7536 100644
--- a/patches/linux-3.2.27/0143-Tidy-up-debug-messages.patch
+++ b/patches/linux-3.6.7/0141-Tidy-up-debug-messages.patch
@@ -3,7 +3,7 @@ Date: Sun, 9 Sep 2012 23:47:27 +0100
Subject: [PATCH] Tidy up debug messages
---
- sound/arm/bcm2835.c | 14 ++++----------
+ sound/arm/bcm2835.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/sound/arm/bcm2835.c b/sound/arm/bcm2835.c
diff --git a/patches/linux-3.2.27/0145-Enable-fiq-fix-by-default.-Add-NAK-holdoff-scheme.-E.patch b/patches/linux-3.6.7/0142-Enable-fiq-fix-by-default.-Add-NAK-holdoff-scheme.-E.patch
index 2b50981..3274ebd 100644
--- a/patches/linux-3.2.27/0145-Enable-fiq-fix-by-default.-Add-NAK-holdoff-scheme.-E.patch
+++ b/patches/linux-3.6.7/0142-Enable-fiq-fix-by-default.-Add-NAK-holdoff-scheme.-E.patch
@@ -5,11 +5,11 @@ Subject: [PATCH] Enable fiq fix by default. Add NAK holdoff scheme. Enabled
Thanks gsh
---
- drivers/usb/host/dwc_otg/dwc_otg_driver.c | 9 +++++++--
- drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 22 +++++++++++++++++++++-
- drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 5 +++++
- drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 21 +++++++++++++++++++--
- drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 19 +++++++++++++++++++
+ drivers/usb/host/dwc_otg/dwc_otg_driver.c | 9 +++++++--
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 22 +++++++++++++++++++++-
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 5 +++++
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 21 +++++++++++++++++++--
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 19 +++++++++++++++++++
5 files changed, 71 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.c b/drivers/usb/host/dwc_otg/dwc_otg_driver.c
diff --git a/patches/linux-3.2.27/0146-Added-hwmon-thermal-driver-for-reporting-core-temper.patch b/patches/linux-3.6.7/0143-Added-hwmon-thermal-driver-for-reporting-core-temper.patch
index 2dd80d6..b4de9e9 100644
--- a/patches/linux-3.2.27/0146-Added-hwmon-thermal-driver-for-reporting-core-temper.patch
+++ b/patches/linux-3.6.7/0143-Added-hwmon-thermal-driver-for-reporting-core-temper.patch
@@ -4,14 +4,14 @@ Subject: [PATCH] Added hwmon/thermal driver for reporting core temperature.
Thanks Dorian
---
- arch/arm/mach-bcm2708/bcm2708.c | 11 ++
- drivers/hwmon/Kconfig | 9 ++
- drivers/hwmon/Makefile | 1 +
- drivers/hwmon/bcm2835-hwmon.c | 211 +++++++++++++++++++++++++++++++++++++
- drivers/thermal/Kconfig | 10 ++
- drivers/thermal/Makefile | 1 +
- drivers/thermal/bcm2835-thermal.c | 195 ++++++++++++++++++++++++++++++++++
- 7 files changed, 438 insertions(+)
+ arch/arm/mach-bcm2708/bcm2708.c | 11 ++
+ drivers/hwmon/Kconfig | 9 ++
+ drivers/hwmon/Makefile | 1 +
+ drivers/hwmon/bcm2835-hwmon.c | 211 ++++++++++++++++++++++++++++++++++++++
+ drivers/thermal/Kconfig | 11 ++
+ drivers/thermal/Makefile | 3 +-
+ drivers/thermal/bcm2835-thermal.c | 195 +++++++++++++++++++++++++++++++++++
+ 7 files changed, 440 insertions(+), 1 deletion(-)
create mode 100644 drivers/hwmon/bcm2835-hwmon.c
create mode 100644 drivers/thermal/bcm2835-thermal.c
@@ -45,12 +45,12 @@ index 6f63532..b3dbbd1 100644
{
extern void vc_mem_connected_init(void);
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
-index 83e3e9d..761b528 100644
+index b0a2e4c..3009852 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
-@@ -1361,6 +1361,15 @@ config SENSORS_MC13783_ADC
+@@ -1411,6 +1411,15 @@ config SENSORS_MC13783_ADC
help
- Support for the A/D converter on MC13783 PMIC.
+ Support for the A/D converter on MC13783 and MC13892 PMIC.
+config SENSORS_BCM2835
+ tristate "Broadcom BCM2835 HWMON Driver"
@@ -65,10 +65,10 @@ index 83e3e9d..761b528 100644
comment "ACPI drivers"
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
-index 8251ce8..8f2743b 100644
+index 7aa9811..7c1162a 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
-@@ -125,6 +125,7 @@ obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o
+@@ -129,6 +129,7 @@ obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o
obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o
obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o
obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o
@@ -294,13 +294,13 @@ index 0000000..4976387
+
+module_platform_driver(bcm2835_hwmon_driver);
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
-index f7f71b2..a5017b4 100644
+index 3ab2bd5..7d12e17 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
-@@ -18,3 +18,13 @@ config THERMAL_HWMON
- depends on THERMAL
- depends on HWMON=y || HWMON=THERMAL
- default y
+@@ -27,3 +27,14 @@ config SPEAR_THERMAL
+ help
+ Enable this to plug the SPEAr thermal sensor driver into the Linux
+ thermal framework
+
+if THERMAL
+
@@ -311,14 +311,18 @@ index f7f71b2..a5017b4 100644
+ chip. If built as a module, it will be called 'bcm2835-thermal'.
+
+endif # THERMAL_BCM2835
++
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
-index 31108a0..48081d1 100644
+index a9fff0b..666f93c 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
-@@ -3,3 +3,4 @@
+@@ -3,4 +3,5 @@
#
obj-$(CONFIG_THERMAL) += thermal_sys.o
+-obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o
+\ No newline at end of file
++obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o
+obj-$(CONFIG_THERMAL_BCM2835) += bcm2835-thermal.o
diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c
new file mode 100644
diff --git a/patches/linux-3.2.27/0147-Add-config-options-for-thermal-sensor-L2TP-RT2800USB.patch b/patches/linux-3.6.7/0144-Add-config-options-for-thermal-sensor-L2TP-RT2800USB.patch
index bbf111f..0c048a8 100644
--- a/patches/linux-3.2.27/0147-Add-config-options-for-thermal-sensor-L2TP-RT2800USB.patch
+++ b/patches/linux-3.6.7/0144-Add-config-options-for-thermal-sensor-L2TP-RT2800USB.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Add config options for thermal sensor, L2TP,
thermal driver.
---
- arch/arm/configs/bcmrpi_defconfig | 31 +++++++++++++++++++++++++++++++
- drivers/hwmon/Kconfig | 1 +
- drivers/hwmon/bcm2835-hwmon.c | 22 +++++++++++++++-------
- drivers/thermal/bcm2835-thermal.c | 15 ++++++++++++++-
+ arch/arm/configs/bcmrpi_defconfig | 31 +++++++++++++++++++++++++++++++
+ drivers/hwmon/Kconfig | 1 +
+ drivers/hwmon/bcm2835-hwmon.c | 22 +++++++++++++++-------
+ drivers/thermal/bcm2835-thermal.c | 15 ++++++++++++++-
4 files changed, 61 insertions(+), 8 deletions(-)
diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
@@ -75,11 +75,11 @@ index 35c5042..2f80e88 100644
CONFIG_UIO_PDRV=m
CONFIG_UIO_PDRV_GENIRQ=m
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
-index 761b528..a22de2a 100644
+index 3009852..954041a 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
-@@ -1362,6 +1362,7 @@ config SENSORS_MC13783_ADC
- Support for the A/D converter on MC13783 PMIC.
+@@ -1412,6 +1412,7 @@ config SENSORS_MC13783_ADC
+ Support for the A/D converter on MC13783 and MC13892 PMIC.
config SENSORS_BCM2835
+ depends on THERMAL_BCM2835=n
diff --git a/patches/linux-3.6.7/0145-Remove-some-unnecessary-dmesg-output.patch b/patches/linux-3.6.7/0145-Remove-some-unnecessary-dmesg-output.patch
new file mode 100644
index 0000000..abac942
--- /dev/null
+++ b/patches/linux-3.6.7/0145-Remove-some-unnecessary-dmesg-output.patch
@@ -0,0 +1,193 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Mon, 17 Sep 2012 18:17:56 +0100
+Subject: [PATCH] Remove some unnecessary dmesg output.
+
+---
+ drivers/cpufreq/bcm2835-cpufreq.c | 2 +-
+ drivers/video/bcm2708_fb.c | 34 +++++++++++++++++++---------------
+ sound/arm/bcm2835-pcm.c | 4 ++--
+ sound/arm/bcm2835.c | 5 -----
+ 4 files changed, 22 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/cpufreq/bcm2835-cpufreq.c b/drivers/cpufreq/bcm2835-cpufreq.c
+index aa6fc66..6ff1edb 100755
+--- a/drivers/cpufreq/bcm2835-cpufreq.c
++++ b/drivers/cpufreq/bcm2835-cpufreq.c
+@@ -196,7 +196,7 @@ static int bcm2835_cpufreq_driver_target(struct cpufreq_policy *policy, unsigned
+ policy->cur = bcm2835_cpufreq_get_clock(VCMSG_GET_CLOCK_RATE);
+ return -EINVAL;
+ }
+- print_info("Freq %d->%d (min=%d max=%d target=%d request=%d)", cur, policy->cur, policy->min, policy->max, target_freq, target);
++ print_debug("Freq %d->%d (min=%d max=%d target=%d request=%d)", cur, policy->cur, policy->min, policy->max, target_freq, target);
+ return 0;
+ }
+
+diff --git a/drivers/video/bcm2708_fb.c b/drivers/video/bcm2708_fb.c
+index 5ca8aca..efdee9d 100644
+--- a/drivers/video/bcm2708_fb.c
++++ b/drivers/video/bcm2708_fb.c
+@@ -36,6 +36,12 @@
+ #include <linux/io.h>
+ #include <linux/dma-mapping.h>
+
++#ifdef BCM2708_FB_DEBUG
++#define print_debug(fmt,...) pr_debug("%s:%s:%d: "fmt, MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__)
++#else
++#define print_debug(fmt,...)
++#endif
++
+ /* This is limited to 16 characters when displayed by X startup */
+ static const char *bcm2708_name = "BCM2708 FB";
+
+@@ -135,17 +141,15 @@ static int bcm2708_fb_check_var(struct fb_var_screeninfo *var,
+ {
+ /* info input, var output */
+ int yres;
+- /* memory size in pixels */
+- unsigned pixels = info->screen_size * 8 / var->bits_per_pixel;
+
+ /* info input, var output */
+- pr_info("bcm2708_fb_check_var info(%p) %dx%d (%dx%d), %d, %d\n", info,
++ print_debug("bcm2708_fb_check_var info(%p) %dx%d (%dx%d), %d, %d\n", info,
+ info->var.xres, info->var.yres, info->var.xres_virtual,
+ info->var.yres_virtual, (int)info->screen_size,
+ info->var.bits_per_pixel);
+- pr_info("bcm2708_fb_check_var var(%p) %dx%d (%dx%d), %d, %d\n", var,
++ print_debug("bcm2708_fb_check_var var(%p) %dx%d (%dx%d), %d\n", var,
+ var->xres, var->yres, var->xres_virtual, var->yres_virtual,
+- var->bits_per_pixel, pixels);
++ var->bits_per_pixel);
+
+ if (!var->bits_per_pixel)
+ var->bits_per_pixel = 16;
+@@ -211,7 +215,7 @@ static int bcm2708_fb_set_par(struct fb_info *info)
+ fbinfo->base = 0; /* filled in by VC */
+ fbinfo->pitch = 0; /* filled in by VC */
+
+- pr_info("bcm2708_fb_set_par info(%p) %dx%d (%dx%d), %d, %d\n", info,
++ print_debug("bcm2708_fb_set_par info(%p) %dx%d (%dx%d), %d, %d\n", info,
+ info->var.xres, info->var.yres, info->var.xres_virtual,
+ info->var.yres_virtual, (int)info->screen_size,
+ info->var.bits_per_pixel);
+@@ -251,7 +255,7 @@ static int bcm2708_fb_set_par(struct fb_info *info)
+ BUG(); /* what can we do here */
+ }
+ }
+- pr_info
++ print_debug
+ ("BCM2708FB: start = %p,%p width=%d, height=%d, bpp=%d, pitch=%d size=%d success=%d\n",
+ (void *)fb->fb.screen_base, (void *)fb->fb.fix.smem_start,
+ fbinfo->xres, fbinfo->yres, fbinfo->bpp,
+@@ -274,7 +278,7 @@ static int bcm2708_fb_setcolreg(unsigned int regno, unsigned int red,
+ {
+ struct bcm2708_fb *fb = to_bcm2708(info);
+
+- /*pr_info("BCM2708FB: setcolreg %d:(%02x,%02x,%02x,%02x) %x\n", regno, red, green, blue, transp, fb->fb.fix.visual);*/
++ /*print_debug("BCM2708FB: setcolreg %d:(%02x,%02x,%02x,%02x) %x\n", regno, red, green, blue, transp, fb->fb.fix.visual);*/
+ if (fb->fb.var.bits_per_pixel <= 8) {
+ if (regno < 256) {
+ /* blue [0:4], green [5:10], red [11:15] */
+@@ -297,28 +301,28 @@ static int bcm2708_fb_setcolreg(unsigned int regno, unsigned int red,
+
+ static int bcm2708_fb_blank(int blank_mode, struct fb_info *info)
+ {
+- /*pr_info("bcm2708_fb_blank\n"); */
++ /*print_debug("bcm2708_fb_blank\n"); */
+ return -1;
+ }
+
+ static void bcm2708_fb_fillrect(struct fb_info *info,
+ const struct fb_fillrect *rect)
+ {
+- /* (is called) pr_info("bcm2708_fb_fillrect\n"); */
++ /* (is called) print_debug("bcm2708_fb_fillrect\n"); */
+ cfb_fillrect(info, rect);
+ }
+
+ static void bcm2708_fb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *region)
+ {
+- /*pr_info("bcm2708_fb_copyarea\n"); */
++ /*print_debug("bcm2708_fb_copyarea\n"); */
+ cfb_copyarea(info, region);
+ }
+
+ static void bcm2708_fb_imageblit(struct fb_info *info,
+ const struct fb_image *image)
+ {
+- /* (is called) pr_info("bcm2708_fb_imageblit\n"); */
++ /* (is called) print_debug("bcm2708_fb_imageblit\n"); */
+ cfb_imageblit(info, image);
+ }
+
+@@ -393,15 +397,15 @@ static int bcm2708_fb_register(struct bcm2708_fb *fb)
+
+ fb_set_var(&fb->fb, &fb->fb.var);
+
+- pr_info("BCM2708FB: registering framebuffer (%dx%d@%d)\n", fbwidth,
++ print_debug("BCM2708FB: registering framebuffer (%dx%d@%d)\n", fbwidth,
+ fbheight, fbdepth);
+
+ ret = register_framebuffer(&fb->fb);
+- pr_info("BCM2708FB: register framebuffer (%d)\n", ret);
++ print_debug("BCM2708FB: register framebuffer (%d)\n", ret);
+ if (ret == 0)
+ goto out;
+
+- pr_info("BCM2708FB: cannot register framebuffer (%d)\n", ret);
++ print_debug("BCM2708FB: cannot register framebuffer (%d)\n", ret);
+ out:
+ return ret;
+ }
+diff --git a/sound/arm/bcm2835-pcm.c b/sound/arm/bcm2835-pcm.c
+index bc146a2..2f63ac6 100755
+--- a/sound/arm/bcm2835-pcm.c
++++ b/sound/arm/bcm2835-pcm.c
+@@ -98,7 +98,7 @@ static int snd_bcm2835_playback_open(struct snd_pcm_substream *substream)
+
+ audio_info(" .. IN (%d)\n", substream->number);
+
+- audio_warning("Alsa open (%d)\n", substream->number);
++ audio_info("Alsa open (%d)\n", substream->number);
+ idx = substream->number;
+
+ if (idx > MAX_SUBSTREAMS) {
+@@ -167,7 +167,7 @@ static int snd_bcm2835_playback_close(struct snd_pcm_substream *substream)
+ bcm2835_alsa_stream_t *alsa_stream = runtime->private_data;
+
+ audio_info(" .. IN\n");
+- audio_warning("Alsa close\n");
++ audio_info("Alsa close\n");
+
+ /*
+ * Call stop if it's still running. This happens when app
+diff --git a/sound/arm/bcm2835.c b/sound/arm/bcm2835.c
+index 44bedb5..9546fe6 100755
+--- a/sound/arm/bcm2835.c
++++ b/sound/arm/bcm2835.c
+@@ -87,8 +87,6 @@ static int __devinit snd_bcm2835_alsa_probe(struct platform_device *pdev)
+ bcm2835_chip_t *chip;
+ struct snd_card *card;
+ int err;
+- printk(KERN_INFO "Probing FOR bcm2835 ALSA device (%d):(%d)\n",
+- dev, enable[dev]);
+
+ if (dev >= MAX_SUBSTREAMS)
+ return -ENODEV;
+@@ -101,7 +99,6 @@ static int __devinit snd_bcm2835_alsa_probe(struct platform_device *pdev)
+ if (dev > 0)
+ goto add_register_map;
+
+- printk("Creating card...\n");
+ err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &g_card);
+ if (err < 0)
+ goto out;
+@@ -374,8 +371,6 @@ static int __devinit bcm2835_alsa_device_init(void)
+ printk("Error registering bcm2835_alsa7_driver %d .\n", err);
+ goto unregister_6;
+ }
+- printk(KERN_INFO "BCM2835 ALSA driver init %s\n",
+- err ? "FAILED" : "OK");
+
+ return 0;
+
diff --git a/patches/linux-3.6.7/0146-Switch-to-powersave-governor.-We-ll-enable-ondemand-.patch b/patches/linux-3.6.7/0146-Switch-to-powersave-governor.-We-ll-enable-ondemand-.patch
new file mode 100644
index 0000000..19aebba
--- /dev/null
+++ b/patches/linux-3.6.7/0146-Switch-to-powersave-governor.-We-ll-enable-ondemand-.patch
@@ -0,0 +1,26 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Mon, 17 Sep 2012 22:57:29 +0100
+Subject: [PATCH] Switch to powersave governor. We'll enable ondemand in the
+ distribution
+
+---
+ arch/arm/configs/bcmrpi_defconfig | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
+index 2f80e88..b4a3da1 100644
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -48,9 +48,10 @@ CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,11520
+ CONFIG_KEXEC=y
+ CONFIG_CPU_FREQ=y
+ CONFIG_CPU_FREQ_STAT=m
+-CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+-CONFIG_CPU_FREQ_GOV_POWERSAVE=y
++CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y
++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+ CONFIG_CPU_FREQ_GOV_USERSPACE=y
++CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+ CONFIG_CPU_IDLE=y
+ CONFIG_VFP=y
diff --git a/patches/linux-3.6.7/0147-Enable-multiple-ALSA-channels.patch b/patches/linux-3.6.7/0147-Enable-multiple-ALSA-channels.patch
new file mode 100644
index 0000000..145c1ea
--- /dev/null
+++ b/patches/linux-3.6.7/0147-Enable-multiple-ALSA-channels.patch
@@ -0,0 +1,61 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Thu, 20 Sep 2012 21:45:25 +0100
+Subject: [PATCH] Enable multiple ALSA channels
+
+---
+ arch/arm/mach-bcm2708/bcm2708.c | 42 +++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 42 insertions(+)
+
+diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
+index b3dbbd1..72dcf31 100644
+--- a/arch/arm/mach-bcm2708/bcm2708.c
++++ b/arch/arm/mach-bcm2708/bcm2708.c
+@@ -516,6 +516,48 @@ static struct platform_device bcm2708_alsa_devices[] = {
+ .resource = 0,
+ .num_resources = 0,
+ },
++ [1] = {
++ .name = "bcm2835_AUD1",
++ .id = 1, /* second audio device */
++ .resource = 0,
++ .num_resources = 0,
++ },
++ [2] = {
++ .name = "bcm2835_AUD2",
++ .id = 2, /* third audio device */
++ .resource = 0,
++ .num_resources = 0,
++ },
++ [3] = {
++ .name = "bcm2835_AUD3",
++ .id = 3, /* forth audio device */
++ .resource = 0,
++ .num_resources = 0,
++ },
++ [4] = {
++ .name = "bcm2835_AUD4",
++ .id = 4, /* fifth audio device */
++ .resource = 0,
++ .num_resources = 0,
++ },
++ [5] = {
++ .name = "bcm2835_AUD5",
++ .id = 5, /* sixth audio device */
++ .resource = 0,
++ .num_resources = 0,
++ },
++ [6] = {
++ .name = "bcm2835_AUD6",
++ .id = 6, /* seventh audio device */
++ .resource = 0,
++ .num_resources = 0,
++ },
++ [7] = {
++ .name = "bcm2835_AUD7",
++ .id = 7, /* eighth audio device */
++ .resource = 0,
++ .num_resources = 0,
++ },
+ };
+
+ static struct resource bcm2708_spi_resources[] = {
diff --git a/patches/linux-3.6.7/0148-Remove-vcos-abstraction-layer-from-ALSA-driver.-Than.patch b/patches/linux-3.6.7/0148-Remove-vcos-abstraction-layer-from-ALSA-driver.-Than.patch
new file mode 100644
index 0000000..a773a68
--- /dev/null
+++ b/patches/linux-3.6.7/0148-Remove-vcos-abstraction-layer-from-ALSA-driver.-Than.patch
@@ -0,0 +1,384 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Thu, 20 Sep 2012 21:46:14 +0100
+Subject: [PATCH] Remove vcos abstraction layer from ALSA driver. Thanks
+ Dorian
+
+---
+ sound/arm/bcm2835-vchiq.c | 149 ++++++++++++++++++++++------------------------
+ 1 file changed, 70 insertions(+), 79 deletions(-)
+
+diff --git a/sound/arm/bcm2835-vchiq.c b/sound/arm/bcm2835-vchiq.c
+index 68d838d..3b7ed1e 100755
+--- a/sound/arm/bcm2835-vchiq.c
++++ b/sound/arm/bcm2835-vchiq.c
+@@ -32,17 +32,10 @@
+ /* ---- Include Files -------------------------------------------------------- */
+
+ #include "interface/vchi/vchi.h"
+-#include "interface/vcos/vcos.h"
+-#include "interface/vcos/vcos_logging.h"
+ #include "vc_vchi_audioserv_defs.h"
+
+ /* ---- Private Constants and Types ------------------------------------------ */
+
+-/* VCOS logging category for this service */
+-#define VCOS_LOG_CATEGORY (&audio_log_category)
+-
+-/* Default VCOS logging level */
+-#define LOG_LEVEL VCOS_LOG_WARN
+ /* Logging macros (for remapping to other logging mechanisms, i.e., printf) */
+ #ifdef AUDIO_DEBUG_ENABLE
+ #define LOG_ERR( fmt, arg... ) pr_err( "%s:%d " fmt, __func__, __LINE__, ##arg)
+@@ -50,26 +43,23 @@
+ #define LOG_INFO( fmt, arg... ) pr_info( "%s:%d " fmt, __func__, __LINE__, ##arg)
+ #define LOG_DBG( fmt, arg... ) pr_info( "%s:%d " fmt, __func__, __LINE__, ##arg)
+ #else
+- #define LOG_ERR( fmt, arg... ) vcos_log_error( "%s:%d " fmt, __func__, __LINE__, ##arg)
+- #define LOG_WARN( fmt, arg... ) vcos_log_warn( "%s:%d " fmt, __func__, __LINE__, ##arg)
+- #define LOG_INFO( fmt, arg... ) vcos_log_info( "%s:%d " fmt, __func__, __LINE__, ##arg)
+- #define LOG_DBG( fmt, arg... ) vcos_log_info( "%s:%d " fmt, __func__, __LINE__, ##arg)
++ #define LOG_ERR( fmt, arg... )
++ #define LOG_WARN( fmt, arg... )
++ #define LOG_INFO( fmt, arg... )
++ #define LOG_DBG( fmt, arg... )
+ #endif
+
+ typedef struct opaque_AUDIO_INSTANCE_T {
+ uint32_t num_connections;
+ VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS];
+- VCOS_EVENT_T msg_avail_event;
+- VCOS_MUTEX_T vchi_mutex;
++ struct semaphore msg_avail_event;
++ struct mutex vchi_mutex;
+ bcm2835_alsa_stream_t *alsa_stream;
+ int32_t result, got_result;
+ } AUDIO_INSTANCE_T;
+
+ /* ---- Private Variables ---------------------------------------------------- */
+
+-/* VCOS logging category for this service */
+-static VCOS_LOG_CAT_T audio_log_category;
+-
+ /* ---- Private Function Prototypes ------------------------------------------ */
+
+ /* ---- Private Functions ---------------------------------------------------- */
+@@ -186,7 +176,7 @@ static void audio_vchi_callback(void *param,
+ BUG_ON(instance->got_result);
+ instance->result = m.u.result.success;
+ instance->got_result = 1;
+- vcos_event_signal(&instance->msg_avail_event);
++ up(&instance->msg_avail_event);
+ } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) {
+ irq_handler_t callback = (irq_handler_t) m.u.complete.callback;
+ LOG_DBG
+@@ -199,7 +189,7 @@ static void audio_vchi_callback(void *param,
+ LOG_DBG(" .. unexpected alsa_stream=%p, callback=%p\n",
+ alsa_stream, callback);
+ }
+- vcos_event_signal(&instance->msg_avail_event);
++ up(&instance->msg_avail_event);
+ } else {
+ LOG_DBG(" .. unexpected m.type=%d\n", m.type);
+ }
+@@ -212,7 +202,7 @@ static AUDIO_INSTANCE_T *vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance,
+ {
+ uint32_t i;
+ AUDIO_INSTANCE_T *instance;
+- VCOS_STATUS_T status;
++ int status;
+
+ LOG_DBG("%s: start", __func__);
+
+@@ -223,27 +213,16 @@ static AUDIO_INSTANCE_T *vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance,
+ return NULL;
+ }
+ /* Allocate memory for this instance */
+- instance = vcos_malloc(sizeof(*instance), "audio_instance");
++ instance = kmalloc(sizeof(*instance), GFP_KERNEL);
++
+ memset(instance, 0, sizeof(*instance));
+
+ instance->num_connections = num_connections;
+ /* Create the message available event */
+- status =
+- vcos_event_create(&instance->msg_avail_event, "audio_msg_avail");
+- if (status != VCOS_SUCCESS) {
+- LOG_ERR("%s: failed to create event (status=%d)", __func__,
+- status);
++ sema_init(&instance->msg_avail_event,1);
+
+- goto err_free_mem;
+- }
+ /* Create a lock for exclusive, serialized VCHI connection access */
+- status = vcos_mutex_create(&instance->vchi_mutex, "audio_vchi_mutex");
+- if (status != VCOS_SUCCESS) {
+- LOG_ERR("%s: failed to create event (status=%d)", __func__,
+- status);
+-
+- goto err_delete_event;
+- }
++ mutex_init(&instance->vchi_mutex);
+ /* Open the VCHI service connections */
+ for (i = 0; i < num_connections; i++) {
+ SERVICE_CREATION_T params = {
+@@ -253,14 +232,14 @@ static AUDIO_INSTANCE_T *vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance,
+ 0, // tx fifo size (unused)
+ audio_vchi_callback, // service callback
+ instance, // service callback parameter
+- VCOS_TRUE, //TODO: remove VCOS_FALSE, // unaligned bulk recieves
+- VCOS_TRUE, //TODO: remove VCOS_FALSE, // unaligned bulk transmits
+- VCOS_FALSE // want crc check on bulk transfers
++ 1, //TODO: remove VCOS_FALSE, // unaligned bulk recieves
++ 1, //TODO: remove VCOS_FALSE, // unaligned bulk transmits
++ 0 // want crc check on bulk transfers
+ };
+
+ status = vchi_service_open(vchi_instance, &params,
+ &instance->vchi_handle[i]);
+- if (status != VCOS_SUCCESS) {
++ if (status) {
+ LOG_ERR
+ ("%s: failed to open VCHI service connection (status=%d)",
+ __func__, status);
+@@ -278,13 +257,7 @@ err_close_services:
+ vchi_service_close(instance->vchi_handle[i]);
+ }
+
+- vcos_mutex_delete(&instance->vchi_mutex);
+-
+-err_delete_event:
+- vcos_event_delete(&instance->msg_avail_event);
+-
+-err_free_mem:
+- vcos_free(instance);
++ kfree(instance);
+
+ return NULL;
+ }
+@@ -302,7 +275,11 @@ static int32_t vc_vchi_audio_deinit(AUDIO_INSTANCE_T * instance)
+ }
+
+ LOG_DBG(" .. about to lock (%d)\n", instance->num_connections);
+- vcos_mutex_lock(&instance->vchi_mutex);
++ if(mutex_lock_interruptible(&instance->vchi_mutex))
++ {
++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections);
++ return -EINTR;
++ }
+
+ /* Close all VCHI service connections */
+ for (i = 0; i < instance->num_connections; i++) {
+@@ -318,16 +295,9 @@ static int32_t vc_vchi_audio_deinit(AUDIO_INSTANCE_T * instance)
+ }
+ }
+
+- vcos_mutex_unlock(&instance->vchi_mutex);
++ mutex_unlock(&instance->vchi_mutex);
+
+- vcos_mutex_delete(&instance->vchi_mutex);
+-
+- vcos_event_delete(&instance->msg_avail_event);
+-
+- vcos_free(instance);
+-
+- /* Unregister the log category so we can add it back next time */
+- vcos_log_unregister(&audio_log_category);
++ kfree(instance);
+
+ LOG_DBG(" .. OUT\n");
+
+@@ -371,10 +341,6 @@ static int bcm2835_audio_open_connection(bcm2835_alsa_stream_t * alsa_stream)
+ goto err_free_mem;
+ }
+
+- /* Set up the VCOS logging */
+- vcos_log_set_level(VCOS_LOG_CATEGORY, LOG_LEVEL);
+- vcos_log_register("audio", VCOS_LOG_CATEGORY);
+-
+ /* Initialize an instance of the audio service */
+ instance = vc_vchi_audio_init(vchi_instance, &vchi_connection, 1);
+
+@@ -412,7 +378,11 @@ int bcm2835_audio_open(bcm2835_alsa_stream_t * alsa_stream)
+ }
+ instance = alsa_stream->instance;
+
+- vcos_mutex_lock(&instance->vchi_mutex);
++ if(mutex_lock_interruptible(&instance->vchi_mutex))
++ {
++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections);
++ return -EINTR;
++ }
+ vchi_service_use(instance->vchi_handle[0]);
+
+ m.type = VC_AUDIO_MSG_TYPE_OPEN;
+@@ -434,7 +404,7 @@ int bcm2835_audio_open(bcm2835_alsa_stream_t * alsa_stream)
+
+ unlock:
+ vchi_service_release(instance->vchi_handle[0]);
+- vcos_mutex_unlock(&instance->vchi_mutex);
++ mutex_unlock(&instance->vchi_mutex);
+ exit:
+ LOG_DBG(" .. OUT\n");
+ return ret;
+@@ -452,7 +422,11 @@ static int bcm2835_audio_set_ctls_chan(bcm2835_alsa_stream_t * alsa_stream,
+ LOG_INFO
+ (" Setting ALSA dest(%d), volume(%d)\n", chip->dest, chip->volume);
+
+- vcos_mutex_lock(&instance->vchi_mutex);
++ if(mutex_lock_interruptible(&instance->vchi_mutex))
++ {
++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections);
++ return -EINTR;
++ }
+ vchi_service_use(instance->vchi_handle[0]);
+
+ instance->got_result = 0;
+@@ -477,8 +451,7 @@ static int bcm2835_audio_set_ctls_chan(bcm2835_alsa_stream_t * alsa_stream,
+
+ /* We are expecting a reply from the videocore */
+ while (!instance->got_result) {
+- success = vcos_event_wait(&instance->msg_avail_event);
+- if (success != VCOS_SUCCESS) {
++ if (down_interruptible(&instance->msg_avail_event)) {
+ LOG_ERR("%s: failed on waiting for event (status=%d)",
+ __func__, success);
+
+@@ -498,7 +471,7 @@ static int bcm2835_audio_set_ctls_chan(bcm2835_alsa_stream_t * alsa_stream,
+
+ unlock:
+ vchi_service_release(instance->vchi_handle[0]);
+- vcos_mutex_unlock(&instance->vchi_mutex);
++ mutex_unlock(&instance->vchi_mutex);
+
+ LOG_DBG(" .. OUT\n");
+ return ret;
+@@ -552,7 +525,11 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream,
+ return -EINVAL;
+ }
+
+- vcos_mutex_lock(&instance->vchi_mutex);
++ if(mutex_lock_interruptible(&instance->vchi_mutex))
++ {
++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections);
++ return -EINTR;
++ }
+ vchi_service_use(instance->vchi_handle[0]);
+
+ instance->got_result = 0;
+@@ -578,8 +555,7 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream,
+
+ /* We are expecting a reply from the videocore */
+ while (!instance->got_result) {
+- success = vcos_event_wait(&instance->msg_avail_event);
+- if (success != VCOS_SUCCESS) {
++ if (down_interruptible(&instance->msg_avail_event)) {
+ LOG_ERR("%s: failed on waiting for event (status=%d)",
+ __func__, success);
+
+@@ -599,7 +575,7 @@ int bcm2835_audio_set_params(bcm2835_alsa_stream_t * alsa_stream,
+
+ unlock:
+ vchi_service_release(instance->vchi_handle[0]);
+- vcos_mutex_unlock(&instance->vchi_mutex);
++ mutex_unlock(&instance->vchi_mutex);
+
+ LOG_DBG(" .. OUT\n");
+ return ret;
+@@ -622,7 +598,11 @@ static int bcm2835_audio_start_worker(bcm2835_alsa_stream_t * alsa_stream)
+ int ret;
+ LOG_DBG(" .. IN\n");
+
+- vcos_mutex_lock(&instance->vchi_mutex);
++ if(mutex_lock_interruptible(&instance->vchi_mutex))
++ {
++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections);
++ return -EINTR;
++ }
+ vchi_service_use(instance->vchi_handle[0]);
+
+ m.type = VC_AUDIO_MSG_TYPE_START;
+@@ -644,7 +624,7 @@ static int bcm2835_audio_start_worker(bcm2835_alsa_stream_t * alsa_stream)
+
+ unlock:
+ vchi_service_release(instance->vchi_handle[0]);
+- vcos_mutex_unlock(&instance->vchi_mutex);
++ mutex_unlock(&instance->vchi_mutex);
+ LOG_DBG(" .. OUT\n");
+ return ret;
+ }
+@@ -657,7 +637,11 @@ static int bcm2835_audio_stop_worker(bcm2835_alsa_stream_t * alsa_stream)
+ int ret;
+ LOG_DBG(" .. IN\n");
+
+- vcos_mutex_lock(&instance->vchi_mutex);
++ if(mutex_lock_interruptible(&instance->vchi_mutex))
++ {
++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections);
++ return -EINTR;
++ }
+ vchi_service_use(instance->vchi_handle[0]);
+
+ m.type = VC_AUDIO_MSG_TYPE_STOP;
+@@ -680,7 +664,7 @@ static int bcm2835_audio_stop_worker(bcm2835_alsa_stream_t * alsa_stream)
+
+ unlock:
+ vchi_service_release(instance->vchi_handle[0]);
+- vcos_mutex_unlock(&instance->vchi_mutex);
++ mutex_unlock(&instance->vchi_mutex);
+ LOG_DBG(" .. OUT\n");
+ return ret;
+ }
+@@ -695,7 +679,11 @@ int bcm2835_audio_close(bcm2835_alsa_stream_t * alsa_stream)
+
+ my_workqueue_quit(alsa_stream);
+
+- vcos_mutex_lock(&instance->vchi_mutex);
++ if(mutex_lock_interruptible(&instance->vchi_mutex))
++ {
++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections);
++ return -EINTR;
++ }
+ vchi_service_use(instance->vchi_handle[0]);
+
+ m.type = VC_AUDIO_MSG_TYPE_CLOSE;
+@@ -712,8 +700,7 @@ int bcm2835_audio_close(bcm2835_alsa_stream_t * alsa_stream)
+ goto unlock;
+ }
+ while (!instance->got_result) {
+- success = vcos_event_wait(&instance->msg_avail_event);
+- if (success != VCOS_SUCCESS) {
++ if (down_interruptible(&instance->msg_avail_event)) {
+ LOG_ERR("%s: failed on waiting for event (status=%d)",
+ __func__, success);
+
+@@ -733,7 +720,7 @@ int bcm2835_audio_close(bcm2835_alsa_stream_t * alsa_stream)
+
+ unlock:
+ vchi_service_release(instance->vchi_handle[0]);
+- vcos_mutex_unlock(&instance->vchi_mutex);
++ mutex_unlock(&instance->vchi_mutex);
+
+ /* Stop the audio service */
+ if (instance) {
+@@ -756,7 +743,11 @@ int bcm2835_audio_write(bcm2835_alsa_stream_t * alsa_stream, uint32_t count,
+
+ LOG_INFO(" Writing %d bytes from %p\n", count, src);
+
+- vcos_mutex_lock(&instance->vchi_mutex);
++ if(mutex_lock_interruptible(&instance->vchi_mutex))
++ {
++ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",instance->num_connections);
++ return -EINTR;
++ }
+ vchi_service_use(instance->vchi_handle[0]);
+
+ m.type = VC_AUDIO_MSG_TYPE_WRITE;
+@@ -801,7 +792,7 @@ int bcm2835_audio_write(bcm2835_alsa_stream_t * alsa_stream, uint32_t count,
+
+ unlock:
+ vchi_service_release(instance->vchi_handle[0]);
+- vcos_mutex_unlock(&instance->vchi_mutex);
++ mutex_unlock(&instance->vchi_mutex);
+ LOG_DBG(" .. OUT\n");
+ return ret;
+ }
diff --git a/patches/linux-3.6.7/0149-Fix-Kernel-OOPS-in-SDHCI-on-boot-with-the-llm-patch..patch b/patches/linux-3.6.7/0149-Fix-Kernel-OOPS-in-SDHCI-on-boot-with-the-llm-patch..patch
new file mode 100644
index 0000000..d7e8f07
--- /dev/null
+++ b/patches/linux-3.6.7/0149-Fix-Kernel-OOPS-in-SDHCI-on-boot-with-the-llm-patch..patch
@@ -0,0 +1,45 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Sat, 22 Sep 2012 18:56:57 +0100
+Subject: [PATCH] Fix Kernel OOPS in SDHCI on boot with the llm patch. Thanks
+ ddv2005
+
+---
+ drivers/mmc/host/sdhci.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index 4500ef7..9b7a727 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -144,9 +144,9 @@ void sdhci_spin_unlock(struct sdhci_host *host)
+ if(enable_llm)
+ {
+ local_irq_disable();
+- enable_irq(host->irq);
+ if(host->second_irq)
+ enable_irq(host->second_irq);
++ enable_irq(host->irq);
+ }
+ #endif
+ spin_unlock(&host->lock);
+@@ -178,9 +178,9 @@ void sdhci_spin_unlock_irqrestore(struct sdhci_host *host,unsigned long flags)
+ if(enable_llm)
+ {
+ local_irq_disable();
+- enable_irq(host->irq);
+ if(host->second_irq)
+ enable_irq(host->second_irq);
++ enable_irq(host->irq);
+ }
+ #endif
+ spin_unlock_irqrestore(&host->lock,flags);
+@@ -291,9 +291,7 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
+ return;
+ }
+ timeout--;
+- sdhci_spin_enable_schedule(host);
+ mdelay(1);
+- sdhci_spin_disable_schedule(host);
+ }
+
+ if (host->ops->platform_reset_exit)
diff --git a/patches/linux-3.6.7/0150-Use-system-timer-for-udelay-so-unaffected-by-cpufreq.patch b/patches/linux-3.6.7/0150-Use-system-timer-for-udelay-so-unaffected-by-cpufreq.patch
new file mode 100644
index 0000000..0afef5d
--- /dev/null
+++ b/patches/linux-3.6.7/0150-Use-system-timer-for-udelay-so-unaffected-by-cpufreq.patch
@@ -0,0 +1,49 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Mon, 24 Sep 2012 23:40:21 +0100
+Subject: [PATCH] Use system timer for udelay, so unaffected by cpufreq
+
+---
+ arch/arm/mach-bcm2708/bcm2708.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
+index 72dcf31..c9d6bd1 100644
+--- a/arch/arm/mach-bcm2708/bcm2708.c
++++ b/arch/arm/mach-bcm2708/bcm2708.c
+@@ -859,6 +859,36 @@ static inline void bcm2708_init_led(void)
+ }
+ #endif
+
++
++/* The assembly versions in delay.S don't account for core freq changing in cpufreq driver */
++/* Use 1MHz system timer for busy waiting */
++void __udelay(unsigned long usecs)
++{
++ unsigned long start = readl(__io_address(ST_BASE + 0x04));
++ unsigned long now;
++ do {
++ now = readl(__io_address(ST_BASE + 0x04));
++ } while ((long)(now - start) <= usecs);
++}
++
++
++void __const_udelay(unsigned long scaled_usecs)
++{
++ /* want /107374, this is about 3% bigger. We know usecs is less than 2000, so shouldn't overflow */
++ const unsigned long usecs = scaled_usecs * 10 >> 20;
++ unsigned long start = readl(__io_address(ST_BASE + 0x04));
++ unsigned long now;
++ do {
++ now = readl(__io_address(ST_BASE + 0x04));
++ } while ((long)(now - start) <= usecs);
++}
++
++void __delay(int loops)
++{
++ while (--loops > 0)
++ nop();
++}
++
+ MACHINE_START(BCM2708, "BCM2708")
+ /* Maintainer: Broadcom Europe Ltd. */
+ .map_io = bcm2708_map_io,.init_irq = bcm2708_init_irq,.timer =
diff --git a/patches/linux-3.6.7/0151-Move-__delay-function-into-assembly-to-get-accurate-.patch b/patches/linux-3.6.7/0151-Move-__delay-function-into-assembly-to-get-accurate-.patch
new file mode 100644
index 0000000..1b8a9b1
--- /dev/null
+++ b/patches/linux-3.6.7/0151-Move-__delay-function-into-assembly-to-get-accurate-.patch
@@ -0,0 +1,67 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Wed, 26 Sep 2012 13:46:03 +0100
+Subject: [PATCH] Move __delay function into assembly to get accurate BogoMips
+
+---
+ arch/arm/mach-bcm2708/Makefile | 2 +-
+ arch/arm/mach-bcm2708/bcm2708.c | 6 ------
+ arch/arm/mach-bcm2708/delay.S | 20 ++++++++++++++++++++
+ 3 files changed, 21 insertions(+), 7 deletions(-)
+ create mode 100644 arch/arm/mach-bcm2708/delay.S
+
+diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile
+index 164ecb2..3ee8a4b 100644
+--- a/arch/arm/mach-bcm2708/Makefile
++++ b/arch/arm/mach-bcm2708/Makefile
+@@ -2,7 +2,7 @@
+ # Makefile for the linux kernel.
+ #
+
+-obj-$(CONFIG_MACH_BCM2708) += clock.o bcm2708.o armctrl.o vcio.o power.o dma.o
++obj-$(CONFIG_MACH_BCM2708) += clock.o bcm2708.o armctrl.o vcio.o power.o dma.o delay.o
+ obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o
+ obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o
+
+diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
+index c9d6bd1..ac118a4 100644
+--- a/arch/arm/mach-bcm2708/bcm2708.c
++++ b/arch/arm/mach-bcm2708/bcm2708.c
+@@ -883,12 +883,6 @@ void __const_udelay(unsigned long scaled_usecs)
+ } while ((long)(now - start) <= usecs);
+ }
+
+-void __delay(int loops)
+-{
+- while (--loops > 0)
+- nop();
+-}
+-
+ MACHINE_START(BCM2708, "BCM2708")
+ /* Maintainer: Broadcom Europe Ltd. */
+ .map_io = bcm2708_map_io,.init_irq = bcm2708_init_irq,.timer =
+diff --git a/arch/arm/mach-bcm2708/delay.S b/arch/arm/mach-bcm2708/delay.S
+new file mode 100644
+index 0000000..4256d29
+--- /dev/null
++++ b/arch/arm/mach-bcm2708/delay.S
+@@ -0,0 +1,20 @@
++/*
++ * 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
++@ Delay routine
++ENTRY(__delay)
++ subs r0, r0, #1
++ bhi __delay
++ mov pc, lr
++ENDPROC(__delay)
diff --git a/patches/linux-3.6.7/0152-set-i2c-speed-via-module-parameter-or-menuconfig.-Th.patch b/patches/linux-3.6.7/0152-set-i2c-speed-via-module-parameter-or-menuconfig.-Th.patch
new file mode 100644
index 0000000..61ede15
--- /dev/null
+++ b/patches/linux-3.6.7/0152-set-i2c-speed-via-module-parameter-or-menuconfig.-Th.patch
@@ -0,0 +1,73 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Wed, 3 Oct 2012 20:08:19 +0100
+Subject: [PATCH] set i2c speed via module-parameter or menuconfig. Thanks
+ FrankBoesing
+
+---
+ drivers/i2c/busses/Kconfig | 11 +++++++++++
+ drivers/i2c/busses/i2c-bcm2708.c | 12 ++++++++----
+ 2 files changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
+index 99cb85b..3d7b81d 100644
+--- a/drivers/i2c/busses/Kconfig
++++ b/drivers/i2c/busses/Kconfig
+@@ -322,6 +322,17 @@ config I2C_BCM2708
+ support for the BCM2708. BSC is a Broadcom proprietary bus compatible
+ with I2C/TWI/SMBus.
+
++config I2C_BCM2708_BAUDRATE
++ prompt "BCM2708 I2C baudrate"
++ depends on I2C_BCM2708
++ int
++ default 100000
++ help
++ Set the I2C baudrate. This will alter the default value. A
++ different baudrate can be set by using a module parameter as well. If
++ no parameter is provided when loading, this is the value that will be
++ used.
++
+ config I2C_BLACKFIN_TWI
+ tristate "Blackfin TWI I2C support"
+ depends on BLACKFIN
+diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c
+index 70e8d29..63414a3 100644
+--- a/drivers/i2c/busses/i2c-bcm2708.c
++++ b/drivers/i2c/busses/i2c-bcm2708.c
+@@ -66,11 +66,15 @@
+ #define BSC_S_DONE 0x00000002
+ #define BSC_S_TA 0x00000001
+
+-#define I2C_CLOCK_HZ 100000 /* FIXME: get from DT */
+ #define I2C_TIMEOUT_MS 150
+
+ #define DRV_NAME "bcm2708_i2c"
+
++static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE;
++module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
++MODULE_PARM_DESC(baudrate, "The I2C baudrate");
++
++
+ struct bcm2708_i2c {
+ struct i2c_adapter adapter;
+
+@@ -148,7 +152,7 @@ static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi)
+ u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1;
+
+ bus_hz = clk_get_rate(bi->clk);
+- cdiv = bus_hz / I2C_CLOCK_HZ;
++ cdiv = bus_hz / baudrate;
+
+ if (bi->msg->flags & I2C_M_RD)
+ c |= BSC_C_INTR | BSC_C_READ;
+@@ -331,8 +335,8 @@ static int __devinit bcm2708_i2c_probe(struct platform_device *pdev)
+ goto out_free_irq;
+ }
+
+- dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d)\n",
+- pdev->id, (unsigned long)regs->start, irq);
++ dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %dk)\n",
++ pdev->id, (unsigned long)regs->start, irq, baudrate/1000);
+
+ return 0;
+
diff --git a/patches/linux-3.6.7/0153-Allow-the-number-of-cycles-delay-between-sdcard-peri.patch b/patches/linux-3.6.7/0153-Allow-the-number-of-cycles-delay-between-sdcard-peri.patch
new file mode 100644
index 0000000..5023e16
--- /dev/null
+++ b/patches/linux-3.6.7/0153-Allow-the-number-of-cycles-delay-between-sdcard-peri.patch
@@ -0,0 +1,40 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Wed, 3 Oct 2012 21:31:48 +0100
+Subject: [PATCH] Allow the number of cycles delay between sdcard peripheral
+ writes to be specified on command line with
+ sdhci-bcm2708.cycle_delay
+
+---
+ drivers/mmc/host/sdhci-bcm2708.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index 2703103..80e4228 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -82,6 +82,8 @@
+ #define REG_EXRDFIFO_EN 0x80
+ #define REG_EXRDFIFO_CFG 0x84
+
++int cycle_delay=2;
++
+ /*****************************************************************************\
+ * *
+ * Debug *
+@@ -254,7 +256,7 @@ static void sdhci_bcm2708_raw_writel(struct sdhci_host *host, u32 val, int reg)
+ /* host->clock is the clock freq in Hz */
+ static hptime_t last_write_hpt;
+ hptime_t now = hptime();
+- ns_2clk = 2000000000/host->clock;
++ ns_2clk = cycle_delay*1000000/(host->clock/1000);
+
+ if (now == last_write_hpt || now == last_write_hpt+1) {
+ /* we can't guarantee any significant time has
+@@ -1517,6 +1519,7 @@ module_param(emmc_clock_freq, int, 0444);
+ module_param(sync_after_dma, bool, 0444);
+ module_param(missing_status, bool, 0444);
+ module_param(enable_llm, bool, 0444);
++module_param(cycle_delay, int, 0444);
+
+ MODULE_DESCRIPTION("Secure Digital Host Controller Interface platform driver");
+ MODULE_AUTHOR("Broadcom <info@broadcom.com>");
diff --git a/patches/linux-3.6.7/0154-Fix-vc-mem-by-using-module-parameters.patch b/patches/linux-3.6.7/0154-Fix-vc-mem-by-using-module-parameters.patch
new file mode 100644
index 0000000..f7038d8
--- /dev/null
+++ b/patches/linux-3.6.7/0154-Fix-vc-mem-by-using-module-parameters.patch
@@ -0,0 +1,244 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Fri, 5 Oct 2012 17:41:53 +0100
+Subject: [PATCH] Fix vc-mem by using module parameters
+
+---
+ arch/arm/mach-bcm2708/bcm2708.c | 22 +++++----
+ arch/arm/mach-bcm2708/vc_mem.c | 99 +++++++++--------------------------------
+ 2 files changed, 35 insertions(+), 86 deletions(-)
+
+diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
+index ac118a4..93fb75d 100644
+--- a/arch/arm/mach-bcm2708/bcm2708.c
++++ b/arch/arm/mach-bcm2708/bcm2708.c
+@@ -77,6 +77,7 @@ static DEFINE_CLOCK_DATA(cd);
+
+ /* command line parameters */
+ static unsigned boardrev, serial;
++static unsigned uart_clock;
+
+ static void __init bcm2708_init_led(void);
+
+@@ -669,8 +670,12 @@ void __init bcm2708_init(void)
+ {
+ int i;
+
++ printk("bcm2708.uart_clock = %d\n", uart_clock);
+ pm_power_off = bcm2708_power_off;
+
++ if (uart_clock)
++ lookups[0].clk->rate = uart_clock;
++
+ for (i = 0; i < ARRAY_SIZE(lookups); i++)
+ clkdev_add(&lookups[i]);
+
+@@ -709,12 +714,6 @@ void __init bcm2708_init(void)
+ bcm_register_device(&bcm2835_hwmon_device);
+ bcm_register_device(&bcm2835_thermal_device);
+
+-#ifdef CONFIG_BCM2708_VCMEM
+- {
+- extern void vc_mem_connected_init(void);
+- vc_mem_connected_init();
+- }
+-#endif
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+@@ -885,7 +884,12 @@ void __const_udelay(unsigned long scaled_usecs)
+
+ MACHINE_START(BCM2708, "BCM2708")
+ /* Maintainer: Broadcom Europe Ltd. */
+- .map_io = bcm2708_map_io,.init_irq = bcm2708_init_irq,.timer =
+- &bcm2708_timer,.init_machine =
+- bcm2708_init, MACHINE_END module_param(boardrev, uint, 0644);
++ .map_io = bcm2708_map_io,
++ .init_irq = bcm2708_init_irq,
++ .timer =&bcm2708_timer,
++ .init_machine =bcm2708_init,
++MACHINE_END
++
++module_param(boardrev, uint, 0644);
+ module_param(serial, uint, 0644);
++module_param(uart_clock, uint, 0644);
+diff --git a/arch/arm/mach-bcm2708/vc_mem.c b/arch/arm/mach-bcm2708/vc_mem.c
+index ae1810c..5c56b31 100644
+--- a/arch/arm/mach-bcm2708/vc_mem.c
++++ b/arch/arm/mach-bcm2708/vc_mem.c
+@@ -36,7 +36,7 @@
+ #define DRIVER_NAME "vc-mem"
+
+ // Uncomment to enable debug logging
+-#define ENABLE_DBG
++// #define ENABLE_DBG
+
+ #if defined(ENABLE_DBG)
+ #define LOG_DBG( fmt, ... ) printk( KERN_INFO fmt "\n", ##__VA_ARGS__ )
+@@ -77,6 +77,11 @@ 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
+@@ -111,53 +116,6 @@ vc_mem_release(struct inode *inode, struct file *file)
+ return 0;
+ }
+
+-
+-/* tag part of the message */
+-struct vc_msg_tag {
+- uint32_t tag_id; /* the message id */
+- uint32_t buffer_size; /* size of the buffer (which in this case is always 8 bytes) */
+- uint32_t data_size; /* amount of data being sent or received */
+- uint32_t base; /* the address of memory base */
+- uint32_t size; /* the size of memory in bytes */
+-};
+-
+-struct vc_set_msg {
+- uint32_t msg_size; /* simply, sizeof(struct vc_msg) */
+- uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */
+- struct vc_msg_tag tag[2]; /* the array of tag structures above to make */
+- uint32_t end_tag; /* an end identifier, should be set to NULL */
+-};
+-
+-static void vc_mem_update(void)
+-{
+- struct vc_set_msg msg; /* the memory address accessed from driver */
+- uint32_t s;
+-
+- memset(&msg, 0, sizeof msg);
+- /* create the message */
+- msg.msg_size = sizeof msg;
+- msg.tag[0].tag_id = VCMSG_GET_VC_MEMORY;
+- msg.tag[0].buffer_size = 8;
+- msg.tag[0].data_size = 0;
+- msg.tag[1].tag_id = VCMSG_GET_ARM_MEMORY;
+- msg.tag[1].buffer_size = 8;
+- msg.tag[1].data_size = 0;
+-
+- /* send the message */
+- s = bcm_mailbox_property(&msg, sizeof msg);
+-
+- LOG_DBG("%s: success=%d resp %x, vcbase=%x vcsize=%x armbase=%x armsize=%x", __func__, s, msg.request_code,
+- msg.tag[0].base, msg.tag[0].size, msg.tag[1].base, msg.tag[1].size);
+-
+- /* check we're all good */
+- if (s == 0 && msg.request_code & 0x80000000) {
+- mm_vc_mem_base = msg.tag[0].base;
+- mm_vc_mem_size = msg.tag[0].size+msg.tag[1].size;
+- mm_vc_mem_phys_addr = msg.tag[1].base;
+- }
+-}
+-
+-
+ /****************************************************************************
+ *
+ * vc_mem_get_size
+@@ -167,7 +125,6 @@ static void vc_mem_update(void)
+ static void
+ vc_mem_get_size(void)
+ {
+- vc_mem_update();
+ }
+
+ /****************************************************************************
+@@ -179,7 +136,6 @@ vc_mem_get_size(void)
+ static void
+ vc_mem_get_base(void)
+ {
+- vc_mem_update();
+ }
+
+ /****************************************************************************
+@@ -191,7 +147,6 @@ vc_mem_get_base(void)
+ int
+ vc_mem_get_current_size(void)
+ {
+- vc_mem_get_size();
+ return mm_vc_mem_size;
+ }
+
+@@ -382,25 +337,26 @@ vc_mem_proc_write(struct file *file, const char __user * buffer,
+
+ /****************************************************************************
+ *
+-* vc_mem_connected_init
+-*
+-* This function is called once the videocore has been connected.
++* vc_mem_init
+ *
+ ***************************************************************************/
+
+-void
+-vc_mem_connected_init(void)
++static int __init
++vc_mem_init(void)
+ {
+ int rc = -EFAULT;
+ struct device *dev;
+
+ LOG_DBG("%s: called", __func__);
+
++ mm_vc_mem_phys_addr = phys_addr;
++ mm_vc_mem_size = mem_size;
++ mm_vc_mem_base = mem_base;
++
+ vc_mem_get_size();
+
+- printk("vc-mem: mm_vc_mem_phys_addr = 0x%08lx\n", mm_vc_mem_phys_addr);
+- printk("vc-mem: mm_vc_mem_size = 0x%08x (%u MiB)\n",
+- mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024));
++ printk("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) {
+ LOG_ERR("%s: alloc_chrdev_region failed (rc=%d)", __func__, rc);
+@@ -438,7 +394,7 @@ vc_mem_connected_init(void)
+ vc_mem_proc_entry->write_proc = vc_mem_proc_write;
+
+ vc_mem_inited = 1;
+- return;
++ return 0;
+
+ out_device_destroy:
+ device_destroy(vc_mem_class, vc_mem_devnum);
+@@ -454,23 +410,7 @@ vc_mem_connected_init(void)
+ unregister_chrdev_region(vc_mem_devnum, 1);
+
+ out_err:
+- return;
+-}
+-
+-/****************************************************************************
+-*
+-* vc_mem_init
+-*
+-***************************************************************************/
+-
+-static int __init
+-vc_mem_init(void)
+-{
+- printk(KERN_INFO "vc-mem: Videocore memory driver\n");
+-
+- //vchiq_add_connected_callback(vc_mem_connected_init);
+-
+- return 0;
++ return -1;
+ }
+
+ /****************************************************************************
+@@ -497,3 +437,8 @@ 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);
++
diff --git a/patches/linux-3.6.7/0155-Move-to-version-5-of-VCHIQ.-Note-this-requires-a-cor.patch b/patches/linux-3.6.7/0155-Move-to-version-5-of-VCHIQ.-Note-this-requires-a-cor.patch
new file mode 100644
index 0000000..59bcdd3
--- /dev/null
+++ b/patches/linux-3.6.7/0155-Move-to-version-5-of-VCHIQ.-Note-this-requires-a-cor.patch
@@ -0,0 +1,25103 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Fri, 5 Oct 2012 17:43:41 +0100
+Subject: [PATCH] Move to version 5 of VCHIQ. Note: this requires a
+ corresponding start.elf and /opt/vc/lib update
+
+---
+ drivers/misc/vc04_services/Kconfig | 9 +-
+ drivers/misc/vc04_services/Makefile | 100 +-
+ .../interface/vchi/connections/connection.h | 28 +-
+ .../interface/vchi/message_drivers/message.h | 21 +-
+ drivers/misc/vc04_services/interface/vchi/vchi.h | 44 +-
+ .../misc/vc04_services/interface/vchi/vchi_cfg.h | 7 +-
+ .../interface/vchi/vchi_cfg_internal.h | 2 +-
+ .../vc04_services/interface/vchi/vchi_common.h | 6 +-
+ .../misc/vc04_services/interface/vchi/vchi_mh.h | 2 +-
+ .../misc/vc04_services/interface/vchiq_arm/vchiq.h | 1 -
+ .../interface/vchiq_arm/vchiq_2835_arm.c | 278 +-
+ .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 4018 ++++++++------
+ .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 157 +-
+ .../vc04_services/interface/vchiq_arm/vchiq_cfg.h | 10 +-
+ .../interface/vchiq_arm/vchiq_connected.c | 99 +-
+ .../interface/vchiq_arm/vchiq_connected.h | 6 +-
+ .../vc04_services/interface/vchiq_arm/vchiq_core.c | 5717 ++++++++++++--------
+ .../vc04_services/interface/vchiq_arm/vchiq_core.h | 667 ++-
+ .../vc04_services/interface/vchiq_arm/vchiq_if.h | 186 +-
+ .../interface/vchiq_arm/vchiq_ioctl.h | 91 +-
+ .../interface/vchiq_arm/vchiq_kern_lib.c | 292 +-
+ .../vc04_services/interface/vchiq_arm/vchiq_lib.c | 1628 ------
+ .../interface/vchiq_arm/vchiq_memdrv.h | 29 +-
+ .../vc04_services/interface/vchiq_arm/vchiq_shim.c | 1058 ++--
+ .../vc04_services/interface/vchiq_arm/vchiq_util.c | 94 +-
+ .../vc04_services/interface/vchiq_arm/vchiq_util.h | 34 +-
+ .../interface/vcos/generic/vcos_cmd.c | 681 ---
+ .../interface/vcos/generic/vcos_common.h | 87 -
+ .../vcos/generic/vcos_generic_blockpool.h | 271 -
+ .../vcos/generic/vcos_generic_event_flags.c | 311 --
+ .../vcos/generic/vcos_generic_event_flags.h | 118 -
+ .../vcos/generic/vcos_generic_named_sem.h | 92 -
+ .../vcos/generic/vcos_generic_quickslow_mutex.h | 86 -
+ .../vcos/generic/vcos_generic_reentrant_mtx.h | 86 -
+ .../interface/vcos/generic/vcos_generic_tls.h | 155 -
+ .../vcos/generic/vcos_joinable_thread_from_plain.h | 214 -
+ .../interface/vcos/generic/vcos_latch_from_sem.h | 59 -
+ .../interface/vcos/generic/vcos_logcat.c | 560 --
+ .../interface/vcos/generic/vcos_mem_from_malloc.c | 84 -
+ .../interface/vcos/generic/vcos_mem_from_malloc.h | 65 -
+ .../vcos/generic/vcos_mutexes_are_reentrant.h | 79 -
+ .../interface/vcos/generic/vcos_thread_reaper.h | 46 -
+ .../interface/vcos/linuxkernel/stdint.h | 31 -
+ .../interface/vcos/linuxkernel/vcos_linuxkernel.c | 627 ---
+ .../vcos/linuxkernel/vcos_linuxkernel_cfg.c | 332 --
+ .../vcos/linuxkernel/vcos_linuxkernel_misc.c | 111 -
+ .../interface/vcos/linuxkernel/vcos_mod_init.c | 64 -
+ .../interface/vcos/linuxkernel/vcos_platform.h | 507 --
+ .../vcos/linuxkernel/vcos_platform_types.h | 59 -
+ .../interface/vcos/linuxkernel/vcos_thread_map.c | 129 -
+ .../interface/vcos/linuxkernel/vcos_thread_map.h | 39 -
+ drivers/misc/vc04_services/interface/vcos/vcos.h | 212 -
+ .../vc04_services/interface/vcos/vcos_assert.h | 280 -
+ .../interface/vcos/vcos_atomic_flags.h | 83 -
+ .../vc04_services/interface/vcos/vcos_build_info.h | 23 -
+ .../misc/vc04_services/interface/vcos/vcos_cfg.h | 113 -
+ .../misc/vc04_services/interface/vcos/vcos_cmd.h | 98 -
+ .../misc/vc04_services/interface/vcos/vcos_ctype.h | 40 -
+ .../misc/vc04_services/interface/vcos/vcos_dlfcn.h | 80 -
+ .../misc/vc04_services/interface/vcos/vcos_event.h | 108 -
+ .../interface/vcos/vcos_event_flags.h | 109 -
+ .../misc/vc04_services/interface/vcos/vcos_init.h | 54 -
+ .../vc04_services/interface/vcos/vcos_logging.h | 290 -
+ .../interface/vcos/vcos_lowlevel_thread.h | 118 -
+ .../misc/vc04_services/interface/vcos/vcos_mem.h | 92 -
+ .../vc04_services/interface/vcos/vcos_msgqueue.h | 168 -
+ .../misc/vc04_services/interface/vcos/vcos_mutex.h | 103 -
+ .../misc/vc04_services/interface/vcos/vcos_once.h | 53 -
+ .../vc04_services/interface/vcos/vcos_semaphore.h | 126 -
+ .../vc04_services/interface/vcos/vcos_stdbool.h | 34 -
+ .../vc04_services/interface/vcos/vcos_stdint.h | 203 -
+ .../vc04_services/interface/vcos/vcos_string.h | 84 -
+ .../vc04_services/interface/vcos/vcos_thread.h | 270 -
+ .../interface/vcos/vcos_thread_attr.h | 87 -
+ .../misc/vc04_services/interface/vcos/vcos_timer.h | 106 -
+ .../misc/vc04_services/interface/vcos/vcos_types.h | 211 -
+ sound/arm/bcm2835-vchiq.c | 1 +
+ sound/arm/vc_vchi_audioserv_defs.h | 2 +
+ 78 files changed, 7481 insertions(+), 15144 deletions(-)
+ mode change 100644 => 100755 drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
+ delete mode 100644 drivers/misc/vc04_services/interface/vchiq_arm/vchiq_lib.c
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_cmd.c
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_common.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_blockpool.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_event_flags.c
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_event_flags.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_named_sem.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_quickslow_mutex.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_reentrant_mtx.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_tls.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_joinable_thread_from_plain.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_latch_from_sem.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_logcat.c
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_mem_from_malloc.c
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_mem_from_malloc.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_mutexes_are_reentrant.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/generic/vcos_thread_reaper.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/linuxkernel/stdint.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel.c
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel_cfg.c
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel_misc.c
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_mod_init.c
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_platform.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_platform_types.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_thread_map.c
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_thread_map.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_assert.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_atomic_flags.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_build_info.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_cfg.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_cmd.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_ctype.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_dlfcn.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_event.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_event_flags.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_init.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_logging.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_lowlevel_thread.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_mem.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_msgqueue.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_mutex.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_once.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_semaphore.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_stdbool.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_stdint.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_string.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_thread.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_thread_attr.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_timer.h
+ delete mode 100644 drivers/misc/vc04_services/interface/vcos/vcos_types.h
+
+diff --git a/drivers/misc/vc04_services/Kconfig b/drivers/misc/vc04_services/Kconfig
+index d97a1e2..ff83aaa 100644
+--- a/drivers/misc/vc04_services/Kconfig
++++ b/drivers/misc/vc04_services/Kconfig
+@@ -1,7 +1,10 @@
+ config BCM2708_VCHIQ
+ tristate "Videocore VCHIQ"
+ depends on MACH_BCM2708
+- default y
+- help
+- Helper for communication for VideoCore.
++ default CONFIG_BCM_VC_SERVICES
++ help
++ Kernel to VideoCore communication interface for the
++ BCM2708 family of products.
++ Defaults to Y when the Broadcom Videocore services
++ are included in the build, N otherwise.
+
+diff --git a/drivers/misc/vc04_services/Makefile b/drivers/misc/vc04_services/Makefile
+index ee53af7..85b6ba3 100644
+--- a/drivers/misc/vc04_services/Makefile
++++ b/drivers/misc/vc04_services/Makefile
+@@ -1,21 +1,101 @@
++ifeq ($(CONFIG_MACH_BCM2708),y)
++
++##############################################################################
++#
++# This section is for building the RaspberryPi model
++#
++##############################################################################
++
+ obj-$(CONFIG_BCM2708_VCHIQ) += vchiq.o
+
+ vchiq-objs := \
+ interface/vchiq_arm/vchiq_core.o \
+- interface/vchiq_arm/vchiq_shim.o \
+- interface/vchiq_arm/vchiq_util.o \
+ interface/vchiq_arm/vchiq_arm.o \
+ interface/vchiq_arm/vchiq_kern_lib.o \
+ interface/vchiq_arm/vchiq_2835_arm.o \
+- interface/vcos/linuxkernel/vcos_linuxkernel.o \
+- interface/vcos/linuxkernel/vcos_thread_map.o \
+- interface/vcos/linuxkernel/vcos_linuxkernel_cfg.o \
+- interface/vcos/generic/vcos_generic_event_flags.o \
+- interface/vcos/generic/vcos_logcat.o \
+- interface/vcos/generic/vcos_mem_from_malloc.o \
+- interface/vcos/generic/vcos_cmd.o
++ interface/vchiq_arm/vchiq_proc.o \
++ interface/vchiq_arm/vchiq_shim.o \
++ interface/vchiq_arm/vchiq_util.o \
++ interface/vchiq_arm/vchiq_connected.o \
++
++EXTRA_CFLAGS += -DVCOS_VERIFY_BKPTS=1 -Idrivers/misc/vc04_services -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000
++
++endif
++
++ifeq ($(CONFIG_ARCH_KONA),y)
++
++##############################################################################
++#
++# This section is for building the Capri/Island model
++#
++##############################################################################
++
++# Remove the quotes from the platform config name
++VCHIQ_PLATFORM_CONFIG = $(patsubst "%",%,$(CONFIG_VCHIQ_PLATFORM_CFG_NAME))
++
++$(info VCHIQ_PLATFORM_CONFIG = $(VCHIQ_PLATFORM_CONFIG))
++include $(srctree)/drivers/misc/vc04_services/interface/vchiq_arm/platform-cfg/$(VCHIQ_PLATFORM_CONFIG).mk
++
++$(info Building for MAP build system)
++$(info CONFIG_ARCH_KONA = $(CONFIG_ARCH_KONA))
++
++EXTRA_CFLAGS += -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -Wno-declaration-after-statement -Wno-parentheses
++
++EXTRA_CFLAGS += -I"drivers/misc/vc04_services/"
++EXTRA_CFLAGS += -I"drivers/misc/vc04_services/interface/vchiq_arm"
++EXTRA_CFLAGS += -I"drivers/misc/vc04_services/interface/debug_sym"
++EXTRA_CFLAGS += -I"include/linux/broadcom"
++
++EXTRA_CFLAGS += -Werror
++
++VCHIQ_HOST_BUS_ALIGNMENT = 3
++
++EXTRA_CFLAGS += -DOS_ASSERT_FAILURE
++EXTRA_CFLAGS += -D__STDC_VERSION=199901L
++EXTRA_CFLAGS += -D__STDC_VERSION__=199901L
++EXTRA_CFLAGS += -D__VCCOREVER__=0
++EXTRA_CFLAGS += -D__linux__
++EXTRA_CFLAGS += -D__KERNEL__
++EXTRA_CFLAGS += -DVCHIQ_HOST_BUS_ALIGNMENT=$(VCHIQ_HOST_BUS_ALIGNMENT)
++EXTRA_CFLAGS += -DVCHIQ_SLOT_PADDING=16
++EXTRA_CFLAGS += -DVCHIQ_ARM_SIDE
++EXTRA_CFLAGS += -DUSE_VCHIQ_ARM
++ifeq ($(VCHIQ_SM_ALLOC),vcddr)
++EXTRA_CFLAGS += -DVCHIQ_SM_ALLOC_VCDDR
++endif
++
++obj-$(CONFIG_KONA_VCHIQ) += vc-vchiq.o
++vc-vchiq-objs := \
++ interface/vchiq_arm/vchiq_arm.o \
++ interface/vchiq_arm/vchiq_connected.o \
++ interface/vchiq_arm/vchiq_core.o \
++ interface/vchiq_arm/vchiq_kern_lib.o \
++ interface/vchiq_arm/vchiq_shim.o \
++ interface/vchiq_arm/vchiq_util.o \
++ interface/vchiq_arm/vchiq_kona_arm.o \
++ interface/vchiq_arm/vchiq_$(VCHIQ_PLATFORM)_arm.o \
++ interface/vchiq_arm/vchiq_version.o \
++ interface/vchiq_arm/vchiq_proc.o
++ifeq ($(VCHIQ_SM_ALLOC),vcddr)
++vc-vchiq-objs += \
++ interface/debug_sym/debug_sym.o
++endif
++
++obj-$(CONFIG_KONA_VCHIQ_MEMDRV) += vc-vchiq-memdrv-kona.o
++vc-vchiq-memdrv-kona-objs := \
++ interface/vchiq_arm/vchiq_memdrv_kona.o
++
++genversion = drivers/misc/vc04_services/interface/vchiq_arm/vchiq_genversion
+
+-EXTRA_CFLAGS += -DVCOS_VERIFY_BKPTS=1 -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -Idrivers/misc/vc04_services -Idrivers/misc/vc04_services/interface/vcos/linuxkernel
++GENVERSION_SRC_ROOT_DIR = .
++ifeq ($(CONFIG_ANDROID),y)
++GENVERSION_SRC_ROOT_DIR = $(srctree)
++endif
+
++$(obj)/interface/vchiq_arm/vchiq_version.c: $(genversion) FORCE
++ echo "(new) Generating $@ ..."
++ perl $(srctree)/$(genversion) vchiq $(GENVERSION_SRC_ROOT_DIR) > $@
+
++clean-files := vchiq_version.c
+
++endif
+diff --git a/drivers/misc/vc04_services/interface/vchi/connections/connection.h b/drivers/misc/vc04_services/interface/vchi/connections/connection.h
+index 2fe5742..f4e8225 100644
+--- a/drivers/misc/vc04_services/interface/vchi/connections/connection.h
++++ b/drivers/misc/vc04_services/interface/vchi/connections/connection.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2010-2011 Broadcom Corporation. All rights reserved.
++ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -19,6 +19,10 @@
+ #ifndef CONNECTION_H_
+ #define CONNECTION_H_
+
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/semaphore.h>
++
+ #include "interface/vchi/vchi_cfg_internal.h"
+ #include "interface/vchi/vchi_common.h"
+ #include "interface/vchi/message_drivers/message.h"
+@@ -50,15 +54,15 @@ typedef int32_t (*VCHI_CONNECTION_CRC_CONTROL_T)( VCHI_CONNECTION_STATE_T *state
+
+ // Routine to create a service
+ typedef int32_t (*VCHI_CONNECTION_SERVICE_CONNECT_T)( VCHI_CONNECTION_STATE_T *state_handle,
+- vcos_fourcc_t service_id,
++ int32_t service_id,
+ uint32_t rx_fifo_size,
+ uint32_t tx_fifo_size,
+ int server,
+ VCHI_CALLBACK_T callback,
+ void *callback_param,
+- vcos_bool_t want_crc,
+- vcos_bool_t want_unaligned_bulk_rx,
+- vcos_bool_t want_unaligned_bulk_tx,
++ int32_t want_crc,
++ int32_t want_unaligned_bulk_rx,
++ int32_t want_unaligned_bulk_tx,
+ VCHI_CONNECTION_SERVICE_HANDLE_T *service_handle );
+
+ // Routine to close a service
+@@ -116,7 +120,7 @@ typedef int32_t (*VCHI_CONNECTION_HELD_MSG_INFO_T)( VCHI_CONNECTION_SERVICE_HAND
+ uint32_t *rx_timestamp );
+
+ // Routine to check whether the iterator has a next message
+-typedef vcos_bool_t (*VCHI_CONNECTION_MSG_ITER_HAS_NEXT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service,
++typedef int32_t (*VCHI_CONNECTION_MSG_ITER_HAS_NEXT_T)( VCHI_CONNECTION_SERVICE_HANDLE_T service,
+ const VCHI_MSG_ITER_T *iter );
+
+ // Routine to advance the iterator
+@@ -149,7 +153,7 @@ typedef int32_t (*VCHI_CONNECTION_BULK_QUEUE_RECEIVE_T)( VCHI_CONNECTION_SERVICE
+ void *bulk_handle );
+
+ // Routine to report if a server is available
+-typedef int32_t (*VCHI_CONNECTION_SERVER_PRESENT)( VCHI_CONNECTION_STATE_T *state, vcos_fourcc_t service_id, int32_t peer_flags );
++typedef int32_t (*VCHI_CONNECTION_SERVER_PRESENT)( VCHI_CONNECTION_STATE_T *state, int32_t service_id, int32_t peer_flags );
+
+ // Routine to report the number of RX slots available
+ typedef int (*VCHI_CONNECTION_RX_SLOTS_AVAILABLE)( const VCHI_CONNECTION_STATE_T *state );
+@@ -159,7 +163,7 @@ typedef uint32_t (*VCHI_CONNECTION_RX_SLOT_SIZE)( const VCHI_CONNECTION_STATE_T
+
+ // Callback to indicate that the other side has added a buffer to the rx bulk DMA FIFO
+ typedef void (*VCHI_CONNECTION_RX_BULK_BUFFER_ADDED)(VCHI_CONNECTION_STATE_T *state,
+- vcos_fourcc_t service,
++ int32_t service,
+ uint32_t length,
+ MESSAGE_TX_CHANNEL_T channel,
+ uint32_t channel_params,
+@@ -167,10 +171,10 @@ typedef void (*VCHI_CONNECTION_RX_BULK_BUFFER_ADDED)(VCHI_CONNECTION_STATE_T *st
+ uint32_t data_offset);
+
+ // Callback to inform a service that a Xon or Xoff message has been received
+-typedef void (*VCHI_CONNECTION_FLOW_CONTROL)(VCHI_CONNECTION_STATE_T *state, vcos_fourcc_t service_id, int32_t xoff);
++typedef void (*VCHI_CONNECTION_FLOW_CONTROL)(VCHI_CONNECTION_STATE_T *state, int32_t service_id, int32_t xoff);
+
+ // Callback to inform a service that a server available reply message has been received
+-typedef void (*VCHI_CONNECTION_SERVER_AVAILABLE_REPLY)(VCHI_CONNECTION_STATE_T *state, vcos_fourcc_t service_id, uint32_t flags);
++typedef void (*VCHI_CONNECTION_SERVER_AVAILABLE_REPLY)(VCHI_CONNECTION_STATE_T *state, int32_t service_id, uint32_t flags);
+
+ // Callback to indicate that bulk auxiliary messages have arrived
+ typedef void (*VCHI_CONNECTION_BULK_AUX_RECEIVED)(VCHI_CONNECTION_STATE_T *state);
+@@ -185,7 +189,7 @@ typedef void (*VCHI_CONNECTION_INFO)(VCHI_CONNECTION_STATE_T *state, uint32_t pr
+ typedef void (*VCHI_CONNECTION_DISCONNECT)(VCHI_CONNECTION_STATE_T *state, uint32_t flags);
+
+ // Callback to inform of a power control request
+-typedef void (*VCHI_CONNECTION_POWER_CONTROL)(VCHI_CONNECTION_STATE_T *state, MESSAGE_TX_CHANNEL_T channel, vcos_bool_t enable);
++typedef void (*VCHI_CONNECTION_POWER_CONTROL)(VCHI_CONNECTION_STATE_T *state, MESSAGE_TX_CHANNEL_T channel, int32_t enable);
+
+ // allocate memory suitably aligned for this connection
+ typedef void * (*VCHI_BUFFER_ALLOCATE)(VCHI_CONNECTION_SERVICE_HANDLE_T service_handle, uint32_t * length);
+@@ -299,7 +303,7 @@ struct vchi_connection_t {
+ const VCHI_CONNECTION_API_T *api;
+ VCHI_CONNECTION_STATE_T *state;
+ #ifdef VCHI_COARSE_LOCKING
+- VCOS_SEMAPHORE_T sem;
++ struct semaphore sem;
+ #endif
+ };
+
+diff --git a/drivers/misc/vc04_services/interface/vchi/message_drivers/message.h b/drivers/misc/vc04_services/interface/vchi/message_drivers/message.h
+index 7701b15..1e2da83 100644
+--- a/drivers/misc/vc04_services/interface/vchi/message_drivers/message.h
++++ b/drivers/misc/vc04_services/interface/vchi/message_drivers/message.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2010-2011 Broadcom Corporation. All rights reserved.
++ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -19,8 +19,11 @@
+ #ifndef _VCHI_MESSAGE_H_
+ #define _VCHI_MESSAGE_H_
+
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/semaphore.h>
++
+ #include "interface/vchi/vchi_cfg_internal.h"
+-#include "interface/vcos/vcos.h"
+ #include "interface/vchi/vchi_common.h"
+
+
+@@ -63,7 +66,7 @@ typedef struct rx_msg_slot_info {
+ struct rx_msg_slot_info *next;
+ //struct slot_info *prev;
+ #if !defined VCHI_COARSE_LOCKING
+- VCOS_SEMAPHORE_T sem;
++ struct semaphore sem;
+ #endif
+
+ uint8_t *addr; // base address of slot
+@@ -84,7 +87,7 @@ typedef struct rx_msg_slot_info {
+ typedef struct rx_bulk_slotinfo_t {
+ struct rx_bulk_slotinfo_t *next;
+
+- VCOS_SEMAPHORE_T *blocking;
++ struct semaphore *blocking;
+
+ // needed by DMA
+ void *addr;
+@@ -127,7 +130,7 @@ typedef struct {
+ uint16_t slot_delta; // whether this message indicated slot delta
+ uint32_t len; // length of message
+ RX_MSG_SLOTINFO_T *slot; // slot this message is in
+- vcos_fourcc_t service; // service id this message is destined for
++ int32_t service; // service id this message is destined for
+ uint32_t tx_timestamp; // timestamp from the header
+ uint32_t rx_timestamp; // timestamp when we parsed it
+ } message;
+@@ -156,14 +159,14 @@ struct opaque_vchi_message_driver_t {
+ VCHI_MDRIVER_HANDLE_T *(*open)( VCHI_MESSAGE_DRIVER_OPEN_T *params, void *state );
+ int32_t (*suspending)( VCHI_MDRIVER_HANDLE_T *handle );
+ int32_t (*resumed)( VCHI_MDRIVER_HANDLE_T *handle );
+- int32_t (*power_control)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T, vcos_bool_t enable );
++ int32_t (*power_control)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T, int32_t enable );
+ int32_t (*add_msg_rx_slot)( VCHI_MDRIVER_HANDLE_T *handle, RX_MSG_SLOTINFO_T *slot ); // rx message
+ int32_t (*add_bulk_rx)( VCHI_MDRIVER_HANDLE_T *handle, void *data, uint32_t len, RX_BULK_SLOTINFO_T *slot ); // rx data (bulk)
+ int32_t (*send)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel, const void *data, uint32_t len, VCHI_MSG_FLAGS_T flags, void *send_handle ); // tx (message & bulk)
+ void (*next_event)( VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_EVENT_T *event ); // get the next event from message_driver
+ int32_t (*enable)( VCHI_MDRIVER_HANDLE_T *handle );
+- int32_t (*form_message)( VCHI_MDRIVER_HANDLE_T *handle, vcos_fourcc_t service_id, VCHI_MSG_VECTOR_T *vector, uint32_t count, void
+- *address, uint32_t length_avail, uint32_t max_total_length, vcos_bool_t pad_to_fill, vcos_bool_t allow_partial );
++ int32_t (*form_message)( VCHI_MDRIVER_HANDLE_T *handle, int32_t service_id, VCHI_MSG_VECTOR_T *vector, uint32_t count, void
++ *address, uint32_t length_avail, uint32_t max_total_length, int32_t pad_to_fill, int32_t allow_partial );
+
+ int32_t (*update_message)( VCHI_MDRIVER_HANDLE_T *handle, void *dest, int16_t *slot_count );
+ int32_t (*buffer_aligned)( VCHI_MDRIVER_HANDLE_T *handle, int tx, int uncached, const void *address, const uint32_t length );
+@@ -172,7 +175,7 @@ struct opaque_vchi_message_driver_t {
+ int (*rx_slot_size)( VCHI_MDRIVER_HANDLE_T *handle, int msg_size );
+ int (*tx_slot_size)( VCHI_MDRIVER_HANDLE_T *handle, int msg_size );
+
+- vcos_bool_t (*tx_supports_terminate)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel );
++ int32_t (*tx_supports_terminate)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel );
+ uint32_t (*tx_bulk_chunk_size)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel );
+ int (*tx_alignment)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_TX_CHANNEL_T channel );
+ int (*rx_alignment)( const VCHI_MDRIVER_HANDLE_T *handle, MESSAGE_RX_CHANNEL_T channel );
+diff --git a/drivers/misc/vc04_services/interface/vchi/vchi.h b/drivers/misc/vc04_services/interface/vchi/vchi.h
+index e441d8c..7a7612d 100644
+--- a/drivers/misc/vc04_services/interface/vchi/vchi.h
++++ b/drivers/misc/vc04_services/interface/vchi/vchi.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2010-2011 Broadcom Corporation. All rights reserved.
++ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -16,14 +16,9 @@
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+-/*=============================================================================
+-Contains the protypes for the vchi functions.
+-=============================================================================*/
+-
+ #ifndef VCHI_H_
+ #define VCHI_H_
+
+-#include "interface/vcos/vcos.h"
+ #include "interface/vchi/vchi_cfg.h"
+ #include "interface/vchi/vchi_common.h"
+ #include "interface/vchi/connections/connection.h"
+@@ -44,6 +39,12 @@ Contains the protypes for the vchi functions.
+ #define VCHI_BULK_ALIGNED(x) (((unsigned long)(x) & (VCHI_BULK_ALIGN-1)) == 0)
+ #endif
+
++struct vchi_version {
++ uint32_t version;
++ uint32_t version_min;
++};
++#define VCHI_VERSION(v_) { v_, v_ }
++#define VCHI_VERSION_EX(v_, m_) { v_, m_ }
+
+ typedef enum
+ {
+@@ -88,8 +89,8 @@ typedef struct vchi_msg_vector_ex {
+ // Construct an entry in a msg vector for a message handle (h), starting at offset (o) of length (l)
+ #define VCHI_VEC_HANDLE(h,o,l) VCHI_VEC_HANDLE, { { (h), (o), (l) } }
+
+-// Macros to manipulate fourcc_t values
+-#define MAKE_FOURCC(x) ((fourcc_t)( (x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3] ))
++// Macros to manipulate 'FOURCC' values
++#define MAKE_FOURCC(x) ((int32_t)( (x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3] ))
+ #define FOURCC_TO_CHAR(x) (x >> 24) & 0xFF,(x >> 16) & 0xFF,(x >> 8) & 0xFF, x & 0xFF
+
+
+@@ -108,15 +109,22 @@ typedef struct
+
+ // structure used to provide the information needed to open a server or a client
+ typedef struct {
+- vcos_fourcc_t service_id;
+- VCHI_CONNECTION_T *connection;
+- uint32_t rx_fifo_size;
+- uint32_t tx_fifo_size;
+- VCHI_CALLBACK_T callback;
+- void *callback_param;
+- vcos_bool_t want_unaligned_bulk_rx; // client intends to receive bulk transfers of odd lengths or into unaligned buffers
+- vcos_bool_t want_unaligned_bulk_tx; // client intends to transmit bulk transfers of odd lengths or out of unaligned buffers
+- vcos_bool_t want_crc; // client wants to check CRCs on (bulk) transfers. Only needs to be set at 1 end - will do both directions.
++ struct vchi_version version;
++ int32_t service_id;
++ VCHI_CONNECTION_T *connection;
++ uint32_t rx_fifo_size;
++ uint32_t tx_fifo_size;
++ VCHI_CALLBACK_T callback;
++ void *callback_param;
++ /* client intends to receive bulk transfers of
++ odd lengths or into unaligned buffers */
++ int32_t want_unaligned_bulk_rx;
++ /* client intends to transmit bulk transfers of
++ odd lengths or out of unaligned buffers */
++ int32_t want_unaligned_bulk_tx;
++ /* client wants to check CRCs on (bulk) xfers.
++ Only needs to be set at 1 end - will do both directions. */
++ int32_t want_crc;
+ } SERVICE_CREATION_T;
+
+ // Opaque handle for a VCHI instance
+@@ -269,7 +277,7 @@ extern uint32_t vchi_held_msg_rx_timestamp( const VCHI_HELD_MSG_T *message );
+ extern int32_t vchi_held_msg_release( VCHI_HELD_MSG_T *message );
+
+ // Indicates whether the iterator has a next message.
+-extern vcos_bool_t vchi_msg_iter_has_next( const VCHI_MSG_ITER_T *iter );
++extern int32_t vchi_msg_iter_has_next( const VCHI_MSG_ITER_T *iter );
+
+ // Return the pointer and length for the next message and advance the iterator.
+ extern int32_t vchi_msg_iter_next( VCHI_MSG_ITER_T *iter,
+diff --git a/drivers/misc/vc04_services/interface/vchi/vchi_cfg.h b/drivers/misc/vc04_services/interface/vchi/vchi_cfg.h
+index a66e489..df02282 100644
+--- a/drivers/misc/vc04_services/interface/vchi/vchi_cfg.h
++++ b/drivers/misc/vc04_services/interface/vchi/vchi_cfg.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2010-2011 Broadcom Corporation. All rights reserved.
++ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -16,11 +16,6 @@
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+-/*=============================================================================
+-Contains the #defines for the number of servers / clients etc, these can be
+-over-ridden from the platform makefile if needed
+-=============================================================================*/
+-
+ #ifndef VCHI_CFG_H_
+ #define VCHI_CFG_H_
+
+diff --git a/drivers/misc/vc04_services/interface/vchi/vchi_cfg_internal.h b/drivers/misc/vc04_services/interface/vchi/vchi_cfg_internal.h
+index 958cc55..f334e4c 100644
+--- a/drivers/misc/vc04_services/interface/vchi/vchi_cfg_internal.h
++++ b/drivers/misc/vc04_services/interface/vchi/vchi_cfg_internal.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2010-2011 Broadcom Corporation. All rights reserved.
++ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+diff --git a/drivers/misc/vc04_services/interface/vchi/vchi_common.h b/drivers/misc/vc04_services/interface/vchi/vchi_common.h
+index 4057878..b3aa5e7 100644
+--- a/drivers/misc/vc04_services/interface/vchi/vchi_common.h
++++ b/drivers/misc/vc04_services/interface/vchi/vchi_common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2010-2011 Broadcom Corporation. All rights reserved.
++ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -16,10 +16,6 @@
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+-/*=============================================================================
+-Contains global defs used by submodules within vchi.
+-=============================================================================*/
+-
+ #ifndef VCHI_COMMON_H_
+ #define VCHI_COMMON_H_
+
+diff --git a/drivers/misc/vc04_services/interface/vchi/vchi_mh.h b/drivers/misc/vc04_services/interface/vchi/vchi_mh.h
+index 9bcf12e..9dc3a37 100644
+--- a/drivers/misc/vc04_services/interface/vchi/vchi_mh.h
++++ b/drivers/misc/vc04_services/interface/vchi/vchi_mh.h
+@@ -19,7 +19,7 @@
+ #ifndef VCHI_MH_H_
+ #define VCHI_MH_H_
+
+-#include <interface/vcos/vcos.h>
++#include <linux/types.h>
+
+ typedef int32_t VCHI_MEM_HANDLE_T;
+ #define VCHI_MEM_HANDLE_INVALID 0
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq.h
+index 49d3087..9c359c0 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq.h
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq.h
+@@ -21,7 +21,6 @@
+
+ #include "vchiq_if.h"
+ #include "vchiq_util.h"
+-#include "interface/vcos/vcos.h"
+
+ #endif
+
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+index 35f6afe..93d4c3f 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+@@ -24,9 +24,9 @@
+ #include <linux/pagemap.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/version.h>
++#include <linux/io.h>
++#include <linux/uaccess.h>
+ #include <asm/pgtable.h>
+-#include <asm/io.h>
+-#include <asm/uaccess.h>
+
+ #include <mach/irqs.h>
+
+@@ -40,10 +40,14 @@
+
+ #include "vchiq_arm.h"
+ #include "vchiq_2835.h"
++#include "vchiq_connected.h"
+
+ #define MAX_FRAGMENTS (VCHIQ_NUM_CURRENT_BULKS * 2)
+
+-#define VCOS_LOG_CATEGORY (&vchiq_arm_log_category)
++typedef struct vchiq_2835_state_struct {
++ int inited;
++ VCHIQ_ARM_STATE_T arm_state;
++} VCHIQ_2835_ARM_STATE_T;
+
+ static char *g_slot_mem;
+ static int g_slot_mem_size;
+@@ -52,29 +56,21 @@ static FRAGMENTS_T *g_fragments_base;
+ static FRAGMENTS_T *g_free_fragments;
+ struct semaphore g_free_fragments_sema;
+
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
++extern int vchiq_arm_log_level;
++
+ static DEFINE_SEMAPHORE(g_free_fragments_mutex);
+-#else
+-static DECLARE_MUTEX(g_free_fragments_mutex);
+-#endif
+
+ static irqreturn_t
+ vchiq_doorbell_irq(int irq, void *dev_id);
+
+ static int
+ create_pagelist(char __user *buf, size_t count, unsigned short type,
+- struct task_struct *task, PAGELIST_T ** ppagelist);
++ struct task_struct *task, PAGELIST_T ** ppagelist);
+
+ static void
+ free_pagelist(PAGELIST_T *pagelist, int actual);
+
+ int __init
+-vchiq_platform_vcos_init(void)
+-{
+- return (vcos_init() == VCOS_SUCCESS) ? 0 : -EINVAL;
+-}
+-
+-int __init
+ vchiq_platform_init(VCHIQ_STATE_T *state)
+ {
+ VCHIQ_SLOT_ZERO_T *vchiq_slot_zero;
+@@ -90,48 +86,49 @@ vchiq_platform_init(VCHIQ_STATE_T *state)
+ &g_slot_phys, GFP_ATOMIC);
+
+ if (!g_slot_mem) {
+- vcos_log_error("Unable to allocate channel memory");
++ vchiq_log_error(vchiq_arm_log_level,
++ "Unable to allocate channel memory");
+ err = -ENOMEM;
+ goto failed_alloc;
+ }
+
+- vcos_assert(((int)g_slot_mem & (PAGE_SIZE - 1)) == 0);
++ WARN_ON(((int)g_slot_mem & (PAGE_SIZE - 1)) != 0);
+
+ vchiq_slot_zero = vchiq_init_slots(g_slot_mem, g_slot_mem_size);
+- if (!vchiq_slot_zero)
+- {
+- err = -EINVAL;
+- goto failed_init_slots;
++ if (!vchiq_slot_zero) {
++ err = -EINVAL;
++ goto failed_init_slots;
+ }
+
+- vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX] = (int)g_slot_phys + g_slot_mem_size;
+- vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] = MAX_FRAGMENTS;
++ vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX] =
++ (int)g_slot_phys + g_slot_mem_size;
++ vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] =
++ MAX_FRAGMENTS;
+
+ g_fragments_base = (FRAGMENTS_T *)(g_slot_mem + g_slot_mem_size);
+ g_slot_mem_size += frag_mem_size;
+
+ g_free_fragments = g_fragments_base;
+ for (i = 0; i < (MAX_FRAGMENTS - 1); i++) {
+- *(FRAGMENTS_T **) & g_fragments_base[i] =
++ *(FRAGMENTS_T **)&g_fragments_base[i] =
+ &g_fragments_base[i + 1];
+ }
+- *(FRAGMENTS_T **) & g_fragments_base[i] = NULL;
++ *(FRAGMENTS_T **)&g_fragments_base[i] = NULL;
+ sema_init(&g_free_fragments_sema, MAX_FRAGMENTS);
+
+ if (vchiq_init_state(state, vchiq_slot_zero, 0/*slave*/) !=
+- VCHIQ_SUCCESS)
+- {
++ VCHIQ_SUCCESS) {
+ err = -EINVAL;
+ goto failed_vchiq_init;
+ }
+
+ err = request_irq(VCHIQ_DOORBELL_IRQ, vchiq_doorbell_irq,
+- IRQF_SAMPLE_RANDOM | IRQF_IRQPOLL, "VCHIQ doorbell",
++ IRQF_IRQPOLL, "VCHIQ doorbell",
+ state);
+- if (err < 0)
+- {
+- printk( KERN_ERR "%s: failed to register irq=%d err=%d\n", __func__,
+- VCHIQ_DOORBELL_IRQ, err );
++ if (err < 0) {
++ vchiq_log_error(vchiq_arm_log_level, "%s: failed to register "
++ "irq=%d err=%d", __func__,
++ VCHIQ_DOORBELL_IRQ, err);
+ goto failed_request_irq;
+ }
+
+@@ -141,39 +138,67 @@ vchiq_platform_init(VCHIQ_STATE_T *state)
+
+ bcm_mailbox_write(MBOX_CHAN_VCHIQ, (unsigned int)g_slot_phys);
+
+- vcos_log_info("vchiq_init - done (slots %x, phys %x)",
++ vchiq_log_info(vchiq_arm_log_level,
++ "vchiq_init - done (slots %x, phys %x)",
+ (unsigned int)vchiq_slot_zero, g_slot_phys);
+
+- return 0;
++ vchiq_call_connected_callbacks();
++
++ return 0;
+
+ failed_request_irq:
+ failed_vchiq_init:
+ failed_init_slots:
+- dma_free_coherent(NULL, g_slot_mem_size, g_slot_mem, g_slot_phys);
++ dma_free_coherent(NULL, g_slot_mem_size, g_slot_mem, g_slot_phys);
+
+ failed_alloc:
+- return err;
++ return err;
+ }
+
+ void __exit
+ vchiq_platform_exit(VCHIQ_STATE_T *state)
+ {
+- free_irq(VCHIQ_DOORBELL_IRQ, state);
+- dma_free_coherent(NULL, g_slot_mem_size,
+- g_slot_mem, g_slot_phys);
++ free_irq(VCHIQ_DOORBELL_IRQ, state);
++ dma_free_coherent(NULL, g_slot_mem_size,
++ g_slot_mem, g_slot_phys);
++}
++
++
++VCHIQ_STATUS_T
++vchiq_platform_init_state(VCHIQ_STATE_T *state)
++{
++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
++ state->platform_state = kzalloc(sizeof(VCHIQ_2835_ARM_STATE_T), GFP_KERNEL);
++ ((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->inited = 1;
++ status = vchiq_arm_init_state(state, &((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->arm_state);
++ if(status != VCHIQ_SUCCESS)
++ {
++ ((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->inited = 0;
++ }
++ return status;
++}
++
++VCHIQ_ARM_STATE_T*
++vchiq_platform_get_arm_state(VCHIQ_STATE_T *state)
++{
++ if(!((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->inited)
++ {
++ BUG();
++ }
++ return &((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->arm_state;
+ }
+
+ void
+ remote_event_signal(REMOTE_EVENT_T *event)
+ {
++ wmb();
++
+ event->fired = 1;
+
+- /* The test on the next line also ensures the write on the previous line
+- has completed */
++ dsb(); /* data barrier operation */
+
+ if (event->armed) {
+ /* trigger vc interrupt */
+- dsb(); /* data barrier operation */
+
+ writel(0, __io_address(ARM_0_BELL2));
+ }
+@@ -182,13 +207,10 @@ remote_event_signal(REMOTE_EVENT_T *event)
+ int
+ vchiq_copy_from_user(void *dst, const void *src, int size)
+ {
+- if ( (uint32_t)src < TASK_SIZE)
+- {
++ if ((uint32_t)src < TASK_SIZE) {
+ return copy_from_user(dst, src, size);
+- }
+- else
+- {
+- memcpy( dst, src, size );
++ } else {
++ memcpy(dst, src, size);
+ return 0;
+ }
+ }
+@@ -200,7 +222,7 @@ vchiq_prepare_bulk_data(VCHIQ_BULK_T *bulk, VCHI_MEM_HANDLE_T memhandle,
+ PAGELIST_T *pagelist;
+ int ret;
+
+- vcos_assert(memhandle == VCHI_MEM_HANDLE_INVALID);
++ WARN_ON(memhandle != VCHI_MEM_HANDLE_INVALID);
+
+ ret = create_pagelist((char __user *)offset, size,
+ (dir == VCHIQ_BULK_RECEIVE)
+@@ -224,7 +246,8 @@ vchiq_prepare_bulk_data(VCHIQ_BULK_T *bulk, VCHI_MEM_HANDLE_T memhandle,
+ void
+ vchiq_complete_bulk(VCHIQ_BULK_T *bulk)
+ {
+- free_pagelist((PAGELIST_T *)bulk->remote_data, bulk->actual);
++ if (bulk && bulk->remote_data && bulk->actual)
++ free_pagelist((PAGELIST_T *)bulk->remote_data, bulk->actual);
+ }
+
+ void
+@@ -234,83 +257,57 @@ vchiq_transfer_bulk(VCHIQ_BULK_T *bulk)
+ * This should only be called on the master (VideoCore) side, but
+ * provide an implementation to avoid the need for ifdefery.
+ */
+- vcos_assert(!"This code should not be called by the ARM on BCM2835");
++ BUG();
+ }
+
+ void
+ vchiq_dump_platform_state(void *dump_context)
+ {
+- char buf[80];
+- int len;
+- len = vcos_snprintf(buf, sizeof(buf),
+- " Platform: 2835 (VC master)");
+- vchiq_dump(dump_context, buf, len + 1);
++ char buf[80];
++ int len;
++ len = snprintf(buf, sizeof(buf),
++ " Platform: 2835 (VC master)");
++ vchiq_dump(dump_context, buf, len + 1);
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_platform_suspend(VCHIQ_STATE_T *state)
+ {
+- vcos_unused(state);
+- vcos_assert_msg(0, "Suspend/resume not supported");
+ return VCHIQ_ERROR;
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_platform_resume(VCHIQ_STATE_T *state)
+ {
+- vcos_unused(state);
+- vcos_assert_msg(0, "Suspend/resume not supported");
+- return VCHIQ_ERROR;
++ return VCHIQ_SUCCESS;
+ }
+
+ void
+ vchiq_platform_paused(VCHIQ_STATE_T *state)
+ {
+- vcos_unused(state);
+- vcos_assert_msg(0, "Suspend/resume not supported");
+ }
+
+ void
+ vchiq_platform_resumed(VCHIQ_STATE_T *state)
+ {
+- vcos_unused(state);
+- vcos_assert_msg(0, "Suspend/resume not supported");
+ }
+
+ int
+ vchiq_platform_videocore_wanted(VCHIQ_STATE_T* state)
+ {
+- vcos_unused(state);
+ return 1; // autosuspend not supported - videocore always wanted
+ }
+
+-#if VCOS_HAVE_TIMER
+ int
+ vchiq_platform_use_suspend_timer(void)
+ {
+ return 0;
+ }
+-#endif
+ void
+ vchiq_dump_platform_use_state(VCHIQ_STATE_T *state)
+ {
+- vcos_unused(state);
++ vchiq_log_info((vchiq_arm_log_level>=VCHIQ_LOG_INFO),"Suspend timer not in use");
+ }
+-
+-VCHIQ_STATUS_T
+-vchiq_platform_init_state(VCHIQ_STATE_T *state)
+-{
+- vcos_unused(state);
+- return VCHIQ_SUCCESS;
+-}
+-
+-VCHIQ_ARM_STATE_T*
+-vchiq_platform_get_arm_state(VCHIQ_STATE_T *state)
+-{
+- vcos_unused(state);
+- return NULL;
+-}
+-
+ /*
+ * Local functions
+ */
+@@ -318,7 +315,7 @@ vchiq_platform_get_arm_state(VCHIQ_STATE_T *state)
+ static irqreturn_t
+ vchiq_doorbell_irq(int irq, void *dev_id)
+ {
+- VCHIQ_STATE_T *state = dev_id;
++ VCHIQ_STATE_T *state = dev_id;
+ irqreturn_t ret = IRQ_NONE;
+ unsigned int status;
+
+@@ -334,17 +331,17 @@ vchiq_doorbell_irq(int irq, void *dev_id)
+ }
+
+ /* There is a potential problem with partial cache lines (pages?)
+- at the ends of the block when reading. If the CPU accessed anything in
+- the same line (page?) then it may have pulled old data into the cache,
+- obscuring the new data underneath. We can solve this by transferring the
+- partial cache lines separately, and allowing the ARM to copy into the
+- cached area.
+-
+- N.B. This implementation plays slightly fast and loose with the Linux
+- driver programming rules, e.g. its use of __virt_to_bus instead of
+- dma_map_single, but it isn't a multi-platform driver and it benefits
+- from increased speed as a result.
+- */
++** at the ends of the block when reading. If the CPU accessed anything in
++** the same line (page?) then it may have pulled old data into the cache,
++** obscuring the new data underneath. We can solve this by transferring the
++** partial cache lines separately, and allowing the ARM to copy into the
++** cached area.
++
++** N.B. This implementation plays slightly fast and loose with the Linux
++** driver programming rules, e.g. its use of __virt_to_bus instead of
++** dma_map_single, but it isn't a multi-platform driver and it benefits
++** from increased speed as a result.
++*/
+
+ static int
+ create_pagelist(char __user *buf, size_t count, unsigned short type,
+@@ -363,13 +360,16 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
+
+ *ppagelist = NULL;
+
+- /* Allocate enough storage to hold the page pointers and the page list */
+- pagelist = (PAGELIST_T *) kmalloc(sizeof(PAGELIST_T) +
++ /* Allocate enough storage to hold the page pointers and the page
++ ** list
++ */
++ pagelist = kmalloc(sizeof(PAGELIST_T) +
+ (num_pages * sizeof(unsigned long)) +
+ (num_pages * sizeof(pages[0])),
+ GFP_KERNEL);
+
+- vcos_log_trace("create_pagelist - %x", (unsigned int)pagelist);
++ vchiq_log_trace(vchiq_arm_log_level,
++ "create_pagelist - %x", (unsigned int)pagelist);
+ if (!pagelist)
+ return -ENOMEM;
+
+@@ -380,17 +380,22 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
+ actual_pages = get_user_pages(task, task->mm,
+ (unsigned long)buf & ~(PAGE_SIZE - 1), num_pages,
+ (type == PAGELIST_READ) /*Write */ , 0 /*Force */ ,
+- pages, NULL /*vmas */ );
++ pages, NULL /*vmas */);
+ up_read(&task->mm->mmap_sem);
+
+- if (actual_pages != num_pages)
+- {
+- for (i = 0; i < actual_pages; i++) {
+- page_cache_release(pages[i]);
+- }
+- kfree(pagelist);
+- return -EINVAL;
+- }
++ if (actual_pages != num_pages)
++ {
++ /* This is probably due to the process being killed */
++ while (actual_pages > 0)
++ {
++ actual_pages--;
++ page_cache_release(pages[actual_pages]);
++ }
++ kfree(pagelist);
++ if (actual_pages == 0)
++ actual_pages = -ENOMEM;
++ return actual_pages;
++ }
+
+ pagelist->length = count;
+ pagelist->type = type;
+@@ -423,7 +428,8 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
+ /* Partial cache lines (fragments) require special measures */
+ if ((type == PAGELIST_READ) &&
+ ((pagelist->offset & (CACHE_LINE_SIZE - 1)) ||
+- ((pagelist->offset + pagelist->length) & (CACHE_LINE_SIZE - 1)))) {
++ ((pagelist->offset + pagelist->length) &
++ (CACHE_LINE_SIZE - 1)))) {
+ FRAGMENTS_T *fragments;
+
+ if (down_interruptible(&g_free_fragments_sema) != 0) {
+@@ -431,11 +437,11 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
+ return -EINTR;
+ }
+
+- vcos_assert(g_free_fragments != NULL);
++ WARN_ON(g_free_fragments == NULL);
+
+ down(&g_free_fragments_mutex);
+ fragments = (FRAGMENTS_T *) g_free_fragments;
+- vcos_assert(fragments != NULL);
++ WARN_ON(fragments == NULL);
+ g_free_fragments = *(FRAGMENTS_T **) g_free_fragments;
+ up(&g_free_fragments_mutex);
+ pagelist->type =
+@@ -459,39 +465,40 @@ free_pagelist(PAGELIST_T *pagelist, int actual)
+ struct page **pages;
+ unsigned int num_pages, i;
+
+- vcos_log_trace("free_pagelist - %x, %d", (unsigned int)pagelist, actual);
++ vchiq_log_trace(vchiq_arm_log_level,
++ "free_pagelist - %x, %d", (unsigned int)pagelist, actual);
+
+ num_pages =
+- (pagelist->length + pagelist->offset + PAGE_SIZE - 1) / PAGE_SIZE;
++ (pagelist->length + pagelist->offset + PAGE_SIZE - 1) /
++ PAGE_SIZE;
+
+ pages = (struct page **)(pagelist->addrs + num_pages);
+
+ /* Deal with any partial cache lines (fragments) */
+ if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS) {
+- FRAGMENTS_T *fragments =
+- g_fragments_base + (pagelist->type -
+- PAGELIST_READ_WITH_FRAGMENTS);
++ FRAGMENTS_T *fragments = g_fragments_base +
++ (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS);
+ int head_bytes, tail_bytes;
+-
+- if (actual >= 0)
+- {
+- if ((head_bytes = (CACHE_LINE_SIZE - pagelist->offset) & (CACHE_LINE_SIZE - 1)) != 0) {
+- if (head_bytes > actual)
+- head_bytes = actual;
+-
+- memcpy((char *)page_address(pages[0]) +
+- pagelist->offset, fragments->headbuf,
+- head_bytes);
+- }
+- if ((head_bytes < actual) &&
+- (tail_bytes =
+- (pagelist->offset + actual) & (CACHE_LINE_SIZE -
+- 1)) != 0) {
+- memcpy((char *)page_address(pages[num_pages - 1]) +
+- ((pagelist->offset + actual) & (PAGE_SIZE -
+- 1) & ~(CACHE_LINE_SIZE - 1)),
+- fragments->tailbuf, tail_bytes);
+- }
++ head_bytes = (CACHE_LINE_SIZE - pagelist->offset) &
++ (CACHE_LINE_SIZE - 1);
++ tail_bytes = (pagelist->offset + actual) &
++ (CACHE_LINE_SIZE - 1);
++
++ if ((actual >= 0) && (head_bytes != 0)) {
++ if (head_bytes > actual)
++ head_bytes = actual;
++
++ memcpy((char *)page_address(pages[0]) +
++ pagelist->offset,
++ fragments->headbuf,
++ head_bytes);
++ }
++ if ((actual >= 0) && (head_bytes < actual) &&
++ (tail_bytes != 0)) {
++ memcpy((char *)page_address(pages[num_pages - 1]) +
++ ((pagelist->offset + actual) &
++ (PAGE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1)),
++ fragments->tailbuf, tail_bytes);
+ }
+
+ down(&g_free_fragments_mutex);
+@@ -509,4 +516,3 @@ free_pagelist(PAGELIST_T *pagelist, int actual)
+
+ kfree(pagelist);
+ }
+-
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
+old mode 100644
+new mode 100755
+index 49a53ce..81daf3e
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
+@@ -26,6 +26,10 @@
+ #include <linux/mm.h>
+ #include <linux/highmem.h>
+ #include <linux/pagemap.h>
++#include <linux/bug.h>
++#include <linux/semaphore.h>
++#include <linux/list.h>
++#include <linux/proc_fs.h>
+
+ #include "vchiq_core.h"
+ #include "vchiq_ioctl.h"
+@@ -45,139 +49,128 @@
+ #define MAX_ELEMENTS 8
+ #define MSG_QUEUE_SIZE 64
+
+-#define VCOS_LOG_CATEGORY (&vchiq_arm_log_category)
++#define KEEPALIVE_VER 1
++#define KEEPALIVE_VER_MIN KEEPALIVE_VER
+
+-#define VCHIQ_ARM_VCSUSPEND_TASK_STACK 4096
++/* Run time control of log level, based on KERN_XXX level. */
++int vchiq_arm_log_level = VCHIQ_LOG_DEFAULT;
++int vchiq_susp_log_level = VCHIQ_LOG_DEFAULT;
+
+-#if VCOS_HAVE_TIMER
+ #define SUSPEND_TIMER_TIMEOUT_MS 100
+-static VCOS_TIMER_T g_suspend_timer;
+-static void suspend_timer_callback(void *context);
+-#endif
+-
+-
+-typedef struct client_service_struct {
+- VCHIQ_SERVICE_T *service;
+- void *userdata;
+- VCHIQ_INSTANCE_T instance;
+- int handle;
+- int is_vchi;
+- volatile int dequeue_pending;
+- volatile int message_available_pos;
+- volatile int msg_insert;
+- volatile int msg_remove;
+- VCOS_EVENT_T insert_event;
+- VCOS_EVENT_T remove_event;
+- VCHIQ_HEADER_T *msg_queue[MSG_QUEUE_SIZE];
++#define SUSPEND_RETRY_TIMER_TIMEOUT_MS 1000
++
++#define VC_SUSPEND_NUM_OFFSET 3 /* number of values before idle which are -ve */
++static const char *const suspend_state_names[] = {
++ "VC_SUSPEND_FORCE_CANCELED",
++ "VC_SUSPEND_REJECTED",
++ "VC_SUSPEND_FAILED",
++ "VC_SUSPEND_IDLE",
++ "VC_SUSPEND_REQUESTED",
++ "VC_SUSPEND_IN_PROGRESS",
++ "VC_SUSPEND_SUSPENDED"
++};
++#define VC_RESUME_NUM_OFFSET 1 /* number of values before idle which are -ve */
++static const char *const resume_state_names[] = {
++ "VC_RESUME_FAILED",
++ "VC_RESUME_IDLE",
++ "VC_RESUME_REQUESTED",
++ "VC_RESUME_IN_PROGRESS",
++ "VC_RESUME_RESUMED"
++};
++/* The number of times we allow force suspend to timeout before actually
++** _forcing_ suspend. This is to cater for SW which fails to release vchiq
++** correctly - we don't want to prevent ARM suspend indefinitely in this case.
++*/
++#define FORCE_SUSPEND_FAIL_MAX 8
++
++/* The time in ms allowed for videocore to go idle when force suspend has been
++ * requested */
++#define FORCE_SUSPEND_TIMEOUT_MS 200
++
++
++static void suspend_timer_callback(unsigned long context);
++static int vchiq_proc_add_instance(VCHIQ_INSTANCE_T instance);
++static void vchiq_proc_remove_instance(VCHIQ_INSTANCE_T instance);
++
++
++typedef struct user_service_struct {
++ VCHIQ_SERVICE_T *service;
++ void *userdata;
++ VCHIQ_INSTANCE_T instance;
++ int is_vchi;
++ int dequeue_pending;
++ int message_available_pos;
++ int msg_insert;
++ int msg_remove;
++ struct semaphore insert_event;
++ struct semaphore remove_event;
++ VCHIQ_HEADER_T * msg_queue[MSG_QUEUE_SIZE];
+ } USER_SERVICE_T;
+
++struct bulk_waiter_node {
++ struct bulk_waiter bulk_waiter;
++ int pid;
++ struct list_head list;
++};
++
+ struct vchiq_instance_struct {
+- VCHIQ_STATE_T *state;
+- VCHIQ_COMPLETION_DATA_T completions[MAX_COMPLETIONS];
+- volatile int completion_insert;
+- volatile int completion_remove;
+- VCOS_EVENT_T insert_event;
+- VCOS_EVENT_T remove_event;
+-
+- USER_SERVICE_T services[MAX_SERVICES];
+-
+- int connected;
+- int closing;
+- int pid;
+- int mark;
++ VCHIQ_STATE_T *state;
++ VCHIQ_COMPLETION_DATA_T completions[MAX_COMPLETIONS];
++ int completion_insert;
++ int completion_remove;
++ struct semaphore insert_event;
++ struct semaphore remove_event;
++ struct mutex completion_mutex;
++
++ int connected;
++ int closing;
++ int pid;
++ int mark;
++
++ struct list_head bulk_waiter_list;
++ struct mutex bulk_waiter_list_mutex;
++
++ struct proc_dir_entry *proc_entry;
+ };
+
+-typedef struct dump_context_struct
+-{
+- char __user *buf;
+- size_t actual;
+- size_t space;
+- loff_t offset;
++typedef struct dump_context_struct {
++ char __user *buf;
++ size_t actual;
++ size_t space;
++ loff_t offset;
+ } DUMP_CONTEXT_T;
+
+-VCOS_LOG_CAT_T vchiq_arm_log_category;
+-
+ static struct cdev vchiq_cdev;
+ static dev_t vchiq_devid;
+ static VCHIQ_STATE_T g_state;
+ static struct class *vchiq_class;
+ static struct device *vchiq_dev;
+-
+-static const char *ioctl_names[] =
+-{
+- "CONNECT",
+- "SHUTDOWN",
+- "CREATE_SERVICE",
+- "REMOVE_SERVICE",
+- "QUEUE_MESSAGE",
+- "QUEUE_BULK_TRANSMIT",
+- "QUEUE_BULK_RECEIVE",
+- "AWAIT_COMPLETION",
+- "DEQUEUE_MESSAGE",
+- "GET_CLIENT_ID",
+- "GET_CONFIG",
+- "CLOSE_SERVICE",
+- "USE_SERVICE",
+- "RELEASE_SERVICE",
+- "SET_SERVICE_OPTION",
+- "DUMP_PHYS_MEM"
++static DEFINE_SPINLOCK(msg_queue_spinlock);
++
++static const char *const ioctl_names[] = {
++ "CONNECT",
++ "SHUTDOWN",
++ "CREATE_SERVICE",
++ "REMOVE_SERVICE",
++ "QUEUE_MESSAGE",
++ "QUEUE_BULK_TRANSMIT",
++ "QUEUE_BULK_RECEIVE",
++ "AWAIT_COMPLETION",
++ "DEQUEUE_MESSAGE",
++ "GET_CLIENT_ID",
++ "GET_CONFIG",
++ "CLOSE_SERVICE",
++ "USE_SERVICE",
++ "RELEASE_SERVICE",
++ "SET_SERVICE_OPTION",
++ "DUMP_PHYS_MEM"
+ };
+
+-vcos_static_assert(vcos_countof(ioctl_names) == (VCHIQ_IOC_MAX + 1));
+-
+-VCOS_LOG_LEVEL_T vchiq_default_arm_log_level = VCOS_LOG_ERROR;
++vchiq_static_assert((sizeof(ioctl_names)/sizeof(ioctl_names[0])) ==
++ (VCHIQ_IOC_MAX + 1));
+
+ static void
+-dump_phys_mem( void *virt_addr, uint32_t num_bytes );
+-
+-/****************************************************************************
+-*
+-* find_service_by_handle
+-*
+-***************************************************************************/
+-
+-static inline USER_SERVICE_T *find_service_by_handle(
+- VCHIQ_INSTANCE_T instance, int handle )
+-{
+- USER_SERVICE_T *user_service;
+-
+- if (( handle >= 0 )
+- && ( handle < MAX_SERVICES ))
+- {
+- user_service = &instance->services[ handle ];
+-
+- if ( user_service->service != NULL )
+- {
+- return user_service;
+- }
+- }
+-
+- return NULL;
+-}
+-
+-/****************************************************************************
+-*
+-* find_avail_service_handle
+-*
+-***************************************************************************/
+-
+-static inline USER_SERVICE_T *find_avail_service_handle(
+- VCHIQ_INSTANCE_T instance)
+-{
+- int handle;
+-
+- for ( handle = 0; handle < MAX_SERVICES; handle++ )
+- {
+- if ( instance->services[handle].service == NULL )
+- {
+- instance->services[handle].instance = instance;
+- instance->services[handle].handle = handle;
+-
+- return &instance->services[handle];
+- }
+- }
+- return NULL;
+-}
++dump_phys_mem(void *virt_addr, uint32_t num_bytes);
+
+ /****************************************************************************
+ *
+@@ -187,47 +180,58 @@ static inline USER_SERVICE_T *find_avail_service_handle(
+
+ static VCHIQ_STATUS_T
+ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason,
+- VCHIQ_HEADER_T *header, USER_SERVICE_T *service, void *bulk_userdata)
++ VCHIQ_HEADER_T *header, USER_SERVICE_T *user_service,
++ void *bulk_userdata)
+ {
+- VCHIQ_COMPLETION_DATA_T *completion;
+- DEBUG_INITIALISE(g_state.local)
+-
+- while (instance->completion_insert ==
+- (instance->completion_remove + MAX_COMPLETIONS)) {
+- /* Out of space - wait for the client */
+- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+- vcos_log_trace("add_completion - completion queue full");
+- DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT);
+- if (vcos_event_wait(&instance->remove_event) != VCOS_SUCCESS) {
+- vcos_log_info("service_callback interrupted");
+- return VCHIQ_RETRY;
+- } else if (instance->closing) {
+- vcos_log_info("service_callback closing");
+- return VCHIQ_ERROR;
+- }
+- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+- }
+-
+- completion =
+- &instance->
+- completions[instance->completion_insert & (MAX_COMPLETIONS - 1)];
+-
+- completion->header = header;
+- completion->reason = reason;
+- completion->service_userdata = service;
+- completion->bulk_userdata = bulk_userdata;
+-
+- /* A write barrier is needed here to ensure that the entire completion
+- record is written out before the insert point. */
+- vcos_wmb(&completion->bulk_userdata);
+-
+- if (reason == VCHIQ_MESSAGE_AVAILABLE)
+- service->message_available_pos = instance->completion_insert;
+- instance->completion_insert++;
+-
+- vcos_event_signal(&instance->insert_event);
+-
+- return VCHIQ_SUCCESS;
++ VCHIQ_COMPLETION_DATA_T *completion;
++ DEBUG_INITIALISE(g_state.local)
++
++ while (instance->completion_insert ==
++ (instance->completion_remove + MAX_COMPLETIONS)) {
++ /* Out of space - wait for the client */
++ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
++ vchiq_log_trace(vchiq_arm_log_level,
++ "add_completion - completion queue full");
++ DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT);
++ if (down_interruptible(&instance->remove_event) != 0) {
++ vchiq_log_info(vchiq_arm_log_level,
++ "service_callback interrupted");
++ return VCHIQ_RETRY;
++ } else if (instance->closing) {
++ vchiq_log_info(vchiq_arm_log_level,
++ "service_callback closing");
++ return VCHIQ_ERROR;
++ }
++ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
++ }
++
++ completion =
++ &instance->completions[instance->completion_insert &
++ (MAX_COMPLETIONS - 1)];
++
++ completion->header = header;
++ completion->reason = reason;
++ /* N.B. service_userdata is updated while processing AWAIT_COMPLETION */
++ completion->service_userdata = user_service->service;
++ completion->bulk_userdata = bulk_userdata;
++
++ if (reason == VCHIQ_SERVICE_CLOSED)
++ /* Take an extra reference, to be held until
++ this CLOSED notification is delivered. */
++ lock_service(user_service->service);
++
++ /* A write barrier is needed here to ensure that the entire completion
++ record is written out before the insert point. */
++ wmb();
++
++ if (reason == VCHIQ_MESSAGE_AVAILABLE)
++ user_service->message_available_pos =
++ instance->completion_insert;
++ instance->completion_insert++;
++
++ up(&instance->insert_event);
++
++ return VCHIQ_SUCCESS;
+ }
+
+ /****************************************************************************
+@@ -238,90 +242,104 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason,
+
+ static VCHIQ_STATUS_T
+ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header,
+- VCHIQ_SERVICE_HANDLE_T handle, void *bulk_userdata)
++ VCHIQ_SERVICE_HANDLE_T handle, void *bulk_userdata)
+ {
+- /* How do we ensure the callback goes to the right client?
+- The service_user data points to a USER_SERVICE_T record containing the
+- original callback and the user state structure, which contains a circular
+- buffer for completion records.
+- */
+- USER_SERVICE_T *service =
+- (USER_SERVICE_T *) VCHIQ_GET_SERVICE_USERDATA(handle);
+- VCHIQ_INSTANCE_T instance = service->instance;
+- DEBUG_INITIALISE(g_state.local)
+-
+- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+- vcos_log_trace
+- ("service_callback - service %lx(%d), reason %d, header %lx, "
+- "instance %lx, bulk_userdata %lx",
+- (unsigned long)service, ((VCHIQ_SERVICE_T *) handle)->localport,
+- reason, (unsigned long)header,
+- (unsigned long)instance, (unsigned long)bulk_userdata);
+-
+- if (!instance || instance->closing) {
+- return VCHIQ_SUCCESS;
+- }
+-
+- if (header && service->is_vchi)
+- {
+- while (service->msg_insert == (service->msg_remove + MSG_QUEUE_SIZE))
+- {
+- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+- DEBUG_COUNT(MSG_QUEUE_FULL_COUNT);
+- vcos_log_trace("service_callback - msg queue full");
+- /* If there is no MESSAGE_AVAILABLE in the completion queue, add one */
+- if ((service->message_available_pos - instance->completion_remove) < 0)
+- {
+- VCHIQ_STATUS_T status;
+- vcos_log_warn("Inserting extra MESSAGE_AVAILABLE");
+- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+- status = add_completion(instance, reason, NULL, service, bulk_userdata);
+- if (status != VCHIQ_SUCCESS)
+- {
+- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+- return status;
+- }
+- }
+-
+- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+- if (vcos_event_wait(&service->remove_event) != VCOS_SUCCESS) {
+- vcos_log_info("service_callback interrupted");
+- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+- return VCHIQ_RETRY;
+- } else if (instance->closing) {
+- vcos_log_info("service_callback closing");
+- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+- return VCHIQ_ERROR;
+- }
+- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+- }
+-
+- service->msg_queue[service->msg_insert & (MSG_QUEUE_SIZE - 1)] =
+- header;
+-
+- /* A write memory barrier is needed to ensure that the store of header
+- is completed before the insertion point is updated */
+- vcos_wmb(&service->msg_queue[service->msg_insert & (MSG_QUEUE_SIZE - 1)]);
+-
+- service->msg_insert++;
+- vcos_event_signal(&service->insert_event);
+-
+- /* If there is a thread waiting in DEQUEUE_MESSAGE, or if
+- there is a MESSAGE_AVAILABLE in the completion queue then
+- bypass the completion queue. */
+- if (((service->message_available_pos - instance->completion_remove) >= 0) ||
+- service->dequeue_pending)
+- {
+- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+- service->dequeue_pending = 0;
+- return VCHIQ_SUCCESS;
+- }
+-
+- header = NULL;
+- }
+- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+-
+- return add_completion(instance, reason, header, service, bulk_userdata);
++ /* How do we ensure the callback goes to the right client?
++ ** The service_user data points to a USER_SERVICE_T record containing
++ ** the original callback and the user state structure, which contains a
++ ** circular buffer for completion records.
++ */
++ USER_SERVICE_T *user_service;
++ VCHIQ_SERVICE_T *service;
++ VCHIQ_INSTANCE_T instance;
++ DEBUG_INITIALISE(g_state.local)
++
++ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
++
++ service = handle_to_service(handle);
++ BUG_ON(!service);
++ user_service = (USER_SERVICE_T *)service->base.userdata;
++ instance = user_service->instance;
++
++ if (!instance || instance->closing)
++ return VCHIQ_SUCCESS;
++
++ vchiq_log_trace(vchiq_arm_log_level,
++ "service_callback - service %lx(%d), reason %d, header %lx, "
++ "instance %lx, bulk_userdata %lx",
++ (unsigned long)user_service,
++ service->localport,
++ reason, (unsigned long)header,
++ (unsigned long)instance, (unsigned long)bulk_userdata);
++
++ if (header && user_service->is_vchi) {
++ spin_lock(&msg_queue_spinlock);
++ while (user_service->msg_insert ==
++ (user_service->msg_remove + MSG_QUEUE_SIZE)) {
++ spin_unlock(&msg_queue_spinlock);
++ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
++ DEBUG_COUNT(MSG_QUEUE_FULL_COUNT);
++ vchiq_log_trace(vchiq_arm_log_level,
++ "service_callback - msg queue full");
++ /* If there is no MESSAGE_AVAILABLE in the completion
++ ** queue, add one
++ */
++ if ((user_service->message_available_pos -
++ instance->completion_remove) < 0) {
++ VCHIQ_STATUS_T status;
++ vchiq_log_info(vchiq_arm_log_level,
++ "Inserting extra MESSAGE_AVAILABLE");
++ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
++ status = add_completion(instance, reason,
++ NULL, user_service, bulk_userdata);
++ if (status != VCHIQ_SUCCESS) {
++ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
++ return status;
++ }
++ }
++
++ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
++ if (down_interruptible(&user_service->remove_event)
++ != 0) {
++ vchiq_log_info(vchiq_arm_log_level,
++ "service_callback interrupted");
++ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
++ return VCHIQ_RETRY;
++ } else if (instance->closing) {
++ vchiq_log_info(vchiq_arm_log_level,
++ "service_callback closing");
++ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
++ return VCHIQ_ERROR;
++ }
++ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
++ spin_lock(&msg_queue_spinlock);
++ }
++
++ user_service->msg_queue[user_service->msg_insert &
++ (MSG_QUEUE_SIZE - 1)] = header;
++ user_service->msg_insert++;
++ spin_unlock(&msg_queue_spinlock);
++
++ up(&user_service->insert_event);
++
++ /* If there is a thread waiting in DEQUEUE_MESSAGE, or if
++ ** there is a MESSAGE_AVAILABLE in the completion queue then
++ ** bypass the completion queue.
++ */
++ if (((user_service->message_available_pos -
++ instance->completion_remove) >= 0) ||
++ user_service->dequeue_pending) {
++ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
++ user_service->dequeue_pending = 0;
++ return VCHIQ_SUCCESS;
++ }
++
++ header = NULL;
++ }
++ DEBUG_TRACE(SERVICE_CALLBACK_LINE);
++
++ return add_completion(instance, reason, header, user_service,
++ bulk_userdata);
+ }
+
+ /****************************************************************************
+@@ -333,603 +351,649 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header,
+ static long
+ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ {
+- VCHIQ_INSTANCE_T instance = file->private_data;
+- VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+- long ret = 0;
+- int i, rc;
+- DEBUG_INITIALISE(g_state.local)
+-
+- vcos_log_trace("vchiq_ioctl - instance %x, cmd %s, arg %lx",
+- (unsigned int)instance,
+- ((_IOC_TYPE(cmd) == VCHIQ_IOC_MAGIC) && (_IOC_NR(cmd) <= VCHIQ_IOC_MAX)) ?
+- ioctl_names[_IOC_NR(cmd)] : "<invalid>", arg);
+-
+- switch (cmd) {
+- case VCHIQ_IOC_SHUTDOWN:
+- if (!instance->connected)
+- break;
+-
+- /* Remove all services */
+- for (i = 0; i < MAX_SERVICES; i++) {
+- USER_SERVICE_T *service = &instance->services[i];
+- if (service->service != NULL) {
+- status = vchiq_remove_service(&service->service->base);
+- if (status != VCHIQ_SUCCESS)
+- break;
+- service->service = NULL;
+- }
+- }
+-
+- if (status == VCHIQ_SUCCESS) {
+- /* Wake the completion thread and ask it to exit */
+- instance->closing = 1;
+- vcos_event_signal(&instance->insert_event);
+- }
+-
+- break;
+-
+- case VCHIQ_IOC_CONNECT:
+- if (instance->connected) {
+- ret = -EINVAL;
+- break;
+- }
+- if ((rc=vcos_mutex_lock(&instance->state->mutex)) != VCOS_SUCCESS) {
+- vcos_log_error("vchiq: connect: could not lock mutex for state %d: %d",
+- instance->state->id, rc);
+- ret = -EINTR;
+- break;
+- }
+- status = vchiq_connect_internal(instance->state, instance);
+- vcos_mutex_unlock(&instance->state->mutex);
+-
+- if (status == VCHIQ_SUCCESS)
+- instance->connected = 1;
+- else
+- vcos_log_error("vchiq: could not connect: %d", status);
+- break;
+-
+- case VCHIQ_IOC_CREATE_SERVICE:
+- {
+- VCHIQ_CREATE_SERVICE_T args;
+- VCHIQ_SERVICE_T *service = NULL;
+- USER_SERVICE_T *user_service = NULL;
+- void *userdata;
+- int srvstate;
+-
+- if (copy_from_user
+- (&args, (const void __user *)arg,
+- sizeof(args)) != 0) {
+- ret = -EFAULT;
+- break;
+- }
+-
+- for (i = 0; i < MAX_SERVICES; i++) {
+- if (instance->services[i].service == NULL) {
+- user_service = &instance->services[i];
+- break;
+- }
+- }
+-
+- if (!user_service) {
+- ret = -EMFILE;
+- break;
+- }
+-
+- if (args.is_open) {
+- if (instance->connected)
+- srvstate = VCHIQ_SRVSTATE_OPENING;
+- else {
+- ret = -ENOTCONN;
+- break;
+- }
+- } else {
+- srvstate =
+- instance->connected ?
+- VCHIQ_SRVSTATE_LISTENING :
+- VCHIQ_SRVSTATE_HIDDEN;
+- }
+-
+- vcos_mutex_lock(&instance->state->mutex);
+-
+- userdata = args.params.userdata;
+- args.params.callback = service_callback;
+- args.params.userdata = user_service;
+- service =
+- vchiq_add_service_internal(instance->state,
+- &args.params, srvstate,
+- instance);
+-
+- vcos_mutex_unlock(&instance->state->mutex);
+-
+- if (service != NULL) {
+- user_service->service = service;
+- user_service->userdata = userdata;
+- user_service->instance = instance;
+- user_service->handle = i;
+- user_service->is_vchi = args.is_vchi;
+- user_service->dequeue_pending = 0;
+- user_service->message_available_pos = instance->completion_remove - 1;
+- user_service->msg_insert = 0;
+- user_service->msg_remove = 0;
+- vcos_event_create(&user_service->insert_event, "insert_event");
+- vcos_event_create(&user_service->remove_event, "remove_event");
+-
+- if (args.is_open) {
+- status =
+- vchiq_open_service_internal
+- (service, instance->pid);
+- if (status != VCHIQ_SUCCESS) {
+- vchiq_remove_service
+- (&service->base);
+- ret =
+- (status ==
+- VCHIQ_RETRY) ? -EINTR :
+- -EIO;
+- user_service->service = NULL;
+- user_service->instance = NULL;
+- vcos_event_delete(&user_service->insert_event);
+- vcos_event_delete(&user_service->remove_event);
+- break;
+- }
+- }
+-
+- if (copy_to_user((void __user *)
+- &(((VCHIQ_CREATE_SERVICE_T __user
+- *) arg)->handle),
+- (const void *)&user_service->
+- handle,
+- sizeof(user_service->
+- handle)) != 0)
+- ret = -EFAULT;
+- } else {
+- ret = -EEXIST;
+- }
+- }
+- break;
+-
+- case VCHIQ_IOC_CLOSE_SERVICE:
+- {
+- USER_SERVICE_T *user_service;
+- int handle = (int)arg;
+-
+- user_service = find_service_by_handle(instance, handle);
+- if (user_service != NULL)
+- {
+- int is_server = (user_service->service->public_fourcc != VCHIQ_FOURCC_INVALID);
+-
+- status =
+- vchiq_close_service(&user_service->service->base);
+- if ((status == VCHIQ_SUCCESS) && !is_server)
+- {
+- vcos_event_delete(&user_service->insert_event);
+- vcos_event_delete(&user_service->remove_event);
+- user_service->service = NULL;
+- }
+- } else
+- ret = -EINVAL;
+- }
+- break;
+-
+- case VCHIQ_IOC_REMOVE_SERVICE:
+- {
+- USER_SERVICE_T *user_service;
+- int handle = (int)arg;
+-
+- user_service = find_service_by_handle(instance, handle);
+- if (user_service != NULL)
+- {
+- status =
+- vchiq_remove_service(&user_service->service->base);
+- if (status == VCHIQ_SUCCESS)
+- {
+- vcos_event_delete(&user_service->insert_event);
+- vcos_event_delete(&user_service->remove_event);
+- user_service->service = NULL;
+- }
+- } else
+- ret = -EINVAL;
+- }
+- break;
+-
+- case VCHIQ_IOC_USE_SERVICE:
+- case VCHIQ_IOC_RELEASE_SERVICE:
+- {
+- USER_SERVICE_T *user_service;
+- int handle = (int)arg;
+-
+- user_service = find_service_by_handle(instance, handle);
+- if (user_service != NULL)
+- {
+- status = (cmd == VCHIQ_IOC_USE_SERVICE) ? vchiq_use_service(&user_service->service->base) : vchiq_release_service(&user_service->service->base);
+- if (status != VCHIQ_SUCCESS)
+- {
+- ret = -EINVAL; /* ??? */
+- }
+- }
+- }
+- break;
+-
+- case VCHIQ_IOC_QUEUE_MESSAGE:
+- {
+- VCHIQ_QUEUE_MESSAGE_T args;
+- USER_SERVICE_T *user_service;
+-
+- if (copy_from_user
+- (&args, (const void __user *)arg,
+- sizeof(args)) != 0) {
+- ret = -EFAULT;
+- break;
+- }
+- user_service = find_service_by_handle(instance, args.handle);
+- if ((user_service != NULL) && (args.count <= MAX_ELEMENTS))
+- {
+- /* Copy elements into kernel space */
+- VCHIQ_ELEMENT_T elements[MAX_ELEMENTS];
+- if (copy_from_user
+- (elements, args.elements,
+- args.count * sizeof(VCHIQ_ELEMENT_T)) == 0)
+- status =
+- vchiq_queue_message
+- (&user_service->service->base,
+- elements, args.count);
+- else
+- ret = -EFAULT;
+- } else {
+- ret = -EINVAL;
+- }
+- }
+- break;
+-
+- case VCHIQ_IOC_QUEUE_BULK_TRANSMIT:
+- case VCHIQ_IOC_QUEUE_BULK_RECEIVE:
+- {
+- VCHIQ_QUEUE_BULK_TRANSFER_T args;
+- USER_SERVICE_T *user_service;
+- VCHIQ_BULK_DIR_T dir =
+- (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT) ?
+- VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE;
+-
+- if (copy_from_user
+- (&args, (const void __user *)arg,
+- sizeof(args)) != 0) {
+- ret = -EFAULT;
+- break;
+- }
+- user_service = find_service_by_handle(instance, args.handle);
+- if (user_service != NULL)
+- {
+- status =
+- vchiq_bulk_transfer
+- ((VCHIQ_SERVICE_T *)user_service->service,
+- VCHI_MEM_HANDLE_INVALID,
+- args.data, args.size,
+- args.userdata, args.mode,
+- dir);
+- } else {
+- ret = -EINVAL;
+- }
+- }
+- break;
+-
+- case VCHIQ_IOC_AWAIT_COMPLETION:
+- {
+- VCHIQ_AWAIT_COMPLETION_T args;
+-
+- DEBUG_TRACE(AWAIT_COMPLETION_LINE);
+- if (!instance->connected) {
+- ret = -ENOTCONN;
+- break;
+- }
+-
+- if (copy_from_user
+- (&args, (const void __user *)arg,
+- sizeof(args)) != 0) {
+- ret = -EFAULT;
+- break;
+- }
+- DEBUG_TRACE(AWAIT_COMPLETION_LINE);
+- while ((instance->completion_remove ==
+- instance->completion_insert)
+- && !instance->closing) {
+- DEBUG_TRACE(AWAIT_COMPLETION_LINE);
+- if (vcos_event_wait(&instance->insert_event) !=
+- VCOS_SUCCESS) {
+- DEBUG_TRACE(AWAIT_COMPLETION_LINE);
+- vcos_log_info
+- ("AWAIT_COMPLETION interrupted");
+- ret = -EINTR;
+- break;
+- }
+- }
+- DEBUG_TRACE(AWAIT_COMPLETION_LINE);
+-
+- /* A read memory barrier is needed to stop prefetch of a stale
+- completion record */
+- vcos_rmb();
+-
+- if (ret == 0) {
+- int msgbufcount = args.msgbufcount;
+- for (ret = 0; ret < args.count; ret++) {
+- VCHIQ_COMPLETION_DATA_T *completion;
+- USER_SERVICE_T *service;
+- VCHIQ_HEADER_T *header;
+- if (instance->completion_remove ==
+- instance->completion_insert)
+- break;
+- completion =
+- &instance->
+- completions
+- [instance->completion_remove &
+- (MAX_COMPLETIONS - 1)];
+-
+- service = (USER_SERVICE_T *)completion->service_userdata;
+- completion->service_userdata = service->userdata;
+-
+- header = completion->header;
+- if (header)
+- {
+- void __user *msgbuf;
+- int msglen;
+-
+- msglen = header->size + sizeof(VCHIQ_HEADER_T);
+- /* This must be a VCHIQ-style service */
+- if (args.msgbufsize < msglen)
+- {
+- vcos_log_error("header %x: msgbufsize %x < msglen %x",
+- (unsigned int)header, args.msgbufsize, msglen);
+- vcos_assert(0);
+- if (ret == 0)
+- ret = -EMSGSIZE;
+- break;
+- }
+- if (msgbufcount <= 0)
+- {
+- /* Stall here for lack of a buffer for the message */
+- break;
+- }
+- /* Get the pointer from user space */
+- msgbufcount--;
+- if (copy_from_user(&msgbuf,
+- (const void __user *)&args.msgbufs[msgbufcount],
+- sizeof(msgbuf)) != 0)
+- {
+- if (ret == 0)
+- ret = -EFAULT;
+- break;
+- }
+-
+- /* Copy the message to user space */
+- if (copy_to_user(msgbuf, header, msglen) != 0)
+- {
+- if (ret == 0)
+- ret = -EFAULT;
+- break;
+- }
+-
+- /* Now it has been copied, the message can be released. */
+- vchiq_release_message(&service->service->base, header);
+-
+- /* The completion must point to the msgbuf */
+- completion->header = msgbuf;
+- }
+-
+- if (copy_to_user
+- ((void __user *)((size_t) args.buf +
+- ret *
+- sizeof
+- (VCHIQ_COMPLETION_DATA_T)),
+- completion,
+- sizeof(VCHIQ_COMPLETION_DATA_T)) !=
+- 0) {
+- if (ret == 0)
+- ret = -EFAULT;
+- break;
+- }
+- instance->completion_remove++;
+- }
+-
+- if (msgbufcount != args.msgbufcount)
+- {
+- if (copy_to_user((void __user *)
+- &((VCHIQ_AWAIT_COMPLETION_T *)arg)->msgbufcount,
+- &msgbufcount, sizeof(msgbufcount)) != 0)
+- {
+- ret = -EFAULT;
+- break;
+- }
+- }
+- }
+-
+- if (ret != 0)
+- vcos_event_signal(&instance->remove_event);
+- DEBUG_TRACE(AWAIT_COMPLETION_LINE);
+- }
+- break;
+-
+- case VCHIQ_IOC_DEQUEUE_MESSAGE:
+- {
+- VCHIQ_DEQUEUE_MESSAGE_T args;
+- USER_SERVICE_T *user_service;
+- VCHIQ_HEADER_T *header;
+-
+- DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
+- if (copy_from_user
+- (&args, (const void __user *)arg,
+- sizeof(args)) != 0) {
+- ret = -EFAULT;
+- break;
+- }
+- user_service = &instance->services[args.handle];
+- if ((args.handle < 0) || (args.handle >= MAX_SERVICES) ||
+- (user_service->service == NULL) ||
+- (user_service->is_vchi == 0)) {
+- ret = -EINVAL;
+- break;
+- }
+- if (user_service->msg_remove == user_service->msg_insert)
+- {
+- if (!args.blocking)
+- {
+- DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
+- ret = -EWOULDBLOCK;
+- break;
+- }
+- user_service->dequeue_pending = 1;
+- do {
+- DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
+- if (vcos_event_wait(&user_service->insert_event) !=
+- VCOS_SUCCESS) {
+- vcos_log_info("DEQUEUE_MESSAGE interrupted");
+- ret = -EINTR;
+- break;
+- }
+- }
+- while (user_service->msg_remove == user_service->msg_insert);
+- }
+-
+- /* A read memory barrier is needed to stop prefetch of a stale
+- header value */
+- vcos_rmb();
+-
+- header = user_service->msg_queue[user_service->msg_remove &
+- (MSG_QUEUE_SIZE - 1)];
+- if (header == NULL)
+- ret = -ENOTCONN;
+- else if (header->size <= args.bufsize)
+- {
+- /* Copy to user space if msgbuf is not NULL */
+- if ((args.buf == NULL) ||
+- (copy_to_user((void __user *)args.buf, header->data,
+- header->size) == 0))
+- {
+- ret = header->size;
+- vchiq_release_message(&user_service->service->base,
+- header);
+- user_service->msg_remove++;
+- vcos_event_signal(&user_service->remove_event);
+- }
+- else
+- ret = -EFAULT;
+- }
+- else
+- {
+- vcos_log_error("header %x: bufsize %x < size %x",
+- (unsigned int)header, args.bufsize, header->size);
+- vcos_assert(0);
+- ret = -EMSGSIZE;
+- }
+- DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
+- }
+- break;
+-
+- case VCHIQ_IOC_GET_CLIENT_ID:
+- {
+- USER_SERVICE_T *user_service;
+- int handle = (int)arg;
+-
+- user_service = find_service_by_handle(instance, handle);
+- if (user_service != NULL)
+- ret = vchiq_get_client_id(&user_service->service->base);
+- else
+- ret = 0;
+- }
+- break;
+-
+- case VCHIQ_IOC_GET_CONFIG:
+- {
+- VCHIQ_GET_CONFIG_T args;
+- VCHIQ_CONFIG_T config;
+-
+- if (copy_from_user
+- (&args, (const void __user *)arg,
+- sizeof(args)) != 0) {
+- ret = -EFAULT;
+- break;
+- }
+- if (args.config_size > sizeof(config))
+- {
+- ret = -EINVAL;
+- break;
+- }
+- status = vchiq_get_config(instance, args.config_size, &config);
+- if (status == VCHIQ_SUCCESS)
+- {
+- if (copy_to_user((void __user *)args.pconfig,
+- &config, args.config_size) != 0)
+- {
+- ret = -EFAULT;
+- break;
+- }
+- }
+- }
+- break;
+-
+- case VCHIQ_IOC_SET_SERVICE_OPTION:
+- {
+- VCHIQ_SET_SERVICE_OPTION_T args;
+- USER_SERVICE_T *user_service;
+-
+- if (copy_from_user(
+- &args, (const void __user *)arg,
+- sizeof(args)) != 0)
+- {
+- ret = -EFAULT;
+- break;
+- }
+-
+- user_service = find_service_by_handle(instance, args.handle);
+- if (user_service != NULL)
+- {
+- status = vchiq_set_service_option(
+- &user_service->service->base,
+- args.option, args.value);
+- }
+- else
+- {
+- ret = -EINVAL;
+- }
+- }
+- break;
+-
+- case VCHIQ_IOC_DUMP_PHYS_MEM:
+- {
+- VCHIQ_DUMP_MEM_T args;
+-
+- if (copy_from_user
+- (&args, (const void __user *)arg,
+- sizeof(args)) != 0) {
+- ret = -EFAULT;
+- break;
+- }
+- dump_phys_mem( args.virt_addr, args.num_bytes );
+- }
+- break;
+-
+-
+- default:
+- ret = -ENOTTY;
+- break;
+- }
+-
+- if (ret == 0) {
+- if (status == VCHIQ_ERROR)
+- ret = -EIO;
+- else if (status == VCHIQ_RETRY)
+- ret = -EINTR;
+- }
+-
+- if ((ret < 0) && (ret != -EINTR) && (ret != -EWOULDBLOCK))
+- vcos_log_warn(" ioctl instance %lx, cmd %s -> status %d, %ld",
+- (unsigned long)instance,
+- (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ? ioctl_names[_IOC_NR(cmd)] :
+- "<invalid>", status, ret);
+- else
+- vcos_log_trace(" ioctl instance %lx, cmd %s -> status %d, %ld",
+- (unsigned long)instance,
+- (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ? ioctl_names[_IOC_NR(cmd)] :
+- "<invalid>", status, ret);
+-
+- return ret;
++ VCHIQ_INSTANCE_T instance = file->private_data;
++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
++ VCHIQ_SERVICE_T *service = NULL;
++ long ret = 0;
++ int i, rc;
++ DEBUG_INITIALISE(g_state.local)
++
++ vchiq_log_trace(vchiq_arm_log_level,
++ "vchiq_ioctl - instance %x, cmd %s, arg %lx",
++ (unsigned int)instance,
++ ((_IOC_TYPE(cmd) == VCHIQ_IOC_MAGIC) &&
++ (_IOC_NR(cmd) <= VCHIQ_IOC_MAX)) ?
++ ioctl_names[_IOC_NR(cmd)] : "<invalid>", arg);
++
++ switch (cmd) {
++ case VCHIQ_IOC_SHUTDOWN:
++ if (!instance->connected)
++ break;
++
++ /* Remove all services */
++ i = 0;
++ while ((service = next_service_by_instance(instance->state,
++ instance, &i)) != NULL) {
++ status = vchiq_remove_service(service->handle);
++ unlock_service(service);
++ if (status != VCHIQ_SUCCESS)
++ break;
++ }
++ service = NULL;
++
++ if (status == VCHIQ_SUCCESS) {
++ /* Wake the completion thread and ask it to exit */
++ instance->closing = 1;
++ up(&instance->insert_event);
++ }
++
++ break;
++
++ case VCHIQ_IOC_CONNECT:
++ if (instance->connected) {
++ ret = -EINVAL;
++ break;
++ }
++ rc = mutex_lock_interruptible(&instance->state->mutex);
++ if (rc != 0) {
++ vchiq_log_error(vchiq_arm_log_level,
++ "vchiq: connect: could not lock mutex for "
++ "state %d: %d",
++ instance->state->id, rc);
++ ret = -EINTR;
++ break;
++ }
++ status = vchiq_connect_internal(instance->state, instance);
++ mutex_unlock(&instance->state->mutex);
++
++ if (status == VCHIQ_SUCCESS)
++ instance->connected = 1;
++ else
++ vchiq_log_error(vchiq_arm_log_level,
++ "vchiq: could not connect: %d", status);
++ break;
++
++ case VCHIQ_IOC_CREATE_SERVICE: {
++ VCHIQ_CREATE_SERVICE_T args;
++ USER_SERVICE_T *user_service = NULL;
++ void *userdata;
++ int srvstate;
++
++ if (copy_from_user
++ (&args, (const void __user *)arg,
++ sizeof(args)) != 0) {
++ ret = -EFAULT;
++ break;
++ }
++
++ user_service = kmalloc(sizeof(USER_SERVICE_T), GFP_KERNEL);
++ if (!user_service) {
++ ret = -ENOMEM;
++ break;
++ }
++
++ if (args.is_open) {
++ if (!instance->connected) {
++ ret = -ENOTCONN;
++ break;
++ }
++ srvstate = VCHIQ_SRVSTATE_OPENING;
++ } else {
++ srvstate =
++ instance->connected ?
++ VCHIQ_SRVSTATE_LISTENING :
++ VCHIQ_SRVSTATE_HIDDEN;
++ }
++
++ userdata = args.params.userdata;
++ args.params.callback = service_callback;
++ args.params.userdata = user_service;
++ service = vchiq_add_service_internal(
++ instance->state,
++ &args.params, srvstate,
++ instance);
++
++ if (service != NULL) {
++ user_service->service = service;
++ user_service->userdata = userdata;
++ user_service->instance = instance;
++ user_service->is_vchi = args.is_vchi;
++ user_service->dequeue_pending = 0;
++ user_service->message_available_pos =
++ instance->completion_remove - 1;
++ user_service->msg_insert = 0;
++ user_service->msg_remove = 0;
++ sema_init(&user_service->insert_event, 0);
++ sema_init(&user_service->remove_event, 0);
++
++ if (args.is_open) {
++ status = vchiq_open_service_internal
++ (service, instance->pid);
++ if (status != VCHIQ_SUCCESS) {
++ vchiq_remove_service(service->handle);
++ service = NULL;
++ ret = (status == VCHIQ_RETRY) ?
++ -EINTR : -EIO;
++ user_service->service = NULL;
++ user_service->instance = NULL;
++ break;
++ }
++ }
++
++ if (copy_to_user((void __user *)
++ &(((VCHIQ_CREATE_SERVICE_T __user *)
++ arg)->handle),
++ (const void *)&service->handle,
++ sizeof(service->handle)) != 0) {
++ ret = -EFAULT;
++ vchiq_remove_service(service->handle);
++ kfree(user_service);
++ }
++
++ service = NULL;
++ } else {
++ ret = -EEXIST;
++ kfree(user_service);
++ }
++ } break;
++
++ case VCHIQ_IOC_CLOSE_SERVICE: {
++ VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg;
++
++ service = find_service_for_instance(instance, handle);
++ if (service != NULL)
++ status = vchiq_close_service(service->handle);
++ else
++ ret = -EINVAL;
++ } break;
++
++ case VCHIQ_IOC_REMOVE_SERVICE: {
++ VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg;
++
++ service = find_service_for_instance(instance, handle);
++ if (service != NULL)
++ status = vchiq_remove_service(service->handle);
++ else
++ ret = -EINVAL;
++ } break;
++
++ case VCHIQ_IOC_USE_SERVICE:
++ case VCHIQ_IOC_RELEASE_SERVICE: {
++ VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg;
++
++ service = find_service_for_instance(instance, handle);
++ if (service != NULL) {
++ status = (cmd == VCHIQ_IOC_USE_SERVICE) ?
++ vchiq_use_service_internal(service) :
++ vchiq_release_service_internal(service);
++ if (status != VCHIQ_SUCCESS) {
++ vchiq_log_error(vchiq_susp_log_level,
++ "%s: cmd %s returned error %d for "
++ "service %c%c%c%c:%03d",
++ __func__,
++ (cmd == VCHIQ_IOC_USE_SERVICE) ?
++ "VCHIQ_IOC_USE_SERVICE" :
++ "VCHIQ_IOC_RELEASE_SERVICE",
++ status,
++ VCHIQ_FOURCC_AS_4CHARS(
++ service->base.fourcc),
++ service->client_id);
++ ret = -EINVAL;
++ }
++ } else
++ ret = -EINVAL;
++ } break;
++
++ case VCHIQ_IOC_QUEUE_MESSAGE: {
++ VCHIQ_QUEUE_MESSAGE_T args;
++ if (copy_from_user
++ (&args, (const void __user *)arg,
++ sizeof(args)) != 0) {
++ ret = -EFAULT;
++ break;
++ }
++
++ service = find_service_for_instance(instance, args.handle);
++
++ if ((service != NULL) && (args.count <= MAX_ELEMENTS)) {
++ /* Copy elements into kernel space */
++ VCHIQ_ELEMENT_T elements[MAX_ELEMENTS];
++ if (copy_from_user(elements, args.elements,
++ args.count * sizeof(VCHIQ_ELEMENT_T)) == 0)
++ status = vchiq_queue_message
++ (args.handle,
++ elements, args.count);
++ else
++ ret = -EFAULT;
++ } else {
++ ret = -EINVAL;
++ }
++ } break;
++
++ case VCHIQ_IOC_QUEUE_BULK_TRANSMIT:
++ case VCHIQ_IOC_QUEUE_BULK_RECEIVE: {
++ VCHIQ_QUEUE_BULK_TRANSFER_T args;
++ struct bulk_waiter_node *waiter = NULL;
++ VCHIQ_BULK_DIR_T dir =
++ (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT) ?
++ VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE;
++
++ if (copy_from_user
++ (&args, (const void __user *)arg,
++ sizeof(args)) != 0) {
++ ret = -EFAULT;
++ break;
++ }
++
++ service = find_service_for_instance(instance, args.handle);
++ if (!service) {
++ ret = -EINVAL;
++ break;
++ }
++
++ if (args.mode == VCHIQ_BULK_MODE_BLOCKING) {
++ waiter = kzalloc(sizeof(struct bulk_waiter_node),
++ GFP_KERNEL);
++ if (!waiter) {
++ ret = -ENOMEM;
++ break;
++ }
++ args.userdata = &waiter->bulk_waiter;
++ } else if (args.mode == VCHIQ_BULK_MODE_WAITING) {
++ struct list_head *pos;
++ mutex_lock(&instance->bulk_waiter_list_mutex);
++ list_for_each(pos, &instance->bulk_waiter_list) {
++ if (list_entry(pos, struct bulk_waiter_node,
++ list)->pid == current->pid) {
++ waiter = list_entry(pos,
++ struct bulk_waiter_node,
++ list);
++ list_del(pos);
++ break;
++ }
++
++ }
++ mutex_unlock(&instance->bulk_waiter_list_mutex);
++ if (!waiter) {
++ vchiq_log_error(vchiq_arm_log_level,
++ "no bulk_waiter found for pid %d",
++ current->pid);
++ ret = -ESRCH;
++ break;
++ }
++ vchiq_log_info(vchiq_arm_log_level,
++ "found bulk_waiter %x for pid %d",
++ (unsigned int)waiter, current->pid);
++ args.userdata = &waiter->bulk_waiter;
++ }
++ status = vchiq_bulk_transfer
++ (args.handle,
++ VCHI_MEM_HANDLE_INVALID,
++ args.data, args.size,
++ args.userdata, args.mode,
++ dir);
++ if (!waiter)
++ break;
++ if ((status != VCHIQ_RETRY) || fatal_signal_pending(current) ||
++ !waiter->bulk_waiter.bulk) {
++ if (waiter->bulk_waiter.bulk) {
++ /* Cancel the signal when the transfer
++ ** completes. */
++ spin_lock(&bulk_waiter_spinlock);
++ waiter->bulk_waiter.bulk->userdata = NULL;
++ spin_unlock(&bulk_waiter_spinlock);
++ }
++ kfree(waiter);
++ } else {
++ const VCHIQ_BULK_MODE_T mode_waiting =
++ VCHIQ_BULK_MODE_WAITING;
++ waiter->pid = current->pid;
++ mutex_lock(&instance->bulk_waiter_list_mutex);
++ list_add(&waiter->list, &instance->bulk_waiter_list);
++ mutex_unlock(&instance->bulk_waiter_list_mutex);
++ vchiq_log_info(vchiq_arm_log_level,
++ "saved bulk_waiter %x for pid %d",
++ (unsigned int)waiter, current->pid);
++
++ if (copy_to_user((void __user *)
++ &(((VCHIQ_QUEUE_BULK_TRANSFER_T __user *)
++ arg)->mode),
++ (const void *)&mode_waiting,
++ sizeof(mode_waiting)) != 0)
++ ret = -EFAULT;
++ }
++ } break;
++
++ case VCHIQ_IOC_AWAIT_COMPLETION: {
++ VCHIQ_AWAIT_COMPLETION_T args;
++
++ DEBUG_TRACE(AWAIT_COMPLETION_LINE);
++ if (!instance->connected) {
++ ret = -ENOTCONN;
++ break;
++ }
++
++ if (copy_from_user(&args, (const void __user *)arg,
++ sizeof(args)) != 0) {
++ ret = -EFAULT;
++ break;
++ }
++
++ mutex_lock(&instance->completion_mutex);
++
++ DEBUG_TRACE(AWAIT_COMPLETION_LINE);
++ while ((instance->completion_remove ==
++ instance->completion_insert)
++ && !instance->closing) {
++ int rc;
++ DEBUG_TRACE(AWAIT_COMPLETION_LINE);
++ mutex_unlock(&instance->completion_mutex);
++ rc = down_interruptible(&instance->insert_event);
++ mutex_lock(&instance->completion_mutex);
++ if (rc != 0) {
++ DEBUG_TRACE(AWAIT_COMPLETION_LINE);
++ vchiq_log_info(vchiq_arm_log_level,
++ "AWAIT_COMPLETION interrupted");
++ ret = -EINTR;
++ break;
++ }
++ }
++ DEBUG_TRACE(AWAIT_COMPLETION_LINE);
++
++ /* A read memory barrier is needed to stop prefetch of a stale
++ ** completion record
++ */
++ rmb();
++
++ if ((ret == 0) && !instance->closing) {
++ int msgbufcount = args.msgbufcount;
++ for (ret = 0; ret < args.count; ret++) {
++ VCHIQ_COMPLETION_DATA_T *completion;
++ VCHIQ_SERVICE_T *service;
++ USER_SERVICE_T *user_service;
++ VCHIQ_HEADER_T *header;
++ if (instance->completion_remove ==
++ instance->completion_insert)
++ break;
++ completion = &instance->completions[
++ instance->completion_remove &
++ (MAX_COMPLETIONS - 1)];
++
++ service = completion->service_userdata;
++ user_service = service->base.userdata;
++ completion->service_userdata =
++ user_service->userdata;
++
++ header = completion->header;
++ if (header) {
++ void __user *msgbuf;
++ int msglen;
++
++ msglen = header->size +
++ sizeof(VCHIQ_HEADER_T);
++ /* This must be a VCHIQ-style service */
++ if (args.msgbufsize < msglen) {
++ vchiq_log_error(
++ vchiq_arm_log_level,
++ "header %x: msgbufsize"
++ " %x < msglen %x",
++ (unsigned int)header,
++ args.msgbufsize,
++ msglen);
++ WARN(1, "invalid message "
++ "size\n");
++ if (ret == 0)
++ ret = -EMSGSIZE;
++ break;
++ }
++ if (msgbufcount <= 0)
++ /* Stall here for lack of a
++ ** buffer for the message. */
++ break;
++ /* Get the pointer from user space */
++ msgbufcount--;
++ if (copy_from_user(&msgbuf,
++ (const void __user *)
++ &args.msgbufs[msgbufcount],
++ sizeof(msgbuf)) != 0) {
++ if (ret == 0)
++ ret = -EFAULT;
++ break;
++ }
++
++ /* Copy the message to user space */
++ if (copy_to_user(msgbuf, header,
++ msglen) != 0) {
++ if (ret == 0)
++ ret = -EFAULT;
++ break;
++ }
++
++ /* Now it has been copied, the message
++ ** can be released. */
++ vchiq_release_message(service->handle,
++ header);
++
++ /* The completion must point to the
++ ** msgbuf. */
++ completion->header = msgbuf;
++ }
++
++ if (completion->reason ==
++ VCHIQ_SERVICE_CLOSED) {
++ unlock_service(service);
++ kfree(user_service);
++ }
++
++ if (copy_to_user((void __user *)(
++ (size_t)args.buf +
++ ret * sizeof(VCHIQ_COMPLETION_DATA_T)),
++ completion,
++ sizeof(VCHIQ_COMPLETION_DATA_T)) != 0) {
++ if (ret == 0)
++ ret = -EFAULT;
++ break;
++ }
++
++ instance->completion_remove++;
++ }
++
++ if (msgbufcount != args.msgbufcount) {
++ if (copy_to_user((void __user *)
++ &((VCHIQ_AWAIT_COMPLETION_T *)arg)->
++ msgbufcount,
++ &msgbufcount,
++ sizeof(msgbufcount)) != 0) {
++ ret = -EFAULT;
++ }
++ }
++ }
++
++ if (ret != 0)
++ up(&instance->remove_event);
++ mutex_unlock(&instance->completion_mutex);
++ DEBUG_TRACE(AWAIT_COMPLETION_LINE);
++ } break;
++
++ case VCHIQ_IOC_DEQUEUE_MESSAGE: {
++ VCHIQ_DEQUEUE_MESSAGE_T args;
++ USER_SERVICE_T *user_service;
++ VCHIQ_HEADER_T *header;
++
++ DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
++ if (copy_from_user
++ (&args, (const void __user *)arg,
++ sizeof(args)) != 0) {
++ ret = -EFAULT;
++ break;
++ }
++ service = find_service_for_instance(instance, args.handle);
++ if (!service) {
++ ret = -EINVAL;
++ break;
++ }
++ user_service = (USER_SERVICE_T *)service->base.userdata;
++ if (user_service->is_vchi == 0) {
++ ret = -EINVAL;
++ break;
++ }
++
++ spin_lock(&msg_queue_spinlock);
++ if (user_service->msg_remove == user_service->msg_insert) {
++ if (!args.blocking) {
++ spin_unlock(&msg_queue_spinlock);
++ DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
++ ret = -EWOULDBLOCK;
++ break;
++ }
++ user_service->dequeue_pending = 1;
++ do {
++ spin_unlock(&msg_queue_spinlock);
++ DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
++ if (down_interruptible(
++ &user_service->insert_event) != 0) {
++ vchiq_log_info(vchiq_arm_log_level,
++ "DEQUEUE_MESSAGE interrupted");
++ ret = -EINTR;
++ break;
++ }
++ spin_lock(&msg_queue_spinlock);
++ } while (user_service->msg_remove ==
++ user_service->msg_insert);
++
++ if (ret)
++ break;
++ }
++
++ BUG_ON((int)(user_service->msg_insert -
++ user_service->msg_remove) < 0);
++
++ header = user_service->msg_queue[user_service->msg_remove &
++ (MSG_QUEUE_SIZE - 1)];
++ user_service->msg_remove++;
++ spin_unlock(&msg_queue_spinlock);
++
++ up(&user_service->remove_event);
++ if (header == NULL)
++ ret = -ENOTCONN;
++ else if (header->size <= args.bufsize) {
++ /* Copy to user space if msgbuf is not NULL */
++ if ((args.buf == NULL) ||
++ (copy_to_user((void __user *)args.buf,
++ header->data,
++ header->size) == 0)) {
++ ret = header->size;
++ vchiq_release_message(
++ service->handle,
++ header);
++ } else
++ ret = -EFAULT;
++ } else {
++ vchiq_log_error(vchiq_arm_log_level,
++ "header %x: bufsize %x < size %x",
++ (unsigned int)header, args.bufsize,
++ header->size);
++ WARN(1, "invalid size\n");
++ ret = -EMSGSIZE;
++ }
++ DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
++ } break;
++
++ case VCHIQ_IOC_GET_CLIENT_ID: {
++ VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg;
++
++ ret = vchiq_get_client_id(handle);
++ } break;
++
++ case VCHIQ_IOC_GET_CONFIG: {
++ VCHIQ_GET_CONFIG_T args;
++ VCHIQ_CONFIG_T config;
++
++ if (copy_from_user(&args, (const void __user *)arg,
++ sizeof(args)) != 0) {
++ ret = -EFAULT;
++ break;
++ }
++ if (args.config_size > sizeof(config)) {
++ ret = -EINVAL;
++ break;
++ }
++ status = vchiq_get_config(instance, args.config_size, &config);
++ if (status == VCHIQ_SUCCESS) {
++ if (copy_to_user((void __user *)args.pconfig,
++ &config, args.config_size) != 0) {
++ ret = -EFAULT;
++ break;
++ }
++ }
++ } break;
++
++ case VCHIQ_IOC_SET_SERVICE_OPTION: {
++ VCHIQ_SET_SERVICE_OPTION_T args;
++
++ if (copy_from_user(
++ &args, (const void __user *)arg,
++ sizeof(args)) != 0) {
++ ret = -EFAULT;
++ break;
++ }
++
++ service = find_service_for_instance(instance, args.handle);
++ if (!service) {
++ ret = -EINVAL;
++ break;
++ }
++
++ status = vchiq_set_service_option(
++ args.handle, args.option, args.value);
++ } break;
++
++ case VCHIQ_IOC_DUMP_PHYS_MEM: {
++ VCHIQ_DUMP_MEM_T args;
++
++ if (copy_from_user
++ (&args, (const void __user *)arg,
++ sizeof(args)) != 0) {
++ ret = -EFAULT;
++ break;
++ }
++ dump_phys_mem(args.virt_addr, args.num_bytes);
++ } break;
++
++ default:
++ ret = -ENOTTY;
++ break;
++ }
++
++ if (service)
++ unlock_service(service);
++
++ if (ret == 0) {
++ if (status == VCHIQ_ERROR)
++ ret = -EIO;
++ else if (status == VCHIQ_RETRY)
++ ret = -EINTR;
++ }
++
++ if ((status == VCHIQ_SUCCESS) && (ret < 0) && (ret != -EINTR) &&
++ (ret != -EWOULDBLOCK))
++ vchiq_log_info(vchiq_arm_log_level,
++ " ioctl instance %lx, cmd %s -> status %d, %ld",
++ (unsigned long)instance,
++ (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ?
++ ioctl_names[_IOC_NR(cmd)] :
++ "<invalid>",
++ status, ret);
++ else
++ vchiq_log_trace(vchiq_arm_log_level,
++ " ioctl instance %lx, cmd %s -> status %d, %ld",
++ (unsigned long)instance,
++ (_IOC_NR(cmd) <= VCHIQ_IOC_MAX) ?
++ ioctl_names[_IOC_NR(cmd)] :
++ "<invalid>",
++ status, ret);
++
++ return ret;
+ }
+
+ /****************************************************************************
+@@ -941,39 +1005,49 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ static int
+ vchiq_open(struct inode *inode, struct file *file)
+ {
+- int dev = iminor(inode) & 0x0f;
+- vcos_log_info("vchiq_open");
+- switch (dev) {
+- case VCHIQ_MINOR:
+- {
+- VCHIQ_STATE_T *state = vchiq_get_state();
+- VCHIQ_INSTANCE_T instance;
+-
+- if (!state)
+- {
+- vcos_log_error( "vchiq has no connection to VideoCore");
+- return -ENOTCONN;
+- }
+-
+- instance = kzalloc(sizeof(*instance), GFP_KERNEL);
+- if (!instance)
+- return -ENOMEM;
+-
+- instance->state = state;
+- instance->pid = current->tgid;
+- vcos_event_create(&instance->insert_event, DEVICE_NAME);
+- vcos_event_create(&instance->remove_event, DEVICE_NAME);
+-
+- file->private_data = instance;
+- }
+- break;
+-
+- default:
+- vcos_log_error("Unknown minor device: %d", dev);
+- return -ENXIO;
+- }
+-
+- return 0;
++ int dev = iminor(inode) & 0x0f;
++ vchiq_log_info(vchiq_arm_log_level, "vchiq_open");
++ switch (dev) {
++ case VCHIQ_MINOR: {
++ int ret;
++ VCHIQ_STATE_T *state = vchiq_get_state();
++ VCHIQ_INSTANCE_T instance;
++
++ if (!state) {
++ vchiq_log_error(vchiq_arm_log_level,
++ "vchiq has no connection to VideoCore");
++ return -ENOTCONN;
++ }
++
++ instance = kzalloc(sizeof(*instance), GFP_KERNEL);
++ if (!instance)
++ return -ENOMEM;
++
++ instance->state = state;
++ instance->pid = current->tgid;
++
++ ret = vchiq_proc_add_instance(instance);
++ if (ret != 0) {
++ kfree(instance);
++ return ret;
++ }
++
++ sema_init(&instance->insert_event, 0);
++ sema_init(&instance->remove_event, 0);
++ mutex_init(&instance->completion_mutex);
++ mutex_init(&instance->bulk_waiter_list_mutex);
++ INIT_LIST_HEAD(&instance->bulk_waiter_list);
++
++ file->private_data = instance;
++ } break;
++
++ default:
++ vchiq_log_error(vchiq_arm_log_level,
++ "Unknown minor device: %d", dev);
++ return -ENXIO;
++ }
++
++ return 0;
+ }
+
+ /****************************************************************************
+@@ -985,74 +1059,131 @@ vchiq_open(struct inode *inode, struct file *file)
+ static int
+ vchiq_release(struct inode *inode, struct file *file)
+ {
+- int dev = iminor(inode) & 0x0f;
+- int ret = 0;
+- switch (dev) {
+- case VCHIQ_MINOR:
+- {
+- VCHIQ_INSTANCE_T instance = file->private_data;
+- int i;
+-
+- vcos_log_info("vchiq_release: instance=%lx",
+- (unsigned long)instance);
+-
+- instance->closing = 1;
+-
+- /* Wake the slot handler if the completion queue is full */
+- vcos_event_signal(&instance->remove_event);
+-
+- /* Mark all services for termination... */
+-
+- for (i = 0; i < MAX_SERVICES; i++) {
+- USER_SERVICE_T *user_service =
+- &instance->services[i];
+- if (user_service->service != NULL)
+- {
+- /* Wake the slot handler if the msg queue is full */
+- vcos_event_signal(&user_service->remove_event);
+-
+- if ((user_service->service->srvstate != VCHIQ_SRVSTATE_CLOSEWAIT) &&
+- (user_service->service->srvstate != VCHIQ_SRVSTATE_LISTENING))
+- {
+- vchiq_terminate_service_internal(user_service->service);
+- }
+- }
+- }
+-
+- /* ...and wait for them to die */
+-
+- for (i = 0; i < MAX_SERVICES; i++) {
+- USER_SERVICE_T *user_service =
+- &instance->services[i];
+- if (user_service->service != NULL)
+- {
+- /* Wait in this non-portable fashion because interruptible
+- calls will not block in this context. */
+- while ((user_service->service->srvstate != VCHIQ_SRVSTATE_CLOSEWAIT) &&
+- (user_service->service->srvstate != VCHIQ_SRVSTATE_LISTENING))
+- {
+- down(&user_service->service->remove_event);
+- }
+-
+- vchiq_free_service_internal
+- (user_service->service);
+- }
+- }
+-
+- vcos_event_delete(&instance->insert_event);
+- vcos_event_delete(&instance->remove_event);
+-
+- kfree(instance);
+- file->private_data = NULL;
+- }
+- break;
+-
+- default:
+- vcos_log_error("Unknown minor device: %d", dev);
+- ret = -ENXIO;
+- }
+-
+- return ret;
++ int dev = iminor(inode) & 0x0f;
++ int ret = 0;
++ switch (dev) {
++ case VCHIQ_MINOR: {
++ VCHIQ_INSTANCE_T instance = file->private_data;
++ VCHIQ_STATE_T *state = vchiq_get_state();
++ VCHIQ_SERVICE_T *service;
++ int i;
++
++ vchiq_log_info(vchiq_arm_log_level,
++ "vchiq_release: instance=%lx",
++ (unsigned long)instance);
++
++ if (state) {
++ /* Ensure videocore is awake to allow termination. */
++ vchiq_use_internal(instance->state, NULL,
++ USE_TYPE_VCHIQ);
++ }
++
++ mutex_lock(&instance->completion_mutex);
++
++ /* Wake the completion thread and ask it to exit */
++ instance->closing = 1;
++ up(&instance->insert_event);
++
++ mutex_unlock(&instance->completion_mutex);
++
++ /* Wake the slot handler if the completion queue is full. */
++ up(&instance->remove_event);
++
++ /* Mark all services for termination... */
++ i = 0;
++ while ((service = next_service_by_instance(state, instance,
++ &i)) != NULL) {
++ USER_SERVICE_T *user_service = service->base.userdata;
++
++ /* Wake the slot handler if the msg queue is full. */
++ up(&user_service->remove_event);
++
++ vchiq_terminate_service_internal(service);
++ unlock_service(service);
++ }
++
++ /* ...and wait for them to die */
++ i = 0;
++ while ((service = next_service_by_instance(state, instance, &i))
++ != NULL) {
++ USER_SERVICE_T *user_service = service->base.userdata;
++
++ down(&service->remove_event);
++
++ BUG_ON(service->srvstate != VCHIQ_SRVSTATE_FREE);
++
++ spin_lock(&msg_queue_spinlock);
++
++ while (user_service->msg_remove !=
++ user_service->msg_insert) {
++ VCHIQ_HEADER_T *header = user_service->
++ msg_queue[user_service->msg_remove &
++ (MSG_QUEUE_SIZE - 1)];
++ user_service->msg_remove++;
++ spin_unlock(&msg_queue_spinlock);
++
++ if (header)
++ vchiq_release_message(
++ service->handle,
++ header);
++ spin_lock(&msg_queue_spinlock);
++ }
++
++ spin_unlock(&msg_queue_spinlock);
++
++ unlock_service(service);
++ kfree(user_service);
++ }
++
++ /* Release any closed services */
++ while (instance->completion_remove !=
++ instance->completion_insert) {
++ VCHIQ_COMPLETION_DATA_T *completion;
++ VCHIQ_SERVICE_T *service;
++ completion = &instance->completions[
++ instance->completion_remove &
++ (MAX_COMPLETIONS - 1)];
++ service = completion->service_userdata;
++ if (completion->reason == VCHIQ_SERVICE_CLOSED)
++ unlock_service(service);
++ instance->completion_remove++;
++ }
++
++ if (state) {
++ /* Release the PEER service count. */
++ vchiq_release_internal(instance->state, NULL);
++ }
++
++ {
++ struct list_head *pos, *next;
++ list_for_each_safe(pos, next,
++ &instance->bulk_waiter_list) {
++ struct bulk_waiter_node *waiter;
++ waiter = list_entry(pos,
++ struct bulk_waiter_node,
++ list);
++ list_del(pos);
++ vchiq_log_info(vchiq_arm_log_level,
++ "bulk_waiter - cleaned up %x "
++ "for pid %d",
++ (unsigned int)waiter, waiter->pid);
++ kfree(waiter);
++ }
++ }
++
++ vchiq_proc_remove_instance(instance);
++
++ kfree(instance);
++ file->private_data = NULL;
++ } break;
++
++ default:
++ vchiq_log_error(vchiq_arm_log_level,
++ "Unknown minor device: %d", dev);
++ ret = -ENXIO;
++ }
++
++ return ret;
+ }
+
+ /****************************************************************************
+@@ -1064,40 +1195,37 @@ vchiq_release(struct inode *inode, struct file *file)
+ void
+ vchiq_dump(void *dump_context, const char *str, int len)
+ {
+- DUMP_CONTEXT_T *context = (DUMP_CONTEXT_T *)dump_context;
+-
+- if ((context->actual >= 0) && (context->actual < context->space))
+- {
+- int copy_bytes;
+- if (context->offset > 0)
+- {
+- int skip_bytes = vcos_min(len, context->offset);
+- str += skip_bytes;
+- len -= skip_bytes;
+- context->offset -= skip_bytes;
+- if (context->offset > 0)
+- return;
+- }
+- copy_bytes = vcos_min(len, context->space - context->actual);
+- if (copy_bytes == 0)
+- return;
+- if (copy_to_user(context->buf + context->actual, str, copy_bytes))
+- context->actual = -EFAULT;
+- context->actual += copy_bytes;
+- len -= copy_bytes;
+-
+- /* If tne terminating NUL is included in the length, then it marks
+- * the end of a line and should be replaced with a carriage return.
+- */
+- if ((len == 0) && (str[copy_bytes - 1] == '\0'))
+- {
+- char cr = '\n';
+- if (copy_to_user(context->buf + context->actual - 1, &cr, 1))
+- {
+- context->actual = -EFAULT;
+- }
+- }
+- }
++ DUMP_CONTEXT_T *context = (DUMP_CONTEXT_T *)dump_context;
++
++ if ((context->actual >= 0) && (context->actual < context->space)) {
++ int copy_bytes;
++ if (context->offset > 0) {
++ int skip_bytes = min(len, (int)context->offset);
++ str += skip_bytes;
++ len -= skip_bytes;
++ context->offset -= skip_bytes;
++ if (context->offset > 0)
++ return;
++ }
++ copy_bytes = min(len, (int)(context->space - context->actual));
++ if (copy_bytes == 0)
++ return;
++ if (copy_to_user(context->buf + context->actual, str,
++ copy_bytes))
++ context->actual = -EFAULT;
++ context->actual += copy_bytes;
++ len -= copy_bytes;
++
++ /* If tne terminating NUL is included in the length, then it
++ ** marks the end of a line and should be replaced with a
++ ** carriage return. */
++ if ((len == 0) && (str[copy_bytes - 1] == '\0')) {
++ char cr = '\n';
++ if (copy_to_user(context->buf + context->actual - 1,
++ &cr, 1))
++ context->actual = -EFAULT;
++ }
++ }
+ }
+
+ /****************************************************************************
+@@ -1109,49 +1237,48 @@ vchiq_dump(void *dump_context, const char *str, int len)
+ void
+ vchiq_dump_platform_instances(void *dump_context)
+ {
+- VCHIQ_STATE_T *state = vchiq_get_state();
+- char buf[80];
+- int len;
+- int i;
+-
+- /* There is no list of instances, so instead scan all services,
+- marking those that have been dumped. */
+-
+- for (i = 0; i < state->unused_service; i++)
+- {
+- VCHIQ_SERVICE_T *service = state->services[i];
+- VCHIQ_INSTANCE_T instance;
+-
+- if (service
+- && ((instance = service->instance) != NULL)
+- && (service->base.callback == service_callback))
+- instance->mark = 0;
+- }
+-
+- for (i = 0; i < state->unused_service; i++)
+- {
+- VCHIQ_SERVICE_T *service = state->services[i];
+- VCHIQ_INSTANCE_T instance;
+-
+- if (service
+- && ((instance = service->instance) != NULL)
+- && (service->base.callback == service_callback))
+- {
+- if (!instance->mark)
+- {
+- len = vcos_snprintf(buf, sizeof(buf),
+- "Instance %x: pid %d,%s completions %d/%d",
+- (unsigned int)instance, instance->pid,
+- instance->connected ? " connected," : "",
+- instance->completion_insert - instance->completion_remove,
+- MAX_COMPLETIONS);
+-
+- vchiq_dump(dump_context, buf, len + 1);
+-
+- instance->mark = 1;
+- }
+- }
+- }
++ VCHIQ_STATE_T *state = vchiq_get_state();
++ char buf[80];
++ int len;
++ int i;
++
++ /* There is no list of instances, so instead scan all services,
++ marking those that have been dumped. */
++
++ for (i = 0; i < state->unused_service; i++) {
++ VCHIQ_SERVICE_T *service = state->services[i];
++ VCHIQ_INSTANCE_T instance;
++
++ if (service && (service->base.callback == service_callback)) {
++ instance = service->instance;
++ if (instance)
++ instance->mark = 0;
++ }
++ }
++
++ for (i = 0; i < state->unused_service; i++) {
++ VCHIQ_SERVICE_T *service = state->services[i];
++ VCHIQ_INSTANCE_T instance;
++
++ if (service && (service->base.callback == service_callback)) {
++ instance = service->instance;
++ if (instance && !instance->mark) {
++ len = snprintf(buf, sizeof(buf),
++ "Instance %x: pid %d,%s completions "
++ "%d/%d",
++ (unsigned int)instance, instance->pid,
++ instance->connected ? " connected, " :
++ "",
++ instance->completion_insert -
++ instance->completion_remove,
++ MAX_COMPLETIONS);
++
++ vchiq_dump(dump_context, buf, len + 1);
++
++ instance->mark = 1;
++ }
++ }
++ }
+ }
+
+ /****************************************************************************
+@@ -1163,26 +1290,26 @@ vchiq_dump_platform_instances(void *dump_context)
+ void
+ vchiq_dump_platform_service_state(void *dump_context, VCHIQ_SERVICE_T *service)
+ {
+- USER_SERVICE_T *user_service = (USER_SERVICE_T *)service->base.userdata;
+- char buf[80];
+- int len;
+-
+- len = vcos_snprintf(buf, sizeof(buf), " instance %x",
+- service->instance);
+-
+- if ((service->base.callback == service_callback) && user_service->is_vchi)
+- {
+- len += vcos_snprintf(buf + len, sizeof(buf) - len,
+- ", %d/%d messages",
+- user_service->msg_insert - user_service->msg_remove,
+- MSG_QUEUE_SIZE);
+-
+- if (user_service->dequeue_pending)
+- len += vcos_snprintf(buf + len, sizeof(buf) - len,
+- " (dequeue pending)");
+- }
+-
+- vchiq_dump(dump_context, buf, len + 1);
++ USER_SERVICE_T *user_service = (USER_SERVICE_T *)service->base.userdata;
++ char buf[80];
++ int len;
++
++ len = snprintf(buf, sizeof(buf), " instance %x",
++ (unsigned int)service->instance);
++
++ if ((service->base.callback == service_callback) &&
++ user_service->is_vchi) {
++ len += snprintf(buf + len, sizeof(buf) - len,
++ ", %d/%d messages",
++ user_service->msg_insert - user_service->msg_remove,
++ MSG_QUEUE_SIZE);
++
++ if (user_service->dequeue_pending)
++ len += snprintf(buf + len, sizeof(buf) - len,
++ " (dequeue pending)");
++ }
++
++ vchiq_dump(dump_context, buf, len + 1);
+ }
+
+ /****************************************************************************
+@@ -1192,79 +1319,82 @@ vchiq_dump_platform_service_state(void *dump_context, VCHIQ_SERVICE_T *service)
+ ***************************************************************************/
+
+ static void
+-dump_phys_mem( void *virt_addr, uint32_t num_bytes )
++dump_phys_mem(void *virt_addr, uint32_t num_bytes)
+ {
+- int rc;
+- uint8_t *end_virt_addr = virt_addr + num_bytes;
+- int num_pages;
+- int offset;
+- int end_offset;
+- int page_idx;
+- int prev_idx;
+- struct page *page;
+- struct page **pages;
+- uint8_t *kmapped_virt_ptr;
+-
+- // Align virtAddr and endVirtAddr to 16 byte boundaries.
+-
+- virt_addr = (void *)((unsigned long)virt_addr & ~0x0fuL );
+- end_virt_addr = (void *)(( (unsigned long)end_virt_addr + 15uL ) & ~0x0fuL);
+-
+- offset = (int)(long)virt_addr & ( PAGE_SIZE - 1 );
+- end_offset = (int)(long)end_virt_addr & ( PAGE_SIZE - 1 );
+-
+- num_pages = (offset + num_bytes + PAGE_SIZE - 1) / PAGE_SIZE;
+-
+- if (( pages = kmalloc( sizeof( struct page *) * num_pages, GFP_KERNEL )) == NULL )
+- {
+- printk( KERN_ERR "Unable to allocation memory for %d pages\n", num_pages );
+- return;
+- }
+-
+- down_read( &current->mm->mmap_sem );
+- rc = get_user_pages( current, /* task */
+- current->mm, /* mm */
+- (unsigned long)virt_addr, /* start */
+- num_pages, /* len */
+- 0, /* write */
+- 0, /* force */
+- pages, /* pages (array of pointers to page) */
+- NULL ); /* vmas */
+- up_read( &current->mm->mmap_sem );
+-
+- prev_idx = -1;
+- page = NULL;
+-
+- while ( offset < end_offset ) {
+-
+- int page_offset = offset % PAGE_SIZE;
+- page_idx = offset / PAGE_SIZE;
+-
+- if ( page_idx != prev_idx ) {
+-
+- if (page != NULL) {
+- kunmap( page );
+- }
+- page = pages[page_idx];
+- kmapped_virt_ptr = kmap( page );
+-
+- prev_idx = page_idx;
+- }
+-
+- vcos_log_dump_mem_impl( &vchiq_arm_log_category, "ph",
+- (uint32_t)(unsigned long)&kmapped_virt_ptr[page_offset],
+- &kmapped_virt_ptr[page_offset], 16 );
+-
+- offset += 16;
+- }
+- if (page != NULL) {
+- kunmap( page );
+- }
+-
+- for ( page_idx = 0; page_idx < num_pages; page_idx++ ) {
+- page_cache_release( pages[page_idx] );
+- }
+- kfree( pages );
++ int rc;
++ uint8_t *end_virt_addr = virt_addr + num_bytes;
++ int num_pages;
++ int offset;
++ int end_offset;
++ int page_idx;
++ int prev_idx;
++ struct page *page;
++ struct page **pages;
++ uint8_t *kmapped_virt_ptr;
++
++ /* Align virtAddr and endVirtAddr to 16 byte boundaries. */
++
++ virt_addr = (void *)((unsigned long)virt_addr & ~0x0fuL);
++ end_virt_addr = (void *)(((unsigned long)end_virt_addr + 15uL) &
++ ~0x0fuL);
++
++ offset = (int)(long)virt_addr & (PAGE_SIZE - 1);
++ end_offset = (int)(long)end_virt_addr & (PAGE_SIZE - 1);
++
++ num_pages = (offset + num_bytes + PAGE_SIZE - 1) / PAGE_SIZE;
++
++ pages = kmalloc(sizeof(struct page *) * num_pages, GFP_KERNEL);
++ if (pages == NULL) {
++ vchiq_log_error(vchiq_arm_log_level,
++ "Unable to allocation memory for %d pages\n",
++ num_pages);
++ return;
++ }
++
++ down_read(&current->mm->mmap_sem);
++ rc = get_user_pages(current, /* task */
++ current->mm, /* mm */
++ (unsigned long)virt_addr, /* start */
++ num_pages, /* len */
++ 0, /* write */
++ 0, /* force */
++ pages, /* pages (array of page pointers) */
++ NULL); /* vmas */
++ up_read(&current->mm->mmap_sem);
++
++ prev_idx = -1;
++ page = NULL;
++
++ while (offset < end_offset) {
++
++ page_idx = offset / PAGE_SIZE;
++ int page_offset = offset % PAGE_SIZE;
++
++ if (page_idx != prev_idx) {
++
++ if (page != NULL)
++ kunmap(page);
++ page = pages[page_idx];
++ kmapped_virt_ptr = kmap(page);
++
++ prev_idx = page_idx;
++ }
++
++ if (vchiq_arm_log_level >= VCHIQ_LOG_TRACE)
++ vchiq_log_dump_mem("ph",
++ (uint32_t)(unsigned long)&kmapped_virt_ptr[
++ page_offset],
++ &kmapped_virt_ptr[page_offset], 16);
++
++ offset += 16;
++ }
++ if (page != NULL)
++ kunmap(page);
++
++ for (page_idx = 0; page_idx < num_pages; page_idx++)
++ page_cache_release(pages[page_idx]);
++
++ kfree(pages);
+ }
+
+ /****************************************************************************
+@@ -1274,548 +1404,1182 @@ dump_phys_mem( void *virt_addr, uint32_t num_bytes )
+ ***************************************************************************/
+
+ static ssize_t
+-vchiq_read(struct file * file, char __user * buf,
+- size_t count, loff_t *ppos)
++vchiq_read(struct file *file, char __user *buf,
++ size_t count, loff_t *ppos)
+ {
+- DUMP_CONTEXT_T context;
+- context.buf = buf;
+- context.actual = 0;
+- context.space = count;
+- context.offset = *ppos;
++ DUMP_CONTEXT_T context;
++ context.buf = buf;
++ context.actual = 0;
++ context.space = count;
++ context.offset = *ppos;
+
+- vchiq_dump_state(&context, &g_state);
++ vchiq_dump_state(&context, &g_state);
+
+- if (context.actual >= 0)
+- *ppos += context.actual;
++ if (context.actual >= 0)
++ *ppos += context.actual;
+
+- return context.actual;
++ return context.actual;
+ }
+
+ VCHIQ_STATE_T *
+ vchiq_get_state(void)
+ {
+
+- if (g_state.remote == NULL)
+- {
+- printk( "%s: g_state.remote == NULL\n", __func__ );
+- }
+- else
+- {
+- if ( g_state.remote->initialised != 1)
+- {
+- printk( "%s: g_state.remote->initialised != 1 (%d)\n", __func__, g_state.remote->initialised );
+- }
+- }
+-
+- return ((g_state.remote != NULL) &&
+- (g_state.remote->initialised == 1)) ? &g_state : NULL;
++ if (g_state.remote == NULL)
++ printk(KERN_ERR "%s: g_state.remote == NULL\n", __func__);
++ else if (g_state.remote->initialised != 1)
++ printk(KERN_ERR "%s: g_state.remote->initialised != 1 (%d)\n",
++ __func__, g_state.remote->initialised);
++
++ return ((g_state.remote != NULL) &&
++ (g_state.remote->initialised == 1)) ? &g_state : NULL;
+ }
+
+ static const struct file_operations
+ vchiq_fops = {
+- .owner = THIS_MODULE,
+- .unlocked_ioctl = vchiq_ioctl,
+- .open = vchiq_open,
+- .release = vchiq_release,
+- .read = vchiq_read
++ .owner = THIS_MODULE,
++ .unlocked_ioctl = vchiq_ioctl,
++ .open = vchiq_open,
++ .release = vchiq_release,
++ .read = vchiq_read
+ };
+
+ /*
+ * Autosuspend related functionality
+ */
+
+-static int vchiq_videocore_wanted(VCHIQ_STATE_T* state)
++int
++vchiq_videocore_wanted(VCHIQ_STATE_T *state)
+ {
+- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+- if(!arm_state)
+- { // autosuspend not supported - always return wanted
+- return 1;
+- }
+- else if(!arm_state->videocore_use_count)
+- { // usage count zero - check for override
+- return vchiq_platform_videocore_wanted(state);
+- }
+- else
+- { // non-zero usage count - videocore still required
+- return 1;
+- }
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ if (!arm_state)
++ /* autosuspend not supported - always return wanted */
++ return 1;
++ else if (arm_state->blocked_count)
++ return 1;
++ else if (!arm_state->videocore_use_count)
++ /* usage count zero - check for override unless we're forcing */
++ if (arm_state->resume_blocked)
++ return 0;
++ else
++ return vchiq_platform_videocore_wanted(state);
++ else
++ /* non-zero usage count - videocore still required */
++ return 1;
++}
++static VCHIQ_STATUS_T vchiq_keepalive_vchiq_callback(VCHIQ_REASON_T reason,
++ VCHIQ_HEADER_T *header,
++ VCHIQ_SERVICE_HANDLE_T service_user,
++ void *bulk_user)
++{
++ vchiq_log_error(vchiq_susp_log_level,
++ "%s callback reason %d", __func__, reason);
++ return 0;
++}
++
++static int
++vchiq_keepalive_thread_func(void *v)
++{
++ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v;
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++
++ VCHIQ_STATUS_T status;
++ VCHIQ_INSTANCE_T instance;
++ VCHIQ_SERVICE_HANDLE_T ka_handle;
++
++ VCHIQ_SERVICE_PARAMS_T params = {
++ .fourcc = VCHIQ_MAKE_FOURCC('K', 'E', 'E', 'P'),
++ .callback = vchiq_keepalive_vchiq_callback,
++ .version = KEEPALIVE_VER,
++ .version_min = KEEPALIVE_VER_MIN
++ };
++
++ status = vchiq_initialise(&instance);
++ if (status != VCHIQ_SUCCESS) {
++ vchiq_log_error(vchiq_susp_log_level,
++ "%s vchiq_initialise failed %d", __func__, status);
++ goto exit;
++ }
++
++ status = vchiq_connect(instance);
++ if (status != VCHIQ_SUCCESS) {
++ vchiq_log_error(vchiq_susp_log_level,
++ "%s vchiq_connect failed %d", __func__, status);
++ goto shutdown;
++ }
++
++ status = vchiq_add_service(instance, &params, &ka_handle);
++ if (status != VCHIQ_SUCCESS) {
++ vchiq_log_error(vchiq_susp_log_level,
++ "%s vchiq_open_service failed %d", __func__, status);
++ goto shutdown;
++ }
++
++ while (1) {
++ long rc = 0, uc = 0;
++ if (wait_for_completion_interruptible(&arm_state->ka_evt)
++ != 0) {
++ vchiq_log_error(vchiq_susp_log_level,
++ "%s interrupted", __func__);
++ flush_signals(current);
++ continue;
++ }
++
++ /* read and clear counters. Do release_count then use_count to
++ * prevent getting more releases than uses */
++ rc = atomic_xchg(&arm_state->ka_release_count, 0);
++ uc = atomic_xchg(&arm_state->ka_use_count, 0);
++
++ /* Call use/release service the requisite number of times.
++ * Process use before release so use counts don't go negative */
++ while (uc--) {
++ atomic_inc(&arm_state->ka_use_ack_count);
++ status = vchiq_use_service(ka_handle);
++ if (status != VCHIQ_SUCCESS) {
++ vchiq_log_error(vchiq_susp_log_level,
++ "%s vchiq_use_service error %d",
++ __func__, status);
++ }
++ }
++ while (rc--) {
++ status = vchiq_release_service(ka_handle);
++ if (status != VCHIQ_SUCCESS) {
++ vchiq_log_error(vchiq_susp_log_level,
++ "%s vchiq_release_service error %d",
++ __func__, status);
++ }
++ }
++ }
++
++shutdown:
++ vchiq_shutdown(instance);
++exit:
++ return 0;
+ }
+
+
+-/* Called by the lp thread */
+-static void *
+-lp_func(void *v)
++VCHIQ_STATUS_T
++vchiq_arm_init_state(VCHIQ_STATE_T *state, VCHIQ_ARM_STATE_T *arm_state)
+ {
+- VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v;
+- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+-
+- while (1) {
+- vcos_event_wait(&arm_state->lp_evt);
+-
+- vcos_mutex_lock(&arm_state->use_count_mutex);
+- if (!vchiq_videocore_wanted(state))
+- {
+- arm_state->suspend_pending = 1;
+- }
+- vcos_mutex_unlock(&arm_state->use_count_mutex);
+-
+- vchiq_arm_vcsuspend(state);
+- }
+- return NULL;
++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
++ char threadname[10];
++
++ if (arm_state) {
++ mutex_init(&arm_state->vc_use_cnt_mutex);
++ rwlock_init(&arm_state->susp_res_lock);
++
++ init_completion(&arm_state->ka_evt);
++ atomic_set(&arm_state->ka_use_count, 0);
++ atomic_set(&arm_state->ka_use_ack_count, 0);
++ atomic_set(&arm_state->ka_release_count, 0);
++
++ init_completion(&arm_state->vc_suspend_complete);
++
++ init_completion(&arm_state->vc_resume_complete);
++ /* Initialise to 'done' state. We only want to block on resume
++ * completion while videocore is suspended. */
++ set_resume_state(arm_state, VC_RESUME_RESUMED);
++
++ init_completion(&arm_state->resume_blocker);
++ /* Initialise to 'done' state. We only want to block on this
++ * completion while resume is blocked */
++ complete_all(&arm_state->resume_blocker);
++
++ init_completion(&arm_state->blocked_blocker);
++ /* Initialise to 'done' state. We only want to block on this
++ * completion while things are waiting on the resume blocker */
++ complete_all(&arm_state->blocked_blocker);
++
++ snprintf(threadname, sizeof(threadname), "VCHIQka-%d",
++ state->id);
++ arm_state->ka_thread = kthread_create(
++ &vchiq_keepalive_thread_func,
++ (void *)state,
++ threadname);
++ if (arm_state->ka_thread == NULL) {
++ vchiq_log_error(vchiq_susp_log_level,
++ "vchiq: FATAL: couldn't create thread %s",
++ threadname);
++ status = VCHIQ_ERROR;
++ }
++
++ arm_state->suspend_timer_timeout = SUSPEND_TIMER_TIMEOUT_MS;
++ arm_state->suspend_timer_running = 0;
++ init_timer(&arm_state->suspend_timer);
++ arm_state->suspend_timer.data = (unsigned long)(state);
++ arm_state->suspend_timer.function = suspend_timer_callback;
++
++ arm_state->first_connect = 0;
++
++ }
++ return status;
+ }
+-/* Called by the hp thread */
+-static void *
+-hp_func(void *v)
++
++/*
++** Functions to modify the state variables;
++** set_suspend_state
++** set_resume_state
++**
++** There are more state variables than we might like, so ensure they remain in
++** step. Suspend and resume state are maintained separately, since most of
++** these state machines can operate independently. However, there are a few
++** states where state transitions in one state machine cause a reset to the
++** other state machine. In addition, there are some completion events which
++** need to occur on state machine reset and end-state(s), so these are also
++** dealt with in these functions.
++**
++** In all states we set the state variable according to the input, but in some
++** cases we perform additional steps outlined below;
++**
++** VC_SUSPEND_IDLE - Initialise the suspend completion at the same time.
++** The suspend completion is completed after any suspend
++** attempt. When we reset the state machine we also reset
++** the completion. This reset occurs when videocore is
++** resumed, and also if we initiate suspend after a suspend
++** failure.
++**
++** VC_SUSPEND_IN_PROGRESS - This state is considered the point of no return for
++** suspend - ie from this point on we must try to suspend
++** before resuming can occur. We therefore also reset the
++** resume state machine to VC_RESUME_IDLE in this state.
++**
++** VC_SUSPEND_SUSPENDED - Suspend has completed successfully. Also call
++** complete_all on the suspend completion to notify
++** anything waiting for suspend to happen.
++**
++** VC_SUSPEND_REJECTED - Videocore rejected suspend. Videocore will also
++** initiate resume, so no need to alter resume state.
++** We call complete_all on the suspend completion to notify
++** of suspend rejection.
++**
++** VC_SUSPEND_FAILED - We failed to initiate videocore suspend. We notify the
++** suspend completion and reset the resume state machine.
++**
++** VC_RESUME_IDLE - Initialise the resume completion at the same time. The
++** resume completion is in it's 'done' state whenever
++** videcore is running. Therfore, the VC_RESUME_IDLE state
++** implies that videocore is suspended.
++** Hence, any thread which needs to wait until videocore is
++** running can wait on this completion - it will only block
++** if videocore is suspended.
++**
++** VC_RESUME_RESUMED - Resume has completed successfully. Videocore is running.
++** Call complete_all on the resume completion to unblock
++** any threads waiting for resume. Also reset the suspend
++** state machine to it's idle state.
++**
++** VC_RESUME_FAILED - Currently unused - no mechanism to fail resume exists.
++*/
++
++inline void
++set_suspend_state(VCHIQ_ARM_STATE_T *arm_state,
++ enum vc_suspend_status new_state)
+ {
+- VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v;
+- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+- int send_pending;
+-
+- while (1) {
+- vcos_event_wait(&arm_state->hp_evt);
+-
+- send_pending = 0;
+-
+- vcos_mutex_lock(&arm_state->use_count_mutex);
+- if (vchiq_videocore_wanted(state))
+- {
+- vchiq_arm_vcresume(state);
+- }
+- if(arm_state->use_notify_pending)
+- {
+- send_pending = arm_state->use_notify_pending;
+- arm_state->use_notify_pending=0;
+- }
+- vcos_mutex_unlock(&arm_state->use_count_mutex);
+- while(send_pending--)
+- {
+- vcos_log_info( "%s sending VCHIQ_MSG_REMOTE_USE_ACTIVE", __func__);
+- if ( vchiq_send_remote_use_active(state) != VCHIQ_SUCCESS)
+- {
+- BUG(); /* vc should be resumed, so shouldn't be a problem sending message */
+- }
+- }
+- }
+- return NULL;
++ /* set the state in all cases */
++ arm_state->vc_suspend_state = new_state;
++
++ /* state specific additional actions */
++ switch (new_state) {
++ case VC_SUSPEND_FORCE_CANCELED:
++ complete_all(&arm_state->vc_suspend_complete);
++ break;
++ case VC_SUSPEND_REJECTED:
++ complete_all(&arm_state->vc_suspend_complete);
++ break;
++ case VC_SUSPEND_FAILED:
++ complete_all(&arm_state->vc_suspend_complete);
++ arm_state->vc_resume_state = VC_RESUME_RESUMED;
++ complete_all(&arm_state->vc_resume_complete);
++ break;
++ case VC_SUSPEND_IDLE:
++ INIT_COMPLETION(arm_state->vc_suspend_complete);
++ break;
++ case VC_SUSPEND_REQUESTED:
++ break;
++ case VC_SUSPEND_IN_PROGRESS:
++ set_resume_state(arm_state, VC_RESUME_IDLE);
++ break;
++ case VC_SUSPEND_SUSPENDED:
++ complete_all(&arm_state->vc_suspend_complete);
++ break;
++ default:
++ BUG();
++ break;
++ }
+ }
+
+-VCHIQ_STATUS_T
+-vchiq_arm_init_state(VCHIQ_STATE_T* state, VCHIQ_ARM_STATE_T *arm_state)
++inline void
++set_resume_state(VCHIQ_ARM_STATE_T *arm_state,
++ enum vc_resume_status new_state)
+ {
+- VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+- VCOS_THREAD_ATTR_T attrs;
+- char threadname[10];
+-
+- if(arm_state)
+- {
+- vcos_mutex_create(&arm_state->use_count_mutex, "v.use_count_mutex");
+- vcos_mutex_create(&arm_state->suspend_resume_mutex, "v.susp_res_mutex");
+-
+- vcos_event_create(&arm_state->lp_evt, "LP_EVT");
+- vcos_event_create(&arm_state->hp_evt, "HP_EVT");
+-
+- vcos_thread_attr_init(&attrs);
+- vcos_thread_attr_setstacksize(&attrs, VCHIQ_ARM_VCSUSPEND_TASK_STACK);
+- vcos_thread_attr_setpriority(&attrs, VCOS_THREAD_PRI_LOWEST);
+- vcos_snprintf(threadname, sizeof(threadname), "VCHIQl-%d", state->id);
+- if(vcos_thread_create(&arm_state->lp_thread, threadname, &attrs, lp_func, state) != VCOS_SUCCESS)
+- {
+- vcos_log_error("vchiq: FATAL: couldn't create thread %s", threadname);
+- status = VCHIQ_ERROR;
+- }
+- else
+- {
+- vcos_thread_attr_init(&attrs);
+- vcos_thread_attr_setstacksize(&attrs, VCHIQ_ARM_VCSUSPEND_TASK_STACK);
+- vcos_thread_attr_setpriority(&attrs, VCOS_THREAD_PRI_HIGHEST);
+- vcos_snprintf(threadname, sizeof(threadname), "VCHIQh-%d", state->id);
+-
+- if(vcos_thread_create(&arm_state->hp_thread, threadname, &attrs, hp_func, state) != VCOS_SUCCESS)
+- {
+- vcos_log_error("vchiq: FATAL: couldn't create thread %s", threadname);
+- status = VCHIQ_ERROR;
+- }
+- }
+- }
+- return status;
++ /* set the state in all cases */
++ arm_state->vc_resume_state = new_state;
++
++ /* state specific additional actions */
++ switch (new_state) {
++ case VC_RESUME_FAILED:
++ break;
++ case VC_RESUME_IDLE:
++ INIT_COMPLETION(arm_state->vc_resume_complete);
++ break;
++ case VC_RESUME_REQUESTED:
++ break;
++ case VC_RESUME_IN_PROGRESS:
++ break;
++ case VC_RESUME_RESUMED:
++ complete_all(&arm_state->vc_resume_complete);
++ set_suspend_state(arm_state, VC_SUSPEND_IDLE);
++ break;
++ default:
++ BUG();
++ break;
++ }
+ }
+
+
+-VCHIQ_STATUS_T
+-vchiq_arm_vcsuspend(VCHIQ_STATE_T *state)
++/* should be called with the write lock held */
++inline void
++start_suspend_timer(VCHIQ_ARM_STATE_T *arm_state)
+ {
+- VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+-
+- if (state->conn_state != VCHIQ_CONNSTATE_CONNECTED)
+- return VCHIQ_ERROR;
+-
+- if(arm_state->suspend_pending)
+- {
+- vcos_mutex_lock(&arm_state->suspend_resume_mutex);
+- if(arm_state->videocore_suspended)
+- {
+- vcos_log_info("%s - already suspended", __func__);
+- }
+- else
+- {
+- vcos_log_info("%s - suspending", __func__);
+-
+- status = vchiq_platform_suspend(state);
+- arm_state->videocore_suspended = (status == VCHIQ_SUCCESS) ? 1 : 0;
+-
+- vcos_mutex_unlock(&arm_state->suspend_resume_mutex);
+-
+- vcos_mutex_lock(&arm_state->use_count_mutex);
+- if(!arm_state->suspend_pending)
+- { /* Something has changed the suspend_pending state while we were suspending.
+- Run the HP task to check if we need to resume */
+- vcos_log_info( "%s trigger HP task to check resume", __func__);
+- vcos_event_signal(&arm_state->hp_evt);
+- }
+- arm_state->suspend_pending = 0;
+- vcos_mutex_unlock(&arm_state->use_count_mutex);
+- }
+- }
+- else
+- {
+- vchiq_check_resume(state);
+- }
+- return status;
++ del_timer(&arm_state->suspend_timer);
++ arm_state->suspend_timer.expires = jiffies +
++ msecs_to_jiffies(arm_state->
++ suspend_timer_timeout);
++ add_timer(&arm_state->suspend_timer);
++ arm_state->suspend_timer_running = 1;
+ }
+
++/* should be called with the write lock held */
++static inline void
++stop_suspend_timer(VCHIQ_ARM_STATE_T *arm_state)
++{
++ if (arm_state->suspend_timer_running) {
++ del_timer(&arm_state->suspend_timer);
++ arm_state->suspend_timer_running = 0;
++ }
++}
+
+-VCHIQ_STATUS_T
+-vchiq_arm_vcresume(VCHIQ_STATE_T *state)
++static inline int
++need_resume(VCHIQ_STATE_T *state)
+ {
+- VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+- vcos_mutex_lock(&arm_state->suspend_resume_mutex);
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ return (arm_state->vc_suspend_state > VC_SUSPEND_IDLE) &&
++ (arm_state->vc_resume_state < VC_RESUME_REQUESTED) &&
++ vchiq_videocore_wanted(state);
++}
+
+- status = vchiq_platform_resume(state);
+- arm_state->videocore_suspended = (status == VCHIQ_RETRY) ? 1 : 0;
++static int
++block_resume(VCHIQ_ARM_STATE_T *arm_state)
++{
++ int status = VCHIQ_SUCCESS;
++ while (arm_state->blocked_count) {
++ INIT_COMPLETION(arm_state->blocked_blocker);
++ write_unlock_bh(&arm_state->susp_res_lock);
++ vchiq_log_info(vchiq_susp_log_level, "%s wait for previously "
++ "blocked clients", __func__);
++ if (wait_for_completion_interruptible_timeout(
++ &arm_state->blocked_blocker,
++ msecs_to_jiffies(FORCE_SUSPEND_TIMEOUT_MS))
++ <= 0) {
++ vchiq_log_error(vchiq_susp_log_level, "%s wait for "
++ "previously blocked clients failed" , __func__);
++ status = VCHIQ_ERROR;
++ write_lock_bh(&arm_state->susp_res_lock);
++ goto out;
++ }
++ vchiq_log_info(vchiq_susp_log_level, "%s previously blocked "
++ "clients resumed", __func__);
++ write_lock_bh(&arm_state->susp_res_lock);
++ }
++ while (arm_state->vc_resume_state != VC_RESUME_RESUMED &&
++ arm_state->vc_resume_state > VC_RESUME_IDLE) {
++ if (!try_wait_for_completion(&arm_state->vc_resume_complete)) {
++ write_unlock_bh(&arm_state->susp_res_lock);
++ vchiq_log_info(vchiq_susp_log_level, "%s wait for "
++ "resume", __func__);
++ if (wait_for_completion_interruptible_timeout(
++ &arm_state->vc_resume_complete,
++ msecs_to_jiffies(
++ FORCE_SUSPEND_TIMEOUT_MS))
++ <= 0) {
++ vchiq_log_error(vchiq_susp_log_level, "%s wait "
++ "for resume failed (%s)", __func__,
++ resume_state_names[
++ arm_state->vc_resume_state +
++ VC_RESUME_NUM_OFFSET]);
++ status = VCHIQ_ERROR;
++ write_lock_bh(&arm_state->susp_res_lock);
++ goto out;
++ }
++ vchiq_log_info(vchiq_susp_log_level, "%s resumed",
++ __func__);
++ write_lock_bh(&arm_state->susp_res_lock);
++ }
++ }
++ INIT_COMPLETION(arm_state->resume_blocker);
++ arm_state->resume_blocked = 1;
++
++out:
++ return status;
++}
+
+- vcos_mutex_unlock(&arm_state->suspend_resume_mutex);
++inline static void
++unblock_resume(VCHIQ_ARM_STATE_T *arm_state)
++{
++ complete_all(&arm_state->resume_blocker);
++ arm_state->resume_blocked = 0;
++}
+
+- return status;
++/* Initiate suspend via slot handler. Should be called with the write lock
++ * held */
++VCHIQ_STATUS_T
++vchiq_arm_vcsuspend(VCHIQ_STATE_T *state)
++{
++ VCHIQ_STATUS_T status = VCHIQ_ERROR;
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++
++ if (!arm_state)
++ goto out;
++
++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
++ status = VCHIQ_SUCCESS;
++
++
++ switch (arm_state->vc_suspend_state) {
++ case VC_SUSPEND_REQUESTED:
++ vchiq_log_info(vchiq_susp_log_level, "%s: suspend already "
++ "requested", __func__);
++ break;
++ case VC_SUSPEND_IN_PROGRESS:
++ vchiq_log_info(vchiq_susp_log_level, "%s: suspend already in "
++ "progress", __func__);
++ break;
++
++ default:
++ /* We don't expect to be in other states, so log but continue
++ * anyway */
++ vchiq_log_error(vchiq_susp_log_level,
++ "%s unexpected suspend state %s", __func__,
++ suspend_state_names[arm_state->vc_suspend_state +
++ VC_SUSPEND_NUM_OFFSET]);
++ /* fall through */
++ case VC_SUSPEND_REJECTED:
++ case VC_SUSPEND_FAILED:
++ INIT_COMPLETION(arm_state->vc_suspend_complete);
++ /* fall through */
++ case VC_SUSPEND_IDLE:
++ vchiq_log_info(vchiq_susp_log_level,
++ "%s: suspending", __func__);
++ set_suspend_state(arm_state, VC_SUSPEND_REQUESTED);
++ /* kick the slot handler thread to initiate suspend */
++ request_poll(state, NULL, 0);
++ break;
++ }
++
++out:
++ vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, status);
++ return status;
+ }
+
+ void
+-vchiq_check_resume(VCHIQ_STATE_T* state)
++vchiq_platform_check_suspend(VCHIQ_STATE_T *state)
+ {
+- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+- vcos_mutex_lock(&arm_state->use_count_mutex);
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ int susp = 0;
++
++ if (!arm_state)
++ goto out;
++
++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
++
++ write_lock_bh(&arm_state->susp_res_lock);
++ if (arm_state->vc_suspend_state == VC_SUSPEND_REQUESTED &&
++ arm_state->vc_resume_state == VC_RESUME_RESUMED) {
++ set_suspend_state(arm_state, VC_SUSPEND_IN_PROGRESS);
++ susp = 1;
++ }
++ write_unlock_bh(&arm_state->susp_res_lock);
+
+- if (arm_state->videocore_suspended && vchiq_videocore_wanted(state))
+- { /* signal high priority task to resume vc */
+- vcos_event_signal(&arm_state->hp_evt);
+- }
++ if (susp)
++ vchiq_platform_suspend(state);
+
+- vcos_mutex_unlock(&arm_state->use_count_mutex);
++out:
++ vchiq_log_trace(vchiq_susp_log_level, "%s exit", __func__);
++ return;
++}
++
++
++
++/* Try to get videocore into suspended state, regardless of autosuspend state.
++** We don't actually force suspend, since videocore may get into a bad state
++** if we force suspend at a bad time. Instead, we wait for autosuspend to
++** determine a good point to suspend. If this doesn't happen within 100ms we
++** report failure.
++**
++** Returns VCHIQ_SUCCESS if videocore suspended successfully, VCHIQ_RETRY if
++** videocore failed to suspend in time or VCHIQ_ERROR if interrupted.
++*/
++VCHIQ_STATUS_T
++vchiq_arm_force_suspend(VCHIQ_STATE_T *state)
++{
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ VCHIQ_STATUS_T status = VCHIQ_ERROR;
++ long rc = 0;
++ int repeat = -1;
++ static int autosuspend_override;
++
++ if (!arm_state)
++ goto out;
++
++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
++
++ write_lock_bh(&arm_state->susp_res_lock);
++
++ status = block_resume(arm_state);
++ if (status != VCHIQ_SUCCESS)
++ goto unlock;
++ if (arm_state->vc_suspend_state == VC_SUSPEND_SUSPENDED) {
++ /* Already suspended - just block resume and exit */
++ vchiq_log_info(vchiq_susp_log_level, "%s already "
++ "suspended", __func__);
++ status = VCHIQ_SUCCESS;
++ goto unlock;
++ } else if (arm_state->vc_suspend_state <= VC_SUSPEND_IDLE) {
++ /* initiate suspend immediately in the case that we're waiting
++ * for the timeout */
++ stop_suspend_timer(arm_state);
++ if (!vchiq_videocore_wanted(state)) {
++ vchiq_log_info(vchiq_susp_log_level, "%s videocore "
++ "idle, initiating suspend", __func__);
++ status = vchiq_arm_vcsuspend(state);
++ } else if (autosuspend_override < FORCE_SUSPEND_FAIL_MAX) {
++ vchiq_log_info(vchiq_susp_log_level, "%s letting "
++ "videocore go idle", __func__);
++ status = VCHIQ_SUCCESS;
++ } else {
++ vchiq_log_warning(vchiq_susp_log_level, "%s failed too "
++ "many times - no more Mr Nice Guy... "
++ "initiating suspend", __func__);
++ status = vchiq_arm_vcsuspend(state);
++ }
++ } else {
++ vchiq_log_info(vchiq_susp_log_level, "%s videocore suspend "
++ "in progress - wait for completion", __func__);
++ status = VCHIQ_SUCCESS;
++ }
++
++ /* Wait for suspend to happen due to system idle (not forced..) */
++ if (status == VCHIQ_SUCCESS) {
++ do {
++ write_unlock_bh(&arm_state->susp_res_lock);
++
++ rc = wait_for_completion_interruptible_timeout(
++ &arm_state->vc_suspend_complete,
++ msecs_to_jiffies(FORCE_SUSPEND_TIMEOUT_MS));
++
++ write_lock_bh(&arm_state->susp_res_lock);
++ if (rc < 0) {
++ vchiq_log_warning(vchiq_susp_log_level, "%s "
++ "interrupted waiting for suspend",
++ __func__);
++ status = VCHIQ_ERROR;
++ goto unblock_resume;
++ } else if (rc == 0) {
++ if (arm_state->vc_suspend_state >
++ VC_SUSPEND_IDLE) {
++ /* Repeat timeout once if in progress */
++ if (repeat < 0) {
++ repeat = 1;
++ continue;
++ }
++ }
++ autosuspend_override++;
++ vchiq_log_warning(vchiq_susp_log_level,
++ "%s timed out waiting for vc suspend "
++ "(%d)", __func__, autosuspend_override);
++ status = VCHIQ_RETRY;
++ goto unblock_resume;
++ }
++ } while (0 < (repeat--));
++ } else
++ goto unblock_resume;
++
++ /* Check and report state in case we need to abort ARM suspend */
++ if (arm_state->vc_suspend_state != VC_SUSPEND_SUSPENDED) {
++ status = VCHIQ_RETRY;
++ vchiq_log_error(vchiq_susp_log_level,
++ "%s videocore suspend failed (state %s)", __func__,
++ suspend_state_names[arm_state->vc_suspend_state +
++ VC_SUSPEND_NUM_OFFSET]);
++ /* Reset the state only if it's still in an error state.
++ * Something could have already initiated another suspend. */
++ if (arm_state->vc_suspend_state < VC_SUSPEND_IDLE)
++ set_suspend_state(arm_state, VC_SUSPEND_IDLE);
++
++ goto unblock_resume;
++ }
++
++ /* successfully suspended - reset override counter, unlock and exit */
++ autosuspend_override = 0;
++ goto unlock;
++
++unblock_resume:
++ /* all error states need to unblock resume before exit */
++ unblock_resume(arm_state);
++
++unlock:
++ write_unlock_bh(&arm_state->susp_res_lock);
++
++out:
++ vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, status);
++ return status;
+ }
+
+ void
+-vchiq_check_suspend(VCHIQ_STATE_T* state)
++vchiq_check_suspend(VCHIQ_STATE_T *state)
+ {
+- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+
+- vcos_mutex_lock(&arm_state->use_count_mutex);
++ if (!arm_state)
++ goto out;
+
+- if (!arm_state->videocore_suspended && !vchiq_videocore_wanted(state))
+- { /* signal low priority task to suspend vc */
+- vcos_event_signal(&arm_state->lp_evt);
+- }
++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
+
+- vcos_mutex_unlock(&arm_state->use_count_mutex);
++ write_lock_bh(&arm_state->susp_res_lock);
++ if (arm_state->vc_suspend_state != VC_SUSPEND_SUSPENDED &&
++ arm_state->first_connect &&
++ !vchiq_videocore_wanted(state)) {
++ vchiq_arm_vcsuspend(state);
++ }
++ write_unlock_bh(&arm_state->susp_res_lock);
++
++out:
++ vchiq_log_trace(vchiq_susp_log_level, "%s exit", __func__);
++ return;
+ }
+
+
++int
++vchiq_arm_allow_resume(VCHIQ_STATE_T *state)
++{
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ int resume = 0;
++ int ret = -1;
++
++ if (!arm_state)
++ goto out;
++
++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
++
++ write_lock_bh(&arm_state->susp_res_lock);
++ unblock_resume(arm_state);
++ resume = vchiq_check_resume(state);
++ write_unlock_bh(&arm_state->susp_res_lock);
++
++ if (resume) {
++ wait_for_completion_interruptible(
++ &arm_state->vc_resume_complete);
++ }
++
++ read_lock_bh(&arm_state->susp_res_lock);
++ if (arm_state->vc_suspend_state == VC_SUSPEND_SUSPENDED) {
++ vchiq_log_info(vchiq_susp_log_level,
++ "%s: Videocore remains suspended", __func__);
++ } else {
++ vchiq_log_info(vchiq_susp_log_level,
++ "%s: Videocore resumed", __func__);
++ ret = 0;
++ }
++ read_unlock_bh(&arm_state->susp_res_lock);
++out:
++ vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, ret);
++ return ret;
++}
+
+-static VCHIQ_STATUS_T
+-vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, int block_while_resume)
++/* This function should be called with the write lock held */
++int
++vchiq_check_resume(VCHIQ_STATE_T *state)
+ {
+- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+- VCHIQ_STATUS_T ret = VCHIQ_SUCCESS;
+- char entity[10];
+- int* entity_uc;
+-
+- if(arm_state)
+- {
+- vcos_mutex_lock(&arm_state->use_count_mutex);
+-
+- if (service)
+- {
+- sprintf(entity, "%c%c%c%c:%03d",VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), service->client_id);
+- entity_uc = &service->service_use_count;
+- }
+- else
+- {
+- sprintf(entity, "PEER: ");
+- entity_uc = &arm_state->peer_use_count;
+- }
+-
+- if (!arm_state->videocore_suspended && !vchiq_videocore_wanted(state))
+- {
+-#if VCOS_HAVE_TIMER
+- if (vchiq_platform_use_suspend_timer())
+- {
+- vcos_log_trace( "%s %s - cancel suspend timer", __func__, entity);
+- }
+- vcos_timer_cancel(&g_suspend_timer);
+-#endif
+- }
+-
+- arm_state->videocore_use_count++;
+- (*entity_uc)++;
+- arm_state->suspend_pending = 0;
+-
+- if (arm_state->videocore_suspended && vchiq_videocore_wanted(state))
+- {
+- vcos_log_info( "%s %s count %d, state count %d", __func__, entity, *entity_uc, arm_state->videocore_use_count);
+- if(block_while_resume)
+- {
+- ret = vchiq_arm_vcresume(state);
+- }
+- else
+- {
+- vcos_log_info( "%s trigger HP task to do resume", __func__); /* triggering is done below */
+- }
+- }
+- else
+- {
+- vcos_log_trace( "%s %s count %d, state count %d", __func__, entity, *entity_uc, arm_state->videocore_use_count);
+- }
+- if(!block_while_resume)
+- {
+- arm_state->use_notify_pending++;
+- vcos_event_signal(&arm_state->hp_evt); /* hp task will check if we need to resume and also send use notify */
+- }
+-
+- if (ret == VCHIQ_RETRY)
+- { /* if we're told to retry, decrement the counters. VCHIQ_ERROR probably means we're already resumed. */
+- (*entity_uc)--;
+- arm_state->videocore_use_count--;
+- }
+-
+- vcos_mutex_unlock(&arm_state->use_count_mutex);
+- }
+- return ret;
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ int resume = 0;
++
++ if (!arm_state)
++ goto out;
++
++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
++
++ if (need_resume(state)) {
++ set_resume_state(arm_state, VC_RESUME_REQUESTED);
++ request_poll(state, NULL, 0);
++ resume = 1;
++ }
++
++out:
++ vchiq_log_trace(vchiq_susp_log_level, "%s exit", __func__);
++ return resume;
+ }
+
+-static VCHIQ_STATUS_T
+-vchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service)
++void
++vchiq_platform_check_resume(VCHIQ_STATE_T *state)
+ {
+- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+- VCHIQ_STATUS_T ret = VCHIQ_SUCCESS;
+- char entity[10];
+- int* entity_uc;
+-
+- if(arm_state)
+- {
+- vcos_mutex_lock(&arm_state->use_count_mutex);
+-
+- if (service)
+- {
+- sprintf(entity, "%c%c%c%c:%03d",VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), service->client_id);
+- entity_uc = &service->service_use_count;
+- }
+- else
+- {
+- sprintf(entity, "PEER: ");
+- entity_uc = &arm_state->peer_use_count;
+- }
+-
+- if (*entity_uc && arm_state->videocore_use_count)
+- {
+- arm_state->videocore_use_count--;
+- (*entity_uc)--;
+-
+- if (!vchiq_videocore_wanted(state))
+- {
+-#if VCOS_HAVE_TIMER
+- if (vchiq_platform_use_suspend_timer())
+- {
+- vcos_log_trace( "%s %s count %d, state count %d - starting suspend timer", __func__, entity, *entity_uc, arm_state->videocore_use_count);
+- vcos_timer_cancel(&g_suspend_timer);
+- vcos_timer_set(&g_suspend_timer, SUSPEND_TIMER_TIMEOUT_MS);
+- }
+- else
+-#endif
+- {
+- vcos_log_info( "%s %s count %d, state count %d - suspend pending", __func__, entity, *entity_uc, arm_state->videocore_use_count);
+- vcos_event_signal(&arm_state->lp_evt); /* kick the lp thread to do the suspend */
+- }
+- }
+- else
+- {
+- vcos_log_trace( "%s %s count %d, state count %d", __func__, entity, *entity_uc, arm_state->videocore_use_count);
+- }
+- }
+- else
+- {
+- vcos_log_error( "%s %s ERROR releasing service; count %d, state count %d", __func__, entity, *entity_uc, arm_state->videocore_use_count);
+- ret = VCHIQ_ERROR;
+- }
+-
+- vcos_mutex_unlock(&arm_state->use_count_mutex);
+- }
+- return ret;
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ int res = 0;
++
++ if (!arm_state)
++ goto out;
++
++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
++
++ write_lock_bh(&arm_state->susp_res_lock);
++ if (arm_state->wake_address == 0) {
++ vchiq_log_info(vchiq_susp_log_level,
++ "%s: already awake", __func__);
++ goto unlock;
++ }
++ if (arm_state->vc_resume_state == VC_RESUME_IN_PROGRESS) {
++ vchiq_log_info(vchiq_susp_log_level,
++ "%s: already resuming", __func__);
++ goto unlock;
++ }
++
++ if (arm_state->vc_resume_state == VC_RESUME_REQUESTED) {
++ set_resume_state(arm_state, VC_RESUME_IN_PROGRESS);
++ res = 1;
++ } else
++ vchiq_log_trace(vchiq_susp_log_level,
++ "%s: not resuming (resume state %s)", __func__,
++ resume_state_names[arm_state->vc_resume_state +
++ VC_RESUME_NUM_OFFSET]);
++
++unlock:
++ write_unlock_bh(&arm_state->susp_res_lock);
++
++ if (res)
++ vchiq_platform_resume(state);
++
++out:
++ vchiq_log_trace(vchiq_susp_log_level, "%s exit", __func__);
++ return;
++
+ }
+
++
++
+ VCHIQ_STATUS_T
+-vchiq_on_remote_use(VCHIQ_STATE_T *state)
++vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
++ enum USE_TYPE_E use_type)
+ {
+- vcos_log_info("%s state %p", __func__, state);
+- return state ? vchiq_use_internal(state, NULL, 0) : VCHIQ_ERROR;
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ VCHIQ_STATUS_T ret = VCHIQ_SUCCESS;
++ char entity[16];
++ int *entity_uc;
++ int local_uc, local_entity_uc;
++
++ if (!arm_state)
++ goto out;
++
++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
++
++ if (use_type != USE_TYPE_SERVICE) {
++ sprintf(entity, "PEER: ");
++ entity_uc = &arm_state->peer_use_count;
++ } else if (service) {
++ sprintf(entity, "%c%c%c%c:%03d",
++ VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
++ service->client_id);
++ entity_uc = &service->service_use_count;
++ } else {
++ vchiq_log_error(vchiq_susp_log_level, "%s null service "
++ "ptr", __func__);
++ ret = VCHIQ_ERROR;
++ goto out;
++ }
++
++ write_lock_bh(&arm_state->susp_res_lock);
++ while (arm_state->resume_blocked) {
++ /* If we call 'use' while force suspend is waiting for suspend,
++ * then we're about to block the thread which the force is
++ * waiting to complete, so we're bound to just time out. In this
++ * case, set the suspend state such that the wait will be
++ * canceled, so we can complete as quickly as possible. */
++ if (arm_state->resume_blocked && arm_state->vc_suspend_state ==
++ VC_SUSPEND_IDLE) {
++ set_suspend_state(arm_state, VC_SUSPEND_FORCE_CANCELED);
++ break;
++ }
++ /* If suspend is already in progress then we need to block */
++ if (!try_wait_for_completion(&arm_state->resume_blocker)) {
++ /* Indicate that there are threads waiting on the resume
++ * blocker. These need to be allowed to complete before
++ * a _second_ call to force suspend can complete,
++ * otherwise low priority threads might never actually
++ * continue */
++ arm_state->blocked_count++;
++ write_unlock_bh(&arm_state->susp_res_lock);
++ vchiq_log_info(vchiq_susp_log_level, "%s %s resume "
++ "blocked - waiting...", __func__, entity);
++ if (wait_for_completion_killable(
++ &arm_state->resume_blocker) != 0) {
++ vchiq_log_error(vchiq_susp_log_level, "%s %s "
++ "wait for resume blocker interrupted",
++ __func__, entity);
++ ret = VCHIQ_ERROR;
++ write_lock_bh(&arm_state->susp_res_lock);
++ arm_state->blocked_count--;
++ write_unlock_bh(&arm_state->susp_res_lock);
++ goto out;
++ }
++ vchiq_log_info(vchiq_susp_log_level, "%s %s resume "
++ "unblocked", __func__, entity);
++ write_lock_bh(&arm_state->susp_res_lock);
++ if (--arm_state->blocked_count == 0)
++ complete_all(&arm_state->blocked_blocker);
++ }
++ }
++
++ stop_suspend_timer(arm_state);
++ write_unlock_bh(&arm_state->susp_res_lock);
++
++ mutex_lock(&arm_state->vc_use_cnt_mutex);
++ if (!arm_state->videocore_use_count)
++ pm_qos_add_request(&arm_state->qos_request,
++ PM_QOS_CPU_DMA_LATENCY, 100);
++
++ local_uc = ++arm_state->videocore_use_count;
++ local_entity_uc = ++(*entity_uc);
++ mutex_unlock(&arm_state->vc_use_cnt_mutex);
++
++ write_lock_bh(&arm_state->susp_res_lock);
++
++ /* If there's a pending request which hasn't yet been serviced then
++ * just clear it. If we're past VC_SUSPEND_REQUESTED state then
++ * vc_resume_complete will block until we either resume or fail to
++ * suspend */
++ if (arm_state->vc_suspend_state <= VC_SUSPEND_REQUESTED)
++ set_suspend_state(arm_state, VC_SUSPEND_IDLE);
++
++ if (need_resume(state)) {
++ set_resume_state(arm_state, VC_RESUME_REQUESTED);
++ vchiq_log_info(vchiq_susp_log_level,
++ "%s %s count %d, state count %d",
++ __func__, entity, local_entity_uc, local_uc);
++ request_poll(state, NULL, 0);
++ } else
++ vchiq_log_trace(vchiq_susp_log_level,
++ "%s %s count %d, state count %d",
++ __func__, entity, *entity_uc, local_uc);
++
++
++ write_unlock_bh(&arm_state->susp_res_lock);
++
++ /* Completion is in a done state when we're not suspended, so this won't
++ * block for the non-suspended case. */
++ if (!try_wait_for_completion(&arm_state->vc_resume_complete)) {
++ vchiq_log_info(vchiq_susp_log_level, "%s %s wait for resume",
++ __func__, entity);
++ if (wait_for_completion_killable(
++ &arm_state->vc_resume_complete) != 0) {
++ vchiq_log_error(vchiq_susp_log_level, "%s %s wait for "
++ "resume interrupted", __func__, entity);
++ ret = VCHIQ_ERROR;
++ goto out;
++ }
++ vchiq_log_info(vchiq_susp_log_level, "%s %s resumed", __func__,
++ entity);
++ }
++
++ if (ret == VCHIQ_SUCCESS) {
++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
++ long ack_cnt = atomic_xchg(&arm_state->ka_use_ack_count, 0);
++ while (ack_cnt && (status == VCHIQ_SUCCESS)) {
++ /* Send the use notify to videocore */
++ status = vchiq_send_remote_use_active(state);
++ if (status == VCHIQ_SUCCESS)
++ ack_cnt--;
++ else
++ atomic_add(ack_cnt,
++ &arm_state->ka_use_ack_count);
++ }
++ }
++
++out:
++ vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, ret);
++ return ret;
+ }
+
+ VCHIQ_STATUS_T
++vchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service)
++{
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ VCHIQ_STATUS_T ret = VCHIQ_SUCCESS;
++ char entity[16];
++ int *entity_uc;
++ int local_uc, local_entity_uc;
++
++ if (!arm_state)
++ goto out;
++
++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
++
++ if (service) {
++ sprintf(entity, "%c%c%c%c:%03d",
++ VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
++ service->client_id);
++ entity_uc = &service->service_use_count;
++ } else {
++ sprintf(entity, "PEER: ");
++ entity_uc = &arm_state->peer_use_count;
++ }
++
++ write_lock_bh(&arm_state->susp_res_lock);
++ if (!arm_state->videocore_use_count || !(*entity_uc)) {
++ /* Don't use BUG_ON - don't allow user thread to crash kernel */
++ WARN_ON(!arm_state->videocore_use_count);
++ WARN_ON(!(*entity_uc));
++ ret = VCHIQ_ERROR;
++ goto unlock;
++ }
++ write_unlock_bh(&arm_state->susp_res_lock);
++
++ mutex_lock(&arm_state->vc_use_cnt_mutex);
++ local_uc = --arm_state->videocore_use_count;
++ local_entity_uc = --(*entity_uc);
++
++ if (!arm_state->videocore_use_count)
++ pm_qos_remove_request(&arm_state->qos_request);
++ mutex_unlock(&arm_state->vc_use_cnt_mutex);
++
++ write_lock_bh(&arm_state->susp_res_lock);
++ if (!vchiq_videocore_wanted(state)) {
++ if (vchiq_platform_use_suspend_timer() &&
++ !arm_state->resume_blocked) {
++ /* Only use the timer if we're not trying to force
++ * suspend (=> resume_blocked) */
++ start_suspend_timer(arm_state);
++ } else {
++ vchiq_log_info(vchiq_susp_log_level,
++ "%s %s count %d, state count %d - suspending",
++ __func__, entity, *entity_uc,
++ arm_state->videocore_use_count);
++ vchiq_arm_vcsuspend(state);
++ }
++ } else
++ vchiq_log_trace(vchiq_susp_log_level,
++ "%s %s count %d, state count %d",
++ __func__, entity, *entity_uc,
++ arm_state->videocore_use_count);
++
++unlock:
++ write_unlock_bh(&arm_state->susp_res_lock);
++
++out:
++ vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, ret);
++ return ret;
++}
++
++void
++vchiq_on_remote_use(VCHIQ_STATE_T *state)
++{
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
++ atomic_inc(&arm_state->ka_use_count);
++ complete(&arm_state->ka_evt);
++}
++
++void
+ vchiq_on_remote_release(VCHIQ_STATE_T *state)
+ {
+- vcos_log_info("%s state %p", __func__, state);
+- return state ? vchiq_release_internal(state, NULL) : VCHIQ_ERROR;
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
++ atomic_inc(&arm_state->ka_release_count);
++ complete(&arm_state->ka_evt);
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_use_service_internal(VCHIQ_SERVICE_T *service)
+ {
+- VCHIQ_STATE_T* state = NULL;
+-
+- if (service)
+- {
+- state = service->state;
+- }
+-
+- if (!service || !state)
+- {
+- return VCHIQ_ERROR;
+- }
+- return vchiq_use_internal(state, service, 1);
++ return vchiq_use_internal(service->state, service, USE_TYPE_SERVICE);
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_release_service_internal(VCHIQ_SERVICE_T *service)
+ {
+- VCHIQ_STATE_T* state = NULL;
+-
+- if (service)
+- {
+- state = service->state;
+- }
+-
+- if (!service || !state)
+- {
+- return VCHIQ_ERROR;
+- }
+- return vchiq_release_internal(state, service);
++ return vchiq_release_internal(service->state, service);
+ }
+
+-
+-#if VCOS_HAVE_TIMER
+-static void suspend_timer_callback(void* context)
++static void suspend_timer_callback(unsigned long context)
+ {
+- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state((VCHIQ_STATE_T*)context);
+- vcos_log_info( "%s - suspend pending", __func__);
+- vcos_event_signal(&arm_state->lp_evt);
++ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *)context;
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ if (!arm_state)
++ goto out;
++ vchiq_log_info(vchiq_susp_log_level,
++ "%s - suspend timer expired - check suspend", __func__);
++ vchiq_check_suspend(state);
++out:
++ return;
+ }
+-#endif
+
+ VCHIQ_STATUS_T
+ vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle)
+ {
+- VCHIQ_STATUS_T ret = VCHIQ_ERROR;
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *) handle;
+- if (service)
+- {
+- ret = vchiq_use_service_internal(service);
+- }
+- return ret;
++ VCHIQ_STATUS_T ret = VCHIQ_ERROR;
++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
++ if (service) {
++ ret = vchiq_use_internal(service->state, service,
++ USE_TYPE_SERVICE);
++ unlock_service(service);
++ }
++ return ret;
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_release_service(VCHIQ_SERVICE_HANDLE_T handle)
+ {
+- VCHIQ_STATUS_T ret = VCHIQ_ERROR;
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *) handle;
+- if (service)
+- {
+- ret = vchiq_release_service_internal(service);
+- }
+- return ret;
++ VCHIQ_STATUS_T ret = VCHIQ_ERROR;
++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
++ if (service) {
++ ret = vchiq_release_internal(service->state, service);
++ unlock_service(service);
++ }
++ return ret;
+ }
+
+ void
+ vchiq_dump_service_use_state(VCHIQ_STATE_T *state)
+ {
+- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
+- int i;
+- if(arm_state)
+- {
+- vcos_mutex_lock(&arm_state->suspend_resume_mutex);
+- if (arm_state->videocore_suspended)
+- {
+- vcos_log_warn("--VIDEOCORE SUSPENDED--");
+- }
+- else
+- {
+- vcos_log_warn("--VIDEOCORE AWAKE--");
+- }
+- for (i = 0; i < state->unused_service; i++) {
+- VCHIQ_SERVICE_T *service_ptr = state->services[i];
+- if (service_ptr && (service_ptr->srvstate != VCHIQ_SRVSTATE_FREE))
+- {
+- if (service_ptr->service_use_count)
+- vcos_log_error("----- %c%c%c%c:%d service count %d <-- preventing suspend", VCHIQ_FOURCC_AS_4CHARS(service_ptr->base.fourcc), service_ptr->client_id, service_ptr->service_use_count);
+- else
+- vcos_log_warn("----- %c%c%c%c:%d service count 0", VCHIQ_FOURCC_AS_4CHARS(service_ptr->base.fourcc), service_ptr->client_id);
+- }
+- }
+- vcos_log_warn("----- PEER use count count %d", arm_state->peer_use_count);
+- vcos_log_warn("--- Overall vchiq instance use count %d", arm_state->videocore_use_count);
+-
+- vchiq_dump_platform_use_state(state);
+-
+- vcos_mutex_unlock(&arm_state->suspend_resume_mutex);
+- }
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ int i, j = 0;
++ /* Only dump 64 services */
++ static const int local_max_services = 64;
++ /* If there's more than 64 services, only dump ones with
++ * non-zero counts */
++ int only_nonzero = 0;
++ static const char *nz = "<-- preventing suspend";
++
++ enum vc_suspend_status vc_suspend_state;
++ enum vc_resume_status vc_resume_state;
++ int peer_count;
++ int vc_use_count;
++ int active_services;
++ struct service_data_struct {
++ int fourcc;
++ int clientid;
++ int use_count;
++ } service_data[local_max_services];
++
++ if (!arm_state)
++ return;
++
++ read_lock_bh(&arm_state->susp_res_lock);
++ vc_suspend_state = arm_state->vc_suspend_state;
++ vc_resume_state = arm_state->vc_resume_state;
++ peer_count = arm_state->peer_use_count;
++ vc_use_count = arm_state->videocore_use_count;
++ active_services = state->unused_service;
++ if (active_services > local_max_services)
++ only_nonzero = 1;
++
++ for (i = 0; (i < active_services) && (j < local_max_services); i++) {
++ VCHIQ_SERVICE_T *service_ptr = state->services[i];
++ if (!service_ptr)
++ continue;
++
++ if (only_nonzero && !service_ptr->service_use_count)
++ continue;
++
++ if (service_ptr->srvstate != VCHIQ_SRVSTATE_FREE) {
++ service_data[j].fourcc = service_ptr->base.fourcc;
++ service_data[j].clientid = service_ptr->client_id;
++ service_data[j++].use_count = service_ptr->
++ service_use_count;
++ }
++ }
++
++ read_unlock_bh(&arm_state->susp_res_lock);
++
++ vchiq_log_warning(vchiq_susp_log_level,
++ "-- Videcore suspend state: %s --",
++ suspend_state_names[vc_suspend_state + VC_SUSPEND_NUM_OFFSET]);
++ vchiq_log_warning(vchiq_susp_log_level,
++ "-- Videcore resume state: %s --",
++ resume_state_names[vc_resume_state + VC_RESUME_NUM_OFFSET]);
++
++ if (only_nonzero)
++ vchiq_log_warning(vchiq_susp_log_level, "Too many active "
++ "services (%d). Only dumping up to first %d services "
++ "with non-zero use-count", active_services,
++ local_max_services);
++
++ for (i = 0; i < j; i++) {
++ vchiq_log_error(vchiq_arm_log_level,
++ "----- %c%c%c%c:%d service count %d %s",
++ VCHIQ_FOURCC_AS_4CHARS(service_data[i].fourcc),
++ service_data[i].clientid,
++ service_data[i].use_count,
++ service_data[i].use_count ? nz : "");
++ }
++ vchiq_log_warning(vchiq_susp_log_level,
++ "----- PEER use count count %d", peer_count);
++ vchiq_log_warning(vchiq_susp_log_level,
++ "--- Overall vchiq instance use count %d", vc_use_count);
++
++ vchiq_dump_platform_use_state(state);
+ }
+
+ VCHIQ_STATUS_T
+-vchiq_check_service(VCHIQ_SERVICE_T * service)
++vchiq_check_service(VCHIQ_SERVICE_T *service)
+ {
+- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(service->state);
+- VCHIQ_STATUS_T ret = VCHIQ_ERROR;
+- /* on 2835 vchiq does not have an arm_state */
+- if (!arm_state)
+- return VCHIQ_SUCCESS;
+- if (service && arm_state)
+- {
+- vcos_mutex_lock(&arm_state->use_count_mutex);
+- if (!service->service_use_count)
+- {
+- vcos_log_error( "%s ERROR - %c%c%c%c:%d service count %d, state count %d, videocore_suspended %d", __func__,VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc), service->client_id, service->service_use_count, arm_state->videocore_use_count, arm_state->videocore_suspended);
+- vchiq_dump_service_use_state(service->state);
+- vcos_assert(0); // vcos_assert should kill the calling thread, so a user thread shouldn't be able to kill the kernel.
+- }
+- else
+- {
+- ret = VCHIQ_SUCCESS;
+- }
+- vcos_mutex_unlock(&arm_state->use_count_mutex);
+- }
+- return ret;
++ VCHIQ_ARM_STATE_T *arm_state =
++ vchiq_platform_get_arm_state(service->state);
++ VCHIQ_STATUS_T ret = VCHIQ_ERROR;
++
++ if (!arm_state || !service)
++ goto out;
++
++ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
++
++ read_lock_bh(&arm_state->susp_res_lock);
++ if (service->service_use_count)
++ ret = VCHIQ_SUCCESS;
++ read_unlock_bh(&arm_state->susp_res_lock);
++
++ if (ret == VCHIQ_ERROR) {
++ vchiq_log_error(vchiq_susp_log_level,
++ "%s ERROR - %c%c%c%c:%d service count %d, "
++ "state count %d, videocore suspend state %s", __func__,
++ VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
++ service->client_id, service->service_use_count,
++ arm_state->videocore_use_count,
++ suspend_state_names[arm_state->vc_suspend_state +
++ VC_SUSPEND_NUM_OFFSET]);
++ vchiq_dump_service_use_state(service->state);
++ }
++out:
++ return ret;
+ }
+
+ /* stub functions */
+ void vchiq_on_remote_use_active(VCHIQ_STATE_T *state)
+ {
+- vcos_unused(state);
++ (void)state;
+ }
+
+-void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state, VCHIQ_CONNSTATE_T oldstate, VCHIQ_CONNSTATE_T newstate)
++void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state,
++ VCHIQ_CONNSTATE_T oldstate, VCHIQ_CONNSTATE_T newstate)
+ {
+- vcos_unused(state);
+- vcos_unused(oldstate);
+- vcos_unused(oldstate);
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ vchiq_log_info(vchiq_susp_log_level, "%d: %s->%s", state->id,
++ get_conn_state_name(oldstate), get_conn_state_name(newstate));
++ if (state->conn_state == VCHIQ_CONNSTATE_CONNECTED) {
++ write_lock_bh(&arm_state->susp_res_lock);
++ if (!arm_state->first_connect) {
++ arm_state->first_connect = 1;
++ write_unlock_bh(&arm_state->susp_res_lock);
++ wake_up_process(arm_state->ka_thread);
++ } else
++ write_unlock_bh(&arm_state->susp_res_lock);
++ }
+ }
+
+
+@@ -1828,67 +2592,132 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state, VCHIQ_CONNSTATE_T o
+ static int __init
+ vchiq_init(void)
+ {
+- int err;
+- void *ptr_err;
+-
+- err = vchiq_platform_vcos_init();
+- if (err != 0)
+- goto failed_platform_vcos_init;
+-
+- vcos_log_set_level(VCOS_LOG_CATEGORY, vchiq_default_arm_log_level);
+- vcos_log_register("vchiq_arm", VCOS_LOG_CATEGORY);
+-
+- if ((err =
+- alloc_chrdev_region(&vchiq_devid, VCHIQ_MINOR, 1,
+- DEVICE_NAME)) != 0) {
+- vcos_log_error("Unable to allocate device number");
+- goto failed_alloc_chrdev;
+- }
+- cdev_init(&vchiq_cdev, &vchiq_fops);
+- vchiq_cdev.owner = THIS_MODULE;
+- if ((err = cdev_add(&vchiq_cdev, vchiq_devid, 1)) != 0) {
+- vcos_log_error("Unable to register device");
+- goto failed_cdev_add;
+- }
+-
+- /* create sysfs entries */
+- vchiq_class = class_create(THIS_MODULE, DEVICE_NAME);
+- if (IS_ERR(ptr_err = vchiq_class))
+- goto failed_class_create;
+-
+- vchiq_dev = device_create(vchiq_class, NULL,
+- vchiq_devid, NULL, "vchiq");
+- if (IS_ERR(ptr_err = vchiq_dev))
+- goto failed_device_create;
+-
+- err = vchiq_platform_init(&g_state);
+- if (err != 0)
+- goto failed_platform_init;
+-
+-#if VCOS_HAVE_TIMER
+- vcos_timer_create( &g_suspend_timer, "suspend_timer", suspend_timer_callback, (void*)(&g_state));
+-#endif
+-
+- vcos_log_error("vchiq: initialised - version %d (min %d), device %d.%d",
+- VCHIQ_VERSION, VCHIQ_VERSION_MIN,
+- MAJOR(vchiq_devid), MINOR(vchiq_devid));
+-
+- return 0;
++ int err;
++ void *ptr_err;
++
++ /* create proc entries */
++ err = vchiq_proc_init();
++ if (err != 0)
++ goto failed_proc_init;
++
++ err = alloc_chrdev_region(&vchiq_devid, VCHIQ_MINOR, 1, DEVICE_NAME);
++ if (err != 0) {
++ vchiq_log_error(vchiq_arm_log_level,
++ "Unable to allocate device number");
++ goto failed_alloc_chrdev;
++ }
++ cdev_init(&vchiq_cdev, &vchiq_fops);
++ vchiq_cdev.owner = THIS_MODULE;
++ err = cdev_add(&vchiq_cdev, vchiq_devid, 1);
++ if (err != 0) {
++ vchiq_log_error(vchiq_arm_log_level,
++ "Unable to register device");
++ goto failed_cdev_add;
++ }
++
++ /* create sysfs entries */
++ vchiq_class = class_create(THIS_MODULE, DEVICE_NAME);
++ ptr_err = vchiq_class;
++ if (IS_ERR(ptr_err))
++ goto failed_class_create;
++
++ vchiq_dev = device_create(vchiq_class, NULL,
++ vchiq_devid, NULL, "vchiq");
++ ptr_err = vchiq_dev;
++ if (IS_ERR(ptr_err))
++ goto failed_device_create;
++
++ err = vchiq_platform_init(&g_state);
++ if (err != 0)
++ goto failed_platform_init;
++
++ vchiq_log_info(vchiq_arm_log_level,
++ "vchiq: initialised - version %d (min %d), device %d.%d",
++ VCHIQ_VERSION, VCHIQ_VERSION_MIN,
++ MAJOR(vchiq_devid), MINOR(vchiq_devid));
++
++ return 0;
+
+ failed_platform_init:
+- device_destroy(vchiq_class, vchiq_devid);
++ device_destroy(vchiq_class, vchiq_devid);
+ failed_device_create:
+- class_destroy(vchiq_class);
++ class_destroy(vchiq_class);
+ failed_class_create:
+- cdev_del(&vchiq_cdev);
+- err = PTR_ERR(ptr_err);
++ cdev_del(&vchiq_cdev);
++ err = PTR_ERR(ptr_err);
+ failed_cdev_add:
+- unregister_chrdev_region(vchiq_devid, 1);
++ unregister_chrdev_region(vchiq_devid, 1);
+ failed_alloc_chrdev:
+-failed_platform_vcos_init:
+- printk(KERN_WARNING "could not load vchiq\n");
+- return err;
++ vchiq_proc_deinit();
++failed_proc_init:
++ vchiq_log_warning(vchiq_arm_log_level, "could not load vchiq");
++ return err;
++}
++
++static int vchiq_instance_get_use_count(VCHIQ_INSTANCE_T instance)
++{
++ VCHIQ_SERVICE_T *service;
++ int use_count = 0, i;
++ i = 0;
++ while ((service = next_service_by_instance(instance->state,
++ instance, &i)) != NULL) {
++ use_count += service->service_use_count;
++ unlock_service(service);
++ }
++ return use_count;
+ }
++
++/* read the per-process use-count */
++static int proc_read_use_count(char *page, char **start,
++ off_t off, int count,
++ int *eof, void *data)
++{
++ VCHIQ_INSTANCE_T instance = data;
++ int len, use_count;
++
++ use_count = vchiq_instance_get_use_count(instance);
++ len = snprintf(page+off, count, "%d\n", use_count);
++
++ return len;
++}
++
++/* add an instance (process) to the proc entries */
++static int vchiq_proc_add_instance(VCHIQ_INSTANCE_T instance)
++{
++ char pidstr[32];
++ struct proc_dir_entry *top, *use_count;
++ struct proc_dir_entry *clients = vchiq_clients_top();
++ int pid = instance->pid;
++
++ snprintf(pidstr, sizeof(pidstr), "%d", pid);
++ top = proc_mkdir(pidstr, clients);
++ if (!top)
++ goto fail_top;
++
++ use_count = create_proc_read_entry("use_count",
++ 0444, top,
++ proc_read_use_count,
++ instance);
++ if (!use_count)
++ goto fail_use_count;
++
++ instance->proc_entry = top;
++
++ return 0;
++
++fail_use_count:
++ remove_proc_entry(top->name, clients);
++fail_top:
++ return -ENOMEM;
++}
++
++static void vchiq_proc_remove_instance(VCHIQ_INSTANCE_T instance)
++{
++ struct proc_dir_entry *clients = vchiq_clients_top();
++ remove_proc_entry("use_count", instance->proc_entry);
++ remove_proc_entry(instance->proc_entry->name, clients);
++}
++
+ /****************************************************************************
+ *
+ * vchiq_exit - called when the module is unloaded.
+@@ -1898,12 +2727,11 @@ failed_platform_vcos_init:
+ static void __exit
+ vchiq_exit(void)
+ {
+- vchiq_platform_exit(&g_state);
+- device_destroy(vchiq_class, vchiq_devid);
+- class_destroy(vchiq_class);
+- cdev_del(&vchiq_cdev);
+- unregister_chrdev_region(vchiq_devid, 1);
+- vcos_log_unregister(VCOS_LOG_CATEGORY);
++ vchiq_platform_exit(&g_state);
++ device_destroy(vchiq_class, vchiq_devid);
++ class_destroy(vchiq_class);
++ cdev_del(&vchiq_cdev);
++ unregister_chrdev_region(vchiq_devid, 1);
+ }
+
+ module_init(vchiq_init);
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h
+index 24b42ff..6db1074 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h
+@@ -19,46 +19,101 @@
+ #ifndef VCHIQ_ARM_H
+ #define VCHIQ_ARM_H
+
++#include <linux/mutex.h>
++#include <linux/semaphore.h>
++//#include <linux/pm_qos_params.h>
++#define pm_qos_add_request(a,b,c) do {} while (0)
++#define pm_qos_remove_request(a) do {} while (0)
++struct pm_qos_request_list {int dummy;};
++#include <linux/atomic.h>
+ #include "vchiq_core.h"
+
+
+-typedef struct vchiq_arm_state_struct {
+-
+- VCOS_THREAD_T lp_thread; /* processes low priority messages (eg suspend) */
+- VCOS_THREAD_T hp_thread; /* processes high priority messages (eg resume) */
+-
+- VCOS_EVENT_T lp_evt;
+- VCOS_EVENT_T hp_evt;
++enum vc_suspend_status {
++ VC_SUSPEND_FORCE_CANCELED = -3, /* Force suspend canceled, too busy */
++ VC_SUSPEND_REJECTED = -2, /* Videocore rejected suspend request */
++ VC_SUSPEND_FAILED = -1, /* Videocore suspend failed */
++ VC_SUSPEND_IDLE = 0, /* VC active, no suspend actions */
++ VC_SUSPEND_REQUESTED, /* User has requested suspend */
++ VC_SUSPEND_IN_PROGRESS, /* Slot handler has recvd suspend request */
++ VC_SUSPEND_SUSPENDED /* Videocore suspend succeeded */
++};
+
+- VCOS_MUTEX_T use_count_mutex;
+- VCOS_MUTEX_T suspend_resume_mutex;
++enum vc_resume_status {
++ VC_RESUME_FAILED = -1, /* Videocore resume failed */
++ VC_RESUME_IDLE = 0, /* VC suspended, no resume actions */
++ VC_RESUME_REQUESTED, /* User has requested resume */
++ VC_RESUME_IN_PROGRESS, /* Slot handler has received resume request */
++ VC_RESUME_RESUMED /* Videocore resumed successfully (active) */
++};
+
+- int suspend_pending;
+
+- /* Global use count for videocore.
+- * This is equal to the sum of the use counts for all services. When this hits
+- * zero the videocore suspend procedure will be initiated. */
+- int videocore_use_count;
++enum USE_TYPE_E {
++ USE_TYPE_SERVICE,
++ USE_TYPE_PEER,
++ USE_TYPE_VCHIQ
++};
+
+- /* Use count to track requests from videocore peer.
+- * This use count is not associated with a service, so needs to be tracked separately
+- * with the state.
+- */
+- int peer_use_count;
+
+- /* Flag to indicate whether videocore is currently suspended */
+- int videocore_suspended;
++typedef struct vchiq_arm_state_struct {
++ /* Keepalive-related data */
++ struct task_struct *ka_thread;
++ struct completion ka_evt;
++ atomic_t ka_use_count;
++ atomic_t ka_use_ack_count;
++ atomic_t ka_release_count;
++
++ struct completion vc_suspend_complete;
++ struct completion vc_resume_complete;
++
++ rwlock_t susp_res_lock;
++ enum vc_suspend_status vc_suspend_state;
++ enum vc_resume_status vc_resume_state;
++
++ struct mutex vc_use_cnt_mutex;
++ unsigned int wake_address;
++
++ struct timer_list suspend_timer;
++ int suspend_timer_timeout;
++ int suspend_timer_running;
++
++ /* Global use count for videocore.
++ ** This is equal to the sum of the use counts for all services. When
++ ** this hits zero the videocore suspend procedure will be initiated.
++ */
++ int videocore_use_count;
++
++ /* Use count to track requests from videocore peer.
++ ** This use count is not associated with a service, so needs to be
++ ** tracked separately with the state.
++ */
++ int peer_use_count;
++
++ /* Flag to indicate whether resume is blocked. This happens when the
++ ** ARM is suspending
++ */
++ struct completion resume_blocker;
++ int resume_blocked;
++ struct completion blocked_blocker;
++ int blocked_count;
++
++ /* Flag to indicate that the first vchiq connect has made it through.
++ ** This means that both sides should be fully ready, and we should
++ ** be able to suspend after this point.
++ */
++ int first_connect;
++
++ struct pm_qos_request_list qos_request;
++
++ unsigned long long suspend_start_time;
++ unsigned long long sleep_start_time;
++ unsigned long long resume_start_time;
++ unsigned long long last_wake_time;
+
+- /* Flag to indicate whether a notification is pending back to videocore that it's
+- * "remote use request" has been actioned */
+- int use_notify_pending;
+ } VCHIQ_ARM_STATE_T;
+
+-
+-extern VCOS_LOG_CAT_T vchiq_arm_log_category;
+-
+-extern int __init
+-vchiq_platform_vcos_init(void);
++extern int vchiq_arm_log_level;
++extern int vchiq_susp_log_level;
+
+ extern int __init
+ vchiq_platform_init(VCHIQ_STATE_T *state);
+@@ -73,16 +128,22 @@ extern VCHIQ_STATUS_T
+ vchiq_arm_vcsuspend(VCHIQ_STATE_T *state);
+
+ extern VCHIQ_STATUS_T
++vchiq_arm_force_suspend(VCHIQ_STATE_T *state);
++
++extern int
++vchiq_arm_allow_resume(VCHIQ_STATE_T *state);
++
++extern VCHIQ_STATUS_T
+ vchiq_arm_vcresume(VCHIQ_STATE_T *state);
+
+ extern VCHIQ_STATUS_T
+ vchiq_arm_init_state(VCHIQ_STATE_T *state, VCHIQ_ARM_STATE_T *arm_state);
+
+-extern void
+-vchiq_check_resume(VCHIQ_STATE_T* state);
++extern int
++vchiq_check_resume(VCHIQ_STATE_T *state);
+
+ extern void
+-vchiq_check_suspend(VCHIQ_STATE_T* state);
++vchiq_check_suspend(VCHIQ_STATE_T *state);
+
+ extern VCHIQ_STATUS_T
+ vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle);
+@@ -91,16 +152,13 @@ extern VCHIQ_STATUS_T
+ vchiq_release_service(VCHIQ_SERVICE_HANDLE_T handle);
+
+ extern VCHIQ_STATUS_T
+-vchiq_check_service(VCHIQ_SERVICE_T * service);
++vchiq_check_service(VCHIQ_SERVICE_T *service);
+
+ extern VCHIQ_STATUS_T
+ vchiq_platform_suspend(VCHIQ_STATE_T *state);
+
+-extern VCHIQ_STATUS_T
+-vchiq_platform_resume(VCHIQ_STATE_T *state);
+-
+ extern int
+-vchiq_platform_videocore_wanted(VCHIQ_STATE_T* state);
++vchiq_platform_videocore_wanted(VCHIQ_STATE_T *state);
+
+ extern int
+ vchiq_platform_use_suspend_timer(void);
+@@ -114,5 +172,30 @@ vchiq_dump_service_use_state(VCHIQ_STATE_T *state);
+ extern VCHIQ_ARM_STATE_T*
+ vchiq_platform_get_arm_state(VCHIQ_STATE_T *state);
+
++extern int
++vchiq_videocore_wanted(VCHIQ_STATE_T *state);
++
++extern VCHIQ_STATUS_T
++vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
++ enum USE_TYPE_E use_type);
++extern VCHIQ_STATUS_T
++vchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service);
++
++void
++set_suspend_state(VCHIQ_ARM_STATE_T *arm_state,
++ enum vc_suspend_status new_state);
++
++void
++set_resume_state(VCHIQ_ARM_STATE_T *arm_state,
++ enum vc_resume_status new_state);
++
++void
++start_suspend_timer(VCHIQ_ARM_STATE_T *arm_state);
++
++extern int vchiq_proc_init(void);
++extern void vchiq_proc_deinit(void);
++extern struct proc_dir_entry *vchiq_proc_top(void);
++extern struct proc_dir_entry *vchiq_clients_top(void);
++
+
+ #endif /* VCHIQ_ARM_H */
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_cfg.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_cfg.h
+index cd51d99..bd7f793 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_cfg.h
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_cfg.h
+@@ -19,12 +19,14 @@
+ #ifndef VCHIQ_CFG_H
+ #define VCHIQ_CFG_H
+
+-#define VCHIQ_MAGIC VCHIQ_MAKE_FOURCC('V','C','H','I')
++#define VCHIQ_MAGIC VCHIQ_MAKE_FOURCC('V', 'C', 'H', 'I')
+ /* The version of VCHIQ - change with any non-trivial change */
+-#define VCHIQ_VERSION 2
+-/* The minimum compatible version - update to match VCHIQ_VERSION with any incompatible change */
+-#define VCHIQ_VERSION_MIN 2
++#define VCHIQ_VERSION 5
++/* The minimum compatible version - update to match VCHIQ_VERSION with any
++** incompatible change */
++#define VCHIQ_VERSION_MIN 3
+
++#define VCHIQ_MAX_STATES 1
+ #define VCHIQ_MAX_SERVICES 4096
+ #define VCHIQ_MAX_SLOTS 128
+ #define VCHIQ_MAX_SLOTS_PER_SIDE 64
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.c
+index 62e3006..2927d4b 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.c
+@@ -12,20 +12,18 @@
+ * consent.
+ *****************************************************************************/
+
+-#include "vcos.h"
+ #include "vchiq_connected.h"
++#include "vchiq_core.h"
+ #include <linux/module.h>
++#include <linux/mutex.h>
+
+ #define MAX_CALLBACKS 10
+
+-static int g_connected = 0;
++static int g_connected;
+ static int g_num_deferred_callbacks;
+-static VCHIQ_CONNECTED_CALLBACK_T g_deferred_callback[ MAX_CALLBACKS ];
+-static VCOS_ONCE_T g_once_init;
+-static VCOS_MUTEX_T g_connected_mutex;
+-
+-extern VCOS_LOG_CAT_T vchiq_core_log_category;
+-#define VCOS_LOG_CATEGORY (&vchiq_core_log_category)
++static VCHIQ_CONNECTED_CALLBACK_T g_deferred_callback[MAX_CALLBACKS];
++static int g_once_init;
++static struct mutex g_connected_mutex;
+
+ /****************************************************************************
+ *
+@@ -33,9 +31,12 @@ extern VCOS_LOG_CAT_T vchiq_core_log_category;
+ *
+ ***************************************************************************/
+
+-static void connected_init( void )
++static void connected_init(void)
+ {
+- vcos_mutex_create( &g_connected_mutex, "connected_mutex");
++ if (!g_once_init) {
++ mutex_init(&g_connected_mutex);
++ g_once_init = 1;
++ }
+ }
+
+ /****************************************************************************
+@@ -47,32 +48,30 @@ static void connected_init( void )
+ *
+ ***************************************************************************/
+
+-void vchiq_add_connected_callback( VCHIQ_CONNECTED_CALLBACK_T callback )
++void vchiq_add_connected_callback(VCHIQ_CONNECTED_CALLBACK_T callback)
+ {
+- vcos_once( &g_once_init, connected_init );
+-
+- vcos_mutex_lock( &g_connected_mutex );
+-
+- if ( g_connected )
+- {
+- // We're already connected. Call the callback immediately.
+-
+- callback();
+- }
+- else
+- {
+- if ( g_num_deferred_callbacks >= MAX_CALLBACKS )
+- {
+- vcos_log_error( "There already %d callback registered - please increase MAX_CALLBACKS",
+- g_num_deferred_callbacks );
+- }
+- else
+- {
+- g_deferred_callback[ g_num_deferred_callbacks ] = callback;
+- g_num_deferred_callbacks++;
+- }
+- }
+- vcos_mutex_unlock( &g_connected_mutex );
++ connected_init();
++
++ if (mutex_lock_interruptible(&g_connected_mutex) != 0)
++ return;
++
++ if (g_connected)
++ /* We're already connected. Call the callback immediately. */
++
++ callback();
++ else {
++ if (g_num_deferred_callbacks >= MAX_CALLBACKS)
++ vchiq_log_error(vchiq_core_log_level,
++ "There already %d callback registered - "
++ "please increase MAX_CALLBACKS",
++ g_num_deferred_callbacks);
++ else {
++ g_deferred_callback[g_num_deferred_callbacks] =
++ callback;
++ g_num_deferred_callbacks++;
++ }
++ }
++ mutex_unlock(&g_connected_mutex);
+ }
+
+ /****************************************************************************
+@@ -82,20 +81,20 @@ void vchiq_add_connected_callback( VCHIQ_CONNECTED_CALLBACK_T callback )
+ *
+ ***************************************************************************/
+
+-void vchiq_call_connected_callbacks( void )
++void vchiq_call_connected_callbacks(void)
+ {
+- int i;
+-
+- vcos_once( &g_once_init, connected_init );
+-
+- vcos_mutex_lock( &g_connected_mutex );
+- for ( i = 0; i < g_num_deferred_callbacks; i++ )\
+- {
+- g_deferred_callback[i]();
+- }
+- g_num_deferred_callbacks = 0;
+- g_connected = 1;
+- vcos_mutex_unlock( &g_connected_mutex );
+-}
++ int i;
++
++ connected_init();
+
+-EXPORT_SYMBOL( vchiq_add_connected_callback );
++ if (mutex_lock_interruptible(&g_connected_mutex) != 0)
++ return;
++
++ for (i = 0; i < g_num_deferred_callbacks; i++)
++ g_deferred_callback[i]();
++
++ g_num_deferred_callbacks = 0;
++ g_connected = 1;
++ mutex_unlock(&g_connected_mutex);
++}
++EXPORT_SYMBOL(vchiq_add_connected_callback);
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.h
+index 88cfa58..f62faf0 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.h
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_connected.h
+@@ -19,14 +19,14 @@
+
+ /* ---- Constants and Types ---------------------------------------------- */
+
+-typedef void (*VCHIQ_CONNECTED_CALLBACK_T)( void );
++typedef void (*VCHIQ_CONNECTED_CALLBACK_T)(void);
+
+ /* ---- Variable Externs ------------------------------------------------- */
+
+ /* ---- Function Prototypes ---------------------------------------------- */
+
+-void vchiq_add_connected_callback( VCHIQ_CONNECTED_CALLBACK_T callback );
+-void vchiq_call_connected_callbacks( void );
++void vchiq_add_connected_callback(VCHIQ_CONNECTED_CALLBACK_T callback);
++void vchiq_call_connected_callbacks(void);
+
+ #endif /* VCHIQ_CONNECTED_H */
+
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
+index 749e7d4..0b84988 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
+@@ -20,2698 +20,3741 @@
+
+ #define VCHIQ_SLOT_HANDLER_STACK 8192
+
++#define HANDLE_STATE_SHIFT 12
++
+ #define SLOT_INFO_FROM_INDEX(state, index) (state->slot_info + (index))
+ #define SLOT_DATA_FROM_INDEX(state, index) (state->slot_data + (index))
+-#define SLOT_INDEX_FROM_DATA(state, data) (((unsigned int)((char *)data - (char *)state->slot_data)) / VCHIQ_SLOT_SIZE)
+-#define SLOT_INDEX_FROM_INFO(state, info) ((unsigned int)(info - state->slot_info))
+-#define SLOT_QUEUE_INDEX_FROM_POS(pos) ((int)((unsigned int)(pos) / VCHIQ_SLOT_SIZE))
++#define SLOT_INDEX_FROM_DATA(state, data) \
++ (((unsigned int)((char *)data - (char *)state->slot_data)) / \
++ VCHIQ_SLOT_SIZE)
++#define SLOT_INDEX_FROM_INFO(state, info) \
++ ((unsigned int)(info - state->slot_info))
++#define SLOT_QUEUE_INDEX_FROM_POS(pos) \
++ ((int)((unsigned int)(pos) / VCHIQ_SLOT_SIZE))
+
+-#define VCOS_LOG_CATEGORY (&vchiq_core_log_category)
+
+ #define BULK_INDEX(x) (x & (VCHIQ_NUM_SERVICE_BULKS - 1))
+
+
+-/* Used to check use counts allow vchiq use. */
+-extern VCHIQ_STATUS_T vchiq_check_service(VCHIQ_SERVICE_T * service);
++struct vchiq_open_payload {
++ int fourcc;
++ int client_id;
++ short version;
++ short version_min;
++};
++
++/* we require this for consistency between endpoints */
++vchiq_static_assert(sizeof(VCHIQ_HEADER_T) == 8);
++vchiq_static_assert(IS_POW2(sizeof(VCHIQ_HEADER_T)));
++vchiq_static_assert(IS_POW2(VCHIQ_NUM_CURRENT_BULKS));
++vchiq_static_assert(IS_POW2(VCHIQ_NUM_SERVICE_BULKS));
++vchiq_static_assert(IS_POW2(VCHIQ_MAX_SERVICES));
++vchiq_static_assert(VCHIQ_VERSION >= VCHIQ_VERSION_MIN);
++
++/* Run time control of log level, based on KERN_XXX level. */
++int vchiq_core_log_level = VCHIQ_LOG_DEFAULT;
++int vchiq_core_msg_log_level = VCHIQ_LOG_DEFAULT;
++int vchiq_sync_log_level = VCHIQ_LOG_DEFAULT;
++
++static atomic_t pause_bulks_count = ATOMIC_INIT(0);
++
++static DEFINE_SPINLOCK(service_spinlock);
++DEFINE_SPINLOCK(bulk_waiter_spinlock);
++DEFINE_SPINLOCK(quota_spinlock);
++
++VCHIQ_STATE_T *vchiq_states[VCHIQ_MAX_STATES];
++static unsigned int handle_seq;
++
++static const char *const srvstate_names[] = {
++ "FREE",
++ "HIDDEN",
++ "LISTENING",
++ "OPENING",
++ "OPEN",
++ "OPENSYNC",
++ "CLOSESENT",
++ "CLOSERECVD",
++ "CLOSEWAIT",
++ "CLOSED"
++};
++
++static const char *const reason_names[] = {
++ "SERVICE_OPENED",
++ "SERVICE_CLOSED",
++ "MESSAGE_AVAILABLE",
++ "BULK_TRANSMIT_DONE",
++ "BULK_RECEIVE_DONE",
++ "BULK_TRANSMIT_ABORTED",
++ "BULK_RECEIVE_ABORTED"
++};
++
++static const char *const conn_state_names[] = {
++ "DISCONNECTED",
++ "CONNECTING",
++ "CONNECTED",
++ "PAUSING",
++ "PAUSE_SENT",
++ "PAUSED",
++ "RESUMING"
++};
++
++
++static void
++release_message_sync(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header);
++
++static const char *msg_type_str(unsigned int msg_type)
++{
++ switch (msg_type) {
++ case VCHIQ_MSG_PADDING: return "PADDING";
++ case VCHIQ_MSG_CONNECT: return "CONNECT";
++ case VCHIQ_MSG_OPEN: return "OPEN";
++ case VCHIQ_MSG_OPENACK: return "OPENACK";
++ case VCHIQ_MSG_CLOSE: return "CLOSE";
++ case VCHIQ_MSG_DATA: return "DATA";
++ case VCHIQ_MSG_BULK_RX: return "BULK_RX";
++ case VCHIQ_MSG_BULK_TX: return "BULK_TX";
++ case VCHIQ_MSG_BULK_RX_DONE: return "BULK_RX_DONE";
++ case VCHIQ_MSG_BULK_TX_DONE: return "BULK_TX_DONE";
++ case VCHIQ_MSG_PAUSE: return "PAUSE";
++ case VCHIQ_MSG_RESUME: return "RESUME";
++ case VCHIQ_MSG_REMOTE_USE: return "REMOTE_USE";
++ case VCHIQ_MSG_REMOTE_RELEASE: return "REMOTE_RELEASE";
++ case VCHIQ_MSG_REMOTE_USE_ACTIVE: return "REMOTE_USE_ACTIVE";
++ }
++ return "???";
++}
+
++static inline void
++vchiq_set_service_state(VCHIQ_SERVICE_T *service, int newstate)
++{
++ vchiq_log_info(vchiq_core_log_level, "%d: srv:%d %s->%s",
++ service->state->id, service->localport,
++ srvstate_names[service->srvstate],
++ srvstate_names[newstate]);
++ service->srvstate = newstate;
++}
+
+-typedef struct bulk_waiter_struct
++VCHIQ_SERVICE_T *
++find_service_by_handle(VCHIQ_SERVICE_HANDLE_T handle)
+ {
+- VCOS_EVENT_T event;
+- int actual;
+-} BULK_WAITER_T;
++ VCHIQ_SERVICE_T *service;
+
+-typedef struct vchiq_open_payload_struct{
+- int fourcc;
+- int client_id;
+- short version;
+- short version_min;
+-} VCHIQ_OPEN_PAYLOAD_T;
++ spin_lock(&service_spinlock);
++ service = handle_to_service(handle);
++ if (service && (service->srvstate != VCHIQ_SRVSTATE_FREE) &&
++ (service->handle == handle)) {
++ BUG_ON(service->ref_count == 0);
++ service->ref_count++;
++ } else
++ service = NULL;
++ spin_unlock(&service_spinlock);
+
+-vcos_static_assert(sizeof(VCHIQ_HEADER_T) == 8); /* we require this for consistency between endpoints */
+-vcos_static_assert(IS_POW2(sizeof(VCHIQ_HEADER_T)));
+-vcos_static_assert(IS_POW2(VCHIQ_NUM_CURRENT_BULKS));
+-vcos_static_assert(IS_POW2(VCHIQ_NUM_SERVICE_BULKS));
++ if (!service)
++ vchiq_log_info(vchiq_core_log_level,
++ "Invalid service handle 0x%x", handle);
+
+-VCOS_LOG_CAT_T vchiq_core_log_category;
+-VCOS_LOG_CAT_T vchiq_core_msg_log_category;
+-VCOS_LOG_LEVEL_T vchiq_default_core_log_level = VCOS_LOG_WARN;
+-VCOS_LOG_LEVEL_T vchiq_default_core_msg_log_level = VCOS_LOG_WARN;
++ return service;
++}
+
+-static const char *const srvstate_names[] =
++VCHIQ_SERVICE_T *
++find_service_by_port(VCHIQ_STATE_T *state, int localport)
++{
++ VCHIQ_SERVICE_T *service = NULL;
++ if ((unsigned int)localport <= VCHIQ_PORT_MAX) {
++ spin_lock(&service_spinlock);
++ service = state->services[localport];
++ if (service && (service->srvstate != VCHIQ_SRVSTATE_FREE)) {
++ BUG_ON(service->ref_count == 0);
++ service->ref_count++;
++ } else
++ service = NULL;
++ spin_unlock(&service_spinlock);
++ }
++
++ if (!service)
++ vchiq_log_info(vchiq_core_log_level,
++ "Invalid port %d", localport);
++
++ return service;
++}
++
++VCHIQ_SERVICE_T *
++find_service_for_instance(VCHIQ_INSTANCE_T instance,
++ VCHIQ_SERVICE_HANDLE_T handle) {
++ VCHIQ_SERVICE_T *service;
++
++ spin_lock(&service_spinlock);
++ service = handle_to_service(handle);
++ if (service && (service->srvstate != VCHIQ_SRVSTATE_FREE) &&
++ (service->handle == handle) &&
++ (service->instance == instance)) {
++ BUG_ON(service->ref_count == 0);
++ service->ref_count++;
++ } else
++ service = NULL;
++ spin_unlock(&service_spinlock);
++
++ if (!service)
++ vchiq_log_info(vchiq_core_log_level,
++ "Invalid service handle 0x%x", handle);
++
++ return service;
++}
++
++VCHIQ_SERVICE_T *
++next_service_by_instance(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance,
++ int *pidx)
++{
++ VCHIQ_SERVICE_T *service = NULL;
++ int idx = *pidx;
++
++ spin_lock(&service_spinlock);
++ while (idx < state->unused_service) {
++ VCHIQ_SERVICE_T *srv = state->services[idx++];
++ if (srv && (srv->srvstate != VCHIQ_SRVSTATE_FREE) &&
++ (srv->instance == instance)) {
++ service = srv;
++ BUG_ON(service->ref_count == 0);
++ service->ref_count++;
++ break;
++ }
++ }
++ spin_unlock(&service_spinlock);
++
++ *pidx = idx;
++
++ return service;
++}
++
++void
++lock_service(VCHIQ_SERVICE_T *service)
+ {
+- "FREE",
+- "HIDDEN",
+- "LISTENING",
+- "OPENING",
+- "OPEN",
+- "CLOSESENT",
+- "CLOSING",
+- "CLOSEWAIT"
+-};
++ spin_lock(&service_spinlock);
++ BUG_ON(!service || (service->ref_count == 0));
++ if (service)
++ service->ref_count++;
++ spin_unlock(&service_spinlock);
++}
+
+-static const char *const reason_names[] =
++void
++unlock_service(VCHIQ_SERVICE_T *service)
++{
++ VCHIQ_STATE_T *state = service->state;
++ spin_lock(&service_spinlock);
++ BUG_ON(!service || (service->ref_count == 0));
++ if (service && service->ref_count) {
++ service->ref_count--;
++ if (!service->ref_count) {
++ BUG_ON(service->srvstate != VCHIQ_SRVSTATE_FREE);
++ state->services[service->localport] = NULL;
++ }
++ else
++ service = NULL;
++ }
++ spin_unlock(&service_spinlock);
++
++ kfree(service);
++}
++
++int
++vchiq_get_client_id(VCHIQ_SERVICE_HANDLE_T handle)
+ {
+- "SERVICE_OPENED",
+- "SERVICE_CLOSED",
+- "MESSAGE_AVAILABLE",
+- "BULK_TRANSMIT_DONE",
+- "BULK_RECEIVE_DONE",
+- "BULK_TRANSMIT_ABORTED",
+- "BULK_RECEIVE_ABORTED"
+-};
++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
++ int id;
++
++ id = service ? service->client_id : 0;
++ if (service)
++ unlock_service(service);
++
++ return id;
++}
+
+-static const char *const conn_state_names[] =
++void *
++vchiq_get_service_userdata(VCHIQ_SERVICE_HANDLE_T handle)
+ {
+- "DISCONNECTED",
+- "CONNECTED",
+- "PAUSING",
+- "PAUSE_SENT",
+- "PAUSED",
+- "RESUMING"
+-};
++ VCHIQ_SERVICE_T *service = handle_to_service(handle);
+
+-static const char *msg_type_str( unsigned int msg_type )
+-{
+- switch (msg_type) {
+- case VCHIQ_MSG_PADDING: return "PADDING";
+- case VCHIQ_MSG_CONNECT: return "CONNECT";
+- case VCHIQ_MSG_OPEN: return "OPEN";
+- case VCHIQ_MSG_OPENACK: return "OPENACK";
+- case VCHIQ_MSG_CLOSE: return "CLOSE";
+- case VCHIQ_MSG_DATA: return "DATA";
+- case VCHIQ_MSG_BULK_RX: return "BULK_RX";
+- case VCHIQ_MSG_BULK_TX: return "BULK_TX";
+- case VCHIQ_MSG_BULK_RX_DONE: return "BULK_RX_DONE";
+- case VCHIQ_MSG_BULK_TX_DONE: return "BULK_TX_DONE";
+- case VCHIQ_MSG_PAUSE: return "PAUSE";
+- case VCHIQ_MSG_RESUME: return "RESUME";
+- }
+- return "???";
++ return service ? service->base.userdata : NULL;
+ }
+
+-static inline void
+-vchiq_set_service_state(VCHIQ_SERVICE_T *service, int newstate)
++int
++vchiq_get_service_fourcc(VCHIQ_SERVICE_HANDLE_T handle)
+ {
+- vcos_log_info("%d: srv:%d %s->%s", service->state->id, service->localport,
+- srvstate_names[service->srvstate],
+- srvstate_names[newstate]);
+- service->srvstate = newstate;
++ VCHIQ_SERVICE_T *service = handle_to_service(handle);
++
++ return service ? service->base.fourcc : 0;
+ }
+
+-static inline int
+-is_valid_service(VCHIQ_SERVICE_T *service)
++static void
++mark_service_closing(VCHIQ_SERVICE_T *service)
+ {
+- return ((service != NULL) &&
+- (service->srvstate != VCHIQ_SRVSTATE_FREE));
++ VCHIQ_STATE_T *state = service->state;
++ VCHIQ_SERVICE_QUOTA_T *service_quota;
++
++ service->closing = 1;
++
++ /* Synchronise with other threads. */
++ mutex_lock(&state->recycle_mutex);
++ mutex_unlock(&state->recycle_mutex);
++ mutex_lock(&state->slot_mutex);
++ mutex_unlock(&state->slot_mutex);
++
++ /* Unblock any sending thread. */
++ service_quota = &state->service_quotas[service->localport];
++ up(&service_quota->quota_event);
+ }
+
+ static inline VCHIQ_STATUS_T
+ make_service_callback(VCHIQ_SERVICE_T *service, VCHIQ_REASON_T reason,
+- VCHIQ_HEADER_T *header, void *bulk_userdata)
++ VCHIQ_HEADER_T *header, void *bulk_userdata)
+ {
+- vcos_log_trace("%d: callback:%d (%s, %x, %x)", service->state->id,
+- service->localport, reason_names[reason],
+- (unsigned int)header, (unsigned int)bulk_userdata);
+- return service->base.callback(reason, header, &service->base, bulk_userdata);
++ vchiq_log_trace(vchiq_core_log_level, "%d: callback:%d (%s, %x, %x)",
++ service->state->id, service->localport, reason_names[reason],
++ (unsigned int)header, (unsigned int)bulk_userdata);
++ return service->base.callback(reason, header, service->handle,
++ bulk_userdata);
+ }
+
+ static inline void
+ vchiq_set_conn_state(VCHIQ_STATE_T *state, VCHIQ_CONNSTATE_T newstate)
+ {
+- VCHIQ_CONNSTATE_T oldstate = state->conn_state;
+- vcos_log_info("%d: %s->%s", state->id,
+- conn_state_names[oldstate],
+- conn_state_names[newstate]);
+- state->conn_state = newstate;
+- vchiq_platform_conn_state_changed(state, oldstate, newstate);
++ VCHIQ_CONNSTATE_T oldstate = state->conn_state;
++ vchiq_log_info(vchiq_core_log_level, "%d: %s->%s", state->id,
++ conn_state_names[oldstate],
++ conn_state_names[newstate]);
++ state->conn_state = newstate;
++ vchiq_platform_conn_state_changed(state, oldstate, newstate);
+ }
+
+ static inline void
+ remote_event_create(REMOTE_EVENT_T *event)
+ {
+- event->armed = 0;
+- /* Don't clear the 'fired' flag because it may already have been set by the other side */
+- vcos_event_create(event->event, "vchiq");
++ event->armed = 0;
++ /* Don't clear the 'fired' flag because it may already have been set
++ ** by the other side. */
++ sema_init(event->event, 0);
+ }
+
+ static inline void
+ remote_event_destroy(REMOTE_EVENT_T *event)
+ {
+- vcos_event_delete(event->event);
++ (void)event;
+ }
+
+ static inline int
+ remote_event_wait(REMOTE_EVENT_T *event)
+ {
+- if (!event->fired)
+- {
+- event->armed = 1;
+- if (event->fired) /* Also ensures the write has completed */
+- event->armed = 0;
+- else if (vcos_event_wait(event->event) != VCOS_SUCCESS)
+- return 0;
+- }
+-
+- event->fired = 0;
+- return 1;
++ if (!event->fired) {
++ event->armed = 1;
++ dsb();
++ if (!event->fired) {
++ if (down_interruptible(event->event) != 0) {
++ event->armed = 0;
++ return 0;
++ }
++ }
++ event->armed = 0;
++ wmb();
++ }
++
++ event->fired = 0;
++ return 1;
+ }
+
+ static inline void
+ remote_event_signal_local(REMOTE_EVENT_T *event)
+ {
+- event->armed = 0;
+- vcos_event_signal(event->event);
++ event->armed = 0;
++ up(event->event);
+ }
+
+ static inline void
+ remote_event_poll(REMOTE_EVENT_T *event)
+ {
+- if (event->armed)
+- remote_event_signal_local(event);
++ if (event->fired && event->armed)
++ remote_event_signal_local(event);
+ }
+
+ void
+ remote_event_pollall(VCHIQ_STATE_T *state)
+ {
+- remote_event_poll(&state->local->trigger);
+- remote_event_poll(&state->local->recycle);
++ remote_event_poll(&state->local->sync_trigger);
++ remote_event_poll(&state->local->sync_release);
++ remote_event_poll(&state->local->trigger);
++ remote_event_poll(&state->local->recycle);
+ }
+
+ /* Round up message sizes so that any space at the end of a slot is always big
+- enough for a header. This relies on header size being a power of two, which
+- has been verified earlier by a static assertion. */
++** enough for a header. This relies on header size being a power of two, which
++** has been verified earlier by a static assertion. */
+
+ static inline unsigned int
+ calc_stride(unsigned int size)
+ {
+- /* Allow room for the header */
+- size += sizeof(VCHIQ_HEADER_T);
++ /* Allow room for the header */
++ size += sizeof(VCHIQ_HEADER_T);
+
+- /* Round up */
+- return (size + sizeof(VCHIQ_HEADER_T) - 1) & ~(sizeof(VCHIQ_HEADER_T) - 1);
++ /* Round up */
++ return (size + sizeof(VCHIQ_HEADER_T) - 1) & ~(sizeof(VCHIQ_HEADER_T)
++ - 1);
+ }
+
++/* Called by the slot handler thread */
+ static VCHIQ_SERVICE_T *
+ get_listening_service(VCHIQ_STATE_T *state, int fourcc)
+ {
+- int i;
++ int i;
+
+- vcos_assert(fourcc != VCHIQ_FOURCC_INVALID);
++ WARN_ON(fourcc == VCHIQ_FOURCC_INVALID);
+
+- for (i = 0; i < state->unused_service; i++)
+- {
+- VCHIQ_SERVICE_T *service = state->services[i];
+- if (service &&
+- (service->public_fourcc == fourcc) &&
+- ((service->srvstate == VCHIQ_SRVSTATE_LISTENING) ||
+- ((service->srvstate == VCHIQ_SRVSTATE_OPEN) &&
+- (service->remoteport == VCHIQ_PORT_FREE))))
+- return service;
+- }
++ for (i = 0; i < state->unused_service; i++) {
++ VCHIQ_SERVICE_T *service = state->services[i];
++ if (service &&
++ (service->public_fourcc == fourcc) &&
++ ((service->srvstate == VCHIQ_SRVSTATE_LISTENING) ||
++ ((service->srvstate == VCHIQ_SRVSTATE_OPEN) &&
++ (service->remoteport == VCHIQ_PORT_FREE)))) {
++ lock_service(service);
++ return service;
++ }
++ }
+
+- return NULL;
++ return NULL;
+ }
+
++/* Called by the slot handler thread */
+ static VCHIQ_SERVICE_T *
+ get_connected_service(VCHIQ_STATE_T *state, unsigned int port)
+ {
+- int i;
+- for (i = 0; i < state->unused_service; i++) {
+- VCHIQ_SERVICE_T *service = state->services[i];
+- if (service && (service->srvstate == VCHIQ_SRVSTATE_OPEN)
+- && (service->remoteport == port)) {
+- return service;
+- }
+- }
+- return NULL;
++ int i;
++ for (i = 0; i < state->unused_service; i++) {
++ VCHIQ_SERVICE_T *service = state->services[i];
++ if (service && (service->srvstate == VCHIQ_SRVSTATE_OPEN)
++ && (service->remoteport == port)) {
++ lock_service(service);
++ return service;
++ }
++ }
++ return NULL;
+ }
+
+-static inline void
++inline void
+ request_poll(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, int poll_type)
+ {
+- if (service)
+- {
+- vcos_atomic_flags_or(&service->poll_flags, (1 << poll_type));
+- vcos_atomic_flags_or(&state->poll_services[service->localport>>5],
+- (1 <<(service->localport & 0x1f)));
+- }
++ uint32_t value;
++
++ if (service) {
++ do {
++ value = atomic_read(&service->poll_flags);
++ } while (atomic_cmpxchg(&service->poll_flags, value,
++ value | (1 << poll_type)) != value);
+
+- state->poll_needed = 1;
+- vcos_wmb(&state->poll_needed);
++ do {
++ value = atomic_read(&state->poll_services[
++ service->localport>>5]);
++ } while (atomic_cmpxchg(
++ &state->poll_services[service->localport>>5],
++ value, value | (1 << (service->localport & 0x1f)))
++ != value);
++ }
+
+- /* ... and ensure the slot handler runs. */
+- remote_event_signal_local(&state->local->trigger);
++ state->poll_needed = 1;
++ wmb();
++
++ /* ... and ensure the slot handler runs. */
++ remote_event_signal_local(&state->local->trigger);
+ }
+
+ /* Called from queue_message, by the slot handler and application threads,
+- with slot_mutex held */
++** with slot_mutex held */
+ static VCHIQ_HEADER_T *
+ reserve_space(VCHIQ_STATE_T *state, int space, int is_blocking)
+ {
+- VCHIQ_SHARED_STATE_T *local = state->local;
+- int tx_pos = state->local_tx_pos;
+- int slot_space = VCHIQ_SLOT_SIZE - (tx_pos & VCHIQ_SLOT_MASK);
++ VCHIQ_SHARED_STATE_T *local = state->local;
++ int tx_pos = state->local_tx_pos;
++ int slot_space = VCHIQ_SLOT_SIZE - (tx_pos & VCHIQ_SLOT_MASK);
++
++ if (space > slot_space) {
++ VCHIQ_HEADER_T *header;
++ /* Fill the remaining space with padding */
++ WARN_ON(state->tx_data == NULL);
++ header = (VCHIQ_HEADER_T *)
++ (state->tx_data + (tx_pos & VCHIQ_SLOT_MASK));
++ header->msgid = VCHIQ_MSGID_PADDING;
++ header->size = slot_space - sizeof(VCHIQ_HEADER_T);
++
++ tx_pos += slot_space;
++ }
+
+- if (space > slot_space) {
+- VCHIQ_HEADER_T *header;
+- /* Fill the remaining space with padding */
+- vcos_assert(state->tx_data != NULL);
+- header = (VCHIQ_HEADER_T *) (state->tx_data + (tx_pos & VCHIQ_SLOT_MASK));
+- header->msgid = VCHIQ_MSGID_PADDING;
+- header->size = slot_space - sizeof(VCHIQ_HEADER_T);
++ /* If necessary, get the next slot. */
++ if ((tx_pos & VCHIQ_SLOT_MASK) == 0) {
++ int slot_index;
+
+- tx_pos += slot_space;
+- }
++ /* If there is no free slot... */
+
+- /* If necessary, get the next slot. */
+- if ((tx_pos & VCHIQ_SLOT_MASK) == 0)
+- {
+- int slot_index;
++ if (down_trylock(&state->slot_available_event) != 0) {
++ /* ...wait for one. */
+
+- /* If there is no free slot... */
+- if (tx_pos == (state->slot_queue_available * VCHIQ_SLOT_SIZE))
+- {
+- /* ...wait for one. */
+- VCHIQ_STATS_INC(state, slot_stalls);
++ VCHIQ_STATS_INC(state, slot_stalls);
+
+- /* But first, flush through the last slot. */
+- local->tx_pos = tx_pos;
+- remote_event_signal(&state->remote->trigger);
++ /* But first, flush through the last slot. */
++ state->local_tx_pos = tx_pos;
++ local->tx_pos = tx_pos;
++ remote_event_signal(&state->remote->trigger);
+
+- do {
+- if (!is_blocking ||
+- (vcos_event_wait(&state->slot_available_event) != VCOS_SUCCESS))
+- {
+- return NULL; /* No space available now */
+- }
+- }
+- while (tx_pos == (state->slot_queue_available * VCHIQ_SLOT_SIZE));
+- }
++ if (!is_blocking ||
++ (down_interruptible(
++ &state->slot_available_event) != 0))
++ return NULL; /* No space available */
++ }
+
+- slot_index = local->slot_queue[SLOT_QUEUE_INDEX_FROM_POS(tx_pos) & VCHIQ_SLOT_QUEUE_MASK];
+- state->tx_data = (char *)SLOT_DATA_FROM_INDEX(state, slot_index);
+- }
++ BUG_ON(tx_pos ==
++ (state->slot_queue_available * VCHIQ_SLOT_SIZE));
+
+- state->local_tx_pos = tx_pos + space;
++ slot_index = local->slot_queue[
++ SLOT_QUEUE_INDEX_FROM_POS(tx_pos) &
++ VCHIQ_SLOT_QUEUE_MASK];
++ state->tx_data =
++ (char *)SLOT_DATA_FROM_INDEX(state, slot_index);
++ }
+
+- return (VCHIQ_HEADER_T *)(state->tx_data + (tx_pos & VCHIQ_SLOT_MASK));
++ state->local_tx_pos = tx_pos + space;
++
++ return (VCHIQ_HEADER_T *)(state->tx_data + (tx_pos & VCHIQ_SLOT_MASK));
+ }
+
+-/* Called with slot_mutex held */
++/* Called by the recycle thread. */
+ static void
+ process_free_queue(VCHIQ_STATE_T *state)
+ {
+- VCHIQ_SHARED_STATE_T *local = state->local;
+- BITSET_T service_found[BITSET_SIZE(VCHIQ_MAX_SERVICES)];
+- int slot_queue_available;
+-
+- /* Use a read memory barrier to ensure that any state that may have
+- been modified by another thread is not masked by stale prefetched
+- values. */
+- vcos_rmb();
+-
+- /* Find slots which have been freed by the other side, and return them to
+- the available queue. */
+- slot_queue_available = state->slot_queue_available;
+-
+- while (slot_queue_available != local->slot_queue_recycle)
+- {
+- unsigned int pos;
+- int slot_index = local->slot_queue[slot_queue_available++ & VCHIQ_SLOT_QUEUE_MASK];
+- char *data = (char *)SLOT_DATA_FROM_INDEX(state, slot_index);
+-
+- vcos_log_trace("%d: pfq %d=%x %x %x", state->id, slot_index,
+- (unsigned int)data, local->slot_queue_recycle,
+- slot_queue_available);
+-
+- /* Initialise the bitmask for services which have used this slot */
+- BITSET_ZERO(service_found);
+-
+- pos = 0;
+-
+- while (pos < VCHIQ_SLOT_SIZE)
+- {
+- VCHIQ_HEADER_T *header = (VCHIQ_HEADER_T *)(data + pos);
+- int msgid = header->msgid;
+- if (VCHIQ_MSG_TYPE(msgid) == VCHIQ_MSG_DATA)
+- {
+- int port = VCHIQ_MSG_SRCPORT(msgid);
+- VCHIQ_SERVICE_QUOTA_T *service_quota =
+- &state->service_quotas[port];
+- int count;
+- count = service_quota->message_use_count;
+- if (count > 0)
+- {
+- service_quota->message_use_count = count - 1;
+- if (count == service_quota->message_quota)
+- {
+- /* Signal the service that it has dropped below its quota */
+- vcos_event_signal(&service_quota->quota_event);
+- }
+- }
+- else
+- {
+- vcos_log_error("service %d message_use_count=%d (header %x,"
+- " msgid %x, header->msgid %x, header->size %x)",
+- port, service_quota->message_use_count,
+- (unsigned int)header, msgid, header->msgid,
+- header->size);
+- vcos_assert(0);
+- }
+- if (!BITSET_IS_SET(service_found, port))
+- {
+- /* Set the found bit for this service */
+- BITSET_SET(service_found, port);
+-
+- count = service_quota->slot_use_count;
+- if (count > 0)
+- {
+- service_quota->slot_use_count = count - 1;
+- /* Signal the service in case it has dropped below its quota */
+- vcos_event_signal(&service_quota->quota_event);
+- vcos_log_trace("%d: pfq:%d %x@%x - slot_use->%d",
+- state->id, port,
+- header->size, (unsigned int)header,
+- service_quota->slot_use_count);
+- }
+- else
+- {
+- vcos_log_error("service %d slot_use_count=%d (header %x,"
+- " msgid %x, header->msgid %x, header->size %x)",
+- port, service_quota->slot_use_count,
+- (unsigned int)header, msgid, header->msgid,
+- header->size);
+- vcos_assert(0);
+- }
+- }
+- }
+-
+- pos += calc_stride(header->size);
+- if (pos > VCHIQ_SLOT_SIZE)
+- {
+- vcos_log_error("pfq - pos %x: header %x, msgid %x, header->msgid %x, header->size %x",
+- pos, (unsigned int)header, msgid, header->msgid, header->size);
+- vcos_assert(0);
+- }
+- }
+- }
+-
+- if (slot_queue_available != state->slot_queue_available)
+- {
+- state->slot_queue_available = slot_queue_available;
+- vcos_wmb(&state->slot_queue_available);
+- vcos_event_signal(&state->slot_available_event);
+- }
++ VCHIQ_SHARED_STATE_T *local = state->local;
++ BITSET_T service_found[BITSET_SIZE(VCHIQ_MAX_SERVICES)];
++ int slot_queue_available;
++
++ /* Use a read memory barrier to ensure that any state that may have
++ ** been modified by another thread is not masked by stale prefetched
++ ** values. */
++ rmb();
++
++ /* Find slots which have been freed by the other side, and return them
++ ** to the available queue. */
++ slot_queue_available = state->slot_queue_available;
++
++ while (slot_queue_available != local->slot_queue_recycle) {
++ unsigned int pos;
++ int slot_index = local->slot_queue[slot_queue_available++ &
++ VCHIQ_SLOT_QUEUE_MASK];
++ char *data = (char *)SLOT_DATA_FROM_INDEX(state, slot_index);
++ int data_found = 0;
++
++ vchiq_log_trace(vchiq_core_log_level, "%d: pfq %d=%x %x %x",
++ state->id, slot_index, (unsigned int)data,
++ local->slot_queue_recycle, slot_queue_available);
++
++ /* Initialise the bitmask for services which have used this
++ ** slot */
++ BITSET_ZERO(service_found);
++
++ pos = 0;
++
++ while (pos < VCHIQ_SLOT_SIZE) {
++ VCHIQ_HEADER_T *header =
++ (VCHIQ_HEADER_T *)(data + pos);
++ int msgid = header->msgid;
++ if (VCHIQ_MSG_TYPE(msgid) == VCHIQ_MSG_DATA) {
++ int port = VCHIQ_MSG_SRCPORT(msgid);
++ VCHIQ_SERVICE_QUOTA_T *service_quota =
++ &state->service_quotas[port];
++ int count;
++ spin_lock(&quota_spinlock);
++ count = service_quota->message_use_count;
++ if (count > 0)
++ service_quota->message_use_count =
++ count - 1;
++ spin_unlock(&quota_spinlock);
++
++ if (count == service_quota->message_quota)
++ /* Signal the service that it
++ ** has dropped below its quota
++ */
++ up(&service_quota->quota_event);
++ else if (count == 0) {
++ vchiq_log_error(vchiq_core_log_level,
++ "service %d "
++ "message_use_count=%d "
++ "(header %x, msgid %x, "
++ "header->msgid %x, "
++ "header->size %x)",
++ port,
++ service_quota->
++ message_use_count,
++ (unsigned int)header, msgid,
++ header->msgid,
++ header->size);
++ WARN(1, "invalid message use count\n");
++ }
++ if (!BITSET_IS_SET(service_found, port)) {
++ /* Set the found bit for this service */
++ BITSET_SET(service_found, port);
++
++ spin_lock(&quota_spinlock);
++ count = service_quota->slot_use_count;
++ if (count > 0)
++ service_quota->slot_use_count =
++ count - 1;
++ spin_unlock(&quota_spinlock);
++
++ if (count > 0) {
++ /* Signal the service in case
++ ** it has dropped below its
++ ** quota */
++ up(&service_quota->quota_event);
++ vchiq_log_trace(
++ vchiq_core_log_level,
++ "%d: pfq:%d %x@%x - "
++ "slot_use->%d",
++ state->id, port,
++ header->size,
++ (unsigned int)header,
++ count - 1);
++ } else {
++ vchiq_log_error(
++ vchiq_core_log_level,
++ "service %d "
++ "slot_use_count"
++ "=%d (header %x"
++ ", msgid %x, "
++ "header->msgid"
++ " %x, header->"
++ "size %x)",
++ port, count,
++ (unsigned int)header,
++ msgid,
++ header->msgid,
++ header->size);
++ WARN(1, "bad slot use count\n");
++ }
++ }
++
++ data_found = 1;
++ }
++
++ pos += calc_stride(header->size);
++ if (pos > VCHIQ_SLOT_SIZE) {
++ vchiq_log_error(vchiq_core_log_level,
++ "pfq - pos %x: header %x, msgid %x, "
++ "header->msgid %x, header->size %x",
++ pos, (unsigned int)header, msgid,
++ header->msgid, header->size);
++ WARN(1, "invalid slot position\n");
++ }
++ }
++
++ if (data_found) {
++ int count;
++ spin_lock(&quota_spinlock);
++ count = state->data_use_count;
++ if (count > 0)
++ state->data_use_count =
++ count - 1;
++ spin_unlock(&quota_spinlock);
++ if (count == state->data_quota)
++ up(&state->data_quota_event);
++ }
++
++ state->slot_queue_available = slot_queue_available;
++ up(&state->slot_available_event);
++ }
+ }
+
+ /* Called by the slot handler and application threads */
+ static VCHIQ_STATUS_T
+ queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
+- int msgid, const VCHIQ_ELEMENT_T *elements,
+- int count, int size, int is_blocking)
+-{
+- VCHIQ_SHARED_STATE_T *local;
+- VCHIQ_SERVICE_QUOTA_T *service_quota = NULL;
+- VCHIQ_HEADER_T *header;
+-
+- unsigned int stride;
+-
+- local = state->local;
+-
+- stride = calc_stride(size);
+-
+- vcos_assert(stride <= VCHIQ_SLOT_SIZE);
+-
+- /* On platforms where vcos_mutex_lock cannot fail, the return will never
+- be taken and the compiler may optimise out that code. Let Coverity
+- know this is intentional.
+- */
+- /* coverity[constant_expression_result] */
+- if ((VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_RESUME) &&
+- (vcos_mutex_lock(&state->slot_mutex) != VCOS_SUCCESS))
+- return VCHIQ_RETRY;
+-
+- if (service)
+- {
+- int tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos + stride - 1);
+-
+- if (service->srvstate != VCHIQ_SRVSTATE_OPEN)
+- {
+- /* The service has been closed, probably while waiting for the mutex */
+- vcos_mutex_unlock(&state->slot_mutex);
+- return VCHIQ_ERROR;
+- }
+-
+- service_quota = &state->service_quotas[service->localport];
+-
+- /* ...ensure it doesn't use more than its quota of messages or slots */
+- while ((service_quota->message_use_count == service_quota->message_quota) ||
+- ((tx_end_index != service_quota->previous_tx_index) &&
+- (service_quota->slot_use_count == service_quota->slot_quota)))
+- {
+- vcos_log_trace("%d: qm:%d %s,%x - quota stall (msg %d, slot %d)",
+- state->id, service->localport,
+- msg_type_str(VCHIQ_MSG_TYPE(msgid)), size,
+- service_quota->message_use_count, service_quota->slot_use_count);
+- VCHIQ_SERVICE_STATS_INC(service, quota_stalls);
+- vcos_mutex_unlock(&state->slot_mutex);
+- if (vcos_event_wait(&service_quota->quota_event) != VCOS_SUCCESS)
+- return VCHIQ_RETRY;
+- if (vcos_mutex_lock(&state->slot_mutex) != VCOS_SUCCESS)
+- return VCHIQ_RETRY;
+- tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos + stride - 1);
+- }
+- }
+-
+- header = reserve_space(state, stride, is_blocking);
+-
+- if (!header) {
+- if (service)
+- VCHIQ_SERVICE_STATS_INC(service, slot_stalls);
+- vcos_mutex_unlock(&state->slot_mutex);
+- return VCHIQ_RETRY;
+- }
+-
+- if (service) {
+- int i, pos;
+- int tx_end_index;
+-
+- vcos_log_info("%d: qm %s@%x,%x (%d->%d)", state->id,
+- msg_type_str(VCHIQ_MSG_TYPE(msgid)),
+- (unsigned int)header, size,
+- VCHIQ_MSG_SRCPORT(msgid),
+- VCHIQ_MSG_DSTPORT(msgid));
+-
+- for (i = 0, pos = 0; i < (unsigned int)count;
+- pos += elements[i++].size)
+- if (elements[i].size) {
+- if (vchiq_copy_from_user
+- (header->data + pos, elements[i].data,
+- (size_t) elements[i].size) !=
+- VCHIQ_SUCCESS) {
+- vcos_mutex_unlock(&state->slot_mutex);
+- VCHIQ_SERVICE_STATS_INC(service, error_count);
+- return VCHIQ_ERROR;
+- }
+- if (i == 0) {
+- vcos_log_dump_mem( &vchiq_core_msg_log_category,
+- "Sent", 0, header->data + pos,
+- vcos_min( 64, elements[0].size ));
+- }
+- }
+-
+- /* If this transmission can't fit in the last slot used by this service... */
+- tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos - 1);
+- if (tx_end_index != service_quota->previous_tx_index)
+- {
+- service_quota->slot_use_count++;
+- vcos_log_trace("%d: qm:%d %s,%x - slot_use->%d",
+- state->id, service->localport,
+- msg_type_str(VCHIQ_MSG_TYPE(msgid)), size,
+- service_quota->slot_use_count);
+- }
+-
+- service_quota->previous_tx_index = tx_end_index;
+- service_quota->message_use_count++;
+- VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count);
+- VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size);
+- } else {
+- vcos_log_info("%d: qm %s@%x,%x (%d->%d)", state->id,
+- msg_type_str(VCHIQ_MSG_TYPE(msgid)),
+- (unsigned int)header, size,
+- VCHIQ_MSG_SRCPORT(msgid),
+- VCHIQ_MSG_DSTPORT(msgid));
+- if (size != 0)
+- {
+- vcos_assert((count == 1) && (size == elements[0].size));
+- memcpy(header->data, elements[0].data, elements[0].size);
+- }
+- VCHIQ_STATS_INC(state, ctrl_tx_count);
+- }
+-
+- header->msgid = msgid;
+- header->size = size;
+-
+- if (vcos_is_log_enabled( &vchiq_core_msg_log_category, VCOS_LOG_INFO))
+- {
+- int svc_fourcc;
+-
+- svc_fourcc = service
+- ? service->base.fourcc
+- : VCHIQ_MAKE_FOURCC('?','?','?','?');
+-
+- vcos_log_impl( &vchiq_core_msg_log_category,
+- VCOS_LOG_INFO,
+- "Sent Msg %s(%u) to %c%c%c%c s:%u d:%d len:%d",
+- msg_type_str(VCHIQ_MSG_TYPE(msgid)),
+- VCHIQ_MSG_TYPE(msgid),
+- VCHIQ_FOURCC_AS_4CHARS(svc_fourcc),
+- VCHIQ_MSG_SRCPORT(msgid),
+- VCHIQ_MSG_DSTPORT(msgid),
+- size );
+- }
+-
+- /* Make the new tx_pos visible to the peer. */
+- local->tx_pos = state->local_tx_pos;
+- vcos_wmb(&local->tx_pos);
+-
+- if (VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_PAUSE)
+- vcos_mutex_unlock(&state->slot_mutex);
+-
+- remote_event_signal(&state->remote->trigger);
+-
+- return VCHIQ_SUCCESS;
++ int msgid, const VCHIQ_ELEMENT_T *elements,
++ int count, int size, int is_blocking)
++{
++ VCHIQ_SHARED_STATE_T *local;
++ VCHIQ_SERVICE_QUOTA_T *service_quota = NULL;
++ VCHIQ_HEADER_T *header;
++ int type = VCHIQ_MSG_TYPE(msgid);
++
++ unsigned int stride;
++
++ local = state->local;
++
++ stride = calc_stride(size);
++
++ WARN_ON(!(stride <= VCHIQ_SLOT_SIZE));
++
++ if ((type != VCHIQ_MSG_RESUME) &&
++ (mutex_lock_interruptible(&state->slot_mutex) != 0))
++ return VCHIQ_RETRY;
++
++ if (type == VCHIQ_MSG_DATA) {
++ int tx_end_index;
++
++ BUG_ON(!service);
++
++ if (service->closing) {
++ /* The service has been closed */
++ mutex_unlock(&state->slot_mutex);
++ return VCHIQ_ERROR;
++ }
++
++ service_quota = &state->service_quotas[service->localport];
++
++ spin_lock(&quota_spinlock);
++
++ /* Ensure this service doesn't use more than its quota of
++ ** messages or slots */
++ tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(
++ state->local_tx_pos + stride - 1);
++
++ /* Ensure data messages don't use more than their quota of
++ ** slots */
++ while ((tx_end_index != state->previous_data_index) &&
++ (state->data_use_count == state->data_quota)) {
++ VCHIQ_STATS_INC(state, data_stalls);
++ spin_unlock(&quota_spinlock);
++ mutex_unlock(&state->slot_mutex);
++
++ if (down_interruptible(&state->data_quota_event)
++ != 0)
++ return VCHIQ_RETRY;
++
++ mutex_lock(&state->slot_mutex);
++ spin_lock(&quota_spinlock);
++ tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(
++ state->local_tx_pos + stride - 1);
++ if ((tx_end_index == state->previous_data_index) ||
++ (state->data_use_count < state->data_quota)) {
++ /* Pass the signal on to other waiters */
++ up(&state->data_quota_event);
++ break;
++ }
++ }
++
++ while ((service_quota->message_use_count ==
++ service_quota->message_quota) ||
++ ((tx_end_index != service_quota->previous_tx_index) &&
++ (service_quota->slot_use_count ==
++ service_quota->slot_quota))) {
++ spin_unlock(&quota_spinlock);
++ vchiq_log_trace(vchiq_core_log_level,
++ "%d: qm:%d %s,%x - quota stall "
++ "(msg %d, slot %d)",
++ state->id, service->localport,
++ msg_type_str(type), size,
++ service_quota->message_use_count,
++ service_quota->slot_use_count);
++ VCHIQ_SERVICE_STATS_INC(service, quota_stalls);
++ mutex_unlock(&state->slot_mutex);
++ if (down_interruptible(&service_quota->quota_event)
++ != 0)
++ return VCHIQ_RETRY;
++ if (service->closing)
++ return VCHIQ_ERROR;
++ if (mutex_lock_interruptible(&state->slot_mutex) != 0)
++ return VCHIQ_RETRY;
++ if (service->srvstate != VCHIQ_SRVSTATE_OPEN) {
++ /* The service has been closed */
++ mutex_unlock(&state->slot_mutex);
++ return VCHIQ_ERROR;
++ }
++ spin_lock(&quota_spinlock);
++ tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(
++ state->local_tx_pos + stride - 1);
++ }
++
++ spin_unlock(&quota_spinlock);
++ }
++
++ header = reserve_space(state, stride, is_blocking);
++
++ if (!header) {
++ if (service)
++ VCHIQ_SERVICE_STATS_INC(service, slot_stalls);
++ mutex_unlock(&state->slot_mutex);
++ return VCHIQ_RETRY;
++ }
++
++ if (type == VCHIQ_MSG_DATA) {
++ int i, pos;
++ int tx_end_index;
++ int slot_use_count;
++
++ vchiq_log_info(vchiq_core_log_level,
++ "%d: qm %s@%x,%x (%d->%d)",
++ state->id,
++ msg_type_str(VCHIQ_MSG_TYPE(msgid)),
++ (unsigned int)header, size,
++ VCHIQ_MSG_SRCPORT(msgid),
++ VCHIQ_MSG_DSTPORT(msgid));
++
++ BUG_ON(!service);
++
++ for (i = 0, pos = 0; i < (unsigned int)count;
++ pos += elements[i++].size)
++ if (elements[i].size) {
++ if (vchiq_copy_from_user
++ (header->data + pos, elements[i].data,
++ (size_t) elements[i].size) !=
++ VCHIQ_SUCCESS) {
++ mutex_unlock(&state->slot_mutex);
++ VCHIQ_SERVICE_STATS_INC(service,
++ error_count);
++ return VCHIQ_ERROR;
++ }
++ if (i == 0) {
++ if (vchiq_core_msg_log_level >=
++ VCHIQ_LOG_INFO)
++ vchiq_log_dump_mem("Sent", 0,
++ header->data + pos,
++ min(64,
++ elements[0].size));
++ }
++ }
++
++ spin_lock(&quota_spinlock);
++ service_quota->message_use_count++;
++
++ tx_end_index =
++ SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos - 1);
++
++ /* If this transmission can't fit in the last slot used by any
++ ** service, the data_use_count must be increased. */
++ if (tx_end_index != state->previous_data_index) {
++ state->previous_data_index = tx_end_index;
++ state->data_use_count++;
++ }
++
++ /* If this isn't the same slot last used by this service,
++ ** the service's slot_use_count must be increased. */
++ if (tx_end_index != service_quota->previous_tx_index) {
++ service_quota->previous_tx_index = tx_end_index;
++ slot_use_count = ++service_quota->slot_use_count;
++ } else {
++ slot_use_count = 0;
++ }
++
++ spin_unlock(&quota_spinlock);
++
++ if (slot_use_count)
++ vchiq_log_trace(vchiq_core_log_level,
++ "%d: qm:%d %s,%x - slot_use->%d (hdr %p)",
++ state->id, service->localport,
++ msg_type_str(VCHIQ_MSG_TYPE(msgid)), size,
++ slot_use_count, header);
++
++ VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count);
++ VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size);
++ } else {
++ vchiq_log_info(vchiq_core_log_level,
++ "%d: qm %s@%x,%x (%d->%d)", state->id,
++ msg_type_str(VCHIQ_MSG_TYPE(msgid)),
++ (unsigned int)header, size,
++ VCHIQ_MSG_SRCPORT(msgid),
++ VCHIQ_MSG_DSTPORT(msgid));
++ if (size != 0) {
++ WARN_ON(!((count == 1) && (size == elements[0].size)));
++ memcpy(header->data, elements[0].data,
++ elements[0].size);
++ }
++ VCHIQ_STATS_INC(state, ctrl_tx_count);
++ }
++
++ header->msgid = msgid;
++ header->size = size;
++
++ {
++ int svc_fourcc;
++
++ svc_fourcc = service
++ ? service->base.fourcc
++ : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
++
++ vchiq_log_info(vchiq_core_msg_log_level,
++ "Sent Msg %s(%u) to %c%c%c%c s:%u d:%d len:%d",
++ msg_type_str(VCHIQ_MSG_TYPE(msgid)),
++ VCHIQ_MSG_TYPE(msgid),
++ VCHIQ_FOURCC_AS_4CHARS(svc_fourcc),
++ VCHIQ_MSG_SRCPORT(msgid),
++ VCHIQ_MSG_DSTPORT(msgid),
++ size);
++ }
++
++ /* Make sure the new header is visible to the peer. */
++ wmb();
++
++ /* Make the new tx_pos visible to the peer. */
++ local->tx_pos = state->local_tx_pos;
++ wmb();
++
++ if (service && (type == VCHIQ_MSG_CLOSE))
++ vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSESENT);
++
++ if (VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_PAUSE)
++ mutex_unlock(&state->slot_mutex);
++
++ remote_event_signal(&state->remote->trigger);
++
++ return VCHIQ_SUCCESS;
++}
++
++/* Called by the slot handler and application threads */
++static VCHIQ_STATUS_T
++queue_message_sync(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
++ int msgid, const VCHIQ_ELEMENT_T *elements,
++ int count, int size, int is_blocking)
++{
++ VCHIQ_SHARED_STATE_T *local;
++ VCHIQ_HEADER_T *header;
++
++ local = state->local;
++
++ if ((VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_RESUME) &&
++ (mutex_lock_interruptible(&state->sync_mutex) != 0))
++ return VCHIQ_RETRY;
++
++ remote_event_wait(&local->sync_release);
++
++ rmb();
++
++ header = (VCHIQ_HEADER_T *)SLOT_DATA_FROM_INDEX(state,
++ local->slot_sync);
++
++ {
++ int oldmsgid = header->msgid;
++ if (oldmsgid != VCHIQ_MSGID_PADDING)
++ vchiq_log_error(vchiq_core_log_level,
++ "%d: qms - msgid %x, not PADDING",
++ state->id, oldmsgid);
++ }
++
++ if (service) {
++ int i, pos;
++
++ vchiq_log_info(vchiq_sync_log_level,
++ "%d: qms %s@%x,%x (%d->%d)", state->id,
++ msg_type_str(VCHIQ_MSG_TYPE(msgid)),
++ (unsigned int)header, size,
++ VCHIQ_MSG_SRCPORT(msgid),
++ VCHIQ_MSG_DSTPORT(msgid));
++
++ for (i = 0, pos = 0; i < (unsigned int)count;
++ pos += elements[i++].size)
++ if (elements[i].size) {
++ if (vchiq_copy_from_user
++ (header->data + pos, elements[i].data,
++ (size_t) elements[i].size) !=
++ VCHIQ_SUCCESS) {
++ mutex_unlock(&state->sync_mutex);
++ VCHIQ_SERVICE_STATS_INC(service,
++ error_count);
++ return VCHIQ_ERROR;
++ }
++ if (i == 0) {
++ if (vchiq_sync_log_level >=
++ VCHIQ_LOG_TRACE)
++ vchiq_log_dump_mem("Sent Sync",
++ 0, header->data + pos,
++ min(64,
++ elements[0].size));
++ }
++ }
++
++ VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count);
++ VCHIQ_SERVICE_STATS_ADD(service, ctrl_tx_bytes, size);
++ } else {
++ vchiq_log_info(vchiq_sync_log_level,
++ "%d: qms %s@%x,%x (%d->%d)", state->id,
++ msg_type_str(VCHIQ_MSG_TYPE(msgid)),
++ (unsigned int)header, size,
++ VCHIQ_MSG_SRCPORT(msgid),
++ VCHIQ_MSG_DSTPORT(msgid));
++ if (size != 0) {
++ WARN_ON(!((count == 1) && (size == elements[0].size)));
++ memcpy(header->data, elements[0].data,
++ elements[0].size);
++ }
++ VCHIQ_STATS_INC(state, ctrl_tx_count);
++ }
++
++ header->size = size;
++ header->msgid = msgid;
++
++ if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) {
++ int svc_fourcc;
++
++ svc_fourcc = service
++ ? service->base.fourcc
++ : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
++
++ vchiq_log_trace(vchiq_sync_log_level,
++ "Sent Sync Msg %s(%u) to %c%c%c%c s:%u d:%d len:%d",
++ msg_type_str(VCHIQ_MSG_TYPE(msgid)),
++ VCHIQ_MSG_TYPE(msgid),
++ VCHIQ_FOURCC_AS_4CHARS(svc_fourcc),
++ VCHIQ_MSG_SRCPORT(msgid),
++ VCHIQ_MSG_DSTPORT(msgid),
++ size);
++ }
++
++ /* Make sure the new header is visible to the peer. */
++ wmb();
++
++ remote_event_signal(&state->remote->sync_trigger);
++
++ if (VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_PAUSE)
++ mutex_unlock(&state->sync_mutex);
++
++ return VCHIQ_SUCCESS;
+ }
+
+ static inline void
+ claim_slot(VCHIQ_SLOT_INFO_T *slot)
+ {
+- slot->use_count++;
++ slot->use_count++;
+ }
+
+ static void
+-release_slot(VCHIQ_STATE_T *state, VCHIQ_SLOT_INFO_T *slot_info)
+-{
+- int release_count;
+- vcos_mutex_lock(&state->recycle_mutex);
+-
+- release_count = slot_info->release_count;
+- slot_info->release_count = ++release_count;
+-
+- if (release_count == slot_info->use_count)
+- {
+- int slot_queue_recycle;
+- /* Add to the freed queue */
+-
+- /* A read barrier is necessary here to prevent speculative fetches of
+- remote->slot_queue_recycle from overtaking the mutex. */
+- vcos_rmb();
+-
+- slot_queue_recycle = state->remote->slot_queue_recycle;
+- state->remote->slot_queue[slot_queue_recycle & VCHIQ_SLOT_QUEUE_MASK] =
+- SLOT_INDEX_FROM_INFO(state, slot_info);
+- state->remote->slot_queue_recycle = slot_queue_recycle + 1;
+- vcos_log_info("%d: release_slot %d - recycle->%x",
+- state->id, SLOT_INDEX_FROM_INFO(state, slot_info),
+- state->remote->slot_queue_recycle);
+-
+- /* A write barrier is necessary, but remote_event_signal contains one. */
+- remote_event_signal(&state->remote->recycle);
+- }
+-
+- vcos_mutex_unlock(&state->recycle_mutex);
++release_slot(VCHIQ_STATE_T *state, VCHIQ_SLOT_INFO_T *slot_info,
++ VCHIQ_HEADER_T *header, VCHIQ_SERVICE_T *service)
++{
++ int release_count;
++
++ mutex_lock(&state->recycle_mutex);
++
++ if (header) {
++ int msgid = header->msgid;
++ if (((msgid & VCHIQ_MSGID_CLAIMED) == 0) ||
++ (service && service->closing)) {
++ mutex_unlock(&state->recycle_mutex);
++ return;
++ }
++
++ /* Rewrite the message header to prevent a double
++ ** release */
++ header->msgid = msgid & ~VCHIQ_MSGID_CLAIMED;
++ }
++
++ release_count = slot_info->release_count;
++ slot_info->release_count = ++release_count;
++
++ if (release_count == slot_info->use_count) {
++ int slot_queue_recycle;
++ /* Add to the freed queue */
++
++ /* A read barrier is necessary here to prevent speculative
++ ** fetches of remote->slot_queue_recycle from overtaking the
++ ** mutex. */
++ rmb();
++
++ slot_queue_recycle = state->remote->slot_queue_recycle;
++ state->remote->slot_queue[slot_queue_recycle &
++ VCHIQ_SLOT_QUEUE_MASK] =
++ SLOT_INDEX_FROM_INFO(state, slot_info);
++ state->remote->slot_queue_recycle = slot_queue_recycle + 1;
++ vchiq_log_info(vchiq_core_log_level,
++ "%d: release_slot %d - recycle->%x",
++ state->id, SLOT_INDEX_FROM_INFO(state, slot_info),
++ state->remote->slot_queue_recycle);
++
++ /* A write barrier is necessary, but remote_event_signal
++ ** contains one. */
++ remote_event_signal(&state->remote->recycle);
++ }
++
++ mutex_unlock(&state->recycle_mutex);
+ }
+
+ /* Called by the slot handler - don't hold the bulk mutex */
+ static VCHIQ_STATUS_T
+-notify_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue)
+-{
+- VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+-
+- vcos_log_trace("%d: nb:%d %cx - p=%x rn=%x r=%x",
+- service->state->id, service->localport,
+- (queue == &service->bulk_tx) ? 't' : 'r',
+- queue->process, queue->remote_notify, queue->remove);
+-
+- if (service->state->is_master)
+- {
+- while (queue->remote_notify != queue->process)
+- {
+- VCHIQ_BULK_T *bulk = &queue->bulks[BULK_INDEX(queue->remote_notify)];
+- int msgtype = (bulk->dir == VCHIQ_BULK_TRANSMIT) ?
+- VCHIQ_MSG_BULK_RX_DONE : VCHIQ_MSG_BULK_TX_DONE;
+- int msgid = VCHIQ_MAKE_MSG(msgtype, service->localport, service->remoteport);
+- VCHIQ_ELEMENT_T element = { &bulk->actual, 4 };
+- /* Only reply to non-dummy bulk requests */
+- if (bulk->remote_data)
+- {
+- status = queue_message(service->state, NULL, msgid, &element, 1, 4, 0);
+- if (status != VCHIQ_SUCCESS)
+- break;
+- }
+- queue->remote_notify++;
+- }
+- }
+- else
+- {
+- queue->remote_notify = queue->process;
+- }
+-
+- if (status == VCHIQ_SUCCESS)
+- {
+- while (queue->remove != queue->remote_notify)
+- {
+- VCHIQ_BULK_T *bulk = &queue->bulks[BULK_INDEX(queue->remove)];
+-
+- /* Only generate callbacks for non-dummy bulk requests */
+- if (bulk->data)
+- {
+- if (bulk->actual != VCHIQ_BULK_ACTUAL_ABORTED)
+- {
+- if (bulk->dir == VCHIQ_BULK_TRANSMIT)
+- {
+- VCHIQ_SERVICE_STATS_INC(service, bulk_tx_count);
+- VCHIQ_SERVICE_STATS_ADD(service, bulk_tx_bytes, bulk->actual);
+- }
+- else
+- {
+- VCHIQ_SERVICE_STATS_INC(service, bulk_rx_count);
+- VCHIQ_SERVICE_STATS_ADD(service, bulk_rx_bytes, bulk->actual);
+- }
+- }
+- else
+- {
+- VCHIQ_SERVICE_STATS_INC(service, bulk_aborted_count);
+- }
+- if (bulk->mode == VCHIQ_BULK_MODE_BLOCKING)
+- {
+- BULK_WAITER_T *waiter = (BULK_WAITER_T *)bulk->userdata;
+- if (waiter)
+- {
+- waiter->actual = bulk->actual;
+- vcos_event_signal(&waiter->event);
+- }
+- }
+- else if (bulk->mode == VCHIQ_BULK_MODE_CALLBACK)
+- {
+- VCHIQ_REASON_T reason = (bulk->dir == VCHIQ_BULK_TRANSMIT) ?
+- ((bulk->actual == VCHIQ_BULK_ACTUAL_ABORTED) ?
+- VCHIQ_BULK_TRANSMIT_ABORTED : VCHIQ_BULK_TRANSMIT_DONE) :
+- ((bulk->actual == VCHIQ_BULK_ACTUAL_ABORTED) ?
+- VCHIQ_BULK_RECEIVE_ABORTED : VCHIQ_BULK_RECEIVE_DONE);
+- status = make_service_callback(service, reason,
+- NULL, bulk->userdata);
+- if (status == VCHIQ_RETRY)
+- break;
+- }
+- }
+-
+- queue->remove++;
+- vcos_event_signal(&service->bulk_remove_event);
+- }
+- }
+-
+- if (status != VCHIQ_SUCCESS)
+- request_poll(service->state, service, (queue == &service->bulk_tx) ?
+- VCHIQ_POLL_TXNOTIFY : VCHIQ_POLL_RXNOTIFY);
+-
+- return status;
++notify_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue,
++ int retry_poll)
++{
++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
++
++ vchiq_log_trace(vchiq_core_log_level,
++ "%d: nb:%d %cx - p=%x rn=%x r=%x",
++ service->state->id, service->localport,
++ (queue == &service->bulk_tx) ? 't' : 'r',
++ queue->process, queue->remote_notify, queue->remove);
++
++ if (service->state->is_master) {
++ while (queue->remote_notify != queue->process) {
++ VCHIQ_BULK_T *bulk =
++ &queue->bulks[BULK_INDEX(queue->remote_notify)];
++ int msgtype = (bulk->dir == VCHIQ_BULK_TRANSMIT) ?
++ VCHIQ_MSG_BULK_RX_DONE : VCHIQ_MSG_BULK_TX_DONE;
++ int msgid = VCHIQ_MAKE_MSG(msgtype, service->localport,
++ service->remoteport);
++ VCHIQ_ELEMENT_T element = { &bulk->actual, 4 };
++ /* Only reply to non-dummy bulk requests */
++ if (bulk->remote_data) {
++ status = queue_message(service->state, NULL,
++ msgid, &element, 1, 4, 0);
++ if (status != VCHIQ_SUCCESS)
++ break;
++ }
++ queue->remote_notify++;
++ }
++ } else {
++ queue->remote_notify = queue->process;
++ }
++
++ if (status == VCHIQ_SUCCESS) {
++ while (queue->remove != queue->remote_notify) {
++ VCHIQ_BULK_T *bulk =
++ &queue->bulks[BULK_INDEX(queue->remove)];
++
++ /* Only generate callbacks for non-dummy bulk
++ ** requests, and non-terminated services */
++ if (bulk->data && service->instance) {
++ if (bulk->actual != VCHIQ_BULK_ACTUAL_ABORTED) {
++ if (bulk->dir == VCHIQ_BULK_TRANSMIT) {
++ VCHIQ_SERVICE_STATS_INC(service,
++ bulk_tx_count);
++ VCHIQ_SERVICE_STATS_ADD(service,
++ bulk_tx_bytes,
++ bulk->actual);
++ } else {
++ VCHIQ_SERVICE_STATS_INC(service,
++ bulk_rx_count);
++ VCHIQ_SERVICE_STATS_ADD(service,
++ bulk_rx_bytes,
++ bulk->actual);
++ }
++ } else {
++ VCHIQ_SERVICE_STATS_INC(service,
++ bulk_aborted_count);
++ }
++ if (bulk->mode == VCHIQ_BULK_MODE_BLOCKING) {
++ struct bulk_waiter *waiter;
++ spin_lock(&bulk_waiter_spinlock);
++ waiter = bulk->userdata;
++ if (waiter) {
++ waiter->actual = bulk->actual;
++ up(&waiter->event);
++ }
++ spin_unlock(&bulk_waiter_spinlock);
++ } else if (bulk->mode ==
++ VCHIQ_BULK_MODE_CALLBACK) {
++ VCHIQ_REASON_T reason = (bulk->dir ==
++ VCHIQ_BULK_TRANSMIT) ?
++ ((bulk->actual ==
++ VCHIQ_BULK_ACTUAL_ABORTED) ?
++ VCHIQ_BULK_TRANSMIT_ABORTED :
++ VCHIQ_BULK_TRANSMIT_DONE) :
++ ((bulk->actual ==
++ VCHIQ_BULK_ACTUAL_ABORTED) ?
++ VCHIQ_BULK_RECEIVE_ABORTED :
++ VCHIQ_BULK_RECEIVE_DONE);
++ status = make_service_callback(service,
++ reason, NULL, bulk->userdata);
++ if (status == VCHIQ_RETRY)
++ break;
++ status = VCHIQ_SUCCESS;
++ }
++ }
++
++ queue->remove++;
++ up(&service->bulk_remove_event);
++ }
++ if (!retry_poll)
++ status = VCHIQ_SUCCESS;
++ }
++
++ if (status == VCHIQ_RETRY)
++ request_poll(service->state, service,
++ (queue == &service->bulk_tx) ?
++ VCHIQ_POLL_TXNOTIFY : VCHIQ_POLL_RXNOTIFY);
++
++ return status;
+ }
+
+ /* Called by the slot handler thread */
+ static void
+ poll_services(VCHIQ_STATE_T *state)
+ {
+- int group, i;
+-
+- for (group = 0; group < BITSET_SIZE(state->unused_service); group++)
+- {
+- uint32_t flags;
+- flags = vcos_atomic_flags_get_and_clear(&state->poll_services[group]);
+- for (i = 0; flags; i++)
+- {
+- if (flags & (1 << i))
+- {
+- VCHIQ_SERVICE_T *service = state->services[(group<<5) + i];
+- uint32_t service_flags =
+- vcos_atomic_flags_get_and_clear(&service->poll_flags);
+- if (service_flags & (1 << VCHIQ_POLL_TERMINATE))
+- {
+- vcos_log_info("%d: ps - terminate %d<->%d", state->id, service->localport, service->remoteport);
+- if (vchiq_close_service_internal(service, 0/*!close_recvd*/) != VCHIQ_SUCCESS)
+- request_poll(state, service, VCHIQ_POLL_TERMINATE);
+- }
+- if (service_flags & (1 << VCHIQ_POLL_TXNOTIFY))
+- notify_bulks(service, &service->bulk_tx);
+- if (service_flags & (1 << VCHIQ_POLL_RXNOTIFY))
+- notify_bulks(service, &service->bulk_rx);
+- flags &= ~(1 << i);
+- }
+- }
+- }
++ int group, i;
++
++ for (group = 0; group < BITSET_SIZE(state->unused_service); group++) {
++ uint32_t flags;
++ flags = atomic_xchg(&state->poll_services[group], 0);
++ for (i = 0; flags; i++) {
++ if (flags & (1 << i)) {
++ VCHIQ_SERVICE_T *service =
++ find_service_by_port(state,
++ (group<<5) + i);
++ uint32_t service_flags;
++ flags &= ~(1 << i);
++ if (!service)
++ continue;
++ service_flags =
++ atomic_xchg(&service->poll_flags, 0);
++ if (service_flags &
++ (1 << VCHIQ_POLL_TERMINATE)) {
++ vchiq_log_info(vchiq_core_log_level,
++ "%d: ps - terminate %d<->%d",
++ state->id, service->localport,
++ service->remoteport);
++ if (vchiq_close_service_internal(
++ service, 0/*!close_recvd*/) !=
++ VCHIQ_SUCCESS)
++ request_poll(state, service,
++ VCHIQ_POLL_TERMINATE);
++ }
++ if (service_flags & (1 << VCHIQ_POLL_TXNOTIFY))
++ notify_bulks(service,
++ &service->bulk_tx,
++ 1/*retry_poll*/);
++ if (service_flags & (1 << VCHIQ_POLL_RXNOTIFY))
++ notify_bulks(service,
++ &service->bulk_rx,
++ 1/*retry_poll*/);
++ unlock_service(service);
++ }
++ }
++ }
+ }
+
+ /* Called by the slot handler or application threads, holding the bulk mutex. */
+ static int
+ resolve_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue)
+ {
+- VCHIQ_STATE_T *state = service->state;
+- int resolved = 0;
+-
+- while ((queue->process != queue->local_insert) &&
+- (queue->process != queue->remote_insert))
+- {
+- VCHIQ_BULK_T *bulk = &queue->bulks[BULK_INDEX(queue->process)];
+-
+- vcos_log_trace("%d: rb:%d %cx - li=%x ri=%x p=%x",
+- state->id, service->localport,
+- (queue == &service->bulk_tx) ? 't' : 'r',
+- queue->local_insert, queue->remote_insert,
+- queue->process);
+-
+- vcos_assert((int)(queue->local_insert - queue->process) > 0);
+- vcos_assert((int)(queue->remote_insert - queue->process) > 0);
+- vchiq_transfer_bulk(bulk);
+-
+- if (vcos_is_log_enabled( &vchiq_core_msg_log_category, VCOS_LOG_INFO))
+- {
+- const char *header = (queue == &service->bulk_tx) ?
+- "Send Bulk to" : "Recv Bulk from";
+- if (bulk->actual != VCHIQ_BULK_ACTUAL_ABORTED)
+- vcos_log_impl( &vchiq_core_msg_log_category,
+- VCOS_LOG_INFO,
+- "%s %c%c%c%c d:%d len:%d %x<->%x",
+- header,
+- VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
+- service->remoteport,
+- bulk->size,
+- (unsigned int)bulk->data,
+- (unsigned int)bulk->remote_data );
+- else
+- vcos_log_impl( &vchiq_core_msg_log_category,
+- VCOS_LOG_INFO,
+- "%s %c%c%c%c d:%d ABORTED - tx len:%d, rx len:%d %x<->%x",
+- header,
+- VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
+- service->remoteport,
+- bulk->size,
+- bulk->remote_size,
+- (unsigned int)bulk->data,
+- (unsigned int)bulk->remote_data );
+- }
+-
+- vchiq_complete_bulk(bulk);
+- queue->process++;
+- resolved++;
+- }
+- return resolved;
++ VCHIQ_STATE_T *state = service->state;
++ int resolved = 0;
++
++ while ((queue->process != queue->local_insert) &&
++ (queue->process != queue->remote_insert)) {
++ VCHIQ_BULK_T *bulk = &queue->bulks[BULK_INDEX(queue->process)];
++
++ vchiq_log_trace(vchiq_core_log_level,
++ "%d: rb:%d %cx - li=%x ri=%x p=%x",
++ state->id, service->localport,
++ (queue == &service->bulk_tx) ? 't' : 'r',
++ queue->local_insert, queue->remote_insert,
++ queue->process);
++
++ WARN_ON(!((int)(queue->local_insert - queue->process) > 0));
++ WARN_ON(!((int)(queue->remote_insert - queue->process) > 0));
++
++ mutex_lock(&state->bulk_transfer_mutex);
++ vchiq_transfer_bulk(bulk);
++ mutex_unlock(&state->bulk_transfer_mutex);
++
++ if (vchiq_core_msg_log_level >= VCHIQ_LOG_INFO) {
++ const char *header = (queue == &service->bulk_tx) ?
++ "Send Bulk to" : "Recv Bulk from";
++ if (bulk->actual != VCHIQ_BULK_ACTUAL_ABORTED)
++ vchiq_log_info(vchiq_core_msg_log_level,
++ "%s %c%c%c%c d:%d len:%d %x<->%x",
++ header,
++ VCHIQ_FOURCC_AS_4CHARS(
++ service->base.fourcc),
++ service->remoteport,
++ bulk->size,
++ (unsigned int)bulk->data,
++ (unsigned int)bulk->remote_data);
++ else
++ vchiq_log_info(vchiq_core_msg_log_level,
++ "%s %c%c%c%c d:%d ABORTED - tx len:%d,"
++ " rx len:%d %x<->%x",
++ header,
++ VCHIQ_FOURCC_AS_4CHARS(
++ service->base.fourcc),
++ service->remoteport,
++ bulk->size,
++ bulk->remote_size,
++ (unsigned int)bulk->data,
++ (unsigned int)bulk->remote_data);
++ }
++
++ vchiq_complete_bulk(bulk);
++ queue->process++;
++ resolved++;
++ }
++ return resolved;
+ }
+
+ /* Called with the bulk_mutex held */
+ static void
+ abort_outstanding_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue)
+ {
+- int is_tx = (queue == &service->bulk_tx);
+- vcos_log_trace("%d: aob:%d %cx - li=%x ri=%x p=%x",
+- service->state->id, service->localport, is_tx ? 't' : 'r',
+- queue->local_insert, queue->remote_insert, queue->process);
+-
+- vcos_assert((int)(queue->local_insert - queue->process) >= 0);
+- vcos_assert((int)(queue->remote_insert - queue->process) >= 0);
+-
+- while ((queue->process != queue->local_insert) ||
+- (queue->process != queue->remote_insert))
+- {
+- VCHIQ_BULK_T *bulk = &queue->bulks[BULK_INDEX(queue->process)];
+-
+- if (queue->process == queue->remote_insert)
+- {
+- /* fabricate a matching dummy bulk */
+- bulk->remote_data = NULL;
+- bulk->remote_size = 0;
+- queue->remote_insert++;
+- }
+-
+- if (queue->process != queue->local_insert)
+- {
+- vchiq_complete_bulk(bulk);
+-
+- if (vcos_is_log_enabled( &vchiq_core_msg_log_category, VCOS_LOG_INFO))
+- {
+- vcos_log_impl( &vchiq_core_msg_log_category,
+- VCOS_LOG_INFO,
+- "%s %c%c%c%c d:%d ABORTED - tx len:%d, rx len:%d",
+- is_tx ? "Send Bulk to" : "Recv Bulk from",
+- VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
+- service->remoteport,
+- bulk->size,
+- bulk->remote_size );
+- }
+- }
+- else
+- {
+- /* fabricate a matching dummy bulk */
+- bulk->data = NULL;
+- bulk->size = 0;
+- bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED;
+- bulk->dir = is_tx ? VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE;
+- queue->local_insert++;
+- }
+-
+- queue->process++;
+- }
++ int is_tx = (queue == &service->bulk_tx);
++ vchiq_log_trace(vchiq_core_log_level,
++ "%d: aob:%d %cx - li=%x ri=%x p=%x",
++ service->state->id, service->localport, is_tx ? 't' : 'r',
++ queue->local_insert, queue->remote_insert, queue->process);
++
++ WARN_ON(!((int)(queue->local_insert - queue->process) >= 0));
++ WARN_ON(!((int)(queue->remote_insert - queue->process) >= 0));
++
++ while ((queue->process != queue->local_insert) ||
++ (queue->process != queue->remote_insert)) {
++ VCHIQ_BULK_T *bulk = &queue->bulks[BULK_INDEX(queue->process)];
++
++ if (queue->process == queue->remote_insert) {
++ /* fabricate a matching dummy bulk */
++ bulk->remote_data = NULL;
++ bulk->remote_size = 0;
++ queue->remote_insert++;
++ }
++
++ if (queue->process != queue->local_insert) {
++ vchiq_complete_bulk(bulk);
++
++ vchiq_log_info(vchiq_core_msg_log_level,
++ "%s %c%c%c%c d:%d ABORTED - tx len:%d, "
++ "rx len:%d",
++ is_tx ? "Send Bulk to" : "Recv Bulk from",
++ VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
++ service->remoteport,
++ bulk->size,
++ bulk->remote_size);
++ } else {
++ /* fabricate a matching dummy bulk */
++ bulk->data = NULL;
++ bulk->size = 0;
++ bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED;
++ bulk->dir = is_tx ? VCHIQ_BULK_TRANSMIT :
++ VCHIQ_BULK_RECEIVE;
++ queue->local_insert++;
++ }
++
++ queue->process++;
++ }
+ }
+
++/* Called from the slot handler thread */
+ static void
+ pause_bulks(VCHIQ_STATE_T *state)
+ {
+- int i;
++ if (unlikely(atomic_inc_return(&pause_bulks_count) != 1)) {
++ WARN_ON_ONCE(1);
++ atomic_set(&pause_bulks_count, 1);
++ return;
++ }
+
+- /* Block bulk transfers from all services */
+- for (i = 0; i < state->unused_service; i++)
+- {
+- VCHIQ_SERVICE_T *service = state->services[i];
+- if (!service || (service->srvstate != VCHIQ_SRVSTATE_OPEN))
+- continue;
+-
+- vcos_log_trace("locking bulk_mutex for service %d", i);
+- vcos_mutex_lock(&service->bulk_mutex);
+- }
++ /* Block bulk transfers from all services */
++ mutex_lock(&state->bulk_transfer_mutex);
+ }
+
++/* Called from the slot handler thread */
+ static void
+ resume_bulks(VCHIQ_STATE_T *state)
+ {
+- int i;
++ if (unlikely(atomic_dec_return(&pause_bulks_count) != 0)) {
++ WARN_ON_ONCE(1);
++ atomic_set(&pause_bulks_count, 0);
++ return;
++ }
+
+- /* Poll all services in case any bulk transfers have been
+- deferred */
+- for (i = 0; i < state->unused_service; i++)
+- {
+- VCHIQ_SERVICE_T *service = state->services[i];
+- if (!service || (service->srvstate != VCHIQ_SRVSTATE_OPEN))
+- continue;
++ /* Allow bulk transfers from all services */
++ mutex_unlock(&state->bulk_transfer_mutex);
++}
+
+- if (resolve_bulks(service, &service->bulk_tx))
+- request_poll(state, service, VCHIQ_POLL_TXNOTIFY);
+- if (resolve_bulks(service, &service->bulk_rx))
+- request_poll(state, service, VCHIQ_POLL_RXNOTIFY);
+- vcos_log_trace("unlocking bulk_mutex for service %d", i);
+- vcos_mutex_unlock(&service->bulk_mutex);
+- }
++static int
++parse_open(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header)
++{
++ VCHIQ_SERVICE_T *service = NULL;
++ int msgid, size;
++ int type;
++ unsigned int localport, remoteport;
++
++ msgid = header->msgid;
++ size = header->size;
++ type = VCHIQ_MSG_TYPE(msgid);
++ localport = VCHIQ_MSG_DSTPORT(msgid);
++ remoteport = VCHIQ_MSG_SRCPORT(msgid);
++ if (size == sizeof(struct vchiq_open_payload)) {
++ const struct vchiq_open_payload *payload =
++ (struct vchiq_open_payload *)header->data;
++ unsigned int fourcc;
++
++ fourcc = payload->fourcc;
++ vchiq_log_info(vchiq_core_log_level,
++ "%d: prs OPEN@%x (%d->'%c%c%c%c')",
++ state->id, (unsigned int)header,
++ localport,
++ VCHIQ_FOURCC_AS_4CHARS(fourcc));
++
++ service = get_listening_service(state, fourcc);
++
++ if (service) {
++ /* A matching service exists */
++ short version = payload->version;
++ short version_min = payload->version_min;
++ if ((service->version < version_min) ||
++ (version < service->version_min)) {
++ /* Version mismatch */
++ vchiq_loud_error_header();
++ vchiq_loud_error("%d: service %d (%c%c%c%c) "
++ "version mismatch - local (%d, min %d)"
++ " vs. remote (%d, min %d)",
++ state->id, service->localport,
++ VCHIQ_FOURCC_AS_4CHARS(fourcc),
++ service->version, service->version_min,
++ version, version_min);
++ vchiq_loud_error_footer();
++ goto fail_open;
++ }
++ if (service->srvstate == VCHIQ_SRVSTATE_LISTENING) {
++ /* Acknowledge the OPEN */
++ if (service->sync) {
++ if (queue_message_sync(state, NULL,
++ VCHIQ_MAKE_MSG(
++ VCHIQ_MSG_OPENACK,
++ service->localport,
++ remoteport),
++ NULL, 0, 0, 0) == VCHIQ_RETRY)
++ goto bail_not_ready;
++ } else {
++ if (queue_message(state, NULL,
++ VCHIQ_MAKE_MSG(
++ VCHIQ_MSG_OPENACK,
++ service->localport,
++ remoteport),
++ NULL, 0, 0, 0) == VCHIQ_RETRY)
++ goto bail_not_ready;
++ }
++
++ /* The service is now open */
++ vchiq_set_service_state(service,
++ service->sync ? VCHIQ_SRVSTATE_OPENSYNC
++ : VCHIQ_SRVSTATE_OPEN);
++ }
++
++ service->remoteport = remoteport;
++ service->client_id = ((int *)header->data)[1];
++ if (make_service_callback(service, VCHIQ_SERVICE_OPENED,
++ NULL, NULL) == VCHIQ_RETRY) {
++ /* Bail out if not ready */
++ service->remoteport = VCHIQ_PORT_FREE;
++ goto bail_not_ready;
++ }
++
++ /* Success - the message has been dealt with */
++ unlock_service(service);
++ return 1;
++ }
++ }
++
++fail_open:
++ /* No available service, or an invalid request - send a CLOSE */
++ if (queue_message(state, NULL,
++ VCHIQ_MAKE_MSG(VCHIQ_MSG_CLOSE, 0, VCHIQ_MSG_SRCPORT(msgid)),
++ NULL, 0, 0, 0) == VCHIQ_RETRY)
++ goto bail_not_ready;
++
++ unlock_service(service);
++
++ return 1;
++
++bail_not_ready:
++ unlock_service(service);
++
++ return 0;
+ }
+
+ /* Called by the slot handler thread */
+ static void
+ parse_rx_slots(VCHIQ_STATE_T *state)
+ {
+- VCHIQ_SHARED_STATE_T *remote = state->remote;
+- int tx_pos;
+- DEBUG_INITIALISE(state->local)
+-
+- tx_pos = remote->tx_pos;
+-
+- while (state->rx_pos != tx_pos) {
+- VCHIQ_SERVICE_T *service = NULL;
+- VCHIQ_HEADER_T *header;
+- int msgid, size;
+- int type;
+- unsigned int localport, remoteport;
+-
+- DEBUG_TRACE(PARSE_LINE);
+- if (!state->rx_data)
+- {
+- int rx_index;
+- vcos_assert((state->rx_pos & VCHIQ_SLOT_MASK) == 0);
+- rx_index = remote->slot_queue[SLOT_QUEUE_INDEX_FROM_POS(state->rx_pos) & VCHIQ_SLOT_QUEUE_MASK];
+- state->rx_data = (char *)SLOT_DATA_FROM_INDEX(state, rx_index);
+- state->rx_info = SLOT_INFO_FROM_INDEX(state, rx_index);
+-
+- /* Initialise use_count to one, and increment release_count at the end
+- of the slot to avoid releasing the slot prematurely. */
+- state->rx_info->use_count = 1;
+- state->rx_info->release_count = 0;
+- }
+-
+- header = (VCHIQ_HEADER_T *)(state->rx_data + (state->rx_pos & VCHIQ_SLOT_MASK));
+- DEBUG_VALUE(PARSE_HEADER, (int)header);
+- msgid = header->msgid;
+- DEBUG_VALUE(PARSE_MSGID, msgid);
+- size = header->size;
+- type = VCHIQ_MSG_TYPE(msgid);
+- localport = VCHIQ_MSG_DSTPORT(msgid);
+- remoteport = VCHIQ_MSG_SRCPORT(msgid);
+-
+- if (type != VCHIQ_MSG_DATA)
+- {
+- VCHIQ_STATS_INC(state, ctrl_rx_count);
+- }
+-
+- switch (type)
+- {
+- case VCHIQ_MSG_OPENACK:
+- case VCHIQ_MSG_CLOSE:
+- case VCHIQ_MSG_DATA:
+- case VCHIQ_MSG_BULK_RX:
+- case VCHIQ_MSG_BULK_TX:
+- case VCHIQ_MSG_BULK_RX_DONE:
+- case VCHIQ_MSG_BULK_TX_DONE:
+- if (localport <= VCHIQ_PORT_MAX)
+- {
+- service = state->services[localport];
+- if (service && (service->srvstate == VCHIQ_SRVSTATE_FREE))
+- service = NULL;
+- }
+- if (!service)
+- {
+- vcos_log_error(
+- "%d: prs %s@%x (%d->%d) - invalid/closed service %d",
+- state->id, msg_type_str(type), (unsigned int)header,
+- remoteport, localport, localport);
+- goto skip_message;
+- }
+- default:
+- break;
+- }
+-
+- if ( vcos_is_log_enabled( &vchiq_core_msg_log_category, VCOS_LOG_INFO))
+- {
+- int svc_fourcc;
+-
+- svc_fourcc = service
+- ? service->base.fourcc
+- : VCHIQ_MAKE_FOURCC('?','?','?','?');
+- vcos_log_impl( &vchiq_core_msg_log_category,
+- VCOS_LOG_INFO,
+- "Rcvd Msg %s(%u) from %c%c%c%c s:%d d:%d len:%d",
+- msg_type_str(type), type,
+- VCHIQ_FOURCC_AS_4CHARS(svc_fourcc),
+- remoteport, localport, size );
+- if (size > 0) {
+- vcos_log_dump_mem( &vchiq_core_msg_log_category,
+- "Rcvd", 0, header->data,
+- vcos_min( 64, size ));
+- }
+- }
+-
+- if (((unsigned int)header & VCHIQ_SLOT_MASK) + calc_stride(size) > VCHIQ_SLOT_SIZE)
+- {
+- vcos_log_error("header %x (msgid %x) - size %x too big for slot",
+- (unsigned int)header, (unsigned int)msgid, (unsigned int)size);
+- vcos_assert(0);
+- }
+-
+- switch (type) {
+- case VCHIQ_MSG_OPEN:
+- vcos_assert(VCHIQ_MSG_DSTPORT(msgid) == 0);
+- if (vcos_verify(size == sizeof(VCHIQ_OPEN_PAYLOAD_T))) {
+- const VCHIQ_OPEN_PAYLOAD_T *payload = (VCHIQ_OPEN_PAYLOAD_T *)header->data;
+- unsigned int fourcc;
+-
+- fourcc = payload->fourcc;
+- vcos_log_info("%d: prs OPEN@%x (%d->'%c%c%c%c')",
+- state->id, (unsigned int)header,
+- localport,
+- VCHIQ_FOURCC_AS_4CHARS(fourcc));
+-
+- service = get_listening_service(state, fourcc);
+-
+- if (service)
+- {
+- /* A matching service exists */
+- short version = payload->version;
+- short version_min = payload->version_min;
+- if ((service->version < version_min) ||
+- (version < service->version_min))
+- {
+- /* Version mismatch */
+- vcos_log_error("%d: service %d (%c%c%c%c) version mismatch -"
+- " local (%d, min %d) vs. remote (%d, min %d)",
+- state->id, service->localport,
+- VCHIQ_FOURCC_AS_4CHARS(fourcc),
+- service->version, service->version_min,
+- version, version_min);
+- goto fail_open;
+- }
+- if (service->srvstate == VCHIQ_SRVSTATE_LISTENING)
+- {
+- /* Acknowledge the OPEN */
+- if (queue_message(state, NULL,
+- VCHIQ_MAKE_MSG(VCHIQ_MSG_OPENACK, service->localport, remoteport),
+- NULL, 0, 0, 0) == VCHIQ_RETRY)
+- return; /* Bail out if not ready */
+-
+- /* The service is now open */
+- vchiq_set_service_state(service, VCHIQ_SRVSTATE_OPEN);
+- }
+-
+- service->remoteport = remoteport;
+- service->client_id = ((int *)header->data)[1];
+- if (make_service_callback(service, VCHIQ_SERVICE_OPENED,
+- NULL, NULL) == VCHIQ_RETRY)
+- {
+- /* Bail out if not ready */
+- service->remoteport = VCHIQ_PORT_FREE;
+- return;
+- }
+-
+- /* Break out, and skip the failure handling */
+- break;
+- }
+- }
+- fail_open:
+- /* No available service, or an invalid request - send a CLOSE */
+- if (queue_message(state, NULL,
+- VCHIQ_MAKE_MSG(VCHIQ_MSG_CLOSE, 0, VCHIQ_MSG_SRCPORT(msgid)),
+- NULL, 0, 0, 0) == VCHIQ_RETRY)
+- return; /* Bail out if not ready */
+- break;
+- case VCHIQ_MSG_OPENACK:
+- {
+- vcos_log_info("%d: prs OPENACK@%x (%d->%d)",
+- state->id, (unsigned int)header,
+- remoteport, localport);
+- if (service->srvstate == VCHIQ_SRVSTATE_OPENING) {
+- service->remoteport = remoteport;
+- vchiq_set_service_state(service,
+- VCHIQ_SRVSTATE_OPEN);
+- vcos_event_signal(&service->remove_event);
+- }
+- }
+- break;
+- case VCHIQ_MSG_CLOSE:
+- {
+- vcos_assert(size == 0); /* There should be no data */
+-
+- vcos_log_info("%d: prs CLOSE@%x (%d->%d)",
+- state->id, (unsigned int)header,
+- remoteport, localport);
+-
+- if ((service->remoteport != remoteport) &&
+- VCHIQ_PORT_IS_VALID(service->remoteport)) {
+- /* This could be from a client which hadn't yet received
+- the OPENACK - look for the connected service */
+- service = get_connected_service(state, remoteport);
+- if (!service)
+- break;
+- }
+-
+- if (vchiq_close_service_internal(service,
+- 1/*close_recvd*/) == VCHIQ_RETRY)
+- return; /* Bail out if not ready */
+-
+- if (vcos_is_log_enabled( &vchiq_core_msg_log_category, VCOS_LOG_INFO))
+- {
+- vcos_log_impl( &vchiq_core_msg_log_category,
+- VCOS_LOG_INFO,
+- "Close Service %c%c%c%c s:%u d:%d",
+- VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
+- service->localport,
+- service->remoteport );
+- }
+- }
+- break;
+- case VCHIQ_MSG_DATA:
+- {
+- vcos_log_trace("%d: prs DATA@%x,%x (%d->%d)",
+- state->id, (unsigned int)header, size,
+- remoteport, localport);
+-
+- if ((service->remoteport == remoteport)
+- && (service->srvstate ==
+- VCHIQ_SRVSTATE_OPEN)) {
+- header->msgid = msgid | VCHIQ_MSGID_CLAIMED;
+- claim_slot(state->rx_info);
+- DEBUG_TRACE(PARSE_LINE);
+- if (make_service_callback(service,
+- VCHIQ_MESSAGE_AVAILABLE, header,
+- NULL) == VCHIQ_RETRY)
+- {
+- DEBUG_TRACE(PARSE_LINE);
+- return; /* Bail out if not ready */
+- }
+- VCHIQ_SERVICE_STATS_INC(service, ctrl_rx_count);
+- VCHIQ_SERVICE_STATS_ADD(service, ctrl_rx_bytes, size);
+- }
+- else
+- {
+- VCHIQ_STATS_INC(state, error_count);
+- }
+- }
+- break;
+- case VCHIQ_MSG_CONNECT:
+- vcos_log_info("%d: prs CONNECT@%x",
+- state->id, (unsigned int)header);
+- vcos_event_signal(&state->connect);
+- break;
+- case VCHIQ_MSG_BULK_RX:
+- case VCHIQ_MSG_BULK_TX:
+- {
+- VCHIQ_BULK_QUEUE_T *queue;
+- vcos_assert(state->is_master);
+- queue = (type == VCHIQ_MSG_BULK_RX) ?
+- &service->bulk_tx : &service->bulk_rx;
+- if ((service->remoteport == remoteport)
+- && (service->srvstate ==
+- VCHIQ_SRVSTATE_OPEN))
+- {
+- VCHIQ_BULK_T *bulk;
+- int resolved;
+-
+- vcos_assert(queue->remote_insert < queue->remove +
+- VCHIQ_NUM_SERVICE_BULKS);
+- bulk = &queue->bulks[BULK_INDEX(queue->remote_insert)];
+- bulk->remote_data = (void *)((int *)header->data)[0];
+- bulk->remote_size = ((int *)header->data)[1];
+-
+- vcos_log_info("%d: prs %s@%x (%d->%d) %x@%x",
+- state->id, msg_type_str(type),
+- (unsigned int)header,
+- remoteport, localport,
+- bulk->remote_size,
+- (unsigned int)bulk->remote_data);
+-
+- queue->remote_insert++;
+-
+- if (state->conn_state != VCHIQ_CONNSTATE_CONNECTED)
+- break;
+-
+- DEBUG_TRACE(PARSE_LINE);
+- if (vcos_mutex_lock(&service->bulk_mutex) != VCOS_SUCCESS)
+- {
+- DEBUG_TRACE(PARSE_LINE);
+- return;
+- }
+- DEBUG_TRACE(PARSE_LINE);
+- resolved = resolve_bulks(service, queue);
+- vcos_mutex_unlock(&service->bulk_mutex);
+- if (resolved)
+- notify_bulks(service, queue);
+- }
+- }
+- break;
+- case VCHIQ_MSG_BULK_RX_DONE:
+- case VCHIQ_MSG_BULK_TX_DONE:
+- {
+- vcos_assert(!state->is_master);
+- if ((service->remoteport == remoteport)
+- && (service->srvstate !=
+- VCHIQ_SRVSTATE_FREE)) {
+- VCHIQ_BULK_QUEUE_T *queue;
+- VCHIQ_BULK_T *bulk;
+-
+- queue = (type == VCHIQ_MSG_BULK_RX_DONE) ?
+- &service->bulk_rx : &service->bulk_tx;
+-
+- bulk = &queue->bulks[BULK_INDEX(queue->process)];
+- bulk->actual = *(int *)header->data;
+-
+- vcos_log_info("%d: prs %s@%x (%d->%d) %x@%x",
+- state->id, msg_type_str(type),
+- (unsigned int)header,
+- remoteport, localport,
+- bulk->actual, (unsigned int)bulk->data);
+-
+- vcos_log_trace("%d: prs:%d %cx li=%x ri=%x p=%x",
+- state->id, localport,
+- (type == VCHIQ_MSG_BULK_RX_DONE) ? 'r' : 't',
+- queue->local_insert,
+- queue->remote_insert, queue->process);
+-
+- DEBUG_TRACE(PARSE_LINE);
+- if (vcos_mutex_lock(&service->bulk_mutex) != VCOS_SUCCESS)
+- {
+- DEBUG_TRACE(PARSE_LINE);
+- return;
+- }
+- DEBUG_TRACE(PARSE_LINE);
+- vcos_assert(queue->process != queue->local_insert);
+- vchiq_complete_bulk(bulk);
+- queue->process++;
+- vcos_mutex_unlock(&service->bulk_mutex);
+- DEBUG_TRACE(PARSE_LINE);
+- notify_bulks(service, queue);
+- DEBUG_TRACE(PARSE_LINE);
+- }
+- }
+- break;
+- case VCHIQ_MSG_PADDING:
+- vcos_log_trace("%d: prs PADDING@%x,%x",
+- state->id, (unsigned int)header, size);
+- break;
+- case VCHIQ_MSG_PAUSE:
+- /* If initiated, signal the application thread */
+- vcos_log_trace("%d: prs PAUSE@%x,%x",
+- state->id, (unsigned int)header, size);
+- if (state->conn_state != VCHIQ_CONNSTATE_PAUSE_SENT)
+- {
+- /* Send a PAUSE in response */
+- if (queue_message(state, NULL,
+- VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0),
+- NULL, 0, 0, 0) == VCHIQ_RETRY)
+- return; /* Bail out if not ready */
+- if (state->is_master)
+- pause_bulks(state);
+- }
+- /* At this point slot_mutex is held */
+- vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSED);
+- vchiq_platform_paused(state);
+- break;
+- case VCHIQ_MSG_RESUME:
+- vcos_log_trace("%d: prs RESUME@%x,%x",
+- state->id, (unsigned int)header, size);
+- /* Release the slot mutex */
+- vcos_mutex_unlock(&state->slot_mutex);
+- if (state->is_master)
+- resume_bulks(state);
+- vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED);
+- vchiq_platform_resumed(state);
+- break;
+-
+- case VCHIQ_MSG_REMOTE_USE:
+- vchiq_on_remote_use(state);
+- break;
+- case VCHIQ_MSG_REMOTE_RELEASE:
+- vchiq_on_remote_release(state);
+- break;
+- case VCHIQ_MSG_REMOTE_USE_ACTIVE:
+- vchiq_on_remote_use_active(state);
+- break;
+-
+- default:
+- vcos_log_error("%d: prs invalid msgid %x@%x,%x",
+- state->id, msgid, (unsigned int)header, size);
+- vcos_assert(0);
+- break;
+- }
+-
+- skip_message:
+- state->rx_pos += calc_stride(size);
+-
+- DEBUG_TRACE(PARSE_LINE);
+- /* Perform some housekeeping when the end of the slot is reached. */
+- if ((state->rx_pos & VCHIQ_SLOT_MASK) == 0)
+- {
+- /* Remove the extra reference count. */
+- release_slot(state, state->rx_info);
+- state->rx_data = NULL;
+- }
+- }
++ VCHIQ_SHARED_STATE_T *remote = state->remote;
++ VCHIQ_SERVICE_T *service = NULL;
++ int tx_pos;
++ DEBUG_INITIALISE(state->local)
++
++ tx_pos = remote->tx_pos;
++
++ while (state->rx_pos != tx_pos) {
++ VCHIQ_HEADER_T *header;
++ int msgid, size;
++ int type;
++ unsigned int localport, remoteport;
++
++ DEBUG_TRACE(PARSE_LINE);
++ if (!state->rx_data) {
++ int rx_index;
++ WARN_ON(!((state->rx_pos & VCHIQ_SLOT_MASK) == 0));
++ rx_index = remote->slot_queue[
++ SLOT_QUEUE_INDEX_FROM_POS(state->rx_pos) &
++ VCHIQ_SLOT_QUEUE_MASK];
++ state->rx_data = (char *)SLOT_DATA_FROM_INDEX(state,
++ rx_index);
++ state->rx_info = SLOT_INFO_FROM_INDEX(state, rx_index);
++
++ /* Initialise use_count to one, and increment
++ ** release_count at the end of the slot to avoid
++ ** releasing the slot prematurely. */
++ state->rx_info->use_count = 1;
++ state->rx_info->release_count = 0;
++ }
++
++ header = (VCHIQ_HEADER_T *)(state->rx_data +
++ (state->rx_pos & VCHIQ_SLOT_MASK));
++ DEBUG_VALUE(PARSE_HEADER, (int)header);
++ msgid = header->msgid;
++ DEBUG_VALUE(PARSE_MSGID, msgid);
++ size = header->size;
++ type = VCHIQ_MSG_TYPE(msgid);
++ localport = VCHIQ_MSG_DSTPORT(msgid);
++ remoteport = VCHIQ_MSG_SRCPORT(msgid);
++
++ if (type != VCHIQ_MSG_DATA)
++ VCHIQ_STATS_INC(state, ctrl_rx_count);
++
++ switch (type) {
++ case VCHIQ_MSG_OPENACK:
++ case VCHIQ_MSG_CLOSE:
++ case VCHIQ_MSG_DATA:
++ case VCHIQ_MSG_BULK_RX:
++ case VCHIQ_MSG_BULK_TX:
++ case VCHIQ_MSG_BULK_RX_DONE:
++ case VCHIQ_MSG_BULK_TX_DONE:
++ service = find_service_by_port(state, localport);
++ if (!service) {
++ vchiq_log_error(vchiq_core_log_level,
++ "%d: prs %s@%x (%d->%d) - "
++ "invalid/closed service %d",
++ state->id, msg_type_str(type),
++ (unsigned int)header,
++ remoteport, localport, localport);
++ goto skip_message;
++ }
++ default:
++ break;
++ }
++
++ if (vchiq_core_msg_log_level >= VCHIQ_LOG_INFO) {
++ int svc_fourcc;
++
++ svc_fourcc = service
++ ? service->base.fourcc
++ : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
++ vchiq_log_info(vchiq_core_msg_log_level,
++ "Rcvd Msg %s(%u) from %c%c%c%c s:%d d:%d "
++ "len:%d",
++ msg_type_str(type), type,
++ VCHIQ_FOURCC_AS_4CHARS(svc_fourcc),
++ remoteport, localport, size);
++ if (size > 0)
++ vchiq_log_dump_mem("Rcvd", 0, header->data,
++ min(64, size));
++ }
++
++ if (((unsigned int)header & VCHIQ_SLOT_MASK) + calc_stride(size)
++ > VCHIQ_SLOT_SIZE) {
++ vchiq_log_error(vchiq_core_log_level,
++ "header %x (msgid %x) - size %x too big for "
++ "slot",
++ (unsigned int)header, (unsigned int)msgid,
++ (unsigned int)size);
++ WARN(1, "oversized for slot\n");
++ }
++
++ switch (type) {
++ case VCHIQ_MSG_OPEN:
++ WARN_ON(!(VCHIQ_MSG_DSTPORT(msgid) == 0));
++ if (!parse_open(state, header))
++ goto bail_not_ready;
++ break;
++ case VCHIQ_MSG_OPENACK:
++ vchiq_log_info(vchiq_core_log_level,
++ "%d: prs OPENACK@%x (%d->%d)",
++ state->id, (unsigned int)header,
++ remoteport, localport);
++ if (service->srvstate ==
++ VCHIQ_SRVSTATE_OPENING) {
++ service->remoteport = remoteport;
++ vchiq_set_service_state(service,
++ VCHIQ_SRVSTATE_OPEN);
++ up(&service->remove_event);
++ } else
++ vchiq_log_error(vchiq_core_log_level,
++ "OPENACK received in state %s",
++ srvstate_names[service->srvstate]);
++ break;
++ case VCHIQ_MSG_CLOSE:
++ WARN_ON(size != 0); /* There should be no data */
++
++ vchiq_log_info(vchiq_core_log_level,
++ "%d: prs CLOSE@%x (%d->%d)",
++ state->id, (unsigned int)header,
++ remoteport, localport);
++
++ if ((service->remoteport != remoteport) &&
++ VCHIQ_PORT_IS_VALID(service->remoteport)) {
++ /* This could be from a client which hadn't yet
++ ** received the OPENACK - look for the
++ ** connected service */
++ service = get_connected_service(state,
++ remoteport);
++ if (!service)
++ break;
++ }
++
++ mark_service_closing(service);
++
++ if (vchiq_close_service_internal(service,
++ 1/*close_recvd*/) == VCHIQ_RETRY)
++ goto bail_not_ready;
++
++ vchiq_log_info(vchiq_core_log_level,
++ "Close Service %c%c%c%c s:%u d:%d",
++ VCHIQ_FOURCC_AS_4CHARS(service->base.fourcc),
++ service->localport,
++ service->remoteport);
++ break;
++ case VCHIQ_MSG_DATA:
++ vchiq_log_trace(vchiq_core_log_level,
++ "%d: prs DATA@%x,%x (%d->%d)",
++ state->id, (unsigned int)header, size,
++ remoteport, localport);
++
++ if ((service->remoteport == remoteport)
++ && (service->srvstate ==
++ VCHIQ_SRVSTATE_OPEN)) {
++ header->msgid = msgid | VCHIQ_MSGID_CLAIMED;
++ claim_slot(state->rx_info);
++ DEBUG_TRACE(PARSE_LINE);
++ if (make_service_callback(service,
++ VCHIQ_MESSAGE_AVAILABLE, header,
++ NULL) == VCHIQ_RETRY) {
++ DEBUG_TRACE(PARSE_LINE);
++ goto bail_not_ready;
++ }
++ VCHIQ_SERVICE_STATS_INC(service, ctrl_rx_count);
++ VCHIQ_SERVICE_STATS_ADD(service, ctrl_rx_bytes,
++ size);
++ } else {
++ VCHIQ_STATS_INC(state, error_count);
++ }
++ break;
++ case VCHIQ_MSG_CONNECT:
++ vchiq_log_info(vchiq_core_log_level,
++ "%d: prs CONNECT@%x",
++ state->id, (unsigned int)header);
++ up(&state->connect);
++ break;
++ case VCHIQ_MSG_BULK_RX:
++ case VCHIQ_MSG_BULK_TX: {
++ VCHIQ_BULK_QUEUE_T *queue;
++ WARN_ON(!state->is_master);
++ queue = (type == VCHIQ_MSG_BULK_RX) ?
++ &service->bulk_tx : &service->bulk_rx;
++ if ((service->remoteport == remoteport)
++ && (service->srvstate ==
++ VCHIQ_SRVSTATE_OPEN)) {
++ VCHIQ_BULK_T *bulk;
++ int resolved;
++
++ WARN_ON(!(queue->remote_insert < queue->remove +
++ VCHIQ_NUM_SERVICE_BULKS));
++ bulk = &queue->bulks[
++ BULK_INDEX(queue->remote_insert)];
++ bulk->remote_data =
++ (void *)((int *)header->data)[0];
++ bulk->remote_size = ((int *)header->data)[1];
++ wmb();
++
++ vchiq_log_info(vchiq_core_log_level,
++ "%d: prs %s@%x (%d->%d) %x@%x",
++ state->id, msg_type_str(type),
++ (unsigned int)header,
++ remoteport, localport,
++ bulk->remote_size,
++ (unsigned int)bulk->remote_data);
++
++ queue->remote_insert++;
++
++ if (state->conn_state !=
++ VCHIQ_CONNSTATE_CONNECTED)
++ break;
++
++ DEBUG_TRACE(PARSE_LINE);
++ if (mutex_lock_interruptible(
++ &service->bulk_mutex) != 0) {
++ DEBUG_TRACE(PARSE_LINE);
++ goto bail_not_ready;
++ }
++ DEBUG_TRACE(PARSE_LINE);
++ resolved = resolve_bulks(service, queue);
++ mutex_unlock(&service->bulk_mutex);
++ if (resolved)
++ notify_bulks(service, queue,
++ 1/*retry_poll*/);
++ }
++ } break;
++ case VCHIQ_MSG_BULK_RX_DONE:
++ case VCHIQ_MSG_BULK_TX_DONE:
++ WARN_ON(state->is_master);
++ if ((service->remoteport == remoteport)
++ && (service->srvstate !=
++ VCHIQ_SRVSTATE_FREE)) {
++ VCHIQ_BULK_QUEUE_T *queue;
++ VCHIQ_BULK_T *bulk;
++
++ queue = (type == VCHIQ_MSG_BULK_RX_DONE) ?
++ &service->bulk_rx : &service->bulk_tx;
++
++ if ((int)(queue->remote_insert -
++ queue->local_insert) >= 0) {
++ vchiq_log_error(vchiq_core_log_level,
++ "%d: prs %s@%x (%d->%d) "
++ "unexpected",
++ state->id, msg_type_str(type),
++ (unsigned int)header,
++ remoteport, localport);
++ break;
++ }
++
++ BUG_ON(queue->process == queue->local_insert);
++ BUG_ON(queue->process != queue->remote_insert);
++
++ bulk = &queue->bulks[
++ BULK_INDEX(queue->remote_insert)];
++ bulk->actual = *(int *)header->data;
++ queue->remote_insert++;
++
++ vchiq_log_info(vchiq_core_log_level,
++ "%d: prs %s@%x (%d->%d) %x@%x",
++ state->id, msg_type_str(type),
++ (unsigned int)header,
++ remoteport, localport,
++ bulk->actual, (unsigned int)bulk->data);
++
++ vchiq_log_trace(vchiq_core_log_level,
++ "%d: prs:%d %cx li=%x ri=%x p=%x",
++ state->id, localport,
++ (type == VCHIQ_MSG_BULK_RX_DONE) ?
++ 'r' : 't',
++ queue->local_insert,
++ queue->remote_insert, queue->process);
++
++ DEBUG_TRACE(PARSE_LINE);
++ if (mutex_lock_interruptible(
++ &service->bulk_mutex) != 0) {
++ DEBUG_TRACE(PARSE_LINE);
++ goto bail_not_ready;
++ }
++ DEBUG_TRACE(PARSE_LINE);
++ WARN_ON(queue->process == queue->local_insert);
++ vchiq_complete_bulk(bulk);
++ queue->process++;
++ mutex_unlock(&service->bulk_mutex);
++ DEBUG_TRACE(PARSE_LINE);
++ notify_bulks(service, queue, 1/*retry_poll*/);
++ DEBUG_TRACE(PARSE_LINE);
++ }
++ break;
++ case VCHIQ_MSG_PADDING:
++ vchiq_log_trace(vchiq_core_log_level,
++ "%d: prs PADDING@%x,%x",
++ state->id, (unsigned int)header, size);
++ break;
++ case VCHIQ_MSG_PAUSE:
++ /* If initiated, signal the application thread */
++ vchiq_log_trace(vchiq_core_log_level,
++ "%d: prs PAUSE@%x,%x",
++ state->id, (unsigned int)header, size);
++ if (state->conn_state == VCHIQ_CONNSTATE_PAUSED) {
++ vchiq_log_error(vchiq_core_log_level,
++ "%d: PAUSE received in state PAUSED",
++ state->id);
++ break;
++ }
++ if (state->conn_state != VCHIQ_CONNSTATE_PAUSE_SENT) {
++ /* Send a PAUSE in response */
++ if (queue_message(state, NULL,
++ VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0),
++ NULL, 0, 0, 0) == VCHIQ_RETRY)
++ goto bail_not_ready;
++ if (state->is_master)
++ pause_bulks(state);
++ }
++ /* At this point slot_mutex is held */
++ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSED);
++ vchiq_platform_paused(state);
++ break;
++ case VCHIQ_MSG_RESUME:
++ vchiq_log_trace(vchiq_core_log_level,
++ "%d: prs RESUME@%x,%x",
++ state->id, (unsigned int)header, size);
++ /* Release the slot mutex */
++ mutex_unlock(&state->slot_mutex);
++ if (state->is_master)
++ resume_bulks(state);
++ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED);
++ vchiq_platform_resumed(state);
++ break;
++
++ case VCHIQ_MSG_REMOTE_USE:
++ vchiq_on_remote_use(state);
++ break;
++ case VCHIQ_MSG_REMOTE_RELEASE:
++ vchiq_on_remote_release(state);
++ break;
++ case VCHIQ_MSG_REMOTE_USE_ACTIVE:
++ vchiq_on_remote_use_active(state);
++ break;
++
++ default:
++ vchiq_log_error(vchiq_core_log_level,
++ "%d: prs invalid msgid %x@%x,%x",
++ state->id, msgid, (unsigned int)header, size);
++ WARN(1, "invalid message\n");
++ break;
++ }
++
++skip_message:
++ if (service) {
++ unlock_service(service);
++ service = NULL;
++ }
++
++ state->rx_pos += calc_stride(size);
++
++ DEBUG_TRACE(PARSE_LINE);
++ /* Perform some housekeeping when the end of the slot is
++ ** reached. */
++ if ((state->rx_pos & VCHIQ_SLOT_MASK) == 0) {
++ /* Remove the extra reference count. */
++ release_slot(state, state->rx_info, NULL, NULL);
++ state->rx_data = NULL;
++ }
++ }
++
++bail_not_ready:
++ if (service)
++ unlock_service(service);
+ }
+
+ /* Called by the slot handler thread */
+-static void *
++static int
+ slot_handler_func(void *v)
+ {
+- VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v;
+- VCHIQ_SHARED_STATE_T *local = state->local;
+- DEBUG_INITIALISE(local)
+-
+- while (1) {
+- DEBUG_COUNT(SLOT_HANDLER_COUNT);
+- DEBUG_TRACE(SLOT_HANDLER_LINE);
+- remote_event_wait(&local->trigger);
+-
+- vcos_rmb();
+-
+- DEBUG_TRACE(SLOT_HANDLER_LINE);
+- if (state->poll_needed)
+- {
+- state->poll_needed = 0;
+-
+- /* Handle service polling and other rare conditions here out
+- of the mainline code */
+- switch (state->conn_state)
+- {
+- case VCHIQ_CONNSTATE_CONNECTED:
+- /* Poll the services as requested */
+- poll_services(state);
+- break;
+-
+- case VCHIQ_CONNSTATE_PAUSING:
+- if (queue_message(state, NULL,
+- VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0), NULL, 0, 0, 0)
+- != VCHIQ_RETRY)
+- {
+- if (state->is_master)
+- pause_bulks(state);
+- vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSE_SENT);
+- }
+- else
+- {
+- state->poll_needed = 1; /* Retry later */
+- }
+- break;
+-
+- case VCHIQ_CONNSTATE_RESUMING:
+- if (queue_message(state, NULL,
+- VCHIQ_MAKE_MSG(VCHIQ_MSG_RESUME, 0, 0), NULL, 0, 0, 0)
+- != VCHIQ_RETRY)
+- {
+- if (state->is_master)
+- resume_bulks(state);
+- vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED);
+- vchiq_platform_resumed(state);
+- }
+- else
+- {
+- /* This should really be impossible, since the PAUSE should
+- have flushed through outstanding messages. */
+- vcos_log_error("Failed to send RESUME message");
+- vcos_demand(0);
+- }
+- break;
+- default:
+- break;
+- }
+- }
+-
+- DEBUG_TRACE(SLOT_HANDLER_LINE);
+- parse_rx_slots(state);
+- }
+- return NULL;
++ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v;
++ VCHIQ_SHARED_STATE_T *local = state->local;
++ DEBUG_INITIALISE(local)
++
++ while (1) {
++ DEBUG_COUNT(SLOT_HANDLER_COUNT);
++ DEBUG_TRACE(SLOT_HANDLER_LINE);
++ remote_event_wait(&local->trigger);
++
++ rmb();
++
++ DEBUG_TRACE(SLOT_HANDLER_LINE);
++ if (state->poll_needed) {
++ /* Check if we need to suspend - may change our
++ * conn_state */
++ vchiq_platform_check_suspend(state);
++
++ state->poll_needed = 0;
++
++ /* Handle service polling and other rare conditions here
++ ** out of the mainline code */
++ switch (state->conn_state) {
++ case VCHIQ_CONNSTATE_CONNECTED:
++ /* Poll the services as requested */
++ poll_services(state);
++ break;
++
++ case VCHIQ_CONNSTATE_PAUSING:
++ if (state->is_master)
++ pause_bulks(state);
++ if (queue_message(state, NULL,
++ VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0),
++ NULL, 0, 0, 0) != VCHIQ_RETRY) {
++ vchiq_set_conn_state(state,
++ VCHIQ_CONNSTATE_PAUSE_SENT);
++ } else {
++ if (state->is_master)
++ resume_bulks(state);
++ /* Retry later */
++ state->poll_needed = 1;
++ }
++ break;
++
++ case VCHIQ_CONNSTATE_PAUSED:
++ vchiq_platform_resume(state);
++ break;
++
++ case VCHIQ_CONNSTATE_RESUMING:
++ if (queue_message(state, NULL,
++ VCHIQ_MAKE_MSG(VCHIQ_MSG_RESUME, 0, 0),
++ NULL, 0, 0, 0) != VCHIQ_RETRY) {
++ if (state->is_master)
++ resume_bulks(state);
++ vchiq_set_conn_state(state,
++ VCHIQ_CONNSTATE_CONNECTED);
++ vchiq_platform_resumed(state);
++ } else {
++ /* This should really be impossible,
++ ** since the PAUSE should have flushed
++ ** through outstanding messages. */
++ vchiq_log_error(vchiq_core_log_level,
++ "Failed to send RESUME "
++ "message");
++ BUG();
++ }
++ break;
++ default:
++ break;
++ }
++
++
++ }
++
++ DEBUG_TRACE(SLOT_HANDLER_LINE);
++ parse_rx_slots(state);
++ }
++ return 0;
+ }
+
+
+ /* Called by the recycle thread */
+-static void *
++static int
+ recycle_func(void *v)
+ {
+- VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v;
+- VCHIQ_SHARED_STATE_T *local = state->local;
++ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v;
++ VCHIQ_SHARED_STATE_T *local = state->local;
+
+- while (1) {
+- remote_event_wait(&local->recycle);
++ while (1) {
++ remote_event_wait(&local->recycle);
+
+- vcos_mutex_lock(&state->slot_mutex);
++ process_free_queue(state);
++ }
++ return 0;
++}
+
+- process_free_queue(state);
+
+- vcos_mutex_unlock(&state->slot_mutex);
+- }
+- return NULL;
++/* Called by the sync thread */
++static int
++sync_func(void *v)
++{
++ VCHIQ_STATE_T *state = (VCHIQ_STATE_T *) v;
++ VCHIQ_SHARED_STATE_T *local = state->local;
++ VCHIQ_HEADER_T *header = (VCHIQ_HEADER_T *)SLOT_DATA_FROM_INDEX(state,
++ state->remote->slot_sync);
++
++ while (1) {
++ VCHIQ_SERVICE_T *service;
++ int msgid, size;
++ int type;
++ unsigned int localport, remoteport;
++
++ remote_event_wait(&local->sync_trigger);
++
++ rmb();
++
++ msgid = header->msgid;
++ size = header->size;
++ type = VCHIQ_MSG_TYPE(msgid);
++ localport = VCHIQ_MSG_DSTPORT(msgid);
++ remoteport = VCHIQ_MSG_SRCPORT(msgid);
++
++ service = find_service_by_port(state, localport);
++
++ if (!service) {
++ vchiq_log_error(vchiq_sync_log_level,
++ "%d: sf %s@%x (%d->%d) - "
++ "invalid/closed service %d",
++ state->id, msg_type_str(type),
++ (unsigned int)header,
++ remoteport, localport, localport);
++ release_message_sync(state, header);
++ continue;
++ }
++
++ if (vchiq_sync_log_level >= VCHIQ_LOG_TRACE) {
++ int svc_fourcc;
++
++ svc_fourcc = service
++ ? service->base.fourcc
++ : VCHIQ_MAKE_FOURCC('?', '?', '?', '?');
++ vchiq_log_trace(vchiq_sync_log_level,
++ "Rcvd Msg %s from %c%c%c%c s:%d d:%d len:%d",
++ msg_type_str(type),
++ VCHIQ_FOURCC_AS_4CHARS(svc_fourcc),
++ remoteport, localport, size);
++ if (size > 0)
++ vchiq_log_dump_mem("Rcvd", 0, header->data,
++ min(64, size));
++ }
++
++ switch (type) {
++ case VCHIQ_MSG_OPENACK:
++ vchiq_log_info(vchiq_sync_log_level,
++ "%d: sf OPENACK@%x (%d->%d)",
++ state->id, (unsigned int)header,
++ remoteport, localport);
++ if (service->srvstate == VCHIQ_SRVSTATE_OPENING) {
++ service->remoteport = remoteport;
++ vchiq_set_service_state(service,
++ VCHIQ_SRVSTATE_OPENSYNC);
++ up(&service->remove_event);
++ }
++ release_message_sync(state, header);
++ break;
++
++ case VCHIQ_MSG_DATA:
++ vchiq_log_trace(vchiq_sync_log_level,
++ "%d: sf DATA@%x,%x (%d->%d)",
++ state->id, (unsigned int)header, size,
++ remoteport, localport);
++
++ if ((service->remoteport == remoteport) &&
++ (service->srvstate ==
++ VCHIQ_SRVSTATE_OPENSYNC)) {
++ if (make_service_callback(service,
++ VCHIQ_MESSAGE_AVAILABLE, header,
++ NULL) == VCHIQ_RETRY)
++ vchiq_log_error(vchiq_sync_log_level,
++ "synchronous callback to "
++ "service %d returns "
++ "VCHIQ_RETRY",
++ localport);
++ }
++ break;
++
++ default:
++ vchiq_log_error(vchiq_sync_log_level,
++ "%d: sf unexpected msgid %x@%x,%x",
++ state->id, msgid, (unsigned int)header, size);
++ release_message_sync(state, header);
++ break;
++ }
++
++ unlock_service(service);
++ }
++
++ return 0;
+ }
+
+
+ static void
+ init_bulk_queue(VCHIQ_BULK_QUEUE_T *queue)
+ {
+- queue->local_insert = 0;
+- queue->remote_insert = 0;
+- queue->process = 0;
+- queue->remote_notify = 0;
+- queue->remove = 0;
++ queue->local_insert = 0;
++ queue->remote_insert = 0;
++ queue->process = 0;
++ queue->remote_notify = 0;
++ queue->remove = 0;
+ }
+
+-VCHIQ_SLOT_ZERO_T *
+-vchiq_init_slots(void *mem_base, int mem_size)
+-{
+- int mem_align = (VCHIQ_SLOT_SIZE - (int)mem_base) & VCHIQ_SLOT_MASK;
+- VCHIQ_SLOT_ZERO_T *slot_zero = (VCHIQ_SLOT_ZERO_T *)((char *)mem_base + mem_align);
+- int num_slots = (mem_size - mem_align)/VCHIQ_SLOT_SIZE;
+- int first_data_slot = VCHIQ_SLOT_ZERO_SLOTS;
+-
+- /* Ensure there is enough memory to run an absolutely minimum system */
+- num_slots -= first_data_slot;
+-
+- if (num_slots < 4)
+- {
+- vcos_log_error("vchiq_init_slots - insufficient memory %x bytes", mem_size);
+- return NULL;
+- }
+
+- memset(slot_zero, 0, sizeof(VCHIQ_SLOT_ZERO_T));
+-
+- slot_zero->magic = VCHIQ_MAGIC;
+- slot_zero->version = VCHIQ_VERSION;
+- slot_zero->version_min = VCHIQ_VERSION_MIN;
+- slot_zero->slot_zero_size = sizeof(VCHIQ_SLOT_ZERO_T);
+- slot_zero->slot_size = VCHIQ_SLOT_SIZE;
+- slot_zero->max_slots = VCHIQ_MAX_SLOTS;
+- slot_zero->max_slots_per_side = VCHIQ_MAX_SLOTS_PER_SIDE;
++inline const char *
++get_conn_state_name(VCHIQ_CONNSTATE_T conn_state)
++{
++ return conn_state_names[conn_state];
++}
+
+- slot_zero->master.slot_first = first_data_slot;
+- slot_zero->slave.slot_first = first_data_slot + (num_slots/2);
+- slot_zero->master.slot_last = slot_zero->slave.slot_first - 1;
+- slot_zero->slave.slot_last = first_data_slot + num_slots - 1;
+
+- return slot_zero;
++VCHIQ_SLOT_ZERO_T *
++vchiq_init_slots(void *mem_base, int mem_size)
++{
++ int mem_align = (VCHIQ_SLOT_SIZE - (int)mem_base) & VCHIQ_SLOT_MASK;
++ VCHIQ_SLOT_ZERO_T *slot_zero =
++ (VCHIQ_SLOT_ZERO_T *)((char *)mem_base + mem_align);
++ int num_slots = (mem_size - mem_align)/VCHIQ_SLOT_SIZE;
++ int first_data_slot = VCHIQ_SLOT_ZERO_SLOTS;
++
++ /* Ensure there is enough memory to run an absolutely minimum system */
++ num_slots -= first_data_slot;
++
++ if (num_slots < 4) {
++ vchiq_log_error(vchiq_core_log_level,
++ "vchiq_init_slots - insufficient memory %x bytes",
++ mem_size);
++ return NULL;
++ }
++
++ memset(slot_zero, 0, sizeof(VCHIQ_SLOT_ZERO_T));
++
++ slot_zero->magic = VCHIQ_MAGIC;
++ slot_zero->version = VCHIQ_VERSION;
++ slot_zero->version_min = VCHIQ_VERSION_MIN;
++ slot_zero->slot_zero_size = sizeof(VCHIQ_SLOT_ZERO_T);
++ slot_zero->slot_size = VCHIQ_SLOT_SIZE;
++ slot_zero->max_slots = VCHIQ_MAX_SLOTS;
++ slot_zero->max_slots_per_side = VCHIQ_MAX_SLOTS_PER_SIDE;
++
++ slot_zero->master.slot_sync = first_data_slot;
++ slot_zero->master.slot_first = first_data_slot + 1;
++ slot_zero->master.slot_last = first_data_slot + (num_slots/2) - 1;
++ slot_zero->slave.slot_sync = first_data_slot + (num_slots/2);
++ slot_zero->slave.slot_first = first_data_slot + (num_slots/2) + 1;
++ slot_zero->slave.slot_last = first_data_slot + num_slots - 1;
++
++ return slot_zero;
+ }
+
+ VCHIQ_STATUS_T
+-vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero, int is_master)
+-{
+- VCHIQ_SHARED_STATE_T *local;
+- VCHIQ_SHARED_STATE_T *remote;
+- VCOS_THREAD_ATTR_T attrs;
+- VCHIQ_STATUS_T status;
+- char threadname[10];
+- static int id = 0;
+- int i;
+-
+- vcos_log_set_level(&vchiq_core_log_category, vchiq_default_core_log_level);
+- vcos_log_set_level(&vchiq_core_msg_log_category, vchiq_default_core_msg_log_level);
+- vcos_log_register("vchiq_core", &vchiq_core_log_category);
+- vcos_log_register("vchiq_core_msg", &vchiq_core_msg_log_category);
+-
+- vcos_log_warn( "%s: slot_zero = 0x%08lx, is_master = %d", __func__, (unsigned long)slot_zero, is_master );
+-
+- /* Check the input configuration */
+-
+- if (slot_zero->magic != VCHIQ_MAGIC)
+- {
+- vcos_log_error("slot_zero=%x: magic=%x (expected %x)",
+- (unsigned int)slot_zero, slot_zero->magic, VCHIQ_MAGIC);
+- return VCHIQ_ERROR;
+- }
+-
+- if (slot_zero->version < VCHIQ_VERSION_MIN)
+- {
+- vcos_log_error("slot_zero=%x: peer_version=%x (minimum %x)",
+- (unsigned int)slot_zero, slot_zero->version, VCHIQ_VERSION_MIN);
+- return VCHIQ_ERROR;
+- }
+-
+- if (VCHIQ_VERSION < slot_zero->version_min)
+- {
+- vcos_log_error("slot_zero=%x: version=%x (peer minimum %x)",
+- (unsigned int)slot_zero, VCHIQ_VERSION, slot_zero->version_min);
+- return VCHIQ_ERROR;
+- }
+-
+- if (slot_zero->slot_zero_size != sizeof(VCHIQ_SLOT_ZERO_T))
+- {
+- vcos_log_error("slot_zero=%x: slot_zero_size=%x (expected %x)",
+- (unsigned int)slot_zero, slot_zero->slot_zero_size, sizeof(VCHIQ_SLOT_ZERO_T));
+- return VCHIQ_ERROR;
+- }
+-
+- if (slot_zero->slot_size != VCHIQ_SLOT_SIZE)
+- {
+- vcos_log_error("slot_zero=%x: slot_size=%d (expected %d",
+- (unsigned int)slot_zero, slot_zero->slot_size, VCHIQ_SLOT_SIZE);
+- return VCHIQ_ERROR;
+- }
+-
+- if (slot_zero->max_slots != VCHIQ_MAX_SLOTS)
+- {
+- vcos_log_error("slot_zero=%x: max_slots=%d (expected %d)",
+- (unsigned int)slot_zero, slot_zero->max_slots, VCHIQ_MAX_SLOTS);
+- return VCHIQ_ERROR;
+- }
+-
+- if (slot_zero->max_slots_per_side != VCHIQ_MAX_SLOTS_PER_SIDE)
+- {
+- vcos_log_error("slot_zero=%x: max_slots_per_side=%d (expected %d)",
+- (unsigned int)slot_zero, slot_zero->max_slots_per_side,
+- VCHIQ_MAX_SLOTS_PER_SIDE);
+- return VCHIQ_ERROR;
+- }
+-
+- if (is_master)
+- {
+- local = &slot_zero->master;
+- remote = &slot_zero->slave;
+- }
+- else
+- {
+- local = &slot_zero->slave;
+- remote = &slot_zero->master;
+- }
+-
+- if (local->initialised)
+- {
+- if (remote->initialised)
+- vcos_log_error("vchiq: FATAL: local state has already been initialised");
+- else
+- vcos_log_error("vchiq: FATAL: master/slave mismatch - two %ss", is_master ? "master" : "slave");
+- return VCHIQ_ERROR;
+- }
+-
+- memset(state, 0, sizeof(VCHIQ_STATE_T));
+- vcos_log_warn( "%s: called", __func__);
+- state->id = id++;
+- state->is_master = is_master;
+-
+- /*
+- initialize shared state pointers
+- */
+-
+- state->local = local;
+- state->remote = remote;
+- state->slot_data = (VCHIQ_SLOT_T *)slot_zero;
+-
+- /*
+- initialize events and mutexes
+- */
+-
+- vcos_event_create(&state->connect, "v.connect");
+- vcos_mutex_create(&state->mutex, "v.mutex");
+- vcos_event_create(&state->trigger_event, "v.trigger_event");
+- vcos_event_create(&state->recycle_event, "v.recycle_event");
+-
+- vcos_mutex_create(&state->slot_mutex, "v.slot_mutex");
+- vcos_mutex_create(&state->recycle_mutex, "v.recycle_mutex");
+-
+- vcos_event_create(&state->slot_available_event, "v.slot_available_event");
+- vcos_event_create(&state->slot_remove_event, "v.slot_remove_event");
+-
+- state->slot_queue_available = 0;
+-
+- for (i = 0; i < VCHIQ_MAX_SERVICES; i++)
+- {
+- VCHIQ_SERVICE_QUOTA_T *service_quota = &state->service_quotas[i];
+- vcos_event_create(&service_quota->quota_event, "v.quota_event");
+- }
+-
+- for (i = local->slot_first; i <= local->slot_last; i++)
+- {
+- local->slot_queue[state->slot_queue_available++] = i;
+- }
+-
+- state->default_slot_quota = state->slot_queue_available/2;
+- state->default_message_quota = vcos_min(state->default_slot_quota * 256, (unsigned short)~0);
+-
+- local->trigger.event = &state->trigger_event;
+- remote_event_create(&local->trigger);
+- local->tx_pos = 0;
+-
+- local->recycle.event = &state->recycle_event;
+- remote_event_create(&local->recycle);
+- local->slot_queue_recycle = state->slot_queue_available;
+-
+- local->debug[DEBUG_ENTRIES] = DEBUG_MAX;
+-
+- /*
+- bring up slot handler thread
+- */
+-
+- vcos_thread_attr_init(&attrs);
+- vcos_thread_attr_setstacksize(&attrs, VCHIQ_SLOT_HANDLER_STACK);
+- vcos_thread_attr_setpriority(&attrs, VCOS_THREAD_PRI_REALTIME);
+- vcos_snprintf(threadname, sizeof(threadname), "VCHIQ-%d", state->id);
+- if (vcos_thread_create(&state->slot_handler_thread, threadname,
+- &attrs, slot_handler_func, state) != VCOS_SUCCESS)
+- {
+- vcos_log_error("vchiq: FATAL: couldn't create thread %s", threadname);
+- return VCHIQ_ERROR;
+- }
+-
+- vcos_thread_attr_init(&attrs);
+- vcos_thread_attr_setstacksize(&attrs, VCHIQ_SLOT_HANDLER_STACK);
+- vcos_thread_attr_setpriority(&attrs, VCOS_THREAD_PRI_REALTIME);
+- vcos_snprintf(threadname, sizeof(threadname), "VCHIQr-%d", state->id);
+- if (vcos_thread_create(&state->recycle_thread, threadname,
+- &attrs, recycle_func, state) != VCOS_SUCCESS)
+- {
+- vcos_log_error("vchiq: FATAL: couldn't create thread %s", threadname);
+- return VCHIQ_ERROR;
+- }
+-
+- status = vchiq_platform_init_state(state);
+-
+- /* Indicate readiness to the other side */
+- local->initialised = 1;
+-
+- return status;
++vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero,
++ int is_master)
++{
++ VCHIQ_SHARED_STATE_T *local;
++ VCHIQ_SHARED_STATE_T *remote;
++ VCHIQ_STATUS_T status;
++ char threadname[10];
++ static int id;
++ int i;
++
++ vchiq_log_warning(vchiq_core_log_level,
++ "%s: slot_zero = 0x%08lx, is_master = %d",
++ __func__, (unsigned long)slot_zero, is_master);
++
++ /* Check the input configuration */
++
++ if (slot_zero->magic != VCHIQ_MAGIC) {
++ vchiq_loud_error_header();
++ vchiq_loud_error("Invalid VCHIQ magic value found.");
++ vchiq_loud_error("slot_zero=%x: magic=%x (expected %x)",
++ (unsigned int)slot_zero, slot_zero->magic, VCHIQ_MAGIC);
++ vchiq_loud_error_footer();
++ return VCHIQ_ERROR;
++ }
++
++ if (slot_zero->version < VCHIQ_VERSION_MIN) {
++ vchiq_loud_error_header();
++ vchiq_loud_error("Incompatible VCHIQ versions found.");
++ vchiq_loud_error("slot_zero=%x: VideoCore version=%d "
++ "(minimum %d)",
++ (unsigned int)slot_zero, slot_zero->version,
++ VCHIQ_VERSION_MIN);
++ vchiq_loud_error("Restart with a newer VideoCore image.");
++ vchiq_loud_error_footer();
++ return VCHIQ_ERROR;
++ }
++
++ if (VCHIQ_VERSION < slot_zero->version_min) {
++ vchiq_loud_error_header();
++ vchiq_loud_error("Incompatible VCHIQ versions found.");
++ vchiq_loud_error("slot_zero=%x: version=%d (VideoCore "
++ "minimum %d)",
++ (unsigned int)slot_zero, VCHIQ_VERSION,
++ slot_zero->version_min);
++ vchiq_loud_error("Restart with a newer kernel.");
++ vchiq_loud_error_footer();
++ return VCHIQ_ERROR;
++ }
++
++ if ((slot_zero->slot_zero_size != sizeof(VCHIQ_SLOT_ZERO_T)) ||
++ (slot_zero->slot_size != VCHIQ_SLOT_SIZE) ||
++ (slot_zero->max_slots != VCHIQ_MAX_SLOTS) ||
++ (slot_zero->max_slots_per_side != VCHIQ_MAX_SLOTS_PER_SIDE)) {
++ vchiq_loud_error_header();
++ if (slot_zero->slot_zero_size != sizeof(VCHIQ_SLOT_ZERO_T))
++ vchiq_loud_error("slot_zero=%x: slot_zero_size=%x "
++ "(expected %x)",
++ (unsigned int)slot_zero,
++ slot_zero->slot_zero_size,
++ sizeof(VCHIQ_SLOT_ZERO_T));
++ if (slot_zero->slot_size != VCHIQ_SLOT_SIZE)
++ vchiq_loud_error("slot_zero=%x: slot_size=%d "
++ "(expected %d",
++ (unsigned int)slot_zero, slot_zero->slot_size,
++ VCHIQ_SLOT_SIZE);
++ if (slot_zero->max_slots != VCHIQ_MAX_SLOTS)
++ vchiq_loud_error("slot_zero=%x: max_slots=%d "
++ "(expected %d)",
++ (unsigned int)slot_zero, slot_zero->max_slots,
++ VCHIQ_MAX_SLOTS);
++ if (slot_zero->max_slots_per_side != VCHIQ_MAX_SLOTS_PER_SIDE)
++ vchiq_loud_error("slot_zero=%x: max_slots_per_side=%d "
++ "(expected %d)",
++ (unsigned int)slot_zero,
++ slot_zero->max_slots_per_side,
++ VCHIQ_MAX_SLOTS_PER_SIDE);
++ vchiq_loud_error_footer();
++ return VCHIQ_ERROR;
++ }
++
++ if (is_master) {
++ local = &slot_zero->master;
++ remote = &slot_zero->slave;
++ } else {
++ local = &slot_zero->slave;
++ remote = &slot_zero->master;
++ }
++
++ if (local->initialised) {
++ vchiq_loud_error_header();
++ if (remote->initialised)
++ vchiq_loud_error("local state has already been "
++ "initialised");
++ else
++ vchiq_loud_error("master/slave mismatch - two %ss",
++ is_master ? "master" : "slave");
++ vchiq_loud_error_footer();
++ return VCHIQ_ERROR;
++ }
++
++ memset(state, 0, sizeof(VCHIQ_STATE_T));
++
++ state->id = id++;
++ state->is_master = is_master;
++
++ /*
++ initialize shared state pointers
++ */
++
++ state->local = local;
++ state->remote = remote;
++ state->slot_data = (VCHIQ_SLOT_T *)slot_zero;
++
++ /*
++ initialize events and mutexes
++ */
++
++ sema_init(&state->connect, 0);
++ mutex_init(&state->mutex);
++ sema_init(&state->trigger_event, 0);
++ sema_init(&state->recycle_event, 0);
++ sema_init(&state->sync_trigger_event, 0);
++ sema_init(&state->sync_release_event, 0);
++
++ mutex_init(&state->slot_mutex);
++ mutex_init(&state->recycle_mutex);
++ mutex_init(&state->sync_mutex);
++ mutex_init(&state->bulk_transfer_mutex);
++
++ sema_init(&state->slot_available_event, 0);
++ sema_init(&state->slot_remove_event, 0);
++ sema_init(&state->data_quota_event, 0);
++
++ state->slot_queue_available = 0;
++
++ for (i = 0; i < VCHIQ_MAX_SERVICES; i++) {
++ VCHIQ_SERVICE_QUOTA_T *service_quota =
++ &state->service_quotas[i];
++ sema_init(&service_quota->quota_event, 0);
++ }
++
++ for (i = local->slot_first; i <= local->slot_last; i++) {
++ local->slot_queue[state->slot_queue_available++] = i;
++ up(&state->slot_available_event);
++ }
++
++ state->default_slot_quota = state->slot_queue_available/2;
++ state->default_message_quota =
++ min((unsigned short)(state->default_slot_quota * 256),
++ (unsigned short)~0);
++
++ state->previous_data_index = -1;
++ state->data_use_count = 0;
++ state->data_quota = state->slot_queue_available - 1;
++
++ local->trigger.event = &state->trigger_event;
++ remote_event_create(&local->trigger);
++ local->tx_pos = 0;
++
++ local->recycle.event = &state->recycle_event;
++ remote_event_create(&local->recycle);
++ local->slot_queue_recycle = state->slot_queue_available;
++
++ local->sync_trigger.event = &state->sync_trigger_event;
++ remote_event_create(&local->sync_trigger);
++
++ local->sync_release.event = &state->sync_release_event;
++ remote_event_create(&local->sync_release);
++
++ /* At start-of-day, the slot is empty and available */
++ ((VCHIQ_HEADER_T *)SLOT_DATA_FROM_INDEX(state, local->slot_sync))->msgid
++ = VCHIQ_MSGID_PADDING;
++ remote_event_signal_local(&local->sync_release);
++
++ local->debug[DEBUG_ENTRIES] = DEBUG_MAX;
++
++ status = vchiq_platform_init_state(state);
++
++ /*
++ bring up slot handler thread
++ */
++ snprintf(threadname, sizeof(threadname), "VCHIQ-%d", state->id);
++ state->slot_handler_thread = kthread_create(&slot_handler_func,
++ (void *)state,
++ threadname);
++
++ if (state->slot_handler_thread == NULL) {
++ vchiq_loud_error_header();
++ vchiq_loud_error("couldn't create thread %s", threadname);
++ vchiq_loud_error_footer();
++ return VCHIQ_ERROR;
++ }
++ set_user_nice(state->slot_handler_thread, -19);
++ wake_up_process(state->slot_handler_thread);
++
++ snprintf(threadname, sizeof(threadname), "VCHIQr-%d", state->id);
++ state->recycle_thread = kthread_create(&recycle_func,
++ (void *)state,
++ threadname);
++ if (state->recycle_thread == NULL) {
++ vchiq_loud_error_header();
++ vchiq_loud_error("couldn't create thread %s", threadname);
++ vchiq_loud_error_footer();
++ return VCHIQ_ERROR;
++ }
++ set_user_nice(state->recycle_thread, -19);
++ wake_up_process(state->recycle_thread);
++
++ snprintf(threadname, sizeof(threadname), "VCHIQs-%d", state->id);
++ state->sync_thread = kthread_create(&sync_func,
++ (void *)state,
++ threadname);
++ if (state->sync_thread == NULL) {
++ vchiq_loud_error_header();
++ vchiq_loud_error("couldn't create thread %s", threadname);
++ vchiq_loud_error_footer();
++ return VCHIQ_ERROR;
++ }
++ set_user_nice(state->sync_thread, -20);
++ wake_up_process(state->sync_thread);
++
++ BUG_ON(state->id >= VCHIQ_MAX_STATES);
++ vchiq_states[state->id] = state;
++
++ /* Indicate readiness to the other side */
++ local->initialised = 1;
++
++ return status;
+ }
+
+ /* Called from application thread when a client or server service is created. */
+ VCHIQ_SERVICE_T *
+ vchiq_add_service_internal(VCHIQ_STATE_T *state,
+- const VCHIQ_SERVICE_PARAMS_T *params, int srvstate,
+- VCHIQ_INSTANCE_T instance)
+-{
+- VCHIQ_SERVICE_T **pservice = NULL;
+- VCHIQ_SERVICE_T *service = NULL;
+- int i;
+-
+- /* Prepare to use a previously unused service */
+- if (state->unused_service < VCHIQ_MAX_SERVICES)
+- {
+- pservice = &state->services[state->unused_service];
+- }
+-
+- if (srvstate == VCHIQ_SRVSTATE_OPENING) {
+- for (i = 0; i < state->unused_service; i++) {
+- VCHIQ_SERVICE_T *srv = state->services[i];
+- if (!srv)
+- {
+- pservice = &state->services[i];
+- break;
+- }
+- if (srv->srvstate == VCHIQ_SRVSTATE_FREE) {
+- service = srv;
+- break;
+- }
+- }
+- } else {
+- for (i = (state->unused_service - 1); i >= 0; i--) {
+- VCHIQ_SERVICE_T *srv = state->services[i];
+- if (!srv)
+- pservice = &state->services[i];
+- else if (srv->srvstate == VCHIQ_SRVSTATE_FREE) {
+- service = srv;
+- } else if ((srv->public_fourcc == params->fourcc) &&
+- ((srv->instance != instance)
+- || (srv->base.callback != params->callback))) {
+- /* There is another server using this fourcc which doesn't match */
+- pservice = NULL;
+- service = NULL;
+- }
+- }
+- }
+-
+- if (pservice && !service)
+- {
+- service = vcos_malloc(sizeof(VCHIQ_SERVICE_T), "VCHIQ service");
+- if (service)
+- {
+- service->srvstate = VCHIQ_SRVSTATE_FREE;
+- service->localport = (pservice - state->services);
+- vcos_event_create(&service->remove_event, "v.remove_event");
+- vcos_event_create(&service->bulk_remove_event, "v.bulk_remove_event");
+- vcos_mutex_create(&service->bulk_mutex, "v.bulk_mutex");
+- *pservice = service;
+- }
+- else
+- {
+- vcos_log_error("vchiq: Out of memory");
+- }
+- }
+-
+- if (service) {
+- VCHIQ_SERVICE_QUOTA_T *service_quota =
+- &state->service_quotas[service->localport];
+- if (vcos_is_log_enabled( &vchiq_core_msg_log_category, VCOS_LOG_INFO)) {
+- vcos_log_impl( &vchiq_core_msg_log_category,
+- VCOS_LOG_INFO,
+- "%s Service %c%c%c%c SrcPort:%d",
+- ( srvstate == VCHIQ_SRVSTATE_OPENING )
+- ? "Open" : "Add",
+- VCHIQ_FOURCC_AS_4CHARS(params->fourcc),
+- service->localport );
+- }
+- service->state = state;
+- service->base.fourcc = params->fourcc;
+- service->base.callback = params->callback;
+- service->base.userdata = params->userdata;
+- service->version = params->version;
+- service->version_min = params->version_min;
+- vchiq_set_service_state(service, srvstate);
+- service->public_fourcc =
+- (srvstate ==
+- VCHIQ_SRVSTATE_OPENING) ? VCHIQ_FOURCC_INVALID : params->fourcc;
+- service->instance = instance;
+- service->remoteport = VCHIQ_PORT_FREE;
+- service->client_id = 0;
+- service->auto_close = 1;
+- service->service_use_count = 0;
+- init_bulk_queue(&service->bulk_tx);
+- init_bulk_queue(&service->bulk_rx);
+- service_quota->slot_quota = state->default_slot_quota;
+- service_quota->message_quota = state->default_message_quota;
+- if (service_quota->slot_use_count == 0)
+- service_quota->previous_tx_index =
+- SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos) - 1;
+- memset(&service->stats, 0, sizeof(service->stats));
+- vcos_atomic_flags_create(&service->poll_flags);
+-
+- /* Ensure the events are unsignalled */
+- while (vcos_event_try(&service->remove_event) == VCOS_SUCCESS)
+- continue;
+- while (vcos_event_try(&service_quota->quota_event) == VCOS_SUCCESS)
+- continue;
+-
+- if (pservice == &state->services[state->unused_service])
+- state->unused_service++;
+- }
+-
+- return service;
++ const VCHIQ_SERVICE_PARAMS_T *params, int srvstate,
++ VCHIQ_INSTANCE_T instance)
++{
++ VCHIQ_SERVICE_T *service;
++
++ service = kmalloc(sizeof(VCHIQ_SERVICE_T), GFP_KERNEL);
++ if (service) {
++ service->base.fourcc = params->fourcc;
++ service->base.callback = params->callback;
++ service->base.userdata = params->userdata;
++ service->handle = VCHIQ_SERVICE_HANDLE_INVALID;
++ service->ref_count = 1;
++ service->srvstate = VCHIQ_SRVSTATE_FREE;
++ service->localport = VCHIQ_PORT_FREE;
++ service->remoteport = VCHIQ_PORT_FREE;
++
++ service->public_fourcc = (srvstate == VCHIQ_SRVSTATE_OPENING) ?
++ VCHIQ_FOURCC_INVALID : params->fourcc;
++ service->client_id = 0;
++ service->auto_close = 1;
++ service->sync = 0;
++ service->closing = 0;
++ atomic_set(&service->poll_flags, 0);
++ service->version = params->version;
++ service->version_min = params->version_min;
++ service->state = state;
++ service->instance = instance;
++ service->service_use_count = 0;
++ init_bulk_queue(&service->bulk_tx);
++ init_bulk_queue(&service->bulk_rx);
++ sema_init(&service->remove_event, 0);
++ sema_init(&service->bulk_remove_event, 0);
++ mutex_init(&service->bulk_mutex);
++ memset(&service->stats, 0, sizeof(service->stats));
++ } else {
++ vchiq_log_error(vchiq_core_log_level,
++ "Out of memory");
++ }
++
++ if (service) {
++ VCHIQ_SERVICE_T **pservice = NULL;
++ int i;
++
++ /* Although it is perfectly possible to use service_spinlock
++ ** to protect the creation of services, it is overkill as it
++ ** disables interrupts while the array is searched.
++ ** The only danger is of another thread trying to create a
++ ** service - service deletion is safe.
++ ** Therefore it is preferable to use state->mutex which,
++ ** although slower to claim, doesn't block interrupts while
++ ** it is held.
++ */
++
++ mutex_lock(&state->mutex);
++
++ /* Prepare to use a previously unused service */
++ if (state->unused_service < VCHIQ_MAX_SERVICES)
++ pservice = &state->services[state->unused_service];
++
++ if (srvstate == VCHIQ_SRVSTATE_OPENING) {
++ for (i = 0; i < state->unused_service; i++) {
++ VCHIQ_SERVICE_T *srv = state->services[i];
++ if (!srv) {
++ pservice = &state->services[i];
++ break;
++ }
++ }
++ } else {
++ for (i = (state->unused_service - 1); i >= 0; i--) {
++ VCHIQ_SERVICE_T *srv = state->services[i];
++ if (!srv)
++ pservice = &state->services[i];
++ else if ((srv->public_fourcc == params->fourcc)
++ && ((srv->instance != instance) ||
++ (srv->base.callback !=
++ params->callback))) {
++ /* There is another server using this
++ ** fourcc which doesn't match. */
++ pservice = NULL;
++ break;
++ }
++ }
++ }
++
++ if (pservice) {
++ service->localport = (pservice - state->services);
++ if (!handle_seq)
++ handle_seq = VCHIQ_MAX_STATES *
++ VCHIQ_MAX_SERVICES;
++ service->handle = handle_seq |
++ (state->id * VCHIQ_MAX_SERVICES) |
++ service->localport;
++ handle_seq += VCHIQ_MAX_STATES * VCHIQ_MAX_SERVICES;
++ *pservice = service;
++ if (pservice == &state->services[state->unused_service])
++ state->unused_service++;
++ }
++
++ mutex_unlock(&state->mutex);
++
++ if (!pservice) {
++ kfree(service);
++ service = NULL;
++ }
++ }
++
++ if (service) {
++ VCHIQ_SERVICE_QUOTA_T *service_quota =
++ &state->service_quotas[service->localport];
++ service_quota->slot_quota = state->default_slot_quota;
++ service_quota->message_quota = state->default_message_quota;
++ if (service_quota->slot_use_count == 0)
++ service_quota->previous_tx_index =
++ SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos)
++ - 1;
++
++ /* Bring this service online */
++ vchiq_set_service_state(service, srvstate);
++
++ vchiq_log_info(vchiq_core_msg_log_level,
++ "%s Service %c%c%c%c SrcPort:%d",
++ (srvstate == VCHIQ_SRVSTATE_OPENING)
++ ? "Open" : "Add",
++ VCHIQ_FOURCC_AS_4CHARS(params->fourcc),
++ service->localport);
++ }
++
++ /* Don't unlock the service - leave it with a ref_count of 1. */
++
++ return service;
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_open_service_internal(VCHIQ_SERVICE_T *service, int client_id)
+ {
+- VCHIQ_OPEN_PAYLOAD_T payload = {
+- service->base.fourcc,
+- client_id,
+- service->version,
+- service->version_min
+- };
+- VCHIQ_ELEMENT_T body = { &payload, sizeof(payload) };
+- VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+-
+- service->client_id = client_id;
+- vchiq_use_service(&service->base);
+- status = queue_message(service->state, NULL,
+- VCHIQ_MAKE_MSG(VCHIQ_MSG_OPEN, service->localport, 0),
+- &body, 1, sizeof(payload), 1);
+- if (status == VCHIQ_SUCCESS) {
+- if (vcos_event_wait(&service->remove_event) != VCOS_SUCCESS) {
+- status = VCHIQ_RETRY;
+- vchiq_release_service(&service->base);
+- } else if (service->srvstate != VCHIQ_SRVSTATE_OPEN) {
+- vcos_log_info("%d: osi - srvstate = %d", service->state->id, service->srvstate);
+- vcos_assert(service->srvstate == VCHIQ_SRVSTATE_CLOSEWAIT);
+- status = VCHIQ_ERROR;
+- VCHIQ_SERVICE_STATS_INC(service, error_count);
+- vchiq_release_service(&service->base);
+- }
+- }
+- return status;
++ struct vchiq_open_payload payload = {
++ service->base.fourcc,
++ client_id,
++ service->version,
++ service->version_min
++ };
++ VCHIQ_ELEMENT_T body = { &payload, sizeof(payload) };
++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
++
++ service->client_id = client_id;
++ vchiq_use_service_internal(service);
++ status = queue_message(service->state, NULL,
++ VCHIQ_MAKE_MSG(VCHIQ_MSG_OPEN, service->localport, 0),
++ &body, 1, sizeof(payload), 1);
++ if (status == VCHIQ_SUCCESS) {
++ if (down_interruptible(&service->remove_event) != 0) {
++ status = VCHIQ_RETRY;
++ vchiq_release_service_internal(service);
++ } else if ((service->srvstate != VCHIQ_SRVSTATE_OPEN) &&
++ (service->srvstate != VCHIQ_SRVSTATE_OPENSYNC)) {
++ if (service->srvstate != VCHIQ_SRVSTATE_CLOSEWAIT)
++ vchiq_log_error(vchiq_core_log_level,
++ "%d: osi - srvstate = %s (ref %d)",
++ service->state->id,
++ srvstate_names[service->srvstate],
++ service->ref_count);
++ status = VCHIQ_ERROR;
++ VCHIQ_SERVICE_STATS_INC(service, error_count);
++ vchiq_release_service_internal(service);
++ }
++ }
++ return status;
++}
++
++static void
++release_service_messages(VCHIQ_SERVICE_T *service)
++{
++ VCHIQ_STATE_T *state = service->state;
++ int slot_last = state->remote->slot_last;
++ int i;
++
++ /* Release any claimed messages */
++ for (i = state->remote->slot_first; i <= slot_last; i++) {
++ VCHIQ_SLOT_INFO_T *slot_info =
++ SLOT_INFO_FROM_INDEX(state, i);
++ if (slot_info->release_count != slot_info->use_count) {
++ char *data =
++ (char *)SLOT_DATA_FROM_INDEX(state, i);
++ unsigned int pos, end;
++
++ end = VCHIQ_SLOT_SIZE;
++ if (data == state->rx_data)
++ /* This buffer is still being read from - stop
++ ** at the current read position */
++ end = state->rx_pos & VCHIQ_SLOT_MASK;
++
++ pos = 0;
++
++ while (pos < end) {
++ VCHIQ_HEADER_T *header =
++ (VCHIQ_HEADER_T *)(data + pos);
++ int msgid = header->msgid;
++ int port = VCHIQ_MSG_DSTPORT(msgid);
++ if ((port == service->localport) &&
++ (msgid & VCHIQ_MSGID_CLAIMED)) {
++ vchiq_log_info(vchiq_core_log_level,
++ " fsi - hdr %x",
++ (unsigned int)header);
++ release_slot(state, slot_info, header,
++ NULL);
++ }
++ pos += calc_stride(header->size);
++ if (pos > VCHIQ_SLOT_SIZE) {
++ vchiq_log_error(vchiq_core_log_level,
++ "fsi - pos %x: header %x, "
++ "msgid %x, header->msgid %x, "
++ "header->size %x",
++ pos, (unsigned int)header,
++ msgid, header->msgid,
++ header->size);
++ WARN(1, "invalid slot position\n");
++ }
++ }
++ }
++ }
++}
++
++static int
++do_abort_bulks(VCHIQ_SERVICE_T *service)
++{
++ VCHIQ_STATUS_T status;
++
++ /* Abort any outstanding bulk transfers */
++ if (mutex_lock_interruptible(&service->bulk_mutex) != 0)
++ return 0;
++ abort_outstanding_bulks(service, &service->bulk_tx);
++ abort_outstanding_bulks(service, &service->bulk_rx);
++ mutex_unlock(&service->bulk_mutex);
++
++ status = notify_bulks(service, &service->bulk_tx, 0/*!retry_poll*/);
++ if (status == VCHIQ_SUCCESS)
++ status = notify_bulks(service, &service->bulk_rx,
++ 0/*!retry_poll*/);
++ return (status == VCHIQ_SUCCESS);
++}
++
++static VCHIQ_STATUS_T
++close_service_complete(VCHIQ_SERVICE_T *service, int failstate)
++{
++ VCHIQ_STATUS_T status;
++ int is_server = (service->public_fourcc != VCHIQ_FOURCC_INVALID);
++ int newstate;
++
++ switch (service->srvstate) {
++ case VCHIQ_SRVSTATE_OPEN:
++ case VCHIQ_SRVSTATE_CLOSESENT:
++ case VCHIQ_SRVSTATE_CLOSERECVD:
++ if (is_server)
++ newstate = (service->auto_close ?
++ VCHIQ_SRVSTATE_LISTENING :
++ VCHIQ_SRVSTATE_CLOSEWAIT);
++ else
++ newstate = VCHIQ_SRVSTATE_CLOSED;
++ vchiq_set_service_state(service, newstate);
++ break;
++ default:
++ break;
++ }
++
++ status = make_service_callback(service,
++ VCHIQ_SERVICE_CLOSED, NULL, NULL);
++
++ if (status != VCHIQ_RETRY) {
++ int uc = service->service_use_count;
++ int i;
++ /* Complete the close process */
++ for (i = 0; i < uc; i++)
++ /* cater for cases where close is forced and the
++ ** client may not close all it's handles */
++ vchiq_release_service_internal(service);
++
++ service->client_id = 0;
++ if (status == VCHIQ_ERROR)
++ /* Signal an error (fatal, since the other end
++ ** will probably have closed) */
++ vchiq_set_service_state(service, VCHIQ_SRVSTATE_OPEN);
++
++ if (service->srvstate == VCHIQ_SRVSTATE_CLOSED)
++ vchiq_free_service_internal(service);
++ else {
++ if (is_server)
++ service->closing = 0;
++
++ up(&service->remove_event);
++ }
++ } else
++ vchiq_set_service_state(service, failstate);
++
++ return status;
+ }
+
+ /* Called by the slot handler */
+ VCHIQ_STATUS_T
+ vchiq_close_service_internal(VCHIQ_SERVICE_T *service, int close_recvd)
+ {
+- VCHIQ_STATE_T *state = service->state;
+- VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+-
+- vcos_log_trace("%d: csi:%d (%s)",
+- service->state->id, service->localport,
+- srvstate_names[service->srvstate]);
+-
+- switch (service->srvstate)
+- {
+- case VCHIQ_SRVSTATE_OPENING:
+- if (close_recvd)
+- {
+- /* The open was rejected - tell the user */
+- vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSEWAIT);
+- vcos_event_signal(&service->remove_event);
+- }
+- else
+- {
+- /* Shutdown mid-open - let the other side know */
+- status = queue_message(state, NULL,
+- VCHIQ_MAKE_MSG
+- (VCHIQ_MSG_CLOSE,
+- service->localport,
+- VCHIQ_MSG_DSTPORT(service->remoteport)),
+- NULL, 0, 0, 0);
+-
+- if (status == VCHIQ_SUCCESS)
+- vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSESENT);
+- }
+- break;
+-
+- case VCHIQ_SRVSTATE_OPEN:
+- if (state->is_master)
+- {
+- /* Abort any outstanding bulk transfers */
+- vcos_mutex_lock(&service->bulk_mutex);
+- abort_outstanding_bulks(service, &service->bulk_tx);
+- abort_outstanding_bulks(service, &service->bulk_rx);
+- status = notify_bulks(service, &service->bulk_tx);
+- if (status == VCHIQ_SUCCESS)
+- status = notify_bulks(service, &service->bulk_rx);
+- vcos_mutex_unlock(&service->bulk_mutex);
+- }
+-
+- if (status == VCHIQ_SUCCESS)
+- status = queue_message(state, NULL,
+- VCHIQ_MAKE_MSG
+- (VCHIQ_MSG_CLOSE,
+- service->localport,
+- VCHIQ_MSG_DSTPORT(service->remoteport)),
+- NULL, 0, 0, 0);
+-
+- if (status == VCHIQ_SUCCESS)
+- {
+- if (close_recvd)
+- vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSING);
+- else
+- vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSESENT);
+- }
+- break;
+-
+- case VCHIQ_SRVSTATE_CLOSESENT:
+- vcos_assert(close_recvd);
+-
+- if (!state->is_master)
+- {
+- /* Abort any outstanding bulk transfers */
+- vcos_mutex_lock(&service->bulk_mutex);
+- abort_outstanding_bulks(service, &service->bulk_tx);
+- abort_outstanding_bulks(service, &service->bulk_rx);
+- status = notify_bulks(service, &service->bulk_tx);
+- if (status == VCHIQ_SUCCESS)
+- status = notify_bulks(service, &service->bulk_rx);
+- vcos_mutex_unlock(&service->bulk_mutex);
+- }
+-
+- if (status == VCHIQ_SUCCESS)
+- vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSING);
+- break;
+-
+- case VCHIQ_SRVSTATE_CLOSING:
+- /* We may come here after a retry */
+- vcos_assert(!close_recvd);
+- break;
+-
+- default:
+- vcos_log_error("vchiq_close_service_internal(%d) called in state %s",
+- close_recvd, srvstate_names[service->srvstate]);
+- vcos_assert(0);
+- break;
+- }
+-
+- if (service->srvstate == VCHIQ_SRVSTATE_CLOSING)
+- {
+- int i;
+- int uc = service->service_use_count;
+- /* Complete the close process */
+- for( i=0; i<uc; i++)
+- { /* cater for cases where close is forced and the client may not close all it's handles */
+- vchiq_release_service_internal(service);
+- }
+- service->client_id = 0;
+-
+- /* Now tell the client that the services is closed */
+- if (service->instance)
+- {
+- int oldstate = service->srvstate;
+-
+- /* Change the service state now for the benefit of the callback */
+- vchiq_set_service_state(service,
+- ((service->public_fourcc == VCHIQ_FOURCC_INVALID) ||
+- !service->auto_close) ?
+- VCHIQ_SRVSTATE_CLOSEWAIT :
+- VCHIQ_SRVSTATE_LISTENING);
+-
+- status = make_service_callback(service, VCHIQ_SERVICE_CLOSED, NULL, NULL);
+-
+- if (status == VCHIQ_RETRY)
+- {
+- /* Restore the old state, to be retried later */
+- vchiq_set_service_state(service, oldstate);
+- }
+- else
+- {
+- if (status == VCHIQ_ERROR) {
+- /* Signal an error (fatal, since the other end will probably have closed) */
+- vchiq_set_service_state(service, VCHIQ_SRVSTATE_OPEN);
+- }
+- }
+- }
+-
+- if (status != VCHIQ_RETRY)
+- {
+- if (service->srvstate == VCHIQ_SRVSTATE_CLOSING)
+- vchiq_set_service_state(service, VCHIQ_SRVSTATE_CLOSEWAIT);
+- vcos_event_signal(&service->remove_event);
+- }
+- }
+-
+- return status;
++ VCHIQ_STATE_T *state = service->state;
++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
++
++ vchiq_log_info(vchiq_core_log_level, "%d: csi:%d,%d (%s)",
++ service->state->id, service->localport, close_recvd,
++ srvstate_names[service->srvstate]);
++
++ switch (service->srvstate) {
++ case VCHIQ_SRVSTATE_CLOSED:
++ case VCHIQ_SRVSTATE_HIDDEN:
++ case VCHIQ_SRVSTATE_LISTENING:
++ case VCHIQ_SRVSTATE_CLOSEWAIT:
++ if (close_recvd)
++ vchiq_log_error(vchiq_core_log_level,
++ "vchiq_close_service_internal(1) called "
++ "in state %s",
++ srvstate_names[service->srvstate]);
++ else
++ vchiq_free_service_internal(service);
++ break;
++ case VCHIQ_SRVSTATE_OPENING:
++ if (close_recvd) {
++ /* The open was rejected - tell the user */
++ vchiq_set_service_state(service,
++ VCHIQ_SRVSTATE_CLOSEWAIT);
++ up(&service->remove_event);
++ } else {
++ /* Shutdown mid-open - let the other side know */
++ status = queue_message(state, service,
++ VCHIQ_MAKE_MSG
++ (VCHIQ_MSG_CLOSE,
++ service->localport,
++ VCHIQ_MSG_DSTPORT(service->remoteport)),
++ NULL, 0, 0, 0);
++ }
++ break;
++
++ case VCHIQ_SRVSTATE_OPENSYNC:
++ mutex_lock(&state->sync_mutex);
++ /* Drop through */
++
++ case VCHIQ_SRVSTATE_OPEN:
++ if (state->is_master || close_recvd) {
++ if (!do_abort_bulks(service))
++ status = VCHIQ_RETRY;
++ }
++
++ release_service_messages(service);
++
++ if (status == VCHIQ_SUCCESS)
++ status = queue_message(state, service,
++ VCHIQ_MAKE_MSG
++ (VCHIQ_MSG_CLOSE,
++ service->localport,
++ VCHIQ_MSG_DSTPORT(service->remoteport)),
++ NULL, 0, 0, 0);
++
++ if (status == VCHIQ_SUCCESS) {
++ if (!close_recvd)
++ break;
++ } else if (service->srvstate == VCHIQ_SRVSTATE_OPENSYNC) {
++ mutex_unlock(&state->sync_mutex);
++ break;
++ } else
++ break;
++
++ status = close_service_complete(service,
++ VCHIQ_SRVSTATE_CLOSERECVD);
++ break;
++
++ case VCHIQ_SRVSTATE_CLOSESENT:
++ if (!close_recvd)
++ /* This happens when a process is killed mid-close */
++ break;
++
++ if (!state->is_master) {
++ if (!do_abort_bulks(service)) {
++ status = VCHIQ_RETRY;
++ break;
++ }
++ }
++
++ if (status == VCHIQ_SUCCESS)
++ status = close_service_complete(service,
++ VCHIQ_SRVSTATE_CLOSERECVD);
++ break;
++
++ case VCHIQ_SRVSTATE_CLOSERECVD:
++ if (!close_recvd &&
++ (service->public_fourcc != VCHIQ_FOURCC_INVALID))
++ /* Force into LISTENING mode */
++ vchiq_set_service_state(service,
++ VCHIQ_SRVSTATE_LISTENING);
++ status = close_service_complete(service,
++ VCHIQ_SRVSTATE_CLOSERECVD);
++ break;
++
++ default:
++ vchiq_log_error(vchiq_core_log_level,
++ "vchiq_close_service_internal(%d) called in state %s",
++ close_recvd, srvstate_names[service->srvstate]);
++ break;
++ }
++
++ return status;
+ }
+
+ /* Called from the application process upon process death */
+ void
+ vchiq_terminate_service_internal(VCHIQ_SERVICE_T *service)
+ {
+- VCHIQ_STATE_T *state = service->state;
++ VCHIQ_STATE_T *state = service->state;
+
+- vcos_log_info("%d: tsi - (%d<->%d)", state->id, service->localport, service->remoteport);
++ vchiq_log_info(vchiq_core_log_level, "%d: tsi - (%d<->%d)",
++ state->id, service->localport, service->remoteport);
+
+- /* Disconnect from the instance, to prevent any callbacks */
+- service->instance = NULL;
++ /* Make it look like a client, because it must be removed and not
++ left in the LISTENING state. */
++ service->public_fourcc = VCHIQ_FOURCC_INVALID;
+
+- /* Mark the service for termination by the slot handler */
+- request_poll(state, service, VCHIQ_POLL_TERMINATE);
++ mark_service_closing(service);
++
++ /* Mark the service for termination by the slot handler */
++ request_poll(state, service, VCHIQ_POLL_TERMINATE);
+ }
+
+-/* Called from the application process upon process death, and from
+- vchiq_remove_service */
++/* Called from the slot handler */
+ void
+ vchiq_free_service_internal(VCHIQ_SERVICE_T *service)
+ {
+- VCHIQ_STATE_T *state = service->state;
+- int slot_last = state->remote->slot_last;
+- int i;
+-
+- vcos_log_info("%d: fsi - (%d)", state->id, service->localport);
+-
+- vcos_mutex_lock(&state->mutex);
+-
+- /* Release any claimed messages */
+- for (i = state->remote->slot_first; i <= slot_last; i++)
+- {
+- VCHIQ_SLOT_INFO_T *slot_info = SLOT_INFO_FROM_INDEX(state, i);
+- if (slot_info->release_count != slot_info->use_count)
+- {
+- char *data = (char *)SLOT_DATA_FROM_INDEX(state, i);
+- unsigned int pos, end;
+-
+- end = VCHIQ_SLOT_SIZE;
+- if (data == state->rx_data)
+- {
+- /* This buffer is still being read from - stop at the current read position */
+- end = state->rx_pos & VCHIQ_SLOT_MASK;
+- }
+-
+- pos = 0;
+-
+- while (pos < end)
+- {
+- VCHIQ_HEADER_T *header = (VCHIQ_HEADER_T *)(data + pos);
+- int msgid = header->msgid;
+- int port = VCHIQ_MSG_DSTPORT(msgid);
+- if (port == service->localport)
+- {
+- if (msgid & VCHIQ_MSGID_CLAIMED)
+- {
+- header->msgid = msgid & ~VCHIQ_MSGID_CLAIMED;
+- vcos_log_info(" fsi - hdr %x", (unsigned int)header);
+- release_slot(state, slot_info);
+- }
+- }
+- pos += calc_stride(header->size);
+- if (pos > VCHIQ_SLOT_SIZE)
+- {
+- vcos_log_error("fsi - pos %x: header %x, msgid %x, header->msgid %x, header->size %x",
+- pos, (unsigned int)header, msgid, header->msgid, header->size);
+- vcos_assert(0);
+- }
+- }
+- }
+- }
+-
+- vcos_assert(state->services[service->localport] == service);
+- vchiq_set_service_state(service, VCHIQ_SRVSTATE_FREE);
+- state->services[service->localport] = NULL;
+- vcos_free(service);
+- vcos_mutex_unlock(&state->mutex);
+-}
++ VCHIQ_STATE_T *state = service->state;
+
+-VCHIQ_STATUS_T
+-vchiq_connect_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance)
+-{
+- int i;
++ vchiq_log_info(vchiq_core_log_level, "%d: fsi - (%d)",
++ state->id, service->localport);
+
+- /* Find all services registered to this client and enable them. */
+- for (i = 0; i < state->unused_service; i++)
+- {
+- VCHIQ_SERVICE_T *service = state->services[i];
+- if (service && (service->instance == instance)) {
+- if (service->srvstate == VCHIQ_SRVSTATE_HIDDEN)
+- vchiq_set_service_state(service,
+- VCHIQ_SRVSTATE_LISTENING);
+- }
+- }
++ switch (service->srvstate) {
++ case VCHIQ_SRVSTATE_OPENING:
++ case VCHIQ_SRVSTATE_CLOSED:
++ case VCHIQ_SRVSTATE_HIDDEN:
++ case VCHIQ_SRVSTATE_LISTENING:
++ case VCHIQ_SRVSTATE_CLOSEWAIT:
++ break;
++ default:
++ vchiq_log_error(vchiq_core_log_level,
++ "%d: fsi - (%d) in state %s",
++ state->id, service->localport,
++ srvstate_names[service->srvstate]);
++ return;
++ }
+
+- if (state->conn_state == VCHIQ_CONNSTATE_DISCONNECTED) {
+- if (queue_message(state, NULL,
+- VCHIQ_MAKE_MSG(VCHIQ_MSG_CONNECT, 0, 0), NULL, 0,
+- 0, 1) == VCHIQ_RETRY)
+- return VCHIQ_RETRY;
+- vcos_event_wait(&state->connect);
++ vchiq_set_service_state(service, VCHIQ_SRVSTATE_FREE);
+
+- vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED);
+- }
++ up(&service->remove_event);
++
++ /* Release the initial lock */
++ unlock_service(service);
++}
+
+- return VCHIQ_SUCCESS;
++VCHIQ_STATUS_T
++vchiq_connect_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance)
++{
++ VCHIQ_SERVICE_T *service;
++ int i;
++
++ /* Find all services registered to this client and enable them. */
++ i = 0;
++ while ((service = next_service_by_instance(state, instance,
++ &i)) != NULL) {
++ if (service->srvstate == VCHIQ_SRVSTATE_HIDDEN)
++ vchiq_set_service_state(service,
++ VCHIQ_SRVSTATE_LISTENING);
++ unlock_service(service);
++ }
++
++ if (state->conn_state == VCHIQ_CONNSTATE_DISCONNECTED) {
++ if (queue_message(state, NULL,
++ VCHIQ_MAKE_MSG(VCHIQ_MSG_CONNECT, 0, 0), NULL, 0,
++ 0, 1) == VCHIQ_RETRY)
++ return VCHIQ_RETRY;
++
++ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTING);
++ }
++
++ if (state->conn_state == VCHIQ_CONNSTATE_CONNECTING) {
++ if (down_interruptible(&state->connect) != 0)
++ return VCHIQ_RETRY;
++
++ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_CONNECTED);
++ up(&state->connect);
++ }
++
++ return VCHIQ_SUCCESS;
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_shutdown_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance)
+ {
+- VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+- int i;
++ VCHIQ_SERVICE_T *service;
++ int i;
+
+- /* Find all services registered to this client and close them. */
+- for (i = 0; i < state->unused_service; i++)
+- {
+- VCHIQ_SERVICE_T *service = state->services[i];
+- if (service && (service->instance == instance) &&
+- ((service->srvstate == VCHIQ_SRVSTATE_OPEN) ||
+- (service->srvstate == VCHIQ_SRVSTATE_LISTENING)))
+- {
+- status = vchiq_remove_service(&service->base);
+- if (status != VCHIQ_SUCCESS)
+- break;
+- }
+- }
++ /* Find all services registered to this client and enable them. */
++ i = 0;
++ while ((service = next_service_by_instance(state, instance,
++ &i)) != NULL) {
++ (void)vchiq_remove_service(service->handle);
++ unlock_service(service);
++ }
+
+- return status;
++ return VCHIQ_SUCCESS;
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_pause_internal(VCHIQ_STATE_T *state)
+ {
+- VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+-
+- switch (state->conn_state)
+- {
+- case VCHIQ_CONNSTATE_CONNECTED:
+- /* Request a pause */
+- vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSING);
+- request_poll(state, NULL, 0);
+- break;
+- case VCHIQ_CONNSTATE_PAUSED:
+- break;
+- default:
+- status = VCHIQ_ERROR;
+- VCHIQ_STATS_INC(state, error_count);
+- break;
+- }
+-
+- return status;
++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
++
++ switch (state->conn_state) {
++ case VCHIQ_CONNSTATE_CONNECTED:
++ /* Request a pause */
++ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_PAUSING);
++ request_poll(state, NULL, 0);
++ break;
++ default:
++ vchiq_log_error(vchiq_core_log_level,
++ "vchiq_pause_internal in state %s\n",
++ conn_state_names[state->conn_state]);
++ status = VCHIQ_ERROR;
++ VCHIQ_STATS_INC(state, error_count);
++ break;
++ }
++
++ return status;
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_resume_internal(VCHIQ_STATE_T *state)
+ {
+- VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+
+- if (state->conn_state == VCHIQ_CONNSTATE_PAUSED)
+- {
+- vchiq_set_conn_state(state, VCHIQ_CONNSTATE_RESUMING);
+- request_poll(state, NULL, 0);
+- }
+- else
+- {
+- status = VCHIQ_ERROR;
+- VCHIQ_STATS_INC(state, error_count);
+- }
++ if (state->conn_state == VCHIQ_CONNSTATE_PAUSED) {
++ vchiq_set_conn_state(state, VCHIQ_CONNSTATE_RESUMING);
++ request_poll(state, NULL, 0);
++ } else {
++ status = VCHIQ_ERROR;
++ VCHIQ_STATS_INC(state, error_count);
++ }
+
+- return status;
++ return status;
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_close_service(VCHIQ_SERVICE_HANDLE_T handle)
+ {
+- /* Unregister the service */
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *) handle;
+- VCHIQ_STATUS_T status = VCHIQ_ERROR;
++ /* Unregister the service */
++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
++ VCHIQ_STATUS_T status = VCHIQ_ERROR;
+
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
++ if (!service)
++ return VCHIQ_ERROR;
+
+- vcos_log_info("%d: close_service:%d", service->state->id, service->localport);
++ vchiq_log_info(vchiq_core_log_level,
++ "%d: close_service:%d",
++ service->state->id, service->localport);
+
+- if (service->public_fourcc != VCHIQ_FOURCC_INVALID)
+- {
+- if (service->srvstate == VCHIQ_SRVSTATE_CLOSEWAIT)
+- {
+- /* This is a non-auto-close server */
+- vchiq_set_service_state(service, VCHIQ_SRVSTATE_LISTENING);
+- status = VCHIQ_SUCCESS;
+- }
+- }
+- else
+- {
+- /* For clients, make it an alias of vchiq_remove_service */
+- status = vchiq_remove_service(handle);
+- }
++ mark_service_closing(service);
+
+- return status;
++ /* Mark the service for termination by the slot handler */
++ request_poll(service->state, service, VCHIQ_POLL_TERMINATE);
++
++ while (1) {
++ if (down_interruptible(&service->remove_event) != 0) {
++ status = VCHIQ_RETRY;
++ break;
++ }
++
++ if ((service->srvstate == VCHIQ_SRVSTATE_FREE) ||
++ (service->srvstate == VCHIQ_SRVSTATE_LISTENING) ||
++ (service->srvstate == VCHIQ_SRVSTATE_OPEN))
++ break;
++
++ vchiq_log_warning(vchiq_core_log_level,
++ "%d: close_service:%d - waiting in state %s",
++ service->state->id, service->localport,
++ srvstate_names[service->srvstate]);
++ }
++
++ if ((status == VCHIQ_SUCCESS) &&
++ (service->srvstate != VCHIQ_SRVSTATE_FREE) &&
++ (service->srvstate != VCHIQ_SRVSTATE_LISTENING))
++ status = VCHIQ_ERROR;
++
++ unlock_service(service);
++
++ return status;
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_remove_service(VCHIQ_SERVICE_HANDLE_T handle)
+ {
+- /* Unregister the service */
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *) handle;
+- VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- vcos_log_info("%d: remove_service:%d", service->state->id, service->localport);
+-
+- switch (service->srvstate)
+- {
+- case VCHIQ_SRVSTATE_OPENING:
+- case VCHIQ_SRVSTATE_OPEN:
+- /* Mark the service for termination by the slot handler */
+- request_poll(service->state, service, VCHIQ_POLL_TERMINATE);
+-
+- /* Drop through... */
+- case VCHIQ_SRVSTATE_CLOSESENT:
+- case VCHIQ_SRVSTATE_CLOSING:
+- while ((service->srvstate != VCHIQ_SRVSTATE_CLOSEWAIT) &&
+- (service->srvstate != VCHIQ_SRVSTATE_LISTENING))
+- {
+- if (vcos_event_wait(&service->remove_event) != VCOS_SUCCESS) {
+- status = VCHIQ_RETRY;
+- break;
+- }
+- }
+- break;
+-
+- default:
+- break;
+- }
+-
+- if (status == VCHIQ_SUCCESS) {
+- if (service->srvstate == VCHIQ_SRVSTATE_OPEN)
+- status = VCHIQ_ERROR;
+- else
+- {
+- service->instance = NULL;
+- vchiq_free_service_internal(service);
+- }
+- }
+-
+- return status;
++ /* Unregister the service */
++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
++
++ if (!service)
++ return VCHIQ_ERROR;
++
++ vchiq_log_info(vchiq_core_log_level,
++ "%d: remove_service:%d",
++ service->state->id, service->localport);
++
++ /* Make it look like a client, because it must be removed and not
++ left in the LISTENING state. */
++ service->public_fourcc = VCHIQ_FOURCC_INVALID;
++
++ mark_service_closing(service);
++
++ /* Mark the service for termination by the slot handler */
++ request_poll(service->state, service, VCHIQ_POLL_TERMINATE);
++
++ while (1) {
++ if (down_interruptible(&service->remove_event) != 0) {
++ status = VCHIQ_RETRY;
++ break;
++ }
++
++ if ((service->srvstate == VCHIQ_SRVSTATE_FREE) ||
++ (service->srvstate == VCHIQ_SRVSTATE_OPEN))
++ break;
++
++ vchiq_log_warning(vchiq_core_log_level,
++ "%d: remove_service:%d - waiting in state %s",
++ service->state->id, service->localport,
++ srvstate_names[service->srvstate]);
++ }
++
++ if ((status == VCHIQ_SUCCESS) &&
++ (service->srvstate != VCHIQ_SRVSTATE_FREE))
++ status = VCHIQ_ERROR;
++
++ unlock_service(service);
++
++ return status;
+ }
+
+
++/* This function may be called by kernel threads or user threads.
++ * User threads may receive VCHIQ_RETRY to indicate that a signal has been
++ * received and the call should be retried after being returned to user
++ * context.
++ * When called in blocking mode, the userdata field points to a bulk_waiter
++ * structure.
++ */
+ VCHIQ_STATUS_T
+-vchiq_bulk_transfer(VCHIQ_SERVICE_T *service,
+- VCHI_MEM_HANDLE_T memhandle, void *offset, int size, void *userdata,
+- VCHIQ_BULK_MODE_T mode, VCHIQ_BULK_DIR_T dir)
+-{
+- VCHIQ_BULK_QUEUE_T *queue = (dir == VCHIQ_BULK_TRANSMIT) ?
+- &service->bulk_tx : &service->bulk_rx;
+- VCHIQ_BULK_T *bulk;
+- VCHIQ_STATE_T *state;
+- BULK_WAITER_T bulk_waiter;
+- const char dir_char = (dir == VCHIQ_BULK_TRANSMIT) ? 't' : 'r';
+- const int dir_msgtype = (dir == VCHIQ_BULK_TRANSMIT) ? VCHIQ_MSG_BULK_TX : VCHIQ_MSG_BULK_RX;
+- VCHIQ_STATUS_T status = VCHIQ_ERROR;
+-
+- if (!is_valid_service(service) ||
+- (service->srvstate != VCHIQ_SRVSTATE_OPEN) ||
+- ((memhandle == VCHI_MEM_HANDLE_INVALID) && (offset == NULL)) ||
+- (vchiq_check_service(service) != VCHIQ_SUCCESS))
+- return VCHIQ_ERROR;
+-
+- state = service->state;
+-
+- if (vcos_mutex_lock(&service->bulk_mutex) != VCOS_SUCCESS)
+- return VCHIQ_RETRY;
+-
+- if (queue->local_insert == queue->remove + VCHIQ_NUM_SERVICE_BULKS)
+- {
+- VCHIQ_SERVICE_STATS_INC(service, bulk_stalls);
+- do {
+- vcos_mutex_unlock(&service->bulk_mutex);
+- if (vcos_event_wait(&service->bulk_remove_event) != VCOS_SUCCESS)
+- return VCHIQ_RETRY;
+- if (vcos_mutex_lock(&service->bulk_mutex) != VCOS_SUCCESS)
+- return VCHIQ_RETRY;
+- } while (queue->local_insert == queue->remove + VCHIQ_NUM_SERVICE_BULKS);
+- }
+-
+- bulk = &queue->bulks[BULK_INDEX(queue->local_insert)];
+-
+- if (mode == VCHIQ_BULK_MODE_BLOCKING)
+- {
+- vcos_event_create(&bulk_waiter.event, "bulk_waiter");
+- bulk_waiter.actual = 0;
+- userdata = &bulk_waiter;
+- }
+-
+- bulk->mode = mode;
+- bulk->dir = dir;
+- bulk->userdata = userdata;
+- bulk->size = size;
+- bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED;
+-
+- if (vchiq_prepare_bulk_data(bulk, memhandle, offset, size, dir) != VCHIQ_SUCCESS)
+- {
+- goto error_exit;
+- }
+-
+- vcos_log_info("%d: bt (%d->%d) %cx %x@%x %x", state->id,
+- service->localport, service->remoteport, dir_char,
+- size, (unsigned int)bulk->data, (unsigned int)userdata);
+-
+- if (state->is_master)
+- {
+- queue->local_insert++;
+- if (resolve_bulks(service, queue))
+- request_poll(state, service, (dir == VCHIQ_BULK_TRANSMIT) ?
+- VCHIQ_POLL_TXNOTIFY : VCHIQ_POLL_RXNOTIFY);
+- }
+- else
+- {
+- int payload[2] = { (int)bulk->data, bulk->size };
+- VCHIQ_ELEMENT_T element = { payload, sizeof(payload) };
+-
+- if (queue_message(state, NULL,
+- VCHIQ_MAKE_MSG(dir_msgtype,
+- service->localport, service->remoteport),
+- &element, 1, sizeof(payload), 1) != VCHIQ_SUCCESS)
+- {
+- vchiq_complete_bulk(bulk);
+- goto error_exit;
+- }
+- queue->local_insert++;
+- queue->remote_insert++;
+- }
+-
+- vcos_mutex_unlock(&service->bulk_mutex);
+-
+- vcos_log_trace("%d: bt:%d %cx li=%x ri=%x p=%x", state->id,
+- service->localport, dir_char,
+- queue->local_insert, queue->remote_insert, queue->process);
+-
+- status = VCHIQ_SUCCESS;
+-
+- if (mode == VCHIQ_BULK_MODE_BLOCKING)
+- {
+- if (vcos_event_wait(&bulk_waiter.event) != VCOS_SUCCESS)
+- {
+- vcos_log_info("bulk wait interrupted");
+- /* Stop notify_bulks signalling a non-existent waiter */
+- bulk->userdata = NULL;
+- status = VCHIQ_ERROR;
+- }
+- else if (bulk_waiter.actual == VCHIQ_BULK_ACTUAL_ABORTED)
+- status = VCHIQ_ERROR;
+-
+- vcos_event_delete(&bulk_waiter.event);
+- }
+-
+- return status;
++vchiq_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle,
++ VCHI_MEM_HANDLE_T memhandle, void *offset, int size, void *userdata,
++ VCHIQ_BULK_MODE_T mode, VCHIQ_BULK_DIR_T dir)
++{
++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
++ VCHIQ_BULK_QUEUE_T *queue;
++ VCHIQ_BULK_T *bulk;
++ VCHIQ_STATE_T *state;
++ struct bulk_waiter *bulk_waiter = NULL;
++ const char dir_char = (dir == VCHIQ_BULK_TRANSMIT) ? 't' : 'r';
++ const int dir_msgtype = (dir == VCHIQ_BULK_TRANSMIT) ?
++ VCHIQ_MSG_BULK_TX : VCHIQ_MSG_BULK_RX;
++ VCHIQ_STATUS_T status = VCHIQ_ERROR;
++
++ if (!service ||
++ (service->srvstate != VCHIQ_SRVSTATE_OPEN) ||
++ ((memhandle == VCHI_MEM_HANDLE_INVALID) && (offset == NULL)) ||
++ (vchiq_check_service(service) != VCHIQ_SUCCESS))
++ goto error_exit;
++
++ switch (mode) {
++ case VCHIQ_BULK_MODE_NOCALLBACK:
++ case VCHIQ_BULK_MODE_CALLBACK:
++ break;
++ case VCHIQ_BULK_MODE_BLOCKING:
++ bulk_waiter = (struct bulk_waiter *)userdata;
++ sema_init(&bulk_waiter->event, 0);
++ bulk_waiter->actual = 0;
++ bulk_waiter->bulk = NULL;
++ break;
++ case VCHIQ_BULK_MODE_WAITING:
++ bulk_waiter = (struct bulk_waiter *)userdata;
++ bulk = bulk_waiter->bulk;
++ goto waiting;
++ default:
++ goto error_exit;
++ }
++
++ state = service->state;
++
++ queue = (dir == VCHIQ_BULK_TRANSMIT) ?
++ &service->bulk_tx : &service->bulk_rx;
++
++ if (mutex_lock_interruptible(&service->bulk_mutex) != 0) {
++ status = VCHIQ_RETRY;
++ goto error_exit;
++ }
++
++ if (queue->local_insert == queue->remove + VCHIQ_NUM_SERVICE_BULKS) {
++ VCHIQ_SERVICE_STATS_INC(service, bulk_stalls);
++ do {
++ mutex_unlock(&service->bulk_mutex);
++ if (down_interruptible(&service->bulk_remove_event)
++ != 0) {
++ status = VCHIQ_RETRY;
++ goto error_exit;
++ }
++ if (mutex_lock_interruptible(&service->bulk_mutex)
++ != 0) {
++ status = VCHIQ_RETRY;
++ goto error_exit;
++ }
++ } while (queue->local_insert == queue->remove +
++ VCHIQ_NUM_SERVICE_BULKS);
++ }
++
++ bulk = &queue->bulks[BULK_INDEX(queue->local_insert)];
++
++ bulk->mode = mode;
++ bulk->dir = dir;
++ bulk->userdata = userdata;
++ bulk->size = size;
++ bulk->actual = VCHIQ_BULK_ACTUAL_ABORTED;
++
++ if (vchiq_prepare_bulk_data(bulk, memhandle, offset, size, dir) !=
++ VCHIQ_SUCCESS)
++ goto unlock_error_exit;
++
++ wmb();
++
++ vchiq_log_info(vchiq_core_log_level,
++ "%d: bt (%d->%d) %cx %x@%x %x",
++ state->id,
++ service->localport, service->remoteport, dir_char,
++ size, (unsigned int)bulk->data, (unsigned int)userdata);
++
++ if (state->is_master) {
++ queue->local_insert++;
++ if (resolve_bulks(service, queue))
++ request_poll(state, service,
++ (dir == VCHIQ_BULK_TRANSMIT) ?
++ VCHIQ_POLL_TXNOTIFY : VCHIQ_POLL_RXNOTIFY);
++ } else {
++ int payload[2] = { (int)bulk->data, bulk->size };
++ VCHIQ_ELEMENT_T element = { payload, sizeof(payload) };
++
++ status = queue_message(state, NULL,
++ VCHIQ_MAKE_MSG(dir_msgtype,
++ service->localport, service->remoteport),
++ &element, 1, sizeof(payload), 1);
++ if (status != VCHIQ_SUCCESS) {
++ vchiq_complete_bulk(bulk);
++ goto unlock_error_exit;
++ }
++ queue->local_insert++;
++ }
++
++ mutex_unlock(&service->bulk_mutex);
++
++ vchiq_log_trace(vchiq_core_log_level,
++ "%d: bt:%d %cx li=%x ri=%x p=%x",
++ state->id,
++ service->localport, dir_char,
++ queue->local_insert, queue->remote_insert, queue->process);
++
++waiting:
++ unlock_service(service);
++
++ status = VCHIQ_SUCCESS;
++
++ if (bulk_waiter) {
++ bulk_waiter->bulk = bulk;
++ if (down_interruptible(&bulk_waiter->event) != 0)
++ status = VCHIQ_RETRY;
++ else if (bulk_waiter->actual == VCHIQ_BULK_ACTUAL_ABORTED)
++ status = VCHIQ_ERROR;
++ }
++
++ return status;
++
++unlock_error_exit:
++ mutex_unlock(&service->bulk_mutex);
+
+ error_exit:
+- if (mode == VCHIQ_BULK_MODE_BLOCKING)
+- vcos_event_delete(&bulk_waiter.event);
+- vcos_mutex_unlock(&service->bulk_mutex);
+-
+- return status;
++ if (service)
++ unlock_service(service);
++ return status;
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_queue_bulk_transmit(VCHIQ_SERVICE_HANDLE_T handle,
+- const void *data, int size, void *userdata)
++ const void *data, int size, void *userdata)
+ {
+- return vchiq_bulk_transfer((VCHIQ_SERVICE_T *)handle,
+- VCHI_MEM_HANDLE_INVALID, (void *)data, size, userdata,
+- VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_TRANSMIT);
++ return vchiq_bulk_transfer(handle,
++ VCHI_MEM_HANDLE_INVALID, (void *)data, size, userdata,
++ VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_TRANSMIT);
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_queue_bulk_receive(VCHIQ_SERVICE_HANDLE_T handle, void *data, int size,
+- void *userdata)
++ void *userdata)
+ {
+- return vchiq_bulk_transfer((VCHIQ_SERVICE_T *)handle,
+- VCHI_MEM_HANDLE_INVALID, data, size, userdata,
+- VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_RECEIVE);
++ return vchiq_bulk_transfer(handle,
++ VCHI_MEM_HANDLE_INVALID, data, size, userdata,
++ VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_RECEIVE);
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_queue_bulk_transmit_handle(VCHIQ_SERVICE_HANDLE_T handle,
+- VCHI_MEM_HANDLE_T memhandle, const void *offset, int size, void *userdata)
++ VCHI_MEM_HANDLE_T memhandle, const void *offset, int size,
++ void *userdata)
+ {
+- return vchiq_bulk_transfer((VCHIQ_SERVICE_T *)handle,
+- memhandle, (void *)offset, size, userdata,
+- VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_TRANSMIT);
++ return vchiq_bulk_transfer(handle,
++ memhandle, (void *)offset, size, userdata,
++ VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_TRANSMIT);
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_queue_bulk_receive_handle(VCHIQ_SERVICE_HANDLE_T handle,
+- VCHI_MEM_HANDLE_T memhandle, void *offset, int size, void *userdata)
++ VCHI_MEM_HANDLE_T memhandle, void *offset, int size,
++ void *userdata)
+ {
+- return vchiq_bulk_transfer((VCHIQ_SERVICE_T *)handle,
+- memhandle, offset, size, userdata,
+- VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_RECEIVE);
++ return vchiq_bulk_transfer(handle,
++ memhandle, offset, size, userdata,
++ VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_RECEIVE);
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_bulk_transmit(VCHIQ_SERVICE_HANDLE_T handle, const void *data, int size,
+- void *userdata, VCHIQ_BULK_MODE_T mode)
+-{
+- return vchiq_bulk_transfer((VCHIQ_SERVICE_T *)handle,
+- VCHI_MEM_HANDLE_INVALID, (void *)data, size, userdata,
+- mode, VCHIQ_BULK_TRANSMIT);
++ void *userdata, VCHIQ_BULK_MODE_T mode)
++{
++ struct bulk_waiter bulk_waiter;
++ VCHIQ_STATUS_T status;
++
++ switch (mode) {
++ case VCHIQ_BULK_MODE_NOCALLBACK:
++ case VCHIQ_BULK_MODE_CALLBACK:
++ break;
++ case VCHIQ_BULK_MODE_BLOCKING:
++ userdata = &bulk_waiter;
++ break;
++ default:
++ return VCHIQ_ERROR;
++ }
++
++ status = vchiq_bulk_transfer(handle,
++ VCHI_MEM_HANDLE_INVALID, (void *)data, size, userdata,
++ mode, VCHIQ_BULK_TRANSMIT);
++
++ /* This call is for kernel thread use and should not be interrupted */
++ BUG_ON(status == VCHIQ_RETRY);
++ return status;
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_bulk_receive(VCHIQ_SERVICE_HANDLE_T handle, void *data, int size,
+- void *userdata, VCHIQ_BULK_MODE_T mode)
+-{
+- return vchiq_bulk_transfer((VCHIQ_SERVICE_T *)handle,
+- VCHI_MEM_HANDLE_INVALID, data, size, userdata,
+- mode, VCHIQ_BULK_RECEIVE);
++ void *userdata, VCHIQ_BULK_MODE_T mode)
++{
++ struct bulk_waiter bulk_waiter;
++ VCHIQ_STATUS_T status;
++
++ switch (mode) {
++ case VCHIQ_BULK_MODE_NOCALLBACK:
++ case VCHIQ_BULK_MODE_CALLBACK:
++ break;
++ case VCHIQ_BULK_MODE_BLOCKING:
++ userdata = &bulk_waiter;
++ break;
++ default:
++ return VCHIQ_ERROR;
++ }
++
++ status = vchiq_bulk_transfer(handle,
++ VCHI_MEM_HANDLE_INVALID, data, size, userdata,
++ mode, VCHIQ_BULK_RECEIVE);
++
++ /* This call is for kernel thread use and should not be interrupted */
++ BUG_ON(status == VCHIQ_RETRY);
++ return status;
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_bulk_transmit_handle(VCHIQ_SERVICE_HANDLE_T handle,
+- VCHI_MEM_HANDLE_T memhandle, const void *offset, int size, void *userdata,
+- VCHIQ_BULK_MODE_T mode)
+-{
+- return vchiq_bulk_transfer((VCHIQ_SERVICE_T *)handle,
+- memhandle, (void *)offset, size, userdata,
+- mode, VCHIQ_BULK_TRANSMIT);
++ VCHI_MEM_HANDLE_T memhandle, const void *offset, int size,
++ void *userdata, VCHIQ_BULK_MODE_T mode)
++{
++ struct bulk_waiter bulk_waiter;
++ VCHIQ_STATUS_T status;
++
++ switch (mode) {
++ case VCHIQ_BULK_MODE_NOCALLBACK:
++ case VCHIQ_BULK_MODE_CALLBACK:
++ break;
++ case VCHIQ_BULK_MODE_BLOCKING:
++ userdata = &bulk_waiter;
++ break;
++ default:
++ return VCHIQ_ERROR;
++ }
++
++ status = vchiq_bulk_transfer(handle,
++ memhandle, (void *)offset, size, userdata,
++ mode, VCHIQ_BULK_TRANSMIT);
++
++ /* This call is for kernel thread use and should not be interrupted */
++ BUG_ON(status == VCHIQ_RETRY);
++ return status;
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_bulk_receive_handle(VCHIQ_SERVICE_HANDLE_T handle,
+- VCHI_MEM_HANDLE_T memhandle, void *offset, int size, void *userdata,
+- VCHIQ_BULK_MODE_T mode)
+-{
+- return vchiq_bulk_transfer((VCHIQ_SERVICE_T *)handle,
+- memhandle, offset, size, userdata,
+- mode, VCHIQ_BULK_RECEIVE);
++ VCHI_MEM_HANDLE_T memhandle, void *offset, int size, void *userdata,
++ VCHIQ_BULK_MODE_T mode)
++{
++ struct bulk_waiter bulk_waiter;
++ VCHIQ_STATUS_T status;
++
++ switch (mode) {
++ case VCHIQ_BULK_MODE_NOCALLBACK:
++ case VCHIQ_BULK_MODE_CALLBACK:
++ break;
++ case VCHIQ_BULK_MODE_BLOCKING:
++ userdata = &bulk_waiter;
++ break;
++ default:
++ return VCHIQ_ERROR;
++ }
++
++ status = vchiq_bulk_transfer(handle,
++ memhandle, offset, size, userdata,
++ mode, VCHIQ_BULK_RECEIVE);
++
++ /* This call is for kernel thread use and should not be interrupted */
++ BUG_ON(status == VCHIQ_RETRY);
++ return status;
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_queue_message(VCHIQ_SERVICE_HANDLE_T handle,
+- const VCHIQ_ELEMENT_T *elements, int count)
+-{
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *) handle;
+-
+- unsigned int size = 0;
+- unsigned int i;
+-
+- if (!is_valid_service(service) ||
+- (service->srvstate != VCHIQ_SRVSTATE_OPEN) ||
+- (vchiq_check_service(service) != VCHIQ_SUCCESS))
+- return VCHIQ_ERROR;
+-
+- for (i = 0; i < (unsigned int)count; i++)
+- {
+- if (elements[i].size)
+- {
+- if (elements[i].data == NULL)
+- {
+- VCHIQ_SERVICE_STATS_INC(service, error_count);
+- return VCHIQ_ERROR;
+- }
+- size += elements[i].size;
+- }
+- }
+-
+- if (size > VCHIQ_MAX_MSG_SIZE)
+- {
+- VCHIQ_SERVICE_STATS_INC(service, error_count);
+- return VCHIQ_ERROR;
+- }
+-
+- return queue_message(service->state, service,
+- VCHIQ_MAKE_MSG(VCHIQ_MSG_DATA, service->localport,
+- service->remoteport), elements, count, size, 1);
++ const VCHIQ_ELEMENT_T *elements, int count)
++{
++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
++ VCHIQ_STATUS_T status = VCHIQ_ERROR;
++
++ unsigned int size = 0;
++ unsigned int i;
++
++ if (!service ||
++ (vchiq_check_service(service) != VCHIQ_SUCCESS))
++ goto error_exit;
++
++ for (i = 0; i < (unsigned int)count; i++) {
++ if (elements[i].size) {
++ if (elements[i].data == NULL) {
++ VCHIQ_SERVICE_STATS_INC(service, error_count);
++ goto error_exit;
++ }
++ size += elements[i].size;
++ }
++ }
++
++ if (size > VCHIQ_MAX_MSG_SIZE) {
++ VCHIQ_SERVICE_STATS_INC(service, error_count);
++ goto error_exit;
++ }
++
++ switch (service->srvstate) {
++ case VCHIQ_SRVSTATE_OPEN:
++ status = queue_message(service->state, service,
++ VCHIQ_MAKE_MSG(VCHIQ_MSG_DATA,
++ service->localport,
++ service->remoteport),
++ elements, count, size, 1);
++ break;
++ case VCHIQ_SRVSTATE_OPENSYNC:
++ status = queue_message_sync(service->state, service,
++ VCHIQ_MAKE_MSG(VCHIQ_MSG_DATA,
++ service->localport,
++ service->remoteport),
++ elements, count, size, 1);
++ break;
++ default:
++ status = VCHIQ_ERROR;
++ break;
++ }
++
++error_exit:
++ if (service)
++ unlock_service(service);
++
++ return status;
+ }
+
+ void
+ vchiq_release_message(VCHIQ_SERVICE_HANDLE_T handle, VCHIQ_HEADER_T *header)
+ {
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle;
+- VCHIQ_STATE_T *state;
+- int slot_index;
+- int msgid;
++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
++ VCHIQ_SHARED_STATE_T *remote;
++ VCHIQ_STATE_T *state;
++ int slot_index;
+
+- if (!is_valid_service(service))
+- return;
++ if (!service)
++ return;
+
+- state = service->state;
++ state = service->state;
++ remote = state->remote;
+
+- slot_index = SLOT_INDEX_FROM_DATA(state, (void *)header);
++ slot_index = SLOT_INDEX_FROM_DATA(state, (void *)header);
+
+- if ((slot_index >= state->remote->slot_first) &&
+- (slot_index <= state->remote->slot_last) &&
+- ((msgid = header->msgid) & VCHIQ_MSGID_CLAIMED))
+- {
+- VCHIQ_SLOT_INFO_T *slot_info = SLOT_INFO_FROM_INDEX(state, slot_index);
++ if ((slot_index >= remote->slot_first) &&
++ (slot_index <= remote->slot_last)) {
++ int msgid = header->msgid;
++ if (msgid & VCHIQ_MSGID_CLAIMED) {
++ VCHIQ_SLOT_INFO_T *slot_info =
++ SLOT_INFO_FROM_INDEX(state, slot_index);
+
+- /* Rewrite the message header to prevent a double release */
+- header->msgid = msgid & ~VCHIQ_MSGID_CLAIMED;
++ release_slot(state, slot_info, header, service);
++ }
++ } else if (slot_index == remote->slot_sync)
++ release_message_sync(state, header);
+
+- release_slot(state, slot_info);
+- }
++ unlock_service(service);
+ }
+
+-int
+-vchiq_get_client_id(VCHIQ_SERVICE_HANDLE_T handle)
++static void
++release_message_sync(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header)
+ {
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle;
+- return service ? service->client_id : 0;
++ header->msgid = VCHIQ_MSGID_PADDING;
++ wmb();
++ remote_event_signal(&state->remote->sync_release);
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_get_config(VCHIQ_INSTANCE_T instance,
+- int config_size, VCHIQ_CONFIG_T *pconfig)
++ int config_size, VCHIQ_CONFIG_T *pconfig)
+ {
+- VCHIQ_CONFIG_T config;
++ VCHIQ_CONFIG_T config;
+
+- vcos_unused(instance);
++ (void)instance;
+
+- config.max_msg_size = VCHIQ_MAX_MSG_SIZE;
+- config.bulk_threshold = VCHIQ_MAX_MSG_SIZE;
+- config.max_outstanding_bulks = VCHIQ_NUM_SERVICE_BULKS;
+- config.max_services = VCHIQ_MAX_SERVICES;
+- config.version = VCHIQ_VERSION;
+- config.version_min = VCHIQ_VERSION_MIN;
++ config.max_msg_size = VCHIQ_MAX_MSG_SIZE;
++ config.bulk_threshold = VCHIQ_MAX_MSG_SIZE;
++ config.max_outstanding_bulks = VCHIQ_NUM_SERVICE_BULKS;
++ config.max_services = VCHIQ_MAX_SERVICES;
++ config.version = VCHIQ_VERSION;
++ config.version_min = VCHIQ_VERSION_MIN;
+
+- if (config_size > sizeof(VCHIQ_CONFIG_T))
+- return VCHIQ_ERROR;
++ if (config_size > sizeof(VCHIQ_CONFIG_T))
++ return VCHIQ_ERROR;
+
+- memcpy(pconfig, &config, vcos_min(config_size, sizeof(VCHIQ_CONFIG_T)));
++ memcpy(pconfig, &config,
++ min(config_size, (int)(sizeof(VCHIQ_CONFIG_T))));
+
+- return VCHIQ_SUCCESS;
++ return VCHIQ_SUCCESS;
+ }
+
+ VCHIQ_STATUS_T
+ vchiq_set_service_option(VCHIQ_SERVICE_HANDLE_T handle,
+- VCHIQ_SERVICE_OPTION_T option, int value)
+-{
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle;
+- VCHIQ_STATUS_T status = VCHIQ_ERROR;
+-
+- if (is_valid_service(service))
+- {
+- switch (option)
+- {
+- case VCHIQ_SERVICE_OPTION_AUTOCLOSE:
+- service->auto_close = value;
+- status = VCHIQ_SUCCESS;
+- break;
+-
+- case VCHIQ_SERVICE_OPTION_SLOT_QUOTA:
+- {
+- VCHIQ_SERVICE_QUOTA_T *service_quota =
+- &service->state->service_quotas[service->localport];
+- if (value == 0)
+- value = service->state->default_slot_quota;
+- if ((value >= service_quota->slot_use_count) &&
+- (value < (unsigned short)~0))
+- {
+- service_quota->slot_quota = value;
+- if ((value >= service_quota->slot_use_count) &&
+- (service_quota->message_quota >= service_quota->message_use_count))
+- {
+- /* Signal the service that it may have dropped below its quota */
+- vcos_event_signal(&service_quota->quota_event);
+- }
+- status = VCHIQ_SUCCESS;
+- }
+- }
+- break;
+-
+- case VCHIQ_SERVICE_OPTION_MESSAGE_QUOTA:
+- {
+- VCHIQ_SERVICE_QUOTA_T *service_quota =
+- &service->state->service_quotas[service->localport];
+- if (value == 0)
+- value = service->state->default_message_quota;
+- if ((value >= service_quota->message_use_count) &&
+- (value < (unsigned short)~0))
+- {
+- service_quota->message_quota = value;
+- if ((value >= service_quota->message_use_count) &&
+- (service_quota->slot_quota >= service_quota->slot_use_count))
+- {
+- /* Signal the service that it may have dropped below its quota */
+- vcos_event_signal(&service_quota->quota_event);
+- }
+- status = VCHIQ_SUCCESS;
+- }
+- }
+- break;
+-
+- default:
+- break;
+- }
+- }
+-
+- return status;
++ VCHIQ_SERVICE_OPTION_T option, int value)
++{
++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
++ VCHIQ_STATUS_T status = VCHIQ_ERROR;
++
++ if (service) {
++ switch (option) {
++ case VCHIQ_SERVICE_OPTION_AUTOCLOSE:
++ service->auto_close = value;
++ status = VCHIQ_SUCCESS;
++ break;
++
++ case VCHIQ_SERVICE_OPTION_SLOT_QUOTA: {
++ VCHIQ_SERVICE_QUOTA_T *service_quota =
++ &service->state->service_quotas[
++ service->localport];
++ if (value == 0)
++ value = service->state->default_slot_quota;
++ if ((value >= service_quota->slot_use_count) &&
++ (value < (unsigned short)~0)) {
++ service_quota->slot_quota = value;
++ if ((value >= service_quota->slot_use_count) &&
++ (service_quota->message_quota >=
++ service_quota->message_use_count)) {
++ /* Signal the service that it may have
++ ** dropped below its quota */
++ up(&service_quota->quota_event);
++ }
++ status = VCHIQ_SUCCESS;
++ }
++ } break;
++
++ case VCHIQ_SERVICE_OPTION_MESSAGE_QUOTA: {
++ VCHIQ_SERVICE_QUOTA_T *service_quota =
++ &service->state->service_quotas[
++ service->localport];
++ if (value == 0)
++ value = service->state->default_message_quota;
++ if ((value >= service_quota->message_use_count) &&
++ (value < (unsigned short)~0)) {
++ service_quota->message_quota = value;
++ if ((value >=
++ service_quota->message_use_count) &&
++ (service_quota->slot_quota >=
++ service_quota->slot_use_count))
++ /* Signal the service that it may have
++ ** dropped below its quota */
++ up(&service_quota->quota_event);
++ status = VCHIQ_SUCCESS;
++ }
++ } break;
++
++ case VCHIQ_SERVICE_OPTION_SYNCHRONOUS:
++ if ((service->srvstate == VCHIQ_SRVSTATE_HIDDEN) ||
++ (service->srvstate ==
++ VCHIQ_SRVSTATE_LISTENING)) {
++ service->sync = value;
++ status = VCHIQ_SUCCESS;
++ }
++ break;
++
++ default:
++ break;
++ }
++ unlock_service(service);
++ }
++
++ return status;
+ }
+
+ void
+ vchiq_dump_shared_state(void *dump_context, VCHIQ_STATE_T *state,
+- VCHIQ_SHARED_STATE_T *shared, const char *label)
+-{
+- static const char *const debug_names[] =
+- {
+- "<entries>",
+- "SLOT_HANDLER_COUNT",
+- "SLOT_HANDLER_LINE",
+- "PARSE_LINE",
+- "PARSE_HEADER",
+- "PARSE_MSGID",
+- "AWAIT_COMPLETION_LINE",
+- "DEQUEUE_MESSAGE_LINE",
+- "SERVICE_CALLBACK_LINE",
+- "MSG_QUEUE_FULL_COUNT",
+- "COMPLETION_QUEUE_FULL_COUNT"
+- };
+- int i;
+-
+- char buf[80];
+- int len;
+- len = vcos_snprintf(buf, sizeof(buf),
+- " %s: slots %d-%d tx_pos=%x recycle=%x",
+- label, shared->slot_first, shared->slot_last,
+- shared->tx_pos, shared->slot_queue_recycle);
+- vchiq_dump(dump_context, buf, len + 1);
+-
+- len = vcos_snprintf(buf, sizeof(buf),
+- " Slots claimed:");
+- vchiq_dump(dump_context, buf, len + 1);
+-
+- for (i = shared->slot_first; i <= shared->slot_last; i++)
+- {
+- VCHIQ_SLOT_INFO_T slot_info = *SLOT_INFO_FROM_INDEX(state, i);
+- if (slot_info.use_count != slot_info.release_count)
+- {
+- len = vcos_snprintf(buf, sizeof(buf),
+- " %d: %d/%d", i, slot_info.use_count, slot_info.release_count);
+- vchiq_dump(dump_context, buf, len + 1);
+- }
+- }
+-
+- for (i = 1; i < shared->debug[DEBUG_ENTRIES]; i++)
+- {
+- len = vcos_snprintf(buf, sizeof(buf), " DEBUG: %s = %d(%x)",
+- debug_names[i], shared->debug[i], shared->debug[i]);
+- vchiq_dump(dump_context, buf, len + 1);
+- }
++ VCHIQ_SHARED_STATE_T *shared, const char *label)
++{
++ static const char *const debug_names[] = {
++ "<entries>",
++ "SLOT_HANDLER_COUNT",
++ "SLOT_HANDLER_LINE",
++ "PARSE_LINE",
++ "PARSE_HEADER",
++ "PARSE_MSGID",
++ "AWAIT_COMPLETION_LINE",
++ "DEQUEUE_MESSAGE_LINE",
++ "SERVICE_CALLBACK_LINE",
++ "MSG_QUEUE_FULL_COUNT",
++ "COMPLETION_QUEUE_FULL_COUNT"
++ };
++ int i;
++
++ char buf[80];
++ int len;
++ len = snprintf(buf, sizeof(buf),
++ " %s: slots %d-%d tx_pos=%x recycle=%x",
++ label, shared->slot_first, shared->slot_last,
++ shared->tx_pos, shared->slot_queue_recycle);
++ vchiq_dump(dump_context, buf, len + 1);
++
++ len = snprintf(buf, sizeof(buf),
++ " Slots claimed:");
++ vchiq_dump(dump_context, buf, len + 1);
++
++ for (i = shared->slot_first; i <= shared->slot_last; i++) {
++ VCHIQ_SLOT_INFO_T slot_info = *SLOT_INFO_FROM_INDEX(state, i);
++ if (slot_info.use_count != slot_info.release_count) {
++ len = snprintf(buf, sizeof(buf),
++ " %d: %d/%d", i, slot_info.use_count,
++ slot_info.release_count);
++ vchiq_dump(dump_context, buf, len + 1);
++ }
++ }
++
++ for (i = 1; i < shared->debug[DEBUG_ENTRIES]; i++) {
++ len = snprintf(buf, sizeof(buf), " DEBUG: %s = %d(%x)",
++ debug_names[i], shared->debug[i], shared->debug[i]);
++ vchiq_dump(dump_context, buf, len + 1);
++ }
+ }
+
+ void
+ vchiq_dump_state(void *dump_context, VCHIQ_STATE_T *state)
+ {
+- char buf[80];
+- int len;
+- int i;
+-
+- len = vcos_snprintf(buf, sizeof(buf), "State %d: %s", state->id,
+- conn_state_names[state->conn_state]);
+- vchiq_dump(dump_context, buf, len + 1);
+-
+- len = vcos_snprintf(buf, sizeof(buf),
+- " tx_pos=%x(@%x), rx_pos=%x(@%x)",
+- state->id, state->local->tx_pos,
+- (uint32_t)state->tx_data + (state->local_tx_pos & VCHIQ_SLOT_MASK),
+- state->rx_pos,
+- (uint32_t)state->rx_data + (state->rx_pos & VCHIQ_SLOT_MASK));
+- vchiq_dump(dump_context, buf, len + 1);
+-
+- len = vcos_snprintf(buf, sizeof(buf),
+- " Version: %d (min %d)",
+- VCHIQ_VERSION, VCHIQ_VERSION_MIN);
+- vchiq_dump(dump_context, buf, len + 1);
++ char buf[80];
++ int len;
++ int i;
++
++ len = snprintf(buf, sizeof(buf), "State %d: %s", state->id,
++ conn_state_names[state->conn_state]);
++ vchiq_dump(dump_context, buf, len + 1);
++
++ len = snprintf(buf, sizeof(buf),
++ " tx_pos=%x(@%x), rx_pos=%x(@%x)",
++ state->local->tx_pos,
++ (uint32_t)state->tx_data +
++ (state->local_tx_pos & VCHIQ_SLOT_MASK),
++ state->rx_pos,
++ (uint32_t)state->rx_data +
++ (state->rx_pos & VCHIQ_SLOT_MASK));
++ vchiq_dump(dump_context, buf, len + 1);
++
++ len = snprintf(buf, sizeof(buf),
++ " Version: %d (min %d)",
++ VCHIQ_VERSION, VCHIQ_VERSION_MIN);
++ vchiq_dump(dump_context, buf, len + 1);
++
++ if (VCHIQ_ENABLE_STATS) {
++ len = snprintf(buf, sizeof(buf),
++ " Stats: ctrl_tx_count=%d, ctrl_rx_count=%d, "
++ "error_count=%d",
++ state->stats.ctrl_tx_count, state->stats.ctrl_rx_count,
++ state->stats.error_count);
++ vchiq_dump(dump_context, buf, len + 1);
++ }
++
++ len = snprintf(buf, sizeof(buf),
++ " Slots: %d available (%d data), %d recyclable, %d stalls (%d data)",
++ state->slot_queue_available -
++ SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos),
++ state->data_quota - state->data_use_count,
++ state->local->slot_queue_recycle - state->slot_queue_available,
++ state->stats.slot_stalls, state->stats.data_stalls);
++ vchiq_dump(dump_context, buf, len + 1);
++
++ vchiq_dump_platform_state(dump_context);
++
++ vchiq_dump_shared_state(dump_context, state, state->local, "Local");
++ vchiq_dump_shared_state(dump_context, state, state->remote, "Remote");
++
++ vchiq_dump_platform_instances(dump_context);
++
++ for (i = 0; i < state->unused_service; i++) {
++ VCHIQ_SERVICE_T *service = find_service_by_port(state, i);
++
++ if (service) {
++ vchiq_dump_service_state(dump_context, service);
++ unlock_service(service);
++ }
++ }
++}
+
+- if (VCHIQ_ENABLE_STATS)
+- {
+- len = vcos_snprintf(buf, sizeof(buf),
+- " Stats: ctrl_tx_count=%d, ctrl_rx_count=%d, error_count=%d",
+- state->stats.ctrl_tx_count, state->stats.ctrl_rx_count,
+- state->stats.slot_stalls);
+- vchiq_dump(dump_context, buf, len + 1);
+- }
++void
++vchiq_dump_service_state(void *dump_context, VCHIQ_SERVICE_T *service)
++{
++ char buf[80];
++ int len;
++
++ len = snprintf(buf, sizeof(buf), "Service %d: %s (ref %u)",
++ service->localport, srvstate_names[service->srvstate],
++ service->ref_count - 1); /*Don't include the lock just taken*/
++
++ if (service->srvstate != VCHIQ_SRVSTATE_FREE) {
++ char remoteport[30];
++ VCHIQ_SERVICE_QUOTA_T *service_quota =
++ &service->state->service_quotas[service->localport];
++ int fourcc = service->base.fourcc;
++ int tx_pending, rx_pending;
++ if (service->remoteport != VCHIQ_PORT_FREE) {
++ int len2 = snprintf(remoteport, sizeof(remoteport),
++ "%d", service->remoteport);
++ if (service->public_fourcc != VCHIQ_FOURCC_INVALID)
++ snprintf(remoteport + len2,
++ sizeof(remoteport) - len2,
++ " (client %x)", service->client_id);
++ } else
++ strcpy(remoteport, "n/a");
++
++ len += snprintf(buf + len, sizeof(buf) - len,
++ " '%c%c%c%c' remote %s (msg use %d/%d, slot use %d/%d)",
++ VCHIQ_FOURCC_AS_4CHARS(fourcc),
++ remoteport,
++ service_quota->message_use_count,
++ service_quota->message_quota,
++ service_quota->slot_use_count,
++ service_quota->slot_quota);
++
++ vchiq_dump(dump_context, buf, len + 1);
++
++ tx_pending = service->bulk_tx.local_insert -
++ service->bulk_tx.remote_insert;
++
++ rx_pending = service->bulk_rx.local_insert -
++ service->bulk_rx.remote_insert;
++
++ len = snprintf(buf, sizeof(buf),
++ " Bulk: tx_pending=%d (size %d),"
++ " rx_pending=%d (size %d)",
++ tx_pending,
++ tx_pending ? service->bulk_tx.bulks[
++ BULK_INDEX(service->bulk_tx.remove)].size : 0,
++ rx_pending,
++ rx_pending ? service->bulk_rx.bulks[
++ BULK_INDEX(service->bulk_rx.remove)].size : 0);
++
++ if (VCHIQ_ENABLE_STATS) {
++ vchiq_dump(dump_context, buf, len + 1);
++
++ len = snprintf(buf, sizeof(buf),
++ " Ctrl: tx_count=%d, tx_bytes=%llu, "
++ "rx_count=%d, rx_bytes=%llu",
++ service->stats.ctrl_tx_count,
++ service->stats.ctrl_tx_bytes,
++ service->stats.ctrl_rx_count,
++ service->stats.ctrl_rx_bytes);
++ vchiq_dump(dump_context, buf, len + 1);
++
++ len = snprintf(buf, sizeof(buf),
++ " Bulk: tx_count=%d, tx_bytes=%llu, "
++ "rx_count=%d, rx_bytes=%llu",
++ service->stats.bulk_tx_count,
++ service->stats.bulk_tx_bytes,
++ service->stats.bulk_rx_count,
++ service->stats.bulk_rx_bytes);
++ vchiq_dump(dump_context, buf, len + 1);
++
++ len = snprintf(buf, sizeof(buf),
++ " %d quota stalls, %d slot stalls, "
++ "%d bulk stalls, %d aborted, %d errors",
++ service->stats.quota_stalls,
++ service->stats.slot_stalls,
++ service->stats.bulk_stalls,
++ service->stats.bulk_aborted_count,
++ service->stats.error_count);
++ }
++ }
++
++ vchiq_dump(dump_context, buf, len + 1);
++
++ if (service->srvstate != VCHIQ_SRVSTATE_FREE)
++ vchiq_dump_platform_service_state(dump_context, service);
++}
+
+- len = vcos_snprintf(buf, sizeof(buf),
+- " Slots: %d available, %d recyclable, %d stalls",
+- state->slot_queue_available - SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos),
+- state->local->slot_queue_recycle - state->slot_queue_available,
+- state->stats.slot_stalls);
+- vchiq_dump(dump_context, buf, len + 1);
+
+- vchiq_dump_platform_state(dump_context);
++void
++vchiq_loud_error_header(void)
++{
++ vchiq_log_error(vchiq_core_log_level,
++ "============================================================"
++ "================");
++ vchiq_log_error(vchiq_core_log_level,
++ "============================================================"
++ "================");
++ vchiq_log_error(vchiq_core_log_level, "=====");
++}
+
+- vchiq_dump_shared_state(dump_context, state, state->local, "Local");
+- vchiq_dump_shared_state(dump_context, state, state->remote, "Remote");
++void
++vchiq_loud_error_footer(void)
++{
++ vchiq_log_error(vchiq_core_log_level, "=====");
++ vchiq_log_error(vchiq_core_log_level,
++ "============================================================"
++ "================");
++ vchiq_log_error(vchiq_core_log_level,
++ "============================================================"
++ "================");
++}
+
+- vchiq_dump_platform_instances(dump_context);
+
+- for (i = 0; i < state->unused_service; i++) {
+- VCHIQ_SERVICE_T *service = state->services[i];
++VCHIQ_STATUS_T vchiq_send_remote_use(VCHIQ_STATE_T *state)
++{
++ VCHIQ_STATUS_T status = VCHIQ_RETRY;
++ if (state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED)
++ status = queue_message(state, NULL,
++ VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE, 0, 0),
++ NULL, 0, 0, 0);
++ return status;
++}
+
+- if (service && (service->srvstate != VCHIQ_SRVSTATE_FREE))
+- vchiq_dump_service_state(dump_context, service);
+- }
++VCHIQ_STATUS_T vchiq_send_remote_release(VCHIQ_STATE_T *state)
++{
++ VCHIQ_STATUS_T status = VCHIQ_RETRY;
++ if (state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED)
++ status = queue_message(state, NULL,
++ VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_RELEASE, 0, 0),
++ NULL, 0, 0, 0);
++ return status;
+ }
+
+-void
+-vchiq_dump_service_state(void *dump_context, VCHIQ_SERVICE_T *service)
++VCHIQ_STATUS_T vchiq_send_remote_use_active(VCHIQ_STATE_T *state)
+ {
+- char buf[80];
+- int len;
+-
+- len = vcos_snprintf(buf, sizeof(buf), "Service %d: %s",
+- service->localport, srvstate_names[service->srvstate]);
+-
+- if (service->srvstate != VCHIQ_SRVSTATE_FREE)
+- {
+- char remoteport[30];
+- VCHIQ_SERVICE_QUOTA_T *service_quota =
+- &service->state->service_quotas[service->localport];
+- int fourcc = service->base.fourcc;
+- if (service->remoteport != VCHIQ_PORT_FREE)
+- {
+- int len2 = vcos_snprintf(remoteport, sizeof(remoteport), "%d",
+- service->remoteport);
+- if (service->public_fourcc != VCHIQ_FOURCC_INVALID)
+- vcos_snprintf(remoteport + len2, sizeof(remoteport) - len2,
+- " (client %x)", service->client_id);
+- }
+- else
+- vcos_strcpy(remoteport, "n/a");
+-
+- len += vcos_snprintf(buf + len, sizeof(buf) - len,
+- " '%c%c%c%c' remote %s (msg use %d/%d, slot use %d/%d)",
+- VCHIQ_FOURCC_AS_4CHARS(fourcc),
+- remoteport,
+- service_quota->message_use_count,
+- service_quota->message_quota,
+- service_quota->slot_use_count,
+- service_quota->slot_quota);
+-
+- if (VCHIQ_ENABLE_STATS)
+- {
+- vchiq_dump(dump_context, buf, len + 1);
+-
+- len = vcos_snprintf(buf, sizeof(buf),
+- " Ctrl: tx_count=%d, tx_bytes=%" PRIu64 ", rx_count=%d, rx_bytes=%" PRIu64,
+- service->stats.ctrl_tx_count, service->stats.ctrl_tx_bytes,
+- service->stats.ctrl_rx_count, service->stats.ctrl_rx_bytes);
+- vchiq_dump(dump_context, buf, len + 1);
+-
+- len = vcos_snprintf(buf, sizeof(buf),
+- " Bulk: tx_count=%d, tx_bytes=%" PRIu64 ", rx_count=%d, rx_bytes=%" PRIu64,
+- service->stats.bulk_tx_count, service->stats.bulk_tx_bytes,
+- service->stats.bulk_rx_count, service->stats.bulk_rx_bytes);
+- vchiq_dump(dump_context, buf, len + 1);
+-
+- len = vcos_snprintf(buf, sizeof(buf),
+- " %d quota stalls, %d slot stalls, %d bulk stalls, %d aborted, %d errors",
+- service->stats.quota_stalls, service->stats.slot_stalls,
+- service->stats.bulk_stalls, service->stats.bulk_aborted_count,
+- service->stats.error_count);
+- }
+- }
+-
+- vchiq_dump(dump_context, buf, len + 1);
+-
+- vchiq_dump_platform_service_state(dump_context, service);
+-}
+-
+-
+-VCHIQ_STATUS_T vchiq_send_remote_use(VCHIQ_STATE_T * state)
+-{
+- VCHIQ_STATUS_T status = VCHIQ_RETRY;
+- if(state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED)
+- {
+- status = queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE, 0, 0), NULL, 0, 0, 0);
+- }
+- return status;
+-}
+-
+-VCHIQ_STATUS_T vchiq_send_remote_release(VCHIQ_STATE_T * state)
+-{
+- VCHIQ_STATUS_T status = VCHIQ_RETRY;
+- if(state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED)
+- {
+- status = queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_RELEASE, 0, 0), NULL, 0, 0, 0);
+- }
+- return status;
+-}
+-
+-VCHIQ_STATUS_T vchiq_send_remote_use_active(VCHIQ_STATE_T * state)
+-{
+- VCHIQ_STATUS_T status = VCHIQ_RETRY;
+- if(state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED)
+- {
+- status = queue_message(state, NULL, VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE_ACTIVE, 0, 0), NULL, 0, 0, 0);
+- }
+- return status;
++ VCHIQ_STATUS_T status = VCHIQ_RETRY;
++ if (state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED)
++ status = queue_message(state, NULL,
++ VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE_ACTIVE, 0, 0),
++ NULL, 0, 0, 0);
++ return status;
++}
++
++void vchiq_log_dump_mem(const char *label, uint32_t addr, const void *voidMem,
++ size_t numBytes)
++{
++ const uint8_t *mem = (const uint8_t *)voidMem;
++ size_t offset;
++ char lineBuf[100];
++ char *s;
++
++ while (numBytes > 0) {
++ s = lineBuf;
++
++ for (offset = 0; offset < 16; offset++) {
++ if (offset < numBytes)
++ s += snprintf(s, 4, "%02x ", mem[offset]);
++ else
++ s += snprintf(s, 4, " ");
++ }
++
++ for (offset = 0; offset < 16; offset++) {
++ if (offset < numBytes) {
++ uint8_t ch = mem[offset];
++
++ if ((ch < ' ') || (ch > '~'))
++ ch = '.';
++ *s++ = (char)ch;
++ }
++ }
++ *s++ = '\0';
++
++ if ((label != NULL) && (*label != '\0'))
++ vchiq_log_trace(VCHIQ_LOG_TRACE,
++ "%s: %08x: %s", label, addr, lineBuf);
++ else
++ vchiq_log_trace(VCHIQ_LOG_TRACE,
++ "%08x: %s", addr, lineBuf);
++
++ addr += 16;
++ mem += 16;
++ if (numBytes > 16)
++ numBytes -= 16;
++ else
++ numBytes = 0;
++ }
+ }
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h
+index 37884bd..bcdff3a 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h
+@@ -19,58 +19,105 @@
+ #ifndef VCHIQ_CORE_H
+ #define VCHIQ_CORE_H
+
++#include <linux/mutex.h>
++#include <linux/semaphore.h>
++#include <linux/kthread.h>
++
+ #include "vchiq_cfg.h"
+
+ #include "vchiq.h"
+
++/* Run time control of log level, based on KERN_XXX level. */
++#define VCHIQ_LOG_DEFAULT 4
++#define VCHIQ_LOG_ERROR 3
++#define VCHIQ_LOG_WARNING 4
++#define VCHIQ_LOG_INFO 6
++#define VCHIQ_LOG_TRACE 7
++
++#define VCHIQ_LOG_PREFIX KERN_INFO "vchiq: "
++
++#ifndef vchiq_log_error
++#define vchiq_log_error(cat, fmt, ...) \
++ do { if (cat >= VCHIQ_LOG_ERROR) \
++ printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0)
++#endif
++#ifndef vchiq_log_warning
++#define vchiq_log_warning(cat, fmt, ...) \
++ do { if (cat >= VCHIQ_LOG_WARNING) \
++ printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0)
++#endif
++#ifndef vchiq_log_info
++#define vchiq_log_info(cat, fmt, ...) \
++ do { if (cat >= VCHIQ_LOG_INFO) \
++ printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0)
++#endif
++#ifndef vchiq_log_trace
++#define vchiq_log_trace(cat, fmt, ...) \
++ do { if (cat >= VCHIQ_LOG_TRACE) \
++ printk(VCHIQ_LOG_PREFIX fmt "\n", ##__VA_ARGS__); } while (0)
++#endif
++
++#define vchiq_loud_error(...) \
++ vchiq_log_error(vchiq_core_log_level, "===== " __VA_ARGS__)
++
++#ifndef vchiq_static_assert
++#define vchiq_static_assert(cond) __attribute__((unused)) \
++ extern int vchiq_static_assert[(cond) ? 1 : -1]
++#endif
++
+ #define IS_POW2(x) (x && ((x & (x - 1)) == 0))
+
+ /* Ensure that the slot size and maximum number of slots are powers of 2 */
+-vcos_static_assert(IS_POW2(VCHIQ_SLOT_SIZE));
+-vcos_static_assert(IS_POW2(VCHIQ_MAX_SLOTS));
+-vcos_static_assert(IS_POW2(VCHIQ_MAX_SLOTS_PER_SIDE));
++vchiq_static_assert(IS_POW2(VCHIQ_SLOT_SIZE));
++vchiq_static_assert(IS_POW2(VCHIQ_MAX_SLOTS));
++vchiq_static_assert(IS_POW2(VCHIQ_MAX_SLOTS_PER_SIDE));
+
+ #define VCHIQ_SLOT_MASK (VCHIQ_SLOT_SIZE - 1)
+ #define VCHIQ_SLOT_QUEUE_MASK (VCHIQ_MAX_SLOTS_PER_SIDE - 1)
+ #define VCHIQ_SLOT_ZERO_SLOTS ((sizeof(VCHIQ_SLOT_ZERO_T) + \
+- VCHIQ_SLOT_SIZE - 1) / VCHIQ_SLOT_SIZE)
+-
+-#define VCHIQ_MSG_PADDING 0 // -
+-#define VCHIQ_MSG_CONNECT 1 // -
+-#define VCHIQ_MSG_OPEN 2 // + (srcport, -), fourcc, client_id
+-#define VCHIQ_MSG_OPENACK 3 // + (srcport, dstport)
+-#define VCHIQ_MSG_CLOSE 4 // + (srcport, dstport)
+-#define VCHIQ_MSG_DATA 5 // + (srcport, dstport)
+-#define VCHIQ_MSG_BULK_RX 6 // + (srcport, dstport), data, size
+-#define VCHIQ_MSG_BULK_TX 7 // + (srcport, dstport), data, size
+-#define VCHIQ_MSG_BULK_RX_DONE 8 // + (srcport, dstport), actual
+-#define VCHIQ_MSG_BULK_TX_DONE 9 // + (srcport, dstport), actual
+-#define VCHIQ_MSG_PAUSE 10 // -
+-#define VCHIQ_MSG_RESUME 11 // -
+-#define VCHIQ_MSG_REMOTE_USE 12 // -
+-#define VCHIQ_MSG_REMOTE_RELEASE 13 // -
+-#define VCHIQ_MSG_REMOTE_USE_ACTIVE 14 // -
++ VCHIQ_SLOT_SIZE - 1) / VCHIQ_SLOT_SIZE)
++
++#define VCHIQ_MSG_PADDING 0 /* - */
++#define VCHIQ_MSG_CONNECT 1 /* - */
++#define VCHIQ_MSG_OPEN 2 /* + (srcport, -), fourcc, client_id */
++#define VCHIQ_MSG_OPENACK 3 /* + (srcport, dstport) */
++#define VCHIQ_MSG_CLOSE 4 /* + (srcport, dstport) */
++#define VCHIQ_MSG_DATA 5 /* + (srcport, dstport) */
++#define VCHIQ_MSG_BULK_RX 6 /* + (srcport, dstport), data, size */
++#define VCHIQ_MSG_BULK_TX 7 /* + (srcport, dstport), data, size */
++#define VCHIQ_MSG_BULK_RX_DONE 8 /* + (srcport, dstport), actual */
++#define VCHIQ_MSG_BULK_TX_DONE 9 /* + (srcport, dstport), actual */
++#define VCHIQ_MSG_PAUSE 10 /* - */
++#define VCHIQ_MSG_RESUME 11 /* - */
++#define VCHIQ_MSG_REMOTE_USE 12 /* - */
++#define VCHIQ_MSG_REMOTE_RELEASE 13 /* - */
++#define VCHIQ_MSG_REMOTE_USE_ACTIVE 14 /* - */
+
+ #define VCHIQ_PORT_MAX (VCHIQ_MAX_SERVICES - 1)
+ #define VCHIQ_PORT_FREE 0x1000
+ #define VCHIQ_PORT_IS_VALID(port) (port < VCHIQ_PORT_FREE)
+-#define VCHIQ_MAKE_MSG(type,srcport,dstport) ((type<<24) | (srcport<<12) | (dstport<<0))
++#define VCHIQ_MAKE_MSG(type, srcport, dstport) \
++ ((type<<24) | (srcport<<12) | (dstport<<0))
+ #define VCHIQ_MSG_TYPE(msgid) ((unsigned int)msgid >> 24)
+-#define VCHIQ_MSG_SRCPORT(msgid) (unsigned short)(((unsigned int)msgid >> 12) & 0xfff)
+-#define VCHIQ_MSG_DSTPORT(msgid) ((unsigned short)msgid & 0xfff)
++#define VCHIQ_MSG_SRCPORT(msgid) \
++ (unsigned short)(((unsigned int)msgid >> 12) & 0xfff)
++#define VCHIQ_MSG_DSTPORT(msgid) \
++ ((unsigned short)msgid & 0xfff)
+
+ #define VCHIQ_FOURCC_AS_4CHARS(fourcc) \
+- ((fourcc) >> 24) & 0xff, \
+- ((fourcc) >> 16) & 0xff, \
+- ((fourcc) >> 8) & 0xff, \
+- ((fourcc) ) & 0xff
++ ((fourcc) >> 24) & 0xff, \
++ ((fourcc) >> 16) & 0xff, \
++ ((fourcc) >> 8) & 0xff, \
++ (fourcc) & 0xff
+
+ /* Ensure the fields are wide enough */
+-vcos_static_assert(VCHIQ_MSG_SRCPORT(VCHIQ_MAKE_MSG(0,0,VCHIQ_PORT_MAX)) == 0);
+-vcos_static_assert(VCHIQ_MSG_TYPE(VCHIQ_MAKE_MSG(0,VCHIQ_PORT_MAX,0)) == 0);
+-vcos_static_assert((unsigned int)VCHIQ_PORT_MAX < (unsigned int)VCHIQ_PORT_FREE);
++vchiq_static_assert(VCHIQ_MSG_SRCPORT(VCHIQ_MAKE_MSG(0, 0, VCHIQ_PORT_MAX))
++ == 0);
++vchiq_static_assert(VCHIQ_MSG_TYPE(VCHIQ_MAKE_MSG(0, VCHIQ_PORT_MAX, 0)) == 0);
++vchiq_static_assert((unsigned int)VCHIQ_PORT_MAX <
++ (unsigned int)VCHIQ_PORT_FREE);
+
+-#define VCHIQ_MSGID_PADDING VCHIQ_MAKE_MSG(VCHIQ_MSG_PADDING,0,0)
++#define VCHIQ_MSGID_PADDING VCHIQ_MAKE_MSG(VCHIQ_MSG_PADDING, 0, 0)
+ #define VCHIQ_MSGID_CLAIMED 0x40000000
+
+ #define VCHIQ_FOURCC_INVALID 0x00000000
+@@ -80,7 +127,7 @@ vcos_static_assert((unsigned int)VCHIQ_PORT_MAX < (unsigned int)VCHIQ_PORT_FREE)
+
+ typedef uint32_t BITSET_T;
+
+-vcos_static_assert((sizeof(BITSET_T) * 8) == 32);
++vchiq_static_assert((sizeof(BITSET_T) * 8) == 32);
+
+ #define BITSET_SIZE(b) ((b + 31) >> 5)
+ #define BITSET_WORD(b) (b >> 5)
+@@ -91,314 +138,380 @@ vcos_static_assert((sizeof(BITSET_T) * 8) == 32);
+ #define BITSET_CLR(bs, b) (bs[BITSET_WORD(b)] &= ~BITSET_BIT(b))
+
+ #if VCHIQ_ENABLE_STATS
+-#define VCHIQ_STATS_INC(state, stat) (state->stats. stat ++)
+-#define VCHIQ_SERVICE_STATS_INC(service, stat) (service->stats. stat ++)
+-#define VCHIQ_SERVICE_STATS_ADD(service, stat, addend) (service->stats. stat += addend)
++#define VCHIQ_STATS_INC(state, stat) (state->stats. stat++)
++#define VCHIQ_SERVICE_STATS_INC(service, stat) (service->stats. stat++)
++#define VCHIQ_SERVICE_STATS_ADD(service, stat, addend) \
++ (service->stats. stat += addend)
+ #else
+ #define VCHIQ_STATS_INC(state, stat) ((void)0)
+ #define VCHIQ_SERVICE_STATS_INC(service, stat) ((void)0)
+ #define VCHIQ_SERVICE_STATS_ADD(service, stat, addend) ((void)0)
+ #endif
+
+-enum
+-{
+- DEBUG_ENTRIES,
++enum {
++ DEBUG_ENTRIES,
+ #if VCHIQ_ENABLE_DEBUG
+- DEBUG_SLOT_HANDLER_COUNT,
+- DEBUG_SLOT_HANDLER_LINE,
+- DEBUG_PARSE_LINE,
+- DEBUG_PARSE_HEADER,
+- DEBUG_PARSE_MSGID,
+- DEBUG_AWAIT_COMPLETION_LINE,
+- DEBUG_DEQUEUE_MESSAGE_LINE,
+- DEBUG_SERVICE_CALLBACK_LINE,
+- DEBUG_MSG_QUEUE_FULL_COUNT,
+- DEBUG_COMPLETION_QUEUE_FULL_COUNT,
++ DEBUG_SLOT_HANDLER_COUNT,
++ DEBUG_SLOT_HANDLER_LINE,
++ DEBUG_PARSE_LINE,
++ DEBUG_PARSE_HEADER,
++ DEBUG_PARSE_MSGID,
++ DEBUG_AWAIT_COMPLETION_LINE,
++ DEBUG_DEQUEUE_MESSAGE_LINE,
++ DEBUG_SERVICE_CALLBACK_LINE,
++ DEBUG_MSG_QUEUE_FULL_COUNT,
++ DEBUG_COMPLETION_QUEUE_FULL_COUNT,
+ #endif
+- DEBUG_MAX
++ DEBUG_MAX
+ };
+
+ #if VCHIQ_ENABLE_DEBUG
+
+-#define DEBUG_INITIALISE(local) volatile int *debug_ptr = (local)->debug;
+-#define DEBUG_TRACE(d) debug_ptr[DEBUG_ ## d] = __LINE__
+-#define DEBUG_VALUE(d,v) debug_ptr[DEBUG_ ## d] = (v)
+-#define DEBUG_COUNT(d) debug_ptr[DEBUG_ ## d]++
++#define DEBUG_INITIALISE(local) int *debug_ptr = (local)->debug;
++#define DEBUG_TRACE(d) \
++ do { debug_ptr[DEBUG_ ## d] = __LINE__; dsb(); } while (0)
++#define DEBUG_VALUE(d, v) \
++ do { debug_ptr[DEBUG_ ## d] = (v); dsb(); } while (0)
++#define DEBUG_COUNT(d) \
++ do { debug_ptr[DEBUG_ ## d]++; dsb(); } while (0)
+
+ #else /* VCHIQ_ENABLE_DEBUG */
+
+ #define DEBUG_INITIALISE(local)
+ #define DEBUG_TRACE(d)
+-#define DEBUG_VALUE(d,v)
++#define DEBUG_VALUE(d, v)
+ #define DEBUG_COUNT(d)
+
+ #endif /* VCHIQ_ENABLE_DEBUG */
+
+-typedef enum
+-{
+- VCHIQ_CONNSTATE_DISCONNECTED,
+- VCHIQ_CONNSTATE_CONNECTED,
+- VCHIQ_CONNSTATE_PAUSING,
+- VCHIQ_CONNSTATE_PAUSE_SENT,
+- VCHIQ_CONNSTATE_PAUSED,
+- VCHIQ_CONNSTATE_RESUMING
++typedef enum {
++ VCHIQ_CONNSTATE_DISCONNECTED,
++ VCHIQ_CONNSTATE_CONNECTING,
++ VCHIQ_CONNSTATE_CONNECTED,
++ VCHIQ_CONNSTATE_PAUSING,
++ VCHIQ_CONNSTATE_PAUSE_SENT,
++ VCHIQ_CONNSTATE_PAUSED,
++ VCHIQ_CONNSTATE_RESUMING
+ } VCHIQ_CONNSTATE_T;
+
+-enum
+-{
+- VCHIQ_SRVSTATE_FREE,
+- VCHIQ_SRVSTATE_HIDDEN,
+- VCHIQ_SRVSTATE_LISTENING,
+- VCHIQ_SRVSTATE_OPENING,
+- VCHIQ_SRVSTATE_OPEN,
+- VCHIQ_SRVSTATE_CLOSESENT,
+- VCHIQ_SRVSTATE_CLOSING,
+- VCHIQ_SRVSTATE_CLOSEWAIT
++enum {
++ VCHIQ_SRVSTATE_FREE,
++ VCHIQ_SRVSTATE_HIDDEN,
++ VCHIQ_SRVSTATE_LISTENING,
++ VCHIQ_SRVSTATE_OPENING,
++ VCHIQ_SRVSTATE_OPEN,
++ VCHIQ_SRVSTATE_OPENSYNC,
++ VCHIQ_SRVSTATE_CLOSESENT,
++ VCHIQ_SRVSTATE_CLOSERECVD,
++ VCHIQ_SRVSTATE_CLOSEWAIT,
++ VCHIQ_SRVSTATE_CLOSED
+ };
+
+-enum
+-{
+- VCHIQ_POLL_TERMINATE,
+- VCHIQ_POLL_TXNOTIFY,
+- VCHIQ_POLL_RXNOTIFY,
+- VCHIQ_POLL_COUNT
++enum {
++ VCHIQ_POLL_TERMINATE,
++ VCHIQ_POLL_TXNOTIFY,
++ VCHIQ_POLL_RXNOTIFY,
++ VCHIQ_POLL_COUNT
+ };
+
+-typedef enum
+-{
+- VCHIQ_BULK_TRANSMIT,
+- VCHIQ_BULK_RECEIVE
++typedef enum {
++ VCHIQ_BULK_TRANSMIT,
++ VCHIQ_BULK_RECEIVE
+ } VCHIQ_BULK_DIR_T;
+
+ typedef struct vchiq_bulk_struct {
+- short mode;
+- short dir;
+- void *userdata;
+- VCHI_MEM_HANDLE_T handle;
+- void *data;
+- int size;
+- void *remote_data;
+- int remote_size;
+- int actual;
++ short mode;
++ short dir;
++ void *userdata;
++ VCHI_MEM_HANDLE_T handle;
++ void *data;
++ int size;
++ void *remote_data;
++ int remote_size;
++ int actual;
+ } VCHIQ_BULK_T;
+
+ typedef struct vchiq_bulk_queue_struct {
+- int local_insert; /* Where to insert the next local bulk */
+- int remote_insert; /* Where to insert the next remote bulk (master) */
+- int process; /* Bulk to transfer next */
+- int remote_notify; /* Bulk to notify the remote client of next (master) */
+- int remove; /* Bulk to notify the local client of, and remove, next */
+- VCHIQ_BULK_T bulks[VCHIQ_NUM_SERVICE_BULKS];
++ int local_insert; /* Where to insert the next local bulk */
++ int remote_insert; /* Where to insert the next remote bulk (master) */
++ int process; /* Bulk to transfer next */
++ int remote_notify; /* Bulk to notify the remote client of next (mstr) */
++ int remove; /* Bulk to notify the local client of, and remove,
++ ** next */
++ VCHIQ_BULK_T bulks[VCHIQ_NUM_SERVICE_BULKS];
+ } VCHIQ_BULK_QUEUE_T;
+
+ typedef struct remote_event_struct {
+- volatile int armed;
+- volatile int fired;
+- VCOS_EVENT_T * event;
++ int armed;
++ int fired;
++ struct semaphore *event;
+ } REMOTE_EVENT_T;
+
+-typedef struct opaque_platform_state_t* VCHIQ_PLATFORM_STATE_T;
++typedef struct opaque_platform_state_t *VCHIQ_PLATFORM_STATE_T;
+
+ typedef struct vchiq_state_struct VCHIQ_STATE_T;
+
+ typedef struct vchiq_slot_struct {
+- char data[VCHIQ_SLOT_SIZE];
++ char data[VCHIQ_SLOT_SIZE];
+ } VCHIQ_SLOT_T;
+
+ typedef struct vchiq_slot_info_struct {
+- /* Use two counters rather than one to avoid the need for a mutex. */
+- volatile short use_count;
+- volatile short release_count;
++ /* Use two counters rather than one to avoid the need for a mutex. */
++ short use_count;
++ short release_count;
+ } VCHIQ_SLOT_INFO_T;
+
+ typedef struct vchiq_service_struct {
+- VCHIQ_SERVICE_BASE_T base;
+- volatile int srvstate;
+- unsigned int localport;
+- unsigned int remoteport;
+- int public_fourcc;
+- int client_id;
+- int auto_close;
+- VCOS_ATOMIC_FLAGS_T poll_flags;
+- short version;
+- short version_min;
+-
+- VCHIQ_STATE_T *state;
+- VCHIQ_INSTANCE_T instance;
+-
+- int service_use_count;
+-
+- VCHIQ_BULK_QUEUE_T bulk_tx;
+- VCHIQ_BULK_QUEUE_T bulk_rx;
+-
+- VCOS_EVENT_T remove_event;
+- VCOS_EVENT_T bulk_remove_event;
+- VCOS_MUTEX_T bulk_mutex;
+-
+- struct service_stats_struct
+- {
+- int quota_stalls;
+- int slot_stalls;
+- int bulk_stalls;
+- int error_count;
+- int ctrl_tx_count;
+- int ctrl_rx_count;
+- int bulk_tx_count;
+- int bulk_rx_count;
+- int bulk_aborted_count;
+- uint64_t ctrl_tx_bytes;
+- uint64_t ctrl_rx_bytes;
+- uint64_t bulk_tx_bytes;
+- uint64_t bulk_rx_bytes;
+- } stats;
++ VCHIQ_SERVICE_BASE_T base;
++ VCHIQ_SERVICE_HANDLE_T handle;
++ unsigned int ref_count;
++ int srvstate;
++ unsigned int localport;
++ unsigned int remoteport;
++ int public_fourcc;
++ int client_id;
++ char auto_close;
++ char sync;
++ char closing;
++ atomic_t poll_flags;
++ short version;
++ short version_min;
++
++ VCHIQ_STATE_T *state;
++ VCHIQ_INSTANCE_T instance;
++
++ int service_use_count;
++
++ VCHIQ_BULK_QUEUE_T bulk_tx;
++ VCHIQ_BULK_QUEUE_T bulk_rx;
++
++ struct semaphore remove_event;
++ struct semaphore bulk_remove_event;
++ struct mutex bulk_mutex;
++
++ struct service_stats_struct {
++ int quota_stalls;
++ int slot_stalls;
++ int bulk_stalls;
++ int error_count;
++ int ctrl_tx_count;
++ int ctrl_rx_count;
++ int bulk_tx_count;
++ int bulk_rx_count;
++ int bulk_aborted_count;
++ uint64_t ctrl_tx_bytes;
++ uint64_t ctrl_rx_bytes;
++ uint64_t bulk_tx_bytes;
++ uint64_t bulk_rx_bytes;
++ } stats;
+ } VCHIQ_SERVICE_T;
+
+ /* The quota information is outside VCHIQ_SERVICE_T so that it can be
+- statically allocated, since for accounting reasons a service's slot
+- usage is carried over between users of the same port number.
++ statically allocated, since for accounting reasons a service's slot
++ usage is carried over between users of the same port number.
+ */
+ typedef struct vchiq_service_quota_struct {
+- unsigned short slot_quota;
+- unsigned short slot_use_count;
+- unsigned short message_quota;
+- unsigned short message_use_count;
+- VCOS_EVENT_T quota_event;
+- int previous_tx_index;
++ unsigned short slot_quota;
++ unsigned short slot_use_count;
++ unsigned short message_quota;
++ unsigned short message_use_count;
++ struct semaphore quota_event;
++ int previous_tx_index;
+ } VCHIQ_SERVICE_QUOTA_T;
+
+ typedef struct vchiq_shared_state_struct {
+
+- /* A non-zero value here indicates that the content is valid. */
+- int initialised;
++ /* A non-zero value here indicates that the content is valid. */
++ int initialised;
++
++ /* The first and last (inclusive) slots allocated to the owner. */
++ int slot_first;
++ int slot_last;
+
+- /* The first and last (inclusive) slots allocated to the owner. */
+- int slot_first;
+- int slot_last;
++ /* The slot allocated to synchronous messages from the owner. */
++ int slot_sync;
+
+- /* Signalling this event indicates that owner's slot handler thread should
+- run. */
+- REMOTE_EVENT_T trigger;
++ /* Signalling this event indicates that owner's slot handler thread
++ ** should run. */
++ REMOTE_EVENT_T trigger;
+
+- /* Indicates the byte position within the stream where the next message
+- will be written. The least significant bits are an index into the slot.
+- The next bits are the index of the slot in slot_queue. */
+- volatile int tx_pos;
++ /* Indicates the byte position within the stream where the next message
++ ** will be written. The least significant bits are an index into the
++ ** slot. The next bits are the index of the slot in slot_queue. */
++ int tx_pos;
+
+- /* This event should be signalled when a slot is recycled. */
+- REMOTE_EVENT_T recycle;
++ /* This event should be signalled when a slot is recycled. */
++ REMOTE_EVENT_T recycle;
+
+- /* The slot_queue index where the next recycled slot will be written. */
+- volatile int slot_queue_recycle;
++ /* The slot_queue index where the next recycled slot will be written. */
++ int slot_queue_recycle;
+
+- /* A circular buffer of slot indexes. */
+- int slot_queue[VCHIQ_MAX_SLOTS_PER_SIDE];
++ /* This event should be signalled when a synchronous message is sent. */
++ REMOTE_EVENT_T sync_trigger;
+
+- /* Debugging state */
+- volatile int debug[DEBUG_MAX];
++ /* This event should be signalled when a synchronous message has been
++ ** released. */
++ REMOTE_EVENT_T sync_release;
++
++ /* A circular buffer of slot indexes. */
++ int slot_queue[VCHIQ_MAX_SLOTS_PER_SIDE];
++
++ /* Debugging state */
++ int debug[DEBUG_MAX];
+ } VCHIQ_SHARED_STATE_T;
+
+ typedef struct vchiq_slot_zero_struct {
+- int magic;
+- short version;
+- short version_min;
+- int slot_zero_size;
+- int slot_size;
+- int max_slots;
+- int max_slots_per_side;
+- int platform_data[2];
+- VCHIQ_SHARED_STATE_T master;
+- VCHIQ_SHARED_STATE_T slave;
+- VCHIQ_SLOT_INFO_T slots[VCHIQ_MAX_SLOTS];
++ int magic;
++ short version;
++ short version_min;
++ int slot_zero_size;
++ int slot_size;
++ int max_slots;
++ int max_slots_per_side;
++ int platform_data[2];
++ VCHIQ_SHARED_STATE_T master;
++ VCHIQ_SHARED_STATE_T slave;
++ VCHIQ_SLOT_INFO_T slots[VCHIQ_MAX_SLOTS];
+ } VCHIQ_SLOT_ZERO_T;
+
+ struct vchiq_state_struct {
+- int id;
+- int initialised;
+- VCHIQ_CONNSTATE_T conn_state;
+- int is_master;
++ int id;
++ int initialised;
++ VCHIQ_CONNSTATE_T conn_state;
++ int is_master;
++
++ VCHIQ_SHARED_STATE_T *local;
++ VCHIQ_SHARED_STATE_T *remote;
++ VCHIQ_SLOT_T *slot_data;
++
++ unsigned short default_slot_quota;
++ unsigned short default_message_quota;
++
++ /* Event indicating connect message received */
++ struct semaphore connect;
++
++ /* Mutex protecting services */
++ struct mutex mutex;
++ VCHIQ_INSTANCE_T *instance;
++
++ /* Processes incoming messages */
++ struct task_struct *slot_handler_thread;
++
++ /* Processes recycled slots */
++ struct task_struct *recycle_thread;
++
++ /* Processes synchronous messages */
++ struct task_struct *sync_thread;
+
+- VCHIQ_SHARED_STATE_T *local;
+- VCHIQ_SHARED_STATE_T *remote;
+- VCHIQ_SLOT_T *slot_data;
++ /* Local implementation of the trigger remote event */
++ struct semaphore trigger_event;
+
+- unsigned short default_slot_quota;
+- unsigned short default_message_quota;
++ /* Local implementation of the recycle remote event */
++ struct semaphore recycle_event;
+
+- VCOS_EVENT_T connect; // event indicating connect message received
+- VCOS_MUTEX_T mutex; // mutex protecting services
+- VCHIQ_INSTANCE_T *instance;
++ /* Local implementation of the sync trigger remote event */
++ struct semaphore sync_trigger_event;
+
+- VCOS_THREAD_T slot_handler_thread; // processes incoming messages
+- VCOS_THREAD_T recycle_thread; // processes recycled slots
++ /* Local implementation of the sync release remote event */
++ struct semaphore sync_release_event;
+
+- /* Local implementation of the trigger remote event */
+- VCOS_EVENT_T trigger_event;
++ char *tx_data;
++ char *rx_data;
++ VCHIQ_SLOT_INFO_T *rx_info;
+
+- /* Local implementation of the recycle remote event */
+- VCOS_EVENT_T recycle_event;
++ struct mutex slot_mutex;
+
+- char *tx_data;
+- char *rx_data;
+- VCHIQ_SLOT_INFO_T *rx_info;
++ struct mutex recycle_mutex;
+
+- VCOS_MUTEX_T slot_mutex;
++ struct mutex sync_mutex;
+
+- VCOS_MUTEX_T recycle_mutex;
++ struct mutex bulk_transfer_mutex;
+
+- /* Indicates the byte position within the stream from where the next message
+- will be read. The least significant bits are an index into the slot.
+- The next bits are the index of the slot in remote->slot_queue. */
+- int rx_pos;
++ /* Indicates the byte position within the stream from where the next
++ ** message will be read. The least significant bits are an index into
++ ** the slot.The next bits are the index of the slot in
++ ** remote->slot_queue. */
++ int rx_pos;
+
+- /* A cached copy of local->tx_pos. Only write to local->tx_pos, and read
+- from remote->tx_pos. */
+- int local_tx_pos;
++ /* A cached copy of local->tx_pos. Only write to local->tx_pos, and read
++ from remote->tx_pos. */
++ int local_tx_pos;
+
+- /* The slot_queue index of the slot to become available next. */
+- int slot_queue_available;
++ /* The slot_queue index of the slot to become available next. */
++ int slot_queue_available;
+
+- /* A flag to indicate if any poll has been requested */
+- int poll_needed;
++ /* A flag to indicate if any poll has been requested */
++ int poll_needed;
+
+- /* An array of bit sets indicating which services must be polled. */
+- VCOS_ATOMIC_FLAGS_T poll_services[BITSET_SIZE(VCHIQ_MAX_SERVICES)];
++ /* Ths index of the previous slot used for data messages. */
++ int previous_data_index;
+
+- /* The number of the first unused service */
+- int unused_service;
++ /* The number of slots occupied by data messages. */
++ unsigned short data_use_count;
+
+- /* Signalled when a free slot becomes available. */
+- VCOS_EVENT_T slot_available_event;
++ /* The maximum number of slots to be occupied by data messages. */
++ unsigned short data_quota;
+
+- VCOS_EVENT_T slot_remove_event;
++ /* An array of bit sets indicating which services must be polled. */
++ atomic_t poll_services[BITSET_SIZE(VCHIQ_MAX_SERVICES)];
+
+- struct state_stats_struct
+- {
+- int slot_stalls;
+- int ctrl_tx_count;
+- int ctrl_rx_count;
+- int error_count;
+- } stats;
++ /* The number of the first unused service */
++ int unused_service;
+
+- VCHIQ_SERVICE_T *services[VCHIQ_MAX_SERVICES];
+- VCHIQ_SERVICE_QUOTA_T service_quotas[VCHIQ_MAX_SERVICES];
+- VCHIQ_SLOT_INFO_T slot_info[VCHIQ_MAX_SLOTS];
++ /* Signalled when a free slot becomes available. */
++ struct semaphore slot_available_event;
+
+- VCHIQ_PLATFORM_STATE_T platform_state;
++ struct semaphore slot_remove_event;
++
++ /* Signalled when a free data slot becomes available. */
++ struct semaphore data_quota_event;
++
++ struct state_stats_struct {
++ int slot_stalls;
++ int data_stalls;
++ int ctrl_tx_count;
++ int ctrl_rx_count;
++ int error_count;
++ } stats;
++
++ VCHIQ_SERVICE_T * services[VCHIQ_MAX_SERVICES];
++ VCHIQ_SERVICE_QUOTA_T service_quotas[VCHIQ_MAX_SERVICES];
++ VCHIQ_SLOT_INFO_T slot_info[VCHIQ_MAX_SLOTS];
++
++ VCHIQ_PLATFORM_STATE_T platform_state;
+ };
+
++struct bulk_waiter {
++ VCHIQ_BULK_T *bulk;
++ struct semaphore event;
++ int actual;
++};
++
++extern spinlock_t bulk_waiter_spinlock;
++
++extern int vchiq_core_log_level;
++extern int vchiq_core_msg_log_level;
++extern int vchiq_sync_log_level;
++
++extern VCHIQ_STATE_T *vchiq_states[VCHIQ_MAX_STATES];
++
++extern const char *
++get_conn_state_name(VCHIQ_CONNSTATE_T conn_state);
++
+ extern VCHIQ_SLOT_ZERO_T *
+ vchiq_init_slots(void *mem_base, int mem_size);
+
+ extern VCHIQ_STATUS_T
+-vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero, int is_master);
++vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero,
++ int is_master);
+
+ extern VCHIQ_STATUS_T
+ vchiq_connect_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance);
+
+ extern VCHIQ_SERVICE_T *
+ vchiq_add_service_internal(VCHIQ_STATE_T *state,
+- const VCHIQ_SERVICE_PARAMS_T *params, int srvstate,
+- VCHIQ_INSTANCE_T instance);
++ const VCHIQ_SERVICE_PARAMS_T *params, int srvstate,
++ VCHIQ_INSTANCE_T instance);
+
+ extern VCHIQ_STATUS_T
+ vchiq_open_service_internal(VCHIQ_SERVICE_T *service, int client_id);
+@@ -425,9 +538,9 @@ extern void
+ remote_event_pollall(VCHIQ_STATE_T *state);
+
+ extern VCHIQ_STATUS_T
+-vchiq_bulk_transfer(VCHIQ_SERVICE_T *service,
+- VCHI_MEM_HANDLE_T memhandle, void *offset, int size, void *userdata,
+- VCHIQ_BULK_MODE_T mode, VCHIQ_BULK_DIR_T dir);
++vchiq_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle,
++ VCHI_MEM_HANDLE_T memhandle, void *offset, int size, void *userdata,
++ VCHIQ_BULK_MODE_T mode, VCHIQ_BULK_DIR_T dir);
+
+ extern void
+ vchiq_dump_state(void *dump_context, VCHIQ_STATE_T *state);
+@@ -435,12 +548,52 @@ vchiq_dump_state(void *dump_context, VCHIQ_STATE_T *state);
+ extern void
+ vchiq_dump_service_state(void *dump_context, VCHIQ_SERVICE_T *service);
+
++extern void
++vchiq_loud_error_header(void);
++
++extern void
++vchiq_loud_error_footer(void);
++
++extern void
++request_poll(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, int poll_type);
++
++static inline VCHIQ_SERVICE_T *
++handle_to_service(VCHIQ_SERVICE_HANDLE_T handle)
++{
++ VCHIQ_STATE_T *state = vchiq_states[(handle / VCHIQ_MAX_SERVICES) &
++ (VCHIQ_MAX_STATES - 1)];
++ if (!state)
++ return NULL;
++
++ return state->services[handle & (VCHIQ_MAX_SERVICES - 1)];
++}
++
++extern VCHIQ_SERVICE_T *
++find_service_by_handle(VCHIQ_SERVICE_HANDLE_T handle);
++
++extern VCHIQ_SERVICE_T *
++find_service_by_port(VCHIQ_STATE_T *state, int localport);
++
++extern VCHIQ_SERVICE_T *
++find_service_for_instance(VCHIQ_INSTANCE_T instance,
++ VCHIQ_SERVICE_HANDLE_T handle);
++
++extern VCHIQ_SERVICE_T *
++next_service_by_instance(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance,
++ int *pidx);
++
++extern void
++lock_service(VCHIQ_SERVICE_T *service);
++
++extern void
++unlock_service(VCHIQ_SERVICE_T *service);
++
+ /* The following functions are called from vchiq_core, and external
+- implementations must be provided. */
++** implementations must be provided. */
+
+ extern VCHIQ_STATUS_T
+ vchiq_prepare_bulk_data(VCHIQ_BULK_T *bulk,
+- VCHI_MEM_HANDLE_T memhandle, void *offset, int size, int dir);
++ VCHI_MEM_HANDLE_T memhandle, void *offset, int size, int dir);
+
+ extern void
+ vchiq_transfer_bulk(VCHIQ_BULK_T *bulk);
+@@ -454,9 +607,15 @@ vchiq_copy_from_user(void *dst, const void *src, int size);
+ extern void
+ remote_event_signal(REMOTE_EVENT_T *event);
+
++void
++vchiq_platform_check_suspend(VCHIQ_STATE_T *state);
++
+ extern void
+ vchiq_platform_paused(VCHIQ_STATE_T *state);
+
++extern VCHIQ_STATUS_T
++vchiq_platform_resume(VCHIQ_STATE_T *state);
++
+ extern void
+ vchiq_platform_resumed(VCHIQ_STATE_T *state);
+
+@@ -471,7 +630,7 @@ vchiq_dump_platform_instances(void *dump_context);
+
+ extern void
+ vchiq_dump_platform_service_state(void *dump_context,
+- VCHIQ_SERVICE_T *service);
++ VCHIQ_SERVICE_T *service);
+
+ extern VCHIQ_STATUS_T
+ vchiq_use_service_internal(VCHIQ_SERVICE_T *service);
+@@ -479,28 +638,36 @@ vchiq_use_service_internal(VCHIQ_SERVICE_T *service);
+ extern VCHIQ_STATUS_T
+ vchiq_release_service_internal(VCHIQ_SERVICE_T *service);
+
+-extern VCHIQ_STATUS_T
++extern void
+ vchiq_on_remote_use(VCHIQ_STATE_T *state);
+
+-extern VCHIQ_STATUS_T
++extern void
+ vchiq_on_remote_release(VCHIQ_STATE_T *state);
+
+ extern VCHIQ_STATUS_T
+ vchiq_platform_init_state(VCHIQ_STATE_T *state);
+
++extern VCHIQ_STATUS_T
++vchiq_check_service(VCHIQ_SERVICE_T *service);
++
+ extern void
+ vchiq_on_remote_use_active(VCHIQ_STATE_T *state);
+
+ extern VCHIQ_STATUS_T
+-vchiq_send_remote_use(VCHIQ_STATE_T * state);
++vchiq_send_remote_use(VCHIQ_STATE_T *state);
+
+ extern VCHIQ_STATUS_T
+-vchiq_send_remote_release(VCHIQ_STATE_T * state);
++vchiq_send_remote_release(VCHIQ_STATE_T *state);
+
+ extern VCHIQ_STATUS_T
+-vchiq_send_remote_use_active(VCHIQ_STATE_T * state);
++vchiq_send_remote_use_active(VCHIQ_STATE_T *state);
++
++extern void
++vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state,
++ VCHIQ_CONNSTATE_T oldstate, VCHIQ_CONNSTATE_T newstate);
+
+ extern void
+-vchiq_platform_conn_state_changed(VCHIQ_STATE_T* state, VCHIQ_CONNSTATE_T oldstate, VCHIQ_CONNSTATE_T newstate);
++vchiq_log_dump_mem(const char *label, uint32_t addr, const void *voidMem,
++ size_t numBytes);
+
+ #endif
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_if.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_if.h
+index 42d471b..d89f89e 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_if.h
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_if.h
+@@ -21,135 +21,145 @@
+
+ #include "interface/vchi/vchi_mh.h"
+
+-#define VCHIQ_SLOT_SIZE 4096
+-#define VCHIQ_MAX_MSG_SIZE (VCHIQ_SLOT_SIZE - sizeof(VCHIQ_HEADER_T))
+-#define VCHIQ_CHANNEL_SIZE VCHIQ_MAX_MSG_SIZE /* For backwards compatibility */
++#define VCHIQ_SERVICE_HANDLE_INVALID 0
+
+-#define VCHIQ_MAKE_FOURCC(x0, x1, x2, x3) (((x0) << 24) | ((x1) << 16) | ((x2) << 8) | (x3))
+-#define VCHIQ_GET_SERVICE_USERDATA(service) (service->userdata)
+-#define VCHIQ_GET_SERVICE_FOURCC(service) (service->fourcc)
++#define VCHIQ_SLOT_SIZE 4096
++#define VCHIQ_MAX_MSG_SIZE (VCHIQ_SLOT_SIZE - sizeof(VCHIQ_HEADER_T))
++#define VCHIQ_CHANNEL_SIZE VCHIQ_MAX_MSG_SIZE /* For backwards compatibility */
++
++#define VCHIQ_MAKE_FOURCC(x0, x1, x2, x3) \
++ (((x0) << 24) | ((x1) << 16) | ((x2) << 8) | (x3))
++#define VCHIQ_GET_SERVICE_USERDATA(service) vchiq_get_service_userdata(service)
++#define VCHIQ_GET_SERVICE_FOURCC(service) vchiq_get_service_fourcc(service)
+
+ typedef enum {
+- VCHIQ_SERVICE_OPENED, // service, -, -
+- VCHIQ_SERVICE_CLOSED, // service, -, -
+- VCHIQ_MESSAGE_AVAILABLE, // service, header, -
+- VCHIQ_BULK_TRANSMIT_DONE, // service, -, bulk_userdata
+- VCHIQ_BULK_RECEIVE_DONE, // service, -, bulk_userdata
+- VCHIQ_BULK_TRANSMIT_ABORTED, // service, -, bulk_userdata
+- VCHIQ_BULK_RECEIVE_ABORTED // service, -, bulk_userdata
++ VCHIQ_SERVICE_OPENED, /* service, -, - */
++ VCHIQ_SERVICE_CLOSED, /* service, -, - */
++ VCHIQ_MESSAGE_AVAILABLE, /* service, header, - */
++ VCHIQ_BULK_TRANSMIT_DONE, /* service, -, bulk_userdata */
++ VCHIQ_BULK_RECEIVE_DONE, /* service, -, bulk_userdata */
++ VCHIQ_BULK_TRANSMIT_ABORTED, /* service, -, bulk_userdata */
++ VCHIQ_BULK_RECEIVE_ABORTED /* service, -, bulk_userdata */
+ } VCHIQ_REASON_T;
+
+-typedef enum
+-{
+- VCHIQ_ERROR = -1,
+- VCHIQ_SUCCESS = 0,
+- VCHIQ_RETRY = 1
++typedef enum {
++ VCHIQ_ERROR = -1,
++ VCHIQ_SUCCESS = 0,
++ VCHIQ_RETRY = 1
+ } VCHIQ_STATUS_T;
+
+-typedef enum
+-{
+- VCHIQ_BULK_MODE_CALLBACK,
+- VCHIQ_BULK_MODE_BLOCKING,
+- VCHIQ_BULK_MODE_NOCALLBACK
++typedef enum {
++ VCHIQ_BULK_MODE_CALLBACK,
++ VCHIQ_BULK_MODE_BLOCKING,
++ VCHIQ_BULK_MODE_NOCALLBACK,
++ VCHIQ_BULK_MODE_WAITING /* Reserved for internal use */
+ } VCHIQ_BULK_MODE_T;
+
+-typedef enum
+-{
+- VCHIQ_SERVICE_OPTION_AUTOCLOSE,
+- VCHIQ_SERVICE_OPTION_SLOT_QUOTA,
+- VCHIQ_SERVICE_OPTION_MESSAGE_QUOTA
++typedef enum {
++ VCHIQ_SERVICE_OPTION_AUTOCLOSE,
++ VCHIQ_SERVICE_OPTION_SLOT_QUOTA,
++ VCHIQ_SERVICE_OPTION_MESSAGE_QUOTA,
++ VCHIQ_SERVICE_OPTION_SYNCHRONOUS
+ } VCHIQ_SERVICE_OPTION_T;
+
+-#ifdef __HIGHC__
+-/* Allow zero-sized arrays without warnings */
+-#pragma warning (push)
+-#pragma warning (disable : 4200)
+-#endif
+-
+ typedef struct vchiq_header_struct {
+- /* The message identifier - opaque to applications. */
+- int msgid;
++ /* The message identifier - opaque to applications. */
++ int msgid;
+
+- /* Size of message data. */
+- unsigned int size;
++ /* Size of message data. */
++ unsigned int size;
+
+- char data[0]; /* message */
++ char data[0]; /* message */
+ } VCHIQ_HEADER_T;
+
+-#ifdef __HIGHC__
+-#pragma warning (pop)
+-#endif
+-
+ typedef struct {
+- const void *data;
+- int size;
++ const void *data;
++ int size;
+ } VCHIQ_ELEMENT_T;
+
+-typedef const struct vchiq_service_base_struct *VCHIQ_SERVICE_HANDLE_T;
++typedef unsigned int VCHIQ_SERVICE_HANDLE_T;
+
+-typedef VCHIQ_STATUS_T (*VCHIQ_CALLBACK_T)(VCHIQ_REASON_T, VCHIQ_HEADER_T *, VCHIQ_SERVICE_HANDLE_T, void *);
++typedef VCHIQ_STATUS_T (*VCHIQ_CALLBACK_T)(VCHIQ_REASON_T, VCHIQ_HEADER_T *,
++ VCHIQ_SERVICE_HANDLE_T, void *);
+
+ typedef struct vchiq_service_base_struct {
+- int fourcc;
+- VCHIQ_CALLBACK_T callback;
+- void *userdata;
++ int fourcc;
++ VCHIQ_CALLBACK_T callback;
++ void *userdata;
+ } VCHIQ_SERVICE_BASE_T;
+
+ typedef struct vchiq_service_params_struct {
+- int fourcc;
+- VCHIQ_CALLBACK_T callback;
+- void *userdata;
+- short version; /* Increment for non-trivial changes */
+- short version_min; /* Update for incompatible changes */
++ int fourcc;
++ VCHIQ_CALLBACK_T callback;
++ void *userdata;
++ short version; /* Increment for non-trivial changes */
++ short version_min; /* Update for incompatible changes */
+ } VCHIQ_SERVICE_PARAMS_T;
+
+ typedef struct vchiq_config_struct {
+- int max_msg_size;
+- int bulk_threshold; /* The message size aboce which it is better to use
+- a bulk transfer (<= max_msg_size) */
+- int max_outstanding_bulks;
+- int max_services;
+- short version; /* The version of VCHIQ */
+- short version_min; /* The minimum compatible version of VCHIQ */
++ int max_msg_size;
++ int bulk_threshold; /* The message size aboce which it is better to use
++ a bulk transfer (<= max_msg_size) */
++ int max_outstanding_bulks;
++ int max_services;
++ short version; /* The version of VCHIQ */
++ short version_min; /* The minimum compatible version of VCHIQ */
+ } VCHIQ_CONFIG_T;
+
+ typedef struct vchiq_instance_struct *VCHIQ_INSTANCE_T;
+-typedef void (*VCHIQ_REMOTE_USE_CALLBACK_T)(void* cb_arg);
+-
++typedef void (*VCHIQ_REMOTE_USE_CALLBACK_T)(void *cb_arg);
+
+ extern VCHIQ_STATUS_T vchiq_initialise(VCHIQ_INSTANCE_T *pinstance);
+ extern VCHIQ_STATUS_T vchiq_shutdown(VCHIQ_INSTANCE_T instance);
+ extern VCHIQ_STATUS_T vchiq_connect(VCHIQ_INSTANCE_T instance);
+-extern VCHIQ_STATUS_T vchiq_add_service(VCHIQ_INSTANCE_T instance, int fourcc, VCHIQ_CALLBACK_T callback, void *userdata, VCHIQ_SERVICE_HANDLE_T *pservice);
+-extern VCHIQ_STATUS_T vchiq_open_service(VCHIQ_INSTANCE_T instance, int fourcc, VCHIQ_CALLBACK_T callback, void *userdata, VCHIQ_SERVICE_HANDLE_T *pservice);
+-extern VCHIQ_STATUS_T vchiq_add_service_params(VCHIQ_INSTANCE_T instance,
+- const VCHIQ_SERVICE_PARAMS_T *params,
+- VCHIQ_SERVICE_HANDLE_T *pservice);
+-extern VCHIQ_STATUS_T vchiq_open_service_params(VCHIQ_INSTANCE_T instance,
+- const VCHIQ_SERVICE_PARAMS_T *params,
+- VCHIQ_SERVICE_HANDLE_T *pservice);
++extern VCHIQ_STATUS_T vchiq_add_service(VCHIQ_INSTANCE_T instance,
++ const VCHIQ_SERVICE_PARAMS_T *params,
++ VCHIQ_SERVICE_HANDLE_T *pservice);
++extern VCHIQ_STATUS_T vchiq_open_service(VCHIQ_INSTANCE_T instance,
++ const VCHIQ_SERVICE_PARAMS_T *params,
++ VCHIQ_SERVICE_HANDLE_T *pservice);
+ extern VCHIQ_STATUS_T vchiq_close_service(VCHIQ_SERVICE_HANDLE_T service);
+ extern VCHIQ_STATUS_T vchiq_remove_service(VCHIQ_SERVICE_HANDLE_T service);
+ extern VCHIQ_STATUS_T vchiq_use_service(VCHIQ_SERVICE_HANDLE_T service);
+ extern VCHIQ_STATUS_T vchiq_release_service(VCHIQ_SERVICE_HANDLE_T service);
+
+-extern VCHIQ_STATUS_T vchiq_queue_message(VCHIQ_SERVICE_HANDLE_T service, const VCHIQ_ELEMENT_T *elements, int count);
+-extern void vchiq_release_message(VCHIQ_SERVICE_HANDLE_T service, VCHIQ_HEADER_T *header);
+-extern VCHIQ_STATUS_T vchiq_queue_bulk_transmit(VCHIQ_SERVICE_HANDLE_T service, const void *data, int size, void *userdata);
+-extern VCHIQ_STATUS_T vchiq_queue_bulk_receive(VCHIQ_SERVICE_HANDLE_T service, void *data, int size, void *userdata);
+-extern VCHIQ_STATUS_T vchiq_queue_bulk_transmit_handle(VCHIQ_SERVICE_HANDLE_T service, VCHI_MEM_HANDLE_T handle, const void *offset, int size, void *userdata);
+-extern VCHIQ_STATUS_T vchiq_queue_bulk_receive_handle(VCHIQ_SERVICE_HANDLE_T service, VCHI_MEM_HANDLE_T handle, void *offset, int size, void *userdata);
+-extern VCHIQ_STATUS_T vchiq_bulk_transmit(VCHIQ_SERVICE_HANDLE_T service, const void *data, int size, void *userdata, VCHIQ_BULK_MODE_T mode);
+-extern VCHIQ_STATUS_T vchiq_bulk_receive(VCHIQ_SERVICE_HANDLE_T service, void *data, int size, void *userdata, VCHIQ_BULK_MODE_T mode);
+-extern VCHIQ_STATUS_T vchiq_bulk_transmit_handle(VCHIQ_SERVICE_HANDLE_T service, VCHI_MEM_HANDLE_T handle, const void *offset, int size, void *userdata, VCHIQ_BULK_MODE_T mode);
+-extern VCHIQ_STATUS_T vchiq_bulk_receive_handle(VCHIQ_SERVICE_HANDLE_T service, VCHI_MEM_HANDLE_T handle, void *offset, int size, void *userdata, VCHIQ_BULK_MODE_T mode);
+-extern int vchiq_get_client_id(VCHIQ_SERVICE_HANDLE_T service);
+-extern VCHIQ_STATUS_T vchiq_get_config(VCHIQ_INSTANCE_T instance, int config_size, VCHIQ_CONFIG_T *pconfig);
+-extern VCHIQ_STATUS_T vchiq_set_service_option(VCHIQ_SERVICE_HANDLE_T service, VCHIQ_SERVICE_OPTION_T option, int value);
+-
+-extern VCHIQ_STATUS_T vchiq_remote_use(VCHIQ_INSTANCE_T instance, VCHIQ_REMOTE_USE_CALLBACK_T callback, void* cb_arg);
++extern VCHIQ_STATUS_T vchiq_queue_message(VCHIQ_SERVICE_HANDLE_T service,
++ const VCHIQ_ELEMENT_T *elements, int count);
++extern void vchiq_release_message(VCHIQ_SERVICE_HANDLE_T service,
++ VCHIQ_HEADER_T *header);
++extern VCHIQ_STATUS_T vchiq_queue_bulk_transmit(VCHIQ_SERVICE_HANDLE_T service,
++ const void *data, int size, void *userdata);
++extern VCHIQ_STATUS_T vchiq_queue_bulk_receive(VCHIQ_SERVICE_HANDLE_T service,
++ void *data, int size, void *userdata);
++extern VCHIQ_STATUS_T vchiq_queue_bulk_transmit_handle(
++ VCHIQ_SERVICE_HANDLE_T service, VCHI_MEM_HANDLE_T handle,
++ const void *offset, int size, void *userdata);
++extern VCHIQ_STATUS_T vchiq_queue_bulk_receive_handle(
++ VCHIQ_SERVICE_HANDLE_T service, VCHI_MEM_HANDLE_T handle,
++ void *offset, int size, void *userdata);
++extern VCHIQ_STATUS_T vchiq_bulk_transmit(VCHIQ_SERVICE_HANDLE_T service,
++ const void *data, int size, void *userdata, VCHIQ_BULK_MODE_T mode);
++extern VCHIQ_STATUS_T vchiq_bulk_receive(VCHIQ_SERVICE_HANDLE_T service,
++ void *data, int size, void *userdata, VCHIQ_BULK_MODE_T mode);
++extern VCHIQ_STATUS_T vchiq_bulk_transmit_handle(VCHIQ_SERVICE_HANDLE_T service,
++ VCHI_MEM_HANDLE_T handle, const void *offset, int size, void *userdata,
++ VCHIQ_BULK_MODE_T mode);
++extern VCHIQ_STATUS_T vchiq_bulk_receive_handle(VCHIQ_SERVICE_HANDLE_T service,
++ VCHI_MEM_HANDLE_T handle, void *offset, int size, void *userdata,
++ VCHIQ_BULK_MODE_T mode);
++extern int vchiq_get_client_id(VCHIQ_SERVICE_HANDLE_T service);
++extern void *vchiq_get_service_userdata(VCHIQ_SERVICE_HANDLE_T service);
++extern int vchiq_get_service_fourcc(VCHIQ_SERVICE_HANDLE_T service);
++extern VCHIQ_STATUS_T vchiq_get_config(VCHIQ_INSTANCE_T instance,
++ int config_size, VCHIQ_CONFIG_T *pconfig);
++extern VCHIQ_STATUS_T vchiq_set_service_option(VCHIQ_SERVICE_HANDLE_T service,
++ VCHIQ_SERVICE_OPTION_T option, int value);
++
++extern VCHIQ_STATUS_T vchiq_remote_use(VCHIQ_INSTANCE_T instance,
++ VCHIQ_REMOTE_USE_CALLBACK_T callback, void *cb_arg);
+ extern VCHIQ_STATUS_T vchiq_remote_release(VCHIQ_INSTANCE_T instance);
+
+-extern VCHIQ_STATUS_T vchiq_dump_phys_mem( VCHIQ_SERVICE_HANDLE_T service, void *ptr, size_t num_bytes );
++extern VCHIQ_STATUS_T vchiq_dump_phys_mem(VCHIQ_SERVICE_HANDLE_T service,
++ void *ptr, size_t num_bytes);
+
+ #endif /* VCHIQ_IF_H */
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_ioctl.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_ioctl.h
+index 06298bf..9bcacd2 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_ioctl.h
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_ioctl.h
+@@ -26,80 +26,89 @@
+ #define VCHIQ_INVALID_HANDLE -1
+
+ typedef struct {
+- VCHIQ_SERVICE_PARAMS_T params;
+- int is_open;
+- int is_vchi;
+- int handle; /* OUT */
++ VCHIQ_SERVICE_PARAMS_T params;
++ int is_open;
++ int is_vchi;
++ int handle; /* OUT */
+ } VCHIQ_CREATE_SERVICE_T;
+
+ typedef struct {
+- int handle;
+- int count;
+- const VCHIQ_ELEMENT_T *elements;
++ int handle;
++ int count;
++ const VCHIQ_ELEMENT_T *elements;
+ } VCHIQ_QUEUE_MESSAGE_T;
+
+ typedef struct {
+- int handle;
+- void *data;
+- int size;
+- void *userdata;
+- VCHIQ_BULK_MODE_T mode;
++ int handle;
++ void *data;
++ int size;
++ void *userdata;
++ VCHIQ_BULK_MODE_T mode;
+ } VCHIQ_QUEUE_BULK_TRANSFER_T;
+
+ typedef struct {
+- VCHIQ_REASON_T reason;
+- VCHIQ_HEADER_T *header;
+- void *service_userdata;
+- void *bulk_userdata;
++ VCHIQ_REASON_T reason;
++ VCHIQ_HEADER_T *header;
++ void *service_userdata;
++ void *bulk_userdata;
+ } VCHIQ_COMPLETION_DATA_T;
+
+ typedef struct {
+- int count;
+- VCHIQ_COMPLETION_DATA_T *buf;
+- int msgbufsize;
+- int msgbufcount; /* IN/OUT */
+- void **msgbufs;
++ int count;
++ VCHIQ_COMPLETION_DATA_T *buf;
++ int msgbufsize;
++ int msgbufcount; /* IN/OUT */
++ void **msgbufs;
+ } VCHIQ_AWAIT_COMPLETION_T;
+
+ typedef struct {
+- int handle;
+- int blocking;
+- int bufsize;
+- void *buf;
++ int handle;
++ int blocking;
++ int bufsize;
++ void *buf;
+ } VCHIQ_DEQUEUE_MESSAGE_T;
+
+ typedef struct {
+- int config_size;
+- VCHIQ_CONFIG_T *pconfig;
++ int config_size;
++ VCHIQ_CONFIG_T *pconfig;
+ } VCHIQ_GET_CONFIG_T;
+
+ typedef struct {
+- int handle;
+- VCHIQ_SERVICE_OPTION_T option;
+- int value;
++ int handle;
++ VCHIQ_SERVICE_OPTION_T option;
++ int value;
+ } VCHIQ_SET_SERVICE_OPTION_T;
+
+ typedef struct {
+- void *virt_addr;
+- size_t num_bytes;
++ void *virt_addr;
++ size_t num_bytes;
+ } VCHIQ_DUMP_MEM_T;
+
+ #define VCHIQ_IOC_CONNECT _IO(VCHIQ_IOC_MAGIC, 0)
+ #define VCHIQ_IOC_SHUTDOWN _IO(VCHIQ_IOC_MAGIC, 1)
+-#define VCHIQ_IOC_CREATE_SERVICE _IOWR(VCHIQ_IOC_MAGIC, 2, VCHIQ_CREATE_SERVICE_T)
++#define VCHIQ_IOC_CREATE_SERVICE \
++ _IOWR(VCHIQ_IOC_MAGIC, 2, VCHIQ_CREATE_SERVICE_T)
+ #define VCHIQ_IOC_REMOVE_SERVICE _IO(VCHIQ_IOC_MAGIC, 3)
+-#define VCHIQ_IOC_QUEUE_MESSAGE _IOW(VCHIQ_IOC_MAGIC, 4, VCHIQ_QUEUE_MESSAGE_T)
+-#define VCHIQ_IOC_QUEUE_BULK_TRANSMIT _IOW(VCHIQ_IOC_MAGIC, 5, VCHIQ_QUEUE_BULK_TRANSFER_T)
+-#define VCHIQ_IOC_QUEUE_BULK_RECEIVE _IOW(VCHIQ_IOC_MAGIC, 6, VCHIQ_QUEUE_BULK_TRANSFER_T)
+-#define VCHIQ_IOC_AWAIT_COMPLETION _IOWR(VCHIQ_IOC_MAGIC, 7, VCHIQ_AWAIT_COMPLETION_T)
+-#define VCHIQ_IOC_DEQUEUE_MESSAGE _IOWR(VCHIQ_IOC_MAGIC, 8, VCHIQ_DEQUEUE_MESSAGE_T)
++#define VCHIQ_IOC_QUEUE_MESSAGE \
++ _IOW(VCHIQ_IOC_MAGIC, 4, VCHIQ_QUEUE_MESSAGE_T)
++#define VCHIQ_IOC_QUEUE_BULK_TRANSMIT \
++ _IOWR(VCHIQ_IOC_MAGIC, 5, VCHIQ_QUEUE_BULK_TRANSFER_T)
++#define VCHIQ_IOC_QUEUE_BULK_RECEIVE \
++ _IOWR(VCHIQ_IOC_MAGIC, 6, VCHIQ_QUEUE_BULK_TRANSFER_T)
++#define VCHIQ_IOC_AWAIT_COMPLETION \
++ _IOWR(VCHIQ_IOC_MAGIC, 7, VCHIQ_AWAIT_COMPLETION_T)
++#define VCHIQ_IOC_DEQUEUE_MESSAGE \
++ _IOWR(VCHIQ_IOC_MAGIC, 8, VCHIQ_DEQUEUE_MESSAGE_T)
+ #define VCHIQ_IOC_GET_CLIENT_ID _IO(VCHIQ_IOC_MAGIC, 9)
+-#define VCHIQ_IOC_GET_CONFIG _IOWR(VCHIQ_IOC_MAGIC, 10, VCHIQ_GET_CONFIG_T)
++#define VCHIQ_IOC_GET_CONFIG \
++ _IOWR(VCHIQ_IOC_MAGIC, 10, VCHIQ_GET_CONFIG_T)
+ #define VCHIQ_IOC_CLOSE_SERVICE _IO(VCHIQ_IOC_MAGIC, 11)
+ #define VCHIQ_IOC_USE_SERVICE _IO(VCHIQ_IOC_MAGIC, 12)
+ #define VCHIQ_IOC_RELEASE_SERVICE _IO(VCHIQ_IOC_MAGIC, 13)
+-#define VCHIQ_IOC_SET_SERVICE_OPTION _IOW(VCHIQ_IOC_MAGIC, 14, VCHIQ_SET_SERVICE_OPTION_T)
+-#define VCHIQ_IOC_DUMP_PHYS_MEM _IOW(VCHIQ_IOC_MAGIC, 15, VCHIQ_DUMP_MEM_T)
++#define VCHIQ_IOC_SET_SERVICE_OPTION \
++ _IOW(VCHIQ_IOC_MAGIC, 14, VCHIQ_SET_SERVICE_OPTION_T)
++#define VCHIQ_IOC_DUMP_PHYS_MEM \
++ _IOW(VCHIQ_IOC_MAGIC, 15, VCHIQ_DUMP_MEM_T)
+ #define VCHIQ_IOC_MAX 15
+
+ #endif
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
+index e1768e4..2855873 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
+@@ -16,22 +16,19 @@
+
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/mutex.h>
+
+ #include "vchiq_core.h"
+ #include "vchiq_arm.h"
+-#include "interface/vcos/vcos_logging.h"
+
+ /* ---- Public Variables ------------------------------------------------- */
+
+-extern VCOS_LOG_CAT_T vchiq_core_log_category;
+-#define VCOS_LOG_CATEGORY (&vchiq_core_log_category)
+-
+ /* ---- Private Constants and Types -------------------------------------- */
+
+ struct vchiq_instance_struct {
+- VCHIQ_STATE_T *state;
++ VCHIQ_STATE_T *state;
+
+- int connected;
++ int connected;
+ };
+
+ /****************************************************************************
+@@ -40,40 +37,42 @@ struct vchiq_instance_struct {
+ *
+ ***************************************************************************/
+
+-VCHIQ_STATUS_T vchiq_initialise( VCHIQ_INSTANCE_T *instanceOut )
++VCHIQ_STATUS_T vchiq_initialise(VCHIQ_INSTANCE_T *instanceOut)
+ {
+- VCHIQ_STATUS_T status = VCHIQ_ERROR;
+- VCHIQ_STATE_T *state;
+- VCHIQ_INSTANCE_T instance = NULL;
++ VCHIQ_STATUS_T status = VCHIQ_ERROR;
++ VCHIQ_STATE_T *state;
++ VCHIQ_INSTANCE_T instance = NULL;
++
++ vchiq_log_trace(vchiq_core_log_level, "%s called", __func__);
+
+- vcos_log_trace( "%s called", __func__ );
++ state = vchiq_get_state();
++ if (!state) {
++ vchiq_log_error(vchiq_core_log_level,
++ "%s: videocore not initialized\n", __func__);
++ goto failed;
++ }
+
+- state = vchiq_get_state();
+- if (!state)
+- {
+- printk( KERN_ERR "%s: videocore not initialized\n", __func__ );
+- goto failed;
+- }
++ instance = kzalloc(sizeof(*instance), GFP_KERNEL);
++ if (!instance) {
++ vchiq_log_error(vchiq_core_log_level,
++ "%s: error allocating vchiq instance\n", __func__);
++ goto failed;
++ }
+
+- instance = kzalloc( sizeof(*instance), GFP_KERNEL );
+- if( !instance )
+- {
+- printk( KERN_ERR "%s: error allocating vchiq instance\n", __func__ );
+- goto failed;
+- }
++ instance->connected = 0;
++ instance->state = state;
+
+- instance->connected = 0;
+- instance->state = state;
++ *instanceOut = instance;
+
+- *instanceOut = instance;
+-
+- status = VCHIQ_SUCCESS;
++ status = VCHIQ_SUCCESS;
+
+ failed:
+- vcos_log_trace( "%s(%p): returning %d", __func__, instance, status );
++ vchiq_log_trace(vchiq_core_log_level,
++ "%s(%p): returning %d", __func__, instance, status);
+
+- return status;
++ return status;
+ }
++EXPORT_SYMBOL(vchiq_initialise);
+
+ /****************************************************************************
+ *
+@@ -81,27 +80,31 @@ failed:
+ *
+ ***************************************************************************/
+
+-VCHIQ_STATUS_T vchiq_shutdown( VCHIQ_INSTANCE_T instance )
++VCHIQ_STATUS_T vchiq_shutdown(VCHIQ_INSTANCE_T instance)
+ {
+- VCHIQ_STATUS_T status;
+- VCHIQ_STATE_T *state = instance->state;
++ VCHIQ_STATUS_T status;
++ VCHIQ_STATE_T *state = instance->state;
+
+- vcos_log_trace( "%s(%p) called", __func__, instance );
++ vchiq_log_trace(vchiq_core_log_level,
++ "%s(%p) called", __func__, instance);
+
+- vcos_mutex_lock(&state->mutex);
++ if (mutex_lock_interruptible(&state->mutex) != 0)
++ return VCHIQ_RETRY;
+
+- /* Remove all services */
+- status = vchiq_shutdown_internal(state, instance);
++ /* Remove all services */
++ status = vchiq_shutdown_internal(state, instance);
+
+- vcos_mutex_unlock(&state->mutex);
++ mutex_unlock(&state->mutex);
+
+- if (status == VCHIQ_SUCCESS)
+- kfree(instance);
++ if (status == VCHIQ_SUCCESS)
++ kfree(instance);
+
+- vcos_log_trace( "%s(%p): returning %d", __func__, instance, status );
++ vchiq_log_trace(vchiq_core_log_level,
++ "%s(%p): returning %d", __func__, instance, status);
+
+- return status;
++ return status;
+ }
++EXPORT_SYMBOL(vchiq_shutdown);
+
+ /****************************************************************************
+ *
+@@ -111,7 +114,7 @@ VCHIQ_STATUS_T vchiq_shutdown( VCHIQ_INSTANCE_T instance )
+
+ int vchiq_is_connected(VCHIQ_INSTANCE_T instance)
+ {
+- return instance->connected;
++ return instance->connected;
+ }
+
+ /****************************************************************************
+@@ -122,28 +125,32 @@ int vchiq_is_connected(VCHIQ_INSTANCE_T instance)
+
+ VCHIQ_STATUS_T vchiq_connect(VCHIQ_INSTANCE_T instance)
+ {
+- VCHIQ_STATUS_T status;
+- VCHIQ_STATE_T *state = instance->state;
++ VCHIQ_STATUS_T status;
++ VCHIQ_STATE_T *state = instance->state;
+
+- vcos_log_trace( "%s(%p) called", __func__, instance );
++ vchiq_log_trace(vchiq_core_log_level,
++ "%s(%p) called", __func__, instance);
+
+- if (vcos_mutex_lock(&state->mutex) != VCOS_SUCCESS) {
+- vcos_log_trace( "%s: call to vcos_mutex_lock failed", __func__ );
+- status = VCHIQ_RETRY;
+- goto failed;
+- }
+- status = vchiq_connect_internal(state, instance);
++ if (mutex_lock_interruptible(&state->mutex) != 0) {
++ vchiq_log_trace(vchiq_core_log_level,
++ "%s: call to mutex_lock failed", __func__);
++ status = VCHIQ_RETRY;
++ goto failed;
++ }
++ status = vchiq_connect_internal(state, instance);
+
+- if (status == VCHIQ_SUCCESS)
+- instance->connected = 1;
++ if (status == VCHIQ_SUCCESS)
++ instance->connected = 1;
+
+- vcos_mutex_unlock(&state->mutex);
++ mutex_unlock(&state->mutex);
+
+ failed:
+- vcos_log_trace( "%s(%p): returning %d", __func__, instance, status );
++ vchiq_log_trace(vchiq_core_log_level,
++ "%s(%p): returning %d", __func__, instance, status);
+
+- return status;
++ return status;
+ }
++EXPORT_SYMBOL(vchiq_connect);
+
+ /****************************************************************************
+ *
+@@ -152,146 +159,83 @@ failed:
+ ***************************************************************************/
+
+ VCHIQ_STATUS_T vchiq_add_service(
+- VCHIQ_INSTANCE_T instance,
+- int fourcc,
+- VCHIQ_CALLBACK_T callback,
+- void *userdata,
+- VCHIQ_SERVICE_HANDLE_T *pservice)
++ VCHIQ_INSTANCE_T instance,
++ const VCHIQ_SERVICE_PARAMS_T *params,
++ VCHIQ_SERVICE_HANDLE_T *phandle)
+ {
+- VCHIQ_SERVICE_PARAMS_T params;
++ VCHIQ_STATUS_T status;
++ VCHIQ_STATE_T *state = instance->state;
++ VCHIQ_SERVICE_T *service = NULL;
++ int srvstate;
+
+- params.fourcc = fourcc;
+- params.callback = callback;
+- params.userdata = userdata;
+- params.version = 0;
+- params.version_min = 0;
++ vchiq_log_trace(vchiq_core_log_level,
++ "%s(%p) called", __func__, instance);
+
+- return vchiq_add_service_params(instance, &params, pservice);
+-}
+-
+-/****************************************************************************
+-*
+-* vchiq_open_service
+-*
+-***************************************************************************/
++ *phandle = VCHIQ_SERVICE_HANDLE_INVALID;
+
+-VCHIQ_STATUS_T vchiq_open_service(
+- VCHIQ_INSTANCE_T instance,
+- int fourcc,
+- VCHIQ_CALLBACK_T callback,
+- void *userdata,
+- VCHIQ_SERVICE_HANDLE_T *pservice)
+-{
+- VCHIQ_SERVICE_PARAMS_T params;
++ srvstate = vchiq_is_connected(instance)
++ ? VCHIQ_SRVSTATE_LISTENING
++ : VCHIQ_SRVSTATE_HIDDEN;
+
+- params.fourcc = fourcc;
+- params.callback = callback;
+- params.userdata = userdata;
+- params.version = 0;
+- params.version_min = 0;
++ service = vchiq_add_service_internal(
++ state,
++ params,
++ srvstate,
++ instance);
+
+- return vchiq_open_service_params(instance, &params, pservice);
+-}
++ if (service) {
++ *phandle = service->handle;
++ status = VCHIQ_SUCCESS;
++ } else
++ status = VCHIQ_ERROR;
+
+-/****************************************************************************
+-*
+-* vchiq_add_service_params
+-*
+-***************************************************************************/
++ vchiq_log_trace(vchiq_core_log_level,
++ "%s(%p): returning %d", __func__, instance, status);
+
+-VCHIQ_STATUS_T vchiq_add_service_params(
+- VCHIQ_INSTANCE_T instance,
+- const VCHIQ_SERVICE_PARAMS_T *params,
+- VCHIQ_SERVICE_HANDLE_T *pservice)
+-{
+- VCHIQ_STATUS_T status;
+- VCHIQ_STATE_T *state = instance->state;
+- VCHIQ_SERVICE_T *service;
+- int srvstate;
+-
+- vcos_log_trace( "%s(%p) called", __func__, instance );
+-
+- *pservice = NULL;
+-
+- srvstate = vchiq_is_connected( instance )
+- ? VCHIQ_SRVSTATE_LISTENING
+- : VCHIQ_SRVSTATE_HIDDEN;
+-
+- vcos_mutex_lock(&state->mutex);
+-
+- service = vchiq_add_service_internal(
+- state,
+- params,
+- srvstate,
+- instance);
+-
+- vcos_mutex_unlock(&state->mutex);
+-
+- if ( service )
+- {
+- *pservice = &service->base;
+- status = VCHIQ_SUCCESS;
+- }
+- else
+- {
+- status = VCHIQ_ERROR;
+- }
+-
+- vcos_log_trace( "%s(%p): returning %d", __func__, instance, status );
+-
+- return status;
++ return status;
+ }
++EXPORT_SYMBOL(vchiq_add_service);
+
+ /****************************************************************************
+ *
+-* vchiq_open_service_params
++* vchiq_open_service
+ *
+ ***************************************************************************/
+
+-VCHIQ_STATUS_T vchiq_open_service_params(
+- VCHIQ_INSTANCE_T instance,
+- const VCHIQ_SERVICE_PARAMS_T *params,
+- VCHIQ_SERVICE_HANDLE_T *pservice)
++VCHIQ_STATUS_T vchiq_open_service(
++ VCHIQ_INSTANCE_T instance,
++ const VCHIQ_SERVICE_PARAMS_T *params,
++ VCHIQ_SERVICE_HANDLE_T *phandle)
+ {
+- VCHIQ_STATUS_T status = VCHIQ_ERROR;
+- VCHIQ_STATE_T *state = instance->state;
+- VCHIQ_SERVICE_T *service;
+-
+- vcos_log_trace( "%s(%p) called", __func__, instance );
++ VCHIQ_STATUS_T status = VCHIQ_ERROR;
++ VCHIQ_STATE_T *state = instance->state;
++ VCHIQ_SERVICE_T *service = NULL;
+
+- *pservice = NULL;
++ vchiq_log_trace(vchiq_core_log_level,
++ "%s(%p) called", __func__, instance);
+
+- if (!vchiq_is_connected(instance))
+- goto failed;
++ *phandle = VCHIQ_SERVICE_HANDLE_INVALID;
+
+- vcos_mutex_lock(&state->mutex);
++ if (!vchiq_is_connected(instance))
++ goto failed;
+
+- service = vchiq_add_service_internal(state,
+- params,
+- VCHIQ_SRVSTATE_OPENING,
+- instance);
++ service = vchiq_add_service_internal(state,
++ params,
++ VCHIQ_SRVSTATE_OPENING,
++ instance);
+
+- vcos_mutex_unlock(&state->mutex);
+-
+- if ( service )
+- {
+- status = vchiq_open_service_internal(service, current->pid);
+- if ( status == VCHIQ_SUCCESS )
+- *pservice = &service->base;
+- else
+- vchiq_remove_service(&service->base);
+- }
++ if (service) {
++ status = vchiq_open_service_internal(service, current->pid);
++ if (status == VCHIQ_SUCCESS)
++ *phandle = service->handle;
++ else
++ vchiq_remove_service(service->handle);
++ }
+
+ failed:
+- vcos_log_trace( "%s(%p): returning %d", __func__, instance, status );
++ vchiq_log_trace(vchiq_core_log_level,
++ "%s(%p): returning %d", __func__, instance, status);
+
+- return status;
++ return status;
+ }
+-
+-EXPORT_SYMBOL(vchiq_initialise);
+-EXPORT_SYMBOL(vchiq_shutdown);
+-EXPORT_SYMBOL(vchiq_connect);
+-EXPORT_SYMBOL(vchiq_add_service);
+ EXPORT_SYMBOL(vchiq_open_service);
+-EXPORT_SYMBOL(vchiq_add_service_params);
+-EXPORT_SYMBOL(vchiq_open_service_params);
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_lib.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_lib.c
+deleted file mode 100644
+index f1a8f42..0000000
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_lib.c
++++ /dev/null
+@@ -1,1628 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom Corporation. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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 <unistd.h>
+-#include <fcntl.h>
+-#include <sys/ioctl.h>
+-#include <stdio.h>
+-
+-#include "vchiq.h"
+-#include "vchiq_cfg.h"
+-#include "vchiq_ioctl.h"
+-#include "interface/vchi/vchi.h"
+-#include "interface/vchi/common/endian.h"
+-#include "interface/vcos/vcos.h"
+-
+-#define VCHIQ_MAX_INSTANCE_SERVICES 32
+-#define MSGBUF_SIZE (VCHIQ_MAX_MSG_SIZE + sizeof(VCHIQ_HEADER_T))
+-
+-#define RETRY(r,x) do { r = x; } while ((r == -1) && (errno == EINTR))
+-
+-#define VCOS_LOG_CATEGORY (&vchiq_lib_log_category)
+-
+-typedef struct vchiq_service_struct
+-{
+- VCHIQ_SERVICE_BASE_T base;
+- int handle;
+- int fd;
+- VCHI_CALLBACK_T vchi_callback;
+- void *peek_buf;
+- int peek_size;
+- int client_id;
+-} VCHIQ_SERVICE_T;
+-
+-typedef struct vchiq_service_struct VCHI_SERVICE_T;
+-
+-struct vchiq_instance_struct
+-{
+- int fd;
+- int initialised;
+- int connected;
+- VCOS_THREAD_T completion_thread;
+- VCOS_MUTEX_T mutex;
+- int used_services;
+- VCHIQ_SERVICE_T services[VCHIQ_MAX_INSTANCE_SERVICES];
+-} vchiq_instance;
+-
+-typedef struct vchiq_instance_struct VCHI_STATE_T;
+-
+-/* Local data */
+-static VCOS_LOG_LEVEL_T vchiq_default_lib_log_level = VCOS_LOG_WARN;
+-static VCOS_LOG_CAT_T vchiq_lib_log_category;
+-static VCOS_MUTEX_T vchiq_lib_mutex;
+-static void *free_msgbufs;
+-
+-
+-/* Local utility functions */
+-static VCHIQ_INSTANCE_T
+-vchiq_lib_init(void);
+-
+-static void *completion_thread(void *);
+-
+-static VCHIQ_STATUS_T
+-create_service(VCHIQ_INSTANCE_T instance,
+- const VCHIQ_SERVICE_PARAMS_T *params,
+- VCHI_CALLBACK_T vchi_callback,
+- int is_open,
+- VCHIQ_SERVICE_HANDLE_T *pservice);
+-
+-static int
+-fill_peek_buf(VCHI_SERVICE_T *service,
+- VCHI_FLAGS_T flags);
+-
+-static void *
+-alloc_msgbuf(void);
+-
+-static void
+-free_msgbuf(void *buf);
+-
+-static __inline int
+-is_valid_instance(VCHIQ_INSTANCE_T instance)
+-{
+- return (instance == &vchiq_instance) && (instance->initialised > 0);
+-}
+-
+-static __inline int
+-is_valid_service(VCHIQ_SERVICE_T *service)
+-{
+- return ((service != NULL) && (service->fd != VCHIQ_INVALID_HANDLE));
+-}
+-
+-/*
+- * VCHIQ API
+- */
+-
+-VCHIQ_STATUS_T
+-vchiq_initialise(VCHIQ_INSTANCE_T *pinstance)
+-{
+- VCHIQ_INSTANCE_T instance;
+-
+- instance = vchiq_lib_init();
+-
+- vcos_log_trace( "%s: returning instance handle %p", __func__, instance );
+-
+- *pinstance = instance;
+-
+- return (instance != NULL) ? VCHIQ_SUCCESS : VCHIQ_ERROR;
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_shutdown(VCHIQ_INSTANCE_T instance)
+-{
+- vcos_log_trace( "%s called", __func__ );
+-
+- if (!is_valid_instance(instance))
+- return VCHIQ_ERROR;
+-
+- vcos_mutex_lock(&instance->mutex);
+-
+- if (instance->initialised == 1)
+- {
+- int i;
+-
+- instance->initialised = -1; /* Enter limbo */
+-
+- /* Remove all services */
+-
+- for (i = 0; i < instance->used_services; i++)
+- {
+- if (instance->services[i].handle != VCHIQ_INVALID_HANDLE)
+- {
+- vchiq_remove_service(&instance->services[i].base);
+- instance->services[i].handle = VCHIQ_INVALID_HANDLE;
+- }
+- }
+-
+- if (instance->connected)
+- {
+- int ret;
+- RETRY(ret, ioctl(instance->fd, VCHIQ_IOC_SHUTDOWN, 0));
+- vcos_assert(ret == 0);
+- vcos_thread_join(&instance->completion_thread, NULL);
+- instance->connected = 0;
+- }
+-
+- close(instance->fd);
+- instance->fd = -1;
+- }
+- else if (instance->initialised > 1)
+- {
+- instance->initialised--;
+- }
+-
+- vcos_mutex_unlock(&instance->mutex);
+-
+- vcos_global_lock();
+-
+- if (instance->initialised == -1)
+- {
+- vcos_mutex_delete(&instance->mutex);
+- instance->initialised = 0;
+- }
+-
+- vcos_global_unlock();
+-
+- vcos_log_trace( "%s returning", __func__ );
+-
+- return VCHIQ_SUCCESS;
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_connect(VCHIQ_INSTANCE_T instance)
+-{
+- VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+-
+- vcos_log_trace( "%s called", __func__ );
+-
+- if (!is_valid_instance(instance))
+- return VCHIQ_ERROR;
+-
+- vcos_mutex_lock(&instance->mutex);
+-
+- if (!instance->connected)
+- {
+- int ret = ioctl(instance->fd, VCHIQ_IOC_CONNECT, 0);
+- if (ret == 0)
+- {
+- VCOS_THREAD_ATTR_T attrs;
+- instance->connected = 1;
+- vcos_thread_attr_init(&attrs);
+- vcos_thread_create(&instance->completion_thread, "VCHIQ completion",
+- &attrs, completion_thread, instance);
+- }
+- else
+- {
+- status = VCHIQ_ERROR;
+- }
+- }
+-
+- vcos_mutex_unlock(&instance->mutex);
+-
+- return status;
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_add_service(VCHIQ_INSTANCE_T instance,
+- int fourcc,
+- VCHIQ_CALLBACK_T callback,
+- void *userdata,
+- VCHIQ_SERVICE_HANDLE_T *pservice)
+-{
+- VCHIQ_SERVICE_PARAMS_T params;
+-
+- params.fourcc = fourcc;
+- params.callback = callback;
+- params.userdata = userdata;
+- params.version = 0;
+- params.version_min = 0;
+-
+- return vchiq_add_service_params(instance, &params, pservice);
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_open_service(VCHIQ_INSTANCE_T instance,
+- int fourcc,
+- VCHIQ_CALLBACK_T callback,
+- void *userdata,
+- VCHIQ_SERVICE_HANDLE_T *pservice)
+-{
+- VCHIQ_SERVICE_PARAMS_T params;
+-
+- params.fourcc = fourcc;
+- params.callback = callback;
+- params.userdata = userdata;
+- params.version = 0;
+- params.version_min = 0;
+-
+- return vchiq_open_service_params(instance, &params, pservice);
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_add_service_params(VCHIQ_INSTANCE_T instance,
+- const VCHIQ_SERVICE_PARAMS_T *params,
+- VCHIQ_SERVICE_HANDLE_T *pservice)
+-{
+- VCHIQ_STATUS_T status;
+-
+- vcos_log_trace( "%s called fourcc = 0x%08x (%c%c%c%c)",
+- __func__,
+- params->fourcc,
+- (params->fourcc >> 24) & 0xff,
+- (params->fourcc >> 16) & 0xff,
+- (params->fourcc >> 8) & 0xff,
+- (params->fourcc ) & 0xff );
+-
+- if (!params->callback)
+- return VCHIQ_ERROR;
+-
+- if (!is_valid_instance(instance))
+- return VCHIQ_ERROR;
+-
+- status = create_service(instance,
+- params,
+- NULL/*vchi_callback*/,
+- 0/*!open*/,
+- pservice);
+-
+- vcos_log_trace( "%s returning service handle = 0x%08x", __func__, (uint32_t)*pservice );
+-
+- return status;
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_open_service_params(VCHIQ_INSTANCE_T instance,
+- const VCHIQ_SERVICE_PARAMS_T *params,
+- VCHIQ_SERVICE_HANDLE_T *pservice)
+-{
+- VCHIQ_STATUS_T status;
+-
+- vcos_log_trace( "%s called fourcc = 0x%08x (%c%c%c%c)",
+- __func__,
+- params->fourcc,
+- (params->fourcc >> 24) & 0xff,
+- (params->fourcc >> 16) & 0xff,
+- (params->fourcc >> 8) & 0xff,
+- (params->fourcc ) & 0xff );
+-
+- if (!params->callback)
+- return VCHIQ_ERROR;
+-
+- if (!is_valid_instance(instance))
+- return VCHIQ_ERROR;
+-
+- status = create_service(instance,
+- params,
+- NULL/*vchi_callback*/,
+- 1/*open*/,
+- pservice);
+-
+- vcos_log_trace( "%s returning service handle = 0x%08x", __func__, (uint32_t)*pservice );
+-
+- return status;
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_close_service(VCHIQ_SERVICE_HANDLE_T handle)
+-{
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle;
+- int ret;
+-
+- vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle );
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- RETRY(ret,ioctl(service->fd, VCHIQ_IOC_CLOSE_SERVICE, service->handle));
+-
+- if (ret != 0)
+- return VCHIQ_ERROR;
+-
+- service->handle = VCHIQ_INVALID_HANDLE;
+- return VCHIQ_SUCCESS;
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_remove_service(VCHIQ_SERVICE_HANDLE_T handle)
+-{
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle;
+- int ret;
+-
+- vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle );
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- RETRY(ret,ioctl(service->fd, VCHIQ_IOC_REMOVE_SERVICE, service->handle));
+-
+- if (ret != 0)
+- return VCHIQ_ERROR;
+-
+- service->handle = VCHIQ_INVALID_HANDLE;
+- return VCHIQ_SUCCESS;
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_queue_message(VCHIQ_SERVICE_HANDLE_T handle,
+- const VCHIQ_ELEMENT_T *elements,
+- int count)
+-{
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle;
+- VCHIQ_QUEUE_MESSAGE_T args;
+- int ret;
+-
+- vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle );
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- args.handle = service->handle;
+- args.elements = elements;
+- args.count = count;
+- RETRY(ret, ioctl(service->fd, VCHIQ_IOC_QUEUE_MESSAGE, &args));
+-
+- return (ret >= 0) ? VCHIQ_SUCCESS : VCHIQ_ERROR;
+-}
+-
+-void
+-vchiq_release_message(VCHIQ_SERVICE_HANDLE_T handle,
+- VCHIQ_HEADER_T *header)
+-{
+- vcos_log_trace( "%s handle=%08x, header=%x", __func__, (uint32_t)handle, (uint32_t)header );
+-
+- free_msgbuf(header);
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_queue_bulk_transmit(VCHIQ_SERVICE_HANDLE_T handle,
+- const void *data,
+- int size,
+- void *userdata)
+-{
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle;
+- VCHIQ_QUEUE_BULK_TRANSFER_T args;
+- int ret;
+-
+- vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle );
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- args.handle = service->handle;
+- args.data = (void *)data;
+- args.size = size;
+- args.userdata = userdata;
+- args.mode = VCHIQ_BULK_MODE_CALLBACK;
+- RETRY(ret, ioctl(service->fd, VCHIQ_IOC_QUEUE_BULK_TRANSMIT, &args));
+-
+- return (ret >= 0) ? VCHIQ_SUCCESS : VCHIQ_ERROR;
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_queue_bulk_receive(VCHIQ_SERVICE_HANDLE_T handle,
+- void *data,
+- int size,
+- void *userdata)
+-{
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle;
+- VCHIQ_QUEUE_BULK_TRANSFER_T args;
+- int ret;
+-
+- vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle );
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- args.handle = service->handle;
+- args.data = data;
+- args.size = size;
+- args.userdata = userdata;
+- args.mode = VCHIQ_BULK_MODE_CALLBACK;
+- RETRY(ret, ioctl(service->fd, VCHIQ_IOC_QUEUE_BULK_RECEIVE, &args));
+-
+- return (ret >= 0) ? VCHIQ_SUCCESS : VCHIQ_ERROR;
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_queue_bulk_transmit_handle(VCHIQ_SERVICE_HANDLE_T handle,
+- VCHI_MEM_HANDLE_T memhandle,
+- const void *offset,
+- int size,
+- void *userdata)
+-{
+- vcos_assert(memhandle == VCHI_MEM_HANDLE_INVALID);
+-
+- vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle );
+-
+- return vchiq_queue_bulk_transmit(handle, offset, size, userdata);
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_queue_bulk_receive_handle(VCHIQ_SERVICE_HANDLE_T handle,
+- VCHI_MEM_HANDLE_T memhandle,
+- void *offset,
+- int size,
+- void *userdata)
+-{
+- vcos_assert(memhandle == VCHI_MEM_HANDLE_INVALID);
+-
+- vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle );
+-
+- return vchiq_queue_bulk_receive(handle, offset, size, userdata);
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_bulk_transmit(VCHIQ_SERVICE_HANDLE_T handle,
+- const void *data,
+- int size,
+- void *userdata,
+- VCHIQ_BULK_MODE_T mode)
+-{
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle;
+- VCHIQ_QUEUE_BULK_TRANSFER_T args;
+- int ret;
+-
+- vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle );
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- args.handle = service->handle;
+- args.data = (void *)data;
+- args.size = size;
+- args.userdata = userdata;
+- args.mode = mode;
+- RETRY(ret, ioctl(service->fd, VCHIQ_IOC_QUEUE_BULK_TRANSMIT, &args));
+-
+- return (ret >= 0) ? VCHIQ_SUCCESS : VCHIQ_ERROR;
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_bulk_receive(VCHIQ_SERVICE_HANDLE_T handle,
+- void *data,
+- int size,
+- void *userdata,
+- VCHIQ_BULK_MODE_T mode)
+-{
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle;
+- VCHIQ_QUEUE_BULK_TRANSFER_T args;
+- int ret;
+-
+- vcos_log_trace( "%s called service handle = 0x%08x", __func__, (uint32_t)handle );
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- args.handle = service->handle;
+- args.data = data;
+- args.size = size;
+- args.userdata = userdata;
+- args.mode = mode;
+- RETRY(ret, ioctl(service->fd, VCHIQ_IOC_QUEUE_BULK_RECEIVE, &args));
+-
+- return (ret >= 0) ? VCHIQ_SUCCESS : VCHIQ_ERROR;
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_bulk_transmit_handle(VCHIQ_SERVICE_HANDLE_T handle,
+- VCHI_MEM_HANDLE_T memhandle,
+- const void *offset,
+- int size,
+- void *userdata,
+- VCHIQ_BULK_MODE_T mode)
+-{
+- vcos_assert(memhandle == VCHI_MEM_HANDLE_INVALID);
+-
+- return vchiq_bulk_transmit(handle, offset, size, userdata, mode);
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_bulk_receive_handle(VCHIQ_SERVICE_HANDLE_T handle,
+- VCHI_MEM_HANDLE_T memhandle,
+- void *offset,
+- int size,
+- void *userdata,
+- VCHIQ_BULK_MODE_T mode)
+-{
+- vcos_assert(memhandle == VCHI_MEM_HANDLE_INVALID);
+-
+- return vchiq_bulk_receive(handle, offset, size, userdata, mode);
+-}
+-
+-int
+-vchiq_get_client_id(VCHIQ_SERVICE_HANDLE_T handle)
+-{
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle;
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- return ioctl(service->fd, VCHIQ_IOC_GET_CLIENT_ID, service->handle);
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_get_config(VCHIQ_INSTANCE_T instance,
+- int config_size,
+- VCHIQ_CONFIG_T *pconfig)
+-{
+- VCHIQ_GET_CONFIG_T args;
+- int ret;
+-
+- if (!is_valid_instance(instance))
+- return VCHIQ_ERROR;
+-
+- args.config_size = config_size;
+- args.pconfig = pconfig;
+-
+- RETRY(ret, ioctl(instance->fd, VCHIQ_IOC_GET_CONFIG, &args));
+-
+- return (ret >= 0) ? VCHIQ_SUCCESS : VCHIQ_ERROR;
+-}
+-
+-int32_t
+-vchiq_use_service( const VCHIQ_SERVICE_HANDLE_T handle )
+-{
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle;
+- int ret;
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- RETRY(ret,ioctl(service->fd, VCHIQ_IOC_USE_SERVICE, service->handle));
+- return ret;
+-}
+-
+-int32_t
+-vchiq_release_service( const VCHIQ_SERVICE_HANDLE_T handle )
+-{
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle;
+- int ret;
+- RETRY(ret,ioctl(service->fd, VCHIQ_IOC_RELEASE_SERVICE, service->handle));
+- return ret;
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_set_service_option(VCHIQ_SERVICE_HANDLE_T handle,
+- VCHIQ_SERVICE_OPTION_T option, int value)
+-{
+- VCHIQ_SET_SERVICE_OPTION_T args;
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle;
+- int ret;
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- args.handle = service->handle;
+- args.option = option;
+- args.value = value;
+-
+- RETRY(ret, ioctl(service->fd, VCHIQ_IOC_SET_SERVICE_OPTION, &args));
+-
+- return (ret >= 0) ? VCHIQ_SUCCESS : VCHIQ_ERROR;
+-}
+-
+-/*
+- * VCHI API
+- */
+-
+-/* ----------------------------------------------------------------------
+- * return pointer to the mphi message driver function table
+- * -------------------------------------------------------------------- */
+-const VCHI_MESSAGE_DRIVER_T *
+-vchi_mphi_message_driver_func_table( void )
+-{
+- return NULL;
+-}
+-
+-/* ----------------------------------------------------------------------
+- * return a pointer to the 'single' connection driver fops
+- * -------------------------------------------------------------------- */
+-const VCHI_CONNECTION_API_T *
+-single_get_func_table( void )
+-{
+- return NULL;
+-}
+-
+-VCHI_CONNECTION_T *
+-vchi_create_connection( const VCHI_CONNECTION_API_T * function_table,
+- const VCHI_MESSAGE_DRIVER_T * low_level )
+-{
+- vcos_unused(function_table);
+- vcos_unused(low_level);
+-
+- return NULL;
+-}
+-
+-/***********************************************************
+- * Name: vchi_msg_peek
+- *
+- * Arguments: const VCHI_SERVICE_HANDLE_T handle,
+- * void **data,
+- * uint32_t *msg_size,
+- * VCHI_FLAGS_T flags
+- *
+- * Description: Routine to return a pointer to the current message (to allow in place processing)
+- * The message can be removed using vchi_msg_remove when you're finished
+- *
+- * Returns: int32_t - success == 0
+- *
+- ***********************************************************/
+-int32_t
+-vchi_msg_peek( VCHI_SERVICE_HANDLE_T handle,
+- void **data,
+- uint32_t *msg_size,
+- VCHI_FLAGS_T flags )
+-{
+- VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle;
+- int ret;
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- ret = fill_peek_buf(service, flags);
+-
+- if (ret == 0)
+- {
+- *data = service->peek_buf;
+- *msg_size = service->peek_size;
+- }
+-
+- return ret;
+-}
+-
+-/***********************************************************
+- * Name: vchi_msg_remove
+- *
+- * Arguments: const VCHI_SERVICE_HANDLE_T handle,
+- *
+- * Description: Routine to remove a message (after it has been read with vchi_msg_peek)
+- *
+- * Returns: int32_t - success == 0
+- *
+- ***********************************************************/
+-int32_t
+-vchi_msg_remove( VCHI_SERVICE_HANDLE_T handle )
+-{
+- VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle;
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- /* Why would you call vchi_msg_remove without calling vchi_msg_peek first? */
+- vcos_assert(service->peek_size >= 0);
+-
+- /* Invalidate the content but reuse the buffer */
+- service->peek_size = -1;
+-
+- return 0;
+-}
+-
+-/***********************************************************
+- * Name: vchi_msg_queue
+- *
+- * Arguments: VCHI_SERVICE_HANDLE_T handle,
+- * const void *data,
+- * uint32_t data_size,
+- * VCHI_FLAGS_T flags,
+- * void *msg_handle,
+- *
+- * Description: Thin wrapper to queue a message onto a connection
+- *
+- * Returns: int32_t - success == 0
+- *
+- ***********************************************************/
+-int32_t
+-vchi_msg_queue( VCHI_SERVICE_HANDLE_T handle,
+- const void * data,
+- uint32_t data_size,
+- VCHI_FLAGS_T flags,
+- void * msg_handle )
+-{
+- VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle;
+- VCHIQ_QUEUE_MESSAGE_T args;
+- VCHIQ_ELEMENT_T element = {data, data_size};
+- int ret;
+-
+- vcos_unused(msg_handle);
+- vcos_assert(flags == VCHI_FLAGS_BLOCK_UNTIL_QUEUED);
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- args.handle = service->handle;
+- args.elements = &element;
+- args.count = 1;
+- RETRY(ret, ioctl(service->fd, VCHIQ_IOC_QUEUE_MESSAGE, &args));
+-
+- return ret;
+-}
+-
+-/***********************************************************
+- * Name: vchi_bulk_queue_receive
+- *
+- * Arguments: VCHI_BULK_HANDLE_T handle,
+- * void *data_dst,
+- * const uint32_t data_size,
+- * VCHI_FLAGS_T flags
+- * void *bulk_handle
+- *
+- * Description: Routine to setup a rcv buffer
+- *
+- * Returns: int32_t - success == 0
+- *
+- ***********************************************************/
+-int32_t
+-vchi_bulk_queue_receive( VCHI_SERVICE_HANDLE_T handle,
+- void * data_dst,
+- uint32_t data_size,
+- VCHI_FLAGS_T flags,
+- void * bulk_handle )
+-{
+- VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle;
+- VCHIQ_QUEUE_BULK_TRANSFER_T args;
+- int ret;
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- switch ((int)flags) {
+- case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+- args.mode = VCHIQ_BULK_MODE_CALLBACK;
+- break;
+- case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
+- args.mode = VCHIQ_BULK_MODE_BLOCKING;
+- break;
+- case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+- case VCHI_FLAGS_NONE:
+- args.mode = VCHIQ_BULK_MODE_NOCALLBACK;
+- break;
+- default:
+- vcos_assert(0);
+- break;
+- }
+-
+- args.handle = service->handle;
+- args.data = data_dst;
+- args.size = data_size;
+- args.userdata = bulk_handle;
+- RETRY(ret, ioctl(service->fd, VCHIQ_IOC_QUEUE_BULK_RECEIVE, &args));
+-
+- return ret;
+-}
+-
+-/***********************************************************
+- * Name: vchi_bulk_queue_transmit
+- *
+- * Arguments: VCHI_BULK_HANDLE_T handle,
+- * const void *data_src,
+- * uint32_t data_size,
+- * VCHI_FLAGS_T flags,
+- * void *bulk_handle
+- *
+- * Description: Routine to transmit some data
+- *
+- * Returns: int32_t - success == 0
+- *
+- ***********************************************************/
+-int32_t
+-vchi_bulk_queue_transmit( VCHI_SERVICE_HANDLE_T handle,
+- const void * data_src,
+- uint32_t data_size,
+- VCHI_FLAGS_T flags,
+- void * bulk_handle )
+-{
+- VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle;
+- VCHIQ_QUEUE_BULK_TRANSFER_T args;
+- int ret;
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- switch ((int)flags) {
+- case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+- args.mode = VCHIQ_BULK_MODE_CALLBACK;
+- break;
+- case VCHI_FLAGS_BLOCK_UNTIL_DATA_READ:
+- case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
+- args.mode = VCHIQ_BULK_MODE_BLOCKING;
+- break;
+- case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+- case VCHI_FLAGS_NONE:
+- args.mode = VCHIQ_BULK_MODE_NOCALLBACK;
+- break;
+- default:
+- vcos_assert(0);
+- break;
+- }
+-
+- args.handle = service->handle;
+- args.data = (void *)data_src;
+- args.size = data_size;
+- args.userdata = bulk_handle;
+- RETRY(ret, ioctl(service->fd, VCHIQ_IOC_QUEUE_BULK_TRANSMIT, &args));
+-
+- return ret;
+-}
+-
+-/***********************************************************
+- * Name: vchi_msg_dequeue
+- *
+- * Arguments: VCHI_SERVICE_HANDLE_T handle,
+- * void *data,
+- * uint32_t max_data_size_to_read,
+- * uint32_t *actual_msg_size
+- * VCHI_FLAGS_T flags
+- *
+- * Description: Routine to dequeue a message into the supplied buffer
+- *
+- * Returns: int32_t - success == 0
+- *
+- ***********************************************************/
+-int32_t
+-vchi_msg_dequeue( VCHI_SERVICE_HANDLE_T handle,
+- void *data,
+- uint32_t max_data_size_to_read,
+- uint32_t *actual_msg_size,
+- VCHI_FLAGS_T flags )
+-{
+- VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle;
+- VCHIQ_DEQUEUE_MESSAGE_T args;
+- int ret;
+-
+- vcos_assert(flags == VCHI_FLAGS_NONE || flags == VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE);
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- if (service->peek_size >= 0)
+- {
+- fprintf(stderr, "vchi_msg_dequeue -> using peek buffer\n");
+- if ((uint32_t)service->peek_size <= max_data_size_to_read)
+- {
+- memcpy(data, service->peek_buf, service->peek_size);
+- *actual_msg_size = service->peek_size;
+- /* Invalidate the peek data, but retain the buffer */
+- service->peek_size = -1;
+- ret = 0;
+- }
+- else
+- {
+- ret = -1;
+- }
+- }
+- else
+- {
+- args.handle = service->handle;
+- args.blocking = (flags == VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE);
+- args.bufsize = max_data_size_to_read;
+- args.buf = data;
+- RETRY(ret, ioctl(service->fd, VCHIQ_IOC_DEQUEUE_MESSAGE, &args));
+- if (ret >= 0)
+- {
+- *actual_msg_size = ret;
+- ret = 0;
+- }
+- }
+-
+- if ((ret < 0) && (errno != EWOULDBLOCK))
+- fprintf(stderr, "vchi_msg_dequeue -> %d(%d)\n", ret, errno);
+-
+- return ret;
+-}
+-
+-/***********************************************************
+- * Name: vchi_msg_queuev
+- *
+- * Arguments: VCHI_SERVICE_HANDLE_T handle,
+- * const void *data,
+- * uint32_t data_size,
+- * VCHI_FLAGS_T flags,
+- * void *msg_handle
+- *
+- * Description: Thin wrapper to queue a message onto a connection
+- *
+- * Returns: int32_t - success == 0
+- *
+- ***********************************************************/
+-
+-vcos_static_assert(sizeof(VCHI_MSG_VECTOR_T) == sizeof(VCHIQ_ELEMENT_T));
+-vcos_static_assert(offsetof(VCHI_MSG_VECTOR_T, vec_base) == offsetof(VCHIQ_ELEMENT_T, data));
+-vcos_static_assert(offsetof(VCHI_MSG_VECTOR_T, vec_len) == offsetof(VCHIQ_ELEMENT_T, size));
+-
+-int32_t
+-vchi_msg_queuev( VCHI_SERVICE_HANDLE_T handle,
+- VCHI_MSG_VECTOR_T * vector,
+- uint32_t count,
+- VCHI_FLAGS_T flags,
+- void *msg_handle )
+-{
+- VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle;
+- VCHIQ_QUEUE_MESSAGE_T args;
+- int ret;
+-
+- vcos_unused(msg_handle);
+-
+- vcos_assert(flags == VCHI_FLAGS_BLOCK_UNTIL_QUEUED);
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- args.handle = service->handle;
+- args.elements = (const VCHIQ_ELEMENT_T *)vector;
+- args.count = count;
+- RETRY(ret, ioctl(service->fd, VCHIQ_IOC_QUEUE_MESSAGE, &args));
+-
+- return ret;
+-}
+-
+-/***********************************************************
+- * Name: vchi_held_msg_release
+- *
+- * Arguments: VCHI_HELD_MSG_T *message
+- *
+- * Description: Routine to release a held message (after it has been read with vchi_msg_hold)
+- *
+- * Returns: int32_t - success == 0
+- *
+- ***********************************************************/
+-int32_t
+-vchi_held_msg_release( VCHI_HELD_MSG_T *message )
+-{
+- int ret = -1;
+-
+- if (message && message->message && !message->service)
+- {
+- free_msgbuf(message->message);
+- ret = 0;
+- }
+-
+- return ret;
+-}
+-
+-/***********************************************************
+- * Name: vchi_msg_hold
+- *
+- * Arguments: VCHI_SERVICE_HANDLE_T handle,
+- * void **data,
+- * uint32_t *msg_size,
+- * VCHI_FLAGS_T flags,
+- * VCHI_HELD_MSG_T *message_handle
+- *
+- * Description: Routine to return a pointer to the current message (to allow in place processing)
+- * The message is dequeued - don't forget to release the message using
+- * vchi_held_msg_release when you're finished
+- *
+- * Returns: int32_t - success == 0
+- *
+- ***********************************************************/
+-int32_t
+-vchi_msg_hold( VCHI_SERVICE_HANDLE_T handle,
+- void **data,
+- uint32_t *msg_size,
+- VCHI_FLAGS_T flags,
+- VCHI_HELD_MSG_T *message_handle )
+-{
+- VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle;
+- int ret;
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- ret = fill_peek_buf(service, flags);
+-
+- if (ret == 0)
+- {
+- *data = service->peek_buf;
+- *msg_size = service->peek_size;
+-
+- message_handle->message = service->peek_buf;
+- message_handle->service = NULL;
+-
+- service->peek_size = -1;
+- service->peek_buf = NULL;
+- }
+-
+- return 0;
+-}
+-
+-/***********************************************************
+- * Name: vchi_initialise
+- *
+- * Arguments: VCHI_INSTANCE_T *instance_handle
+- * VCHI_CONNECTION_T **connections
+- * const uint32_t num_connections
+- *
+- * Description: Initialises the hardware but does not transmit anything
+- * When run as a Host App this will be called twice hence the need
+- * to malloc the state information
+- *
+- * Returns: 0 if successful, failure otherwise
+- *
+- ***********************************************************/
+-int32_t
+-vchi_initialise( VCHI_INSTANCE_T *instance_handle )
+-{
+- VCHIQ_INSTANCE_T instance;
+-
+- instance = vchiq_lib_init();
+-
+- vcos_log_trace( "%s: returning instance handle %p", __func__, instance );
+-
+- *instance_handle = (VCHI_INSTANCE_T)instance;
+-
+- return (instance != NULL) ? 0 : -1;
+-}
+-
+-/***********************************************************
+- * Name: vchi_connect
+- *
+- * Arguments: VCHI_CONNECTION_T **connections
+- * const uint32_t num_connections
+- * VCHI_INSTANCE_T instance_handle )
+- *
+- * Description: Starts the command service on each connection,
+- * causing INIT messages to be pinged back and forth
+- *
+- * Returns: 0 if successful, failure otherwise
+- *
+- ***********************************************************/
+-int32_t
+-vchi_connect( VCHI_CONNECTION_T **connections,
+- const uint32_t num_connections,
+- VCHI_INSTANCE_T instance_handle )
+-{
+- VCHIQ_STATUS_T status;
+-
+- vcos_unused(connections);
+- vcos_unused(num_connections);
+-
+- status = vchiq_connect((VCHIQ_INSTANCE_T)instance_handle);
+-
+- return (status == VCHIQ_SUCCESS) ? 0 : -1;
+-}
+-
+-
+-/***********************************************************
+- * Name: vchi_disconnect
+- *
+- * Arguments: VCHI_INSTANCE_T instance_handle
+- *
+- * Description: Stops the command service on each connection,
+- * causing DE-INIT messages to be pinged back and forth
+- *
+- * Returns: 0 if successful, failure otherwise
+- *
+- ***********************************************************/
+-int32_t
+-vchi_disconnect( VCHI_INSTANCE_T instance_handle )
+-{
+- VCHIQ_STATUS_T status;
+-
+- status = vchiq_shutdown((VCHIQ_INSTANCE_T)instance_handle);
+-
+- return (status == VCHIQ_SUCCESS) ? 0 : -1;
+-}
+-
+-
+-/***********************************************************
+- * Name: vchi_service_open
+- * Name: vchi_service_create
+- *
+- * Arguments: VCHI_INSTANCE_T *instance_handle
+- * SERVICE_CREATION_T *setup,
+- * VCHI_SERVICE_HANDLE_T *handle
+- *
+- * Description: Routine to open a service
+- *
+- * Returns: int32_t - success == 0
+- *
+- ***********************************************************/
+-int32_t
+-vchi_service_open( VCHI_INSTANCE_T instance_handle,
+- SERVICE_CREATION_T *setup,
+- VCHI_SERVICE_HANDLE_T *handle )
+-{
+- VCHIQ_SERVICE_PARAMS_T params;
+- VCHIQ_STATUS_T status;
+-
+- memset(&params, 0, sizeof(params));
+- params.fourcc = setup->service_id;
+- params.userdata = setup->callback_param;
+-
+- status = create_service((VCHIQ_INSTANCE_T)instance_handle,
+- &params,
+- setup->callback,
+- 1/*open*/,
+- (VCHIQ_SERVICE_HANDLE_T *)handle);
+-
+- return (status == VCHIQ_SUCCESS) ? 0 : -1;
+-}
+-
+-int32_t
+-vchi_service_create( VCHI_INSTANCE_T instance_handle,
+- SERVICE_CREATION_T *setup, VCHI_SERVICE_HANDLE_T *handle )
+-{
+- VCHIQ_SERVICE_PARAMS_T params;
+- VCHIQ_STATUS_T status;
+-
+- memset(&params, 0, sizeof(params));
+- params.fourcc = setup->service_id;
+- params.userdata = setup->callback_param;
+-
+- status = create_service((VCHIQ_INSTANCE_T)instance_handle,
+- &params,
+- setup->callback,
+- 0/*!open*/,
+- (VCHIQ_SERVICE_HANDLE_T *)handle);
+-
+- return (status == VCHIQ_SUCCESS) ? 0 : -1;
+-}
+-
+-int32_t
+-vchi_service_close( const VCHI_SERVICE_HANDLE_T handle )
+-{
+- VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle;
+- int ret;
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- RETRY(ret,ioctl(service->fd, VCHIQ_IOC_REMOVE_SERVICE, service->handle));
+-
+- if (ret == 0)
+- service->handle = VCHIQ_INVALID_HANDLE;
+-
+- return ret;
+-}
+-
+-int32_t
+-vchi_service_destroy( const VCHI_SERVICE_HANDLE_T handle )
+-{
+- VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle;
+- int ret;
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- RETRY(ret,ioctl(service->fd, VCHIQ_IOC_REMOVE_SERVICE, service->handle));
+-
+- if (ret == 0)
+- service->handle = VCHIQ_INVALID_HANDLE;
+-
+- return ret;
+-}
+-
+-/* ----------------------------------------------------------------------
+- * read a uint32_t from buffer.
+- * network format is defined to be little endian
+- * -------------------------------------------------------------------- */
+-uint32_t
+-vchi_readbuf_uint32( const void *_ptr )
+-{
+- const unsigned char *ptr = _ptr;
+- return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
+-}
+-
+-/* ----------------------------------------------------------------------
+- * write a uint32_t to buffer.
+- * network format is defined to be little endian
+- * -------------------------------------------------------------------- */
+-void
+-vchi_writebuf_uint32( void *_ptr, uint32_t value )
+-{
+- unsigned char *ptr = _ptr;
+- ptr[0] = (unsigned char)((value >> 0) & 0xFF);
+- ptr[1] = (unsigned char)((value >> 8) & 0xFF);
+- ptr[2] = (unsigned char)((value >> 16) & 0xFF);
+- ptr[3] = (unsigned char)((value >> 24) & 0xFF);
+-}
+-
+-/* ----------------------------------------------------------------------
+- * read a uint16_t from buffer.
+- * network format is defined to be little endian
+- * -------------------------------------------------------------------- */
+-uint16_t
+-vchi_readbuf_uint16( const void *_ptr )
+-{
+- const unsigned char *ptr = _ptr;
+- return ptr[0] | (ptr[1] << 8);
+-}
+-
+-/* ----------------------------------------------------------------------
+- * write a uint16_t into the buffer.
+- * network format is defined to be little endian
+- * -------------------------------------------------------------------- */
+-void
+-vchi_writebuf_uint16( void *_ptr, uint16_t value )
+-{
+- unsigned char *ptr = _ptr;
+- ptr[0] = (value >> 0) & 0xFF;
+- ptr[1] = (value >> 8) & 0xFF;
+-}
+-
+-/***********************************************************
+- * Name: vchi_service_use
+- *
+- * Arguments: const VCHI_SERVICE_HANDLE_T handle
+- *
+- * Description: Routine to increment refcount on a service
+- *
+- * Returns: void
+- *
+- ***********************************************************/
+-int32_t
+-vchi_service_use( const VCHI_SERVICE_HANDLE_T handle )
+-{
+- VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle;
+- int ret;
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- RETRY(ret,ioctl(service->fd, VCHIQ_IOC_USE_SERVICE, service->handle));
+- return ret;
+-}
+-
+-/***********************************************************
+- * Name: vchi_service_release
+- *
+- * Arguments: const VCHI_SERVICE_HANDLE_T handle
+- *
+- * Description: Routine to decrement refcount on a service
+- *
+- * Returns: void
+- *
+- ***********************************************************/
+-int32_t vchi_service_release( const VCHI_SERVICE_HANDLE_T handle )
+-{
+- VCHI_SERVICE_T *service = (VCHI_SERVICE_T *)handle;
+- int ret;
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- RETRY(ret,ioctl(service->fd, VCHIQ_IOC_RELEASE_SERVICE, service->handle));
+- return ret;
+-}
+-
+-/***********************************************************
+- * Name: vchiq_dump_phys_mem
+- *
+- * Arguments: const VCHI_SERVICE_HANDLE_T handle
+- * void *buffer
+- * size_t num_bytes
+- *
+- * Description: Dumps the physical memory associated with
+- * a buffer.
+- *
+- * Returns: void
+- *
+- ***********************************************************/
+-VCHIQ_STATUS_T vchiq_dump_phys_mem( VCHIQ_SERVICE_HANDLE_T handle,
+- void *ptr,
+- size_t num_bytes )
+-{
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)handle;
+- VCHIQ_DUMP_MEM_T dump_mem;
+- int ret;
+-
+- if (!is_valid_service(service))
+- return VCHIQ_ERROR;
+-
+- dump_mem.virt_addr = ptr;
+- dump_mem.num_bytes = num_bytes;
+-
+- RETRY(ret,ioctl(service->fd, VCHIQ_IOC_DUMP_PHYS_MEM, &dump_mem));
+- return (ret >= 0) ? VCHIQ_SUCCESS : VCHIQ_ERROR;
+-}
+-
+-
+-
+-/*
+- * Support functions
+- */
+-
+-static VCHIQ_INSTANCE_T
+-vchiq_lib_init(void)
+-{
+- static int mutex_initialised = 0;
+- static VCOS_MUTEX_T vchiq_lib_mutex;
+- VCHIQ_INSTANCE_T instance = &vchiq_instance;
+-
+- vcos_global_lock();
+- if (!mutex_initialised)
+- {
+- vcos_mutex_create(&vchiq_lib_mutex, "vchiq-init");
+-
+- vcos_log_set_level( &vchiq_lib_log_category, vchiq_default_lib_log_level );
+- vcos_log_register( "vchiq_lib", &vchiq_lib_log_category );
+-
+- mutex_initialised = 1;
+- }
+- vcos_global_unlock();
+-
+- vcos_mutex_lock(&vchiq_lib_mutex);
+-
+- if (instance->initialised == 0)
+- {
+- instance->fd = open("/dev/vchiq", O_RDWR);
+- if (instance->fd >= 0)
+- {
+- VCHIQ_GET_CONFIG_T args;
+- VCHIQ_CONFIG_T config;
+- int ret;
+- args.config_size = sizeof(config);
+- args.pconfig = &config;
+- RETRY(ret, ioctl(instance->fd, VCHIQ_IOC_GET_CONFIG, &args));
+- if ((ret == 0) && (config.version >= VCHIQ_VERSION_MIN) && (config.version_min <= VCHIQ_VERSION))
+- {
+- instance->used_services = 0;
+- vcos_mutex_create(&instance->mutex, "VCHIQ instance");
+- instance->initialised = 1;
+- }
+- else
+- {
+- if (ret == 0)
+- {
+- vcos_log_error("Incompatible VCHIQ library - driver version %d (min %d), library version %d (min %d)",
+- config.version, config.version_min, VCHIQ_VERSION, VCHIQ_VERSION_MIN);
+- }
+- else
+- {
+- vcos_log_error("Very incompatible VCHIQ library - cannot retrieve driver version");
+- }
+- close(instance->fd);
+- instance = NULL;
+- }
+- }
+- else
+- {
+- instance = NULL;
+- }
+- }
+- else if (instance->initialised > 0)
+- {
+- instance->initialised++;
+- }
+-
+- vcos_mutex_unlock(&vchiq_lib_mutex);
+-
+- return instance;
+-}
+-
+-static void *
+-completion_thread(void *arg)
+-{
+- VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)arg;
+- VCHIQ_AWAIT_COMPLETION_T args;
+- VCHIQ_COMPLETION_DATA_T completions[8];
+- void *msgbufs[8];
+-
+- static const VCHI_CALLBACK_REASON_T vchiq_reason_to_vchi[] =
+- {
+- VCHI_CALLBACK_SERVICE_OPENED, // VCHIQ_SERVICE_OPENED
+- VCHI_CALLBACK_SERVICE_CLOSED, // VCHIQ_SERVICE_CLOSED
+- VCHI_CALLBACK_MSG_AVAILABLE, // VCHIQ_MESSAGE_AVAILABLE
+- VCHI_CALLBACK_BULK_SENT, // VCHIQ_BULK_TRANSMIT_DONE
+- VCHI_CALLBACK_BULK_RECEIVED, // VCHIQ_BULK_RECEIVE_DONE
+- VCHI_CALLBACK_BULK_TRANSMIT_ABORTED, // VCHIQ_BULK_TRANSMIT_ABORTED
+- VCHI_CALLBACK_BULK_RECEIVE_ABORTED, // VCHIQ_BULK_RECEIVE_ABORTED
+- };
+-
+- args.count = vcos_countof(completions);
+- args.buf = completions;
+- args.msgbufsize = MSGBUF_SIZE;
+- args.msgbufcount = 0;
+- args.msgbufs = msgbufs;
+-
+- while (1)
+- {
+- int ret, i;
+-
+- while ((unsigned int)args.msgbufcount < vcos_countof(msgbufs))
+- {
+- void *msgbuf = alloc_msgbuf();
+- if (msgbuf)
+- {
+- msgbufs[args.msgbufcount++] = msgbuf;
+- }
+- else
+- {
+- fprintf(stderr, "vchiq_lib: failed to allocate a message buffer\n");
+- vcos_demand(args.msgbufcount != 0);
+- }
+- }
+-
+- RETRY(ret, ioctl(instance->fd, VCHIQ_IOC_AWAIT_COMPLETION, &args));
+-
+- if (ret <= 0)
+- break;
+-
+- for (i = 0; i < ret; i++)
+- {
+- VCHIQ_COMPLETION_DATA_T *completion = &completions[i];
+- VCHIQ_SERVICE_T *service = (VCHIQ_SERVICE_T *)completion->service_userdata;
+- if (service->base.callback)
+- {
+- vcos_log_trace( "callback(%x, %x, %x, %x)",
+- completion->reason, (uint32_t)completion->header,
+- (uint32_t)&service->base, (uint32_t)completion->bulk_userdata );
+- service->base.callback(completion->reason, completion->header,
+- &service->base, completion->bulk_userdata);
+- }
+- else if (service->vchi_callback)
+- {
+- VCHI_CALLBACK_REASON_T vchi_reason =
+- vchiq_reason_to_vchi[completion->reason];
+- service->vchi_callback(service->base.userdata, vchi_reason, completion->bulk_userdata);
+- }
+- }
+- }
+- return NULL;
+-}
+-
+-static VCHIQ_STATUS_T
+-create_service(VCHIQ_INSTANCE_T instance,
+- const VCHIQ_SERVICE_PARAMS_T *params,
+- VCHI_CALLBACK_T vchi_callback,
+- int is_open,
+- VCHIQ_SERVICE_HANDLE_T *pservice)
+-{
+- VCHIQ_SERVICE_T *service = NULL;
+- VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+- int i;
+-
+- if (!is_valid_instance(instance))
+- return VCHIQ_ERROR;
+-
+- vcos_mutex_lock(&instance->mutex);
+-
+- /* Find a free service */
+- if (is_open)
+- {
+- /* Find a free service */
+- for (i = 0; i < instance->used_services; i++)
+- {
+- if (instance->services[i].handle == VCHIQ_INVALID_HANDLE)
+- {
+- service = &instance->services[i];
+- break;
+- }
+- }
+- }
+- else
+- {
+- for (i = (instance->used_services - 1); i >= 0; i--)
+- {
+- VCHIQ_SERVICE_T *srv = &instance->services[i];
+- if (srv->handle == VCHIQ_INVALID_HANDLE)
+- {
+- service = srv;
+- }
+- else if (
+- (srv->base.fourcc == params->fourcc) &&
+- ((srv->base.callback != params->callback) ||
+- (srv->vchi_callback != vchi_callback)))
+- {
+- /* There is another server using this fourcc which doesn't match */
+- service = NULL;
+- status = VCHIQ_ERROR;
+- break;
+- }
+- }
+- }
+-
+- if (!service && (status == VCHIQ_SUCCESS) &&
+- (instance->used_services < VCHIQ_MAX_INSTANCE_SERVICES))
+- service = &instance->services[instance->used_services++];
+-
+- if (service)
+- {
+- VCHIQ_CREATE_SERVICE_T args;
+- int ret;
+- service->base.fourcc = params->fourcc;
+- service->base.callback = params->callback;
+- service->vchi_callback = vchi_callback;
+- service->base.userdata = params->userdata;
+- service->fd = instance->fd;
+- service->peek_size = -1;
+- service->peek_buf = NULL;
+-
+- args.params = *params;
+- args.params.userdata = service;
+- args.is_open = is_open;
+- args.is_vchi = (params->callback == NULL);
+- args.handle = -1; /* OUT parameter */
+- RETRY(ret, ioctl(instance->fd, VCHIQ_IOC_CREATE_SERVICE, &args));
+- if (ret == 0)
+- service->handle = args.handle;
+- else
+- status = VCHIQ_ERROR;
+- }
+-
+- *pservice = (status == VCHIQ_SUCCESS) ? &service->base : NULL;
+-
+- vcos_mutex_unlock(&instance->mutex);
+-
+- return status;
+-}
+-
+-static int
+-fill_peek_buf(VCHI_SERVICE_T *service,
+- VCHI_FLAGS_T flags)
+-{
+- VCHIQ_DEQUEUE_MESSAGE_T args;
+- int ret = 0;
+-
+- vcos_assert(flags == VCHI_FLAGS_NONE || flags == VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE);
+-
+- if (service->peek_size < 0)
+- {
+- if (!service->peek_buf)
+- service->peek_buf = alloc_msgbuf();
+-
+- if (service->peek_buf)
+- {
+- args.handle = service->handle;
+- args.blocking = (flags == VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE);
+- args.bufsize = MSGBUF_SIZE;
+- args.buf = service->peek_buf;
+-
+- RETRY(ret, ioctl(service->fd, VCHIQ_IOC_DEQUEUE_MESSAGE, &args));
+-
+- if (ret >= 0)
+- {
+- service->peek_size = ret;
+- ret = 0;
+- }
+- else
+- {
+- ret = -1;
+- }
+- }
+- else
+- {
+- ret = -1;
+- }
+- }
+-
+- return ret;
+-}
+-
+-
+-static void *
+-alloc_msgbuf(void)
+-{
+- void *msgbuf;
+- vcos_mutex_lock(&vchiq_lib_mutex);
+- msgbuf = free_msgbufs;
+- if (msgbuf)
+- free_msgbufs = *(void **)msgbuf;
+- vcos_mutex_unlock(&vchiq_lib_mutex);
+- if (!msgbuf)
+- msgbuf = malloc(MSGBUF_SIZE);
+- return msgbuf;
+-}
+-
+-static void
+-free_msgbuf(void *buf)
+-{
+- vcos_mutex_lock(&vchiq_lib_mutex);
+- *(void **)buf = free_msgbufs;
+- free_msgbufs = buf;
+- vcos_mutex_unlock(&vchiq_lib_mutex);
+-}
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_memdrv.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_memdrv.h
+index a465b91..e53ee0e 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_memdrv.h
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_memdrv.h
+@@ -22,24 +22,31 @@
+
+ /* ---- Constants and Types ---------------------------------------------- */
+
+-typedef struct
+-{
+- void *armSharedMemVirt;
+- dma_addr_t armSharedMemPhys;
+- size_t armSharedMemSize;
+-
+- void *vcSharedMemVirt;
+- dma_addr_t vcSharedMemPhys;
+- size_t vcSharedMemSize;
+-
++typedef struct {
++ void *armSharedMemVirt;
++ dma_addr_t armSharedMemPhys;
++ size_t armSharedMemSize;
++
++ void *vcSharedMemVirt;
++ dma_addr_t vcSharedMemPhys;
++ size_t vcSharedMemSize;
+ } VCHIQ_SHARED_MEM_INFO_T;
+
+ /* ---- Variable Externs ------------------------------------------------- */
+
+ /* ---- Function Prototypes ---------------------------------------------- */
+
+-void vchiq_get_shared_mem_info( VCHIQ_SHARED_MEM_INFO_T *info );
++void vchiq_get_shared_mem_info(VCHIQ_SHARED_MEM_INFO_T *info);
+
+ VCHIQ_STATUS_T vchiq_memdrv_initialise(void);
+
++VCHIQ_STATUS_T vchiq_userdrv_create_instance(
++ const VCHIQ_PLATFORM_DATA_T * platform_data);
++
++VCHIQ_STATUS_T vchiq_userdrv_suspend(
++ const VCHIQ_PLATFORM_DATA_T * platform_data);
++
++VCHIQ_STATUS_T vchiq_userdrv_resume(
++ const VCHIQ_PLATFORM_DATA_T * platform_data);
++
+ #endif
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_shim.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_shim.c
+index 88cd86f..0ed884e 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_shim.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_shim.c
+@@ -15,6 +15,8 @@
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
++#include <linux/module.h>
++#include <linux/types.h>
+
+ #include "interface/vchi/vchi.h"
+ #include "vchiq.h"
+@@ -24,56 +26,42 @@
+
+ #include <stddef.h>
+
+-#if defined(__KERNEL__)
+-#include <linux/module.h>
+-#endif
+-
+ #define vchiq_status_to_vchi(status) ((int32_t)status)
+
+ typedef struct {
+- VCHIQ_SERVICE_HANDLE_T handle;
++ VCHIQ_SERVICE_HANDLE_T handle;
+
+- VCHIU_QUEUE_T queue;
++ VCHIU_QUEUE_T queue;
+
+- VCHI_CALLBACK_T callback;
+- void *callback_param;
++ VCHI_CALLBACK_T callback;
++ void *callback_param;
+ } SHIM_SERVICE_T;
+
+ /* ----------------------------------------------------------------------
+ * return pointer to the mphi message driver function table
+ * -------------------------------------------------------------------- */
+-#ifdef WIN32
+ const VCHI_MESSAGE_DRIVER_T *
+-mphi_get_func_table( void )
++vchi_mphi_message_driver_func_table(void)
+ {
+- return NULL;
+-}
+-#endif
+-
+-/* ----------------------------------------------------------------------
+- * return pointer to the mphi message driver function table
+- * -------------------------------------------------------------------- */
+-const VCHI_MESSAGE_DRIVER_T *
+-vchi_mphi_message_driver_func_table( void )
+-{
+- return NULL;
++ return NULL;
+ }
+
+ /* ----------------------------------------------------------------------
+ * return a pointer to the 'single' connection driver fops
+ * -------------------------------------------------------------------- */
+ const VCHI_CONNECTION_API_T *
+-single_get_func_table( void )
++single_get_func_table(void)
+ {
+- return NULL;
++ return NULL;
+ }
+
+-VCHI_CONNECTION_T * vchi_create_connection( const VCHI_CONNECTION_API_T * function_table,
+- const VCHI_MESSAGE_DRIVER_T * low_level)
++VCHI_CONNECTION_T *vchi_create_connection(
++ const VCHI_CONNECTION_API_T *function_table,
++ const VCHI_MESSAGE_DRIVER_T *low_level)
+ {
+- vcos_unused(function_table);
+- vcos_unused(low_level);
+- return NULL;
++ (void)function_table;
++ (void)low_level;
++ return NULL;
+ }
+
+ /***********************************************************
+@@ -82,57 +70,64 @@ VCHI_CONNECTION_T * vchi_create_connection( const VCHI_CONNECTION_API_T * functi
+ * Arguments: const VCHI_SERVICE_HANDLE_T handle,
+ * void **data,
+ * uint32_t *msg_size,
++
++
+ * VCHI_FLAGS_T flags
+ *
+- * Description: Routine to return a pointer to the current message (to allow in place processing)
+- * The message can be removed using vchi_msg_remove when you're finished
++ * Description: Routine to return a pointer to the current message (to allow in
++ * place processing). The message can be removed using
++ * vchi_msg_remove when you're finished
+ *
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+-int32_t vchi_msg_peek( VCHI_SERVICE_HANDLE_T handle,
+- void **data,
+- uint32_t *msg_size,
+- VCHI_FLAGS_T flags )
++int32_t vchi_msg_peek(VCHI_SERVICE_HANDLE_T handle,
++ void **data,
++ uint32_t *msg_size,
++ VCHI_FLAGS_T flags)
+ {
+- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+- VCHIQ_HEADER_T *header;
++ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
++ VCHIQ_HEADER_T *header;
+
+- vcos_assert(flags == VCHI_FLAGS_NONE || flags == VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE);
++ WARN_ON((flags != VCHI_FLAGS_NONE) &&
++ (flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));
+
+- if (flags == VCHI_FLAGS_NONE)
+- if (vchiu_queue_is_empty(&service->queue))
+- return -1;
++ if (flags == VCHI_FLAGS_NONE)
++ if (vchiu_queue_is_empty(&service->queue))
++ return -1;
+
+- header = vchiu_queue_peek(&service->queue);
++ header = vchiu_queue_peek(&service->queue);
+
+- *data = header->data;
+- *msg_size = header->size;
++ *data = header->data;
++ *msg_size = header->size;
+
+- return 0;
++ return 0;
+ }
++EXPORT_SYMBOL(vchi_msg_peek);
+
+ /***********************************************************
+ * Name: vchi_msg_remove
+ *
+ * Arguments: const VCHI_SERVICE_HANDLE_T handle,
+ *
+- * Description: Routine to remove a message (after it has been read with vchi_msg_peek)
++ * Description: Routine to remove a message (after it has been read with
++ * vchi_msg_peek)
+ *
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+-int32_t vchi_msg_remove( VCHI_SERVICE_HANDLE_T handle )
++int32_t vchi_msg_remove(VCHI_SERVICE_HANDLE_T handle)
+ {
+- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+- VCHIQ_HEADER_T *header;
++ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
++ VCHIQ_HEADER_T *header;
+
+- header = vchiu_queue_pop(&service->queue);
++ header = vchiu_queue_pop(&service->queue);
+
+- vchiq_release_message(service->handle, header);
++ vchiq_release_message(service->handle, header);
+
+- return 0;
++ return 0;
+ }
++EXPORT_SYMBOL(vchi_msg_remove);
+
+ /***********************************************************
+ * Name: vchi_msg_queue
+@@ -148,33 +143,34 @@ int32_t vchi_msg_remove( VCHI_SERVICE_HANDLE_T handle )
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+-int32_t vchi_msg_queue( VCHI_SERVICE_HANDLE_T handle,
+- const void * data,
+- uint32_t data_size,
+- VCHI_FLAGS_T flags,
+- void * msg_handle )
++int32_t vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle,
++ const void *data,
++ uint32_t data_size,
++ VCHI_FLAGS_T flags,
++ void *msg_handle)
+ {
+- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+- VCHIQ_ELEMENT_T element = {data, data_size};
+- VCHIQ_STATUS_T status;
++ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
++ VCHIQ_ELEMENT_T element = {data, data_size};
++ VCHIQ_STATUS_T status;
+
+- vcos_unused(msg_handle);
++ (void)msg_handle;
+
+- vcos_assert(flags == VCHI_FLAGS_BLOCK_UNTIL_QUEUED);
++ WARN_ON(flags != VCHI_FLAGS_BLOCK_UNTIL_QUEUED);
+
+- status = vchiq_queue_message(service->handle, &element, 1);
++ status = vchiq_queue_message(service->handle, &element, 1);
+
+- // On some platforms, like linux kernel, vchiq_queue_message() may return
+- // VCHIQ_RETRY, so we need to implment a retry mechanism since this
+- // function is supposed to block until queued
+- while ( status == VCHIQ_RETRY )
+- {
+- vcos_sleep( 1 );
+- status = vchiq_queue_message(service->handle, &element, 1);
+- }
++ /* vchiq_queue_message() may return VCHIQ_RETRY, so we need to
++ ** implement a retry mechanism since this function is supposed
++ ** to block until queued
++ */
++ while (status == VCHIQ_RETRY) {
++ msleep(1);
++ status = vchiq_queue_message(service->handle, &element, 1);
++ }
+
+- return vchiq_status_to_vchi(status);
++ return vchiq_status_to_vchi(status);
+ }
++EXPORT_SYMBOL(vchi_msg_queue);
+
+ /***********************************************************
+ * Name: vchi_bulk_queue_receive
+@@ -190,107 +186,50 @@ int32_t vchi_msg_queue( VCHI_SERVICE_HANDLE_T handle,
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+-int32_t vchi_bulk_queue_receive( VCHI_SERVICE_HANDLE_T handle,
+- void * data_dst,
+- uint32_t data_size,
+- VCHI_FLAGS_T flags,
+- void * bulk_handle )
+-{
+- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+- VCHIQ_BULK_MODE_T mode;
+- VCHIQ_STATUS_T status;
+-
+- switch ((int)flags) {
+- case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+- vcos_assert(service->callback);
+- mode = VCHIQ_BULK_MODE_CALLBACK;
+- break;
+- case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
+- mode = VCHIQ_BULK_MODE_BLOCKING;
+- break;
+- case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+- case VCHI_FLAGS_NONE:
+- mode = VCHIQ_BULK_MODE_NOCALLBACK;
+- break;
+- default:
+- vcos_assert(0);
+- return vchiq_status_to_vchi(VCHIQ_ERROR);
+- }
+-
+- status = vchiq_bulk_receive(service->handle, data_dst, data_size,
+- bulk_handle, mode);
+-
+- // On some platforms, like linux kernel, vchiq_bulk_receive() may return
+- // VCHIQ_RETRY, so we need to implment a retry mechanism since this
+- // function is supposed to block until queued
+- while ( status == VCHIQ_RETRY )
+- {
+- vcos_sleep( 1 );
+- status = vchiq_bulk_receive(service->handle, data_dst, data_size,
+- bulk_handle, mode);
+- }
+-
+- return vchiq_status_to_vchi(status);
+-}
+-
+-/***********************************************************
+- * Name: vchi_bulk_queue_receive_reloc
+- *
+- * Arguments: VCHI_BULK_HANDLE_T handle,
+- * VCHI_MEM_HANDLE_T h
+- * uint32_t offset
+- * const uint32_t data_size,
+- * VCHI_FLAGS_T flags
+- * void *bulk_handle
+- *
+- * Description: Routine to setup a relocatable rcv buffer
+- *
+- * Returns: int32_t - success == 0
+- *
+- ***********************************************************/
+-int32_t vchi_bulk_queue_receive_reloc( const VCHI_SERVICE_HANDLE_T handle,
+- VCHI_MEM_HANDLE_T h,
+- uint32_t offset,
+- uint32_t data_size,
+- const VCHI_FLAGS_T flags,
+- void * const bulk_handle )
+-{
+- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+- VCHIQ_BULK_MODE_T mode;
+- VCHIQ_STATUS_T status;
+-
+- switch ((int)flags) {
+- case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+- vcos_assert(service->callback);
+- mode = VCHIQ_BULK_MODE_CALLBACK;
+- break;
+- case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
+- mode = VCHIQ_BULK_MODE_BLOCKING;
+- break;
+- case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+- case VCHI_FLAGS_NONE:
+- mode = VCHIQ_BULK_MODE_NOCALLBACK;
+- break;
+- default:
+- vcos_assert(0);
+- return vchiq_status_to_vchi(VCHIQ_ERROR);
+- }
+-
+- status = vchiq_bulk_receive_handle(service->handle, h, (void*)offset,
+- data_size, bulk_handle, mode);
+-
+- // On some platforms, like linux kernel, vchiq_bulk_receive_handle() may
+- // return VCHIQ_RETRY, so we need to implment a retry mechanism since
+- // this function is supposed to block until queued
+- while ( status == VCHIQ_RETRY )
+- {
+- vcos_sleep( 1 );
+- status = vchiq_bulk_receive_handle(service->handle, h, (void*)offset,
+- data_size, bulk_handle, mode);
+- }
+-
+- return vchiq_status_to_vchi(status);
+-}
++int32_t vchi_bulk_queue_receive(VCHI_SERVICE_HANDLE_T handle,
++ void *data_dst,
++ uint32_t data_size,
++ VCHI_FLAGS_T flags,
++ void *bulk_handle)
++{
++ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
++ VCHIQ_BULK_MODE_T mode;
++ VCHIQ_STATUS_T status;
++
++ switch ((int)flags) {
++ case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE
++ | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
++ WARN_ON(!service->callback);
++ mode = VCHIQ_BULK_MODE_CALLBACK;
++ break;
++ case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
++ mode = VCHIQ_BULK_MODE_BLOCKING;
++ break;
++ case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
++ case VCHI_FLAGS_NONE:
++ mode = VCHIQ_BULK_MODE_NOCALLBACK;
++ break;
++ default:
++ WARN(1, "unsupported message\n");
++ return vchiq_status_to_vchi(VCHIQ_ERROR);
++ }
++
++ status = vchiq_bulk_receive(service->handle, data_dst, data_size,
++ bulk_handle, mode);
++
++ /* vchiq_bulk_receive() may return VCHIQ_RETRY, so we need to
++ ** implement a retry mechanism since this function is supposed
++ ** to block until queued
++ */
++ while (status == VCHIQ_RETRY) {
++ msleep(1);
++ status = vchiq_bulk_receive(service->handle, data_dst,
++ data_size, bulk_handle, mode);
++ }
++
++ return vchiq_status_to_vchi(status);
++}
++EXPORT_SYMBOL(vchi_bulk_queue_receive);
+
+ /***********************************************************
+ * Name: vchi_bulk_queue_transmit
+@@ -306,110 +245,51 @@ int32_t vchi_bulk_queue_receive_reloc( const VCHI_SERVICE_HANDLE_T handle,
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+-int32_t vchi_bulk_queue_transmit( VCHI_SERVICE_HANDLE_T handle,
+- const void * data_src,
+- uint32_t data_size,
+- VCHI_FLAGS_T flags,
+- void * bulk_handle )
+-{
+- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+- VCHIQ_BULK_MODE_T mode;
+- VCHIQ_STATUS_T status;
+-
+- switch ((int)flags) {
+- case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+- vcos_assert(service->callback);
+- mode = VCHIQ_BULK_MODE_CALLBACK;
+- break;
+- case VCHI_FLAGS_BLOCK_UNTIL_DATA_READ:
+- case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
+- mode = VCHIQ_BULK_MODE_BLOCKING;
+- break;
+- case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+- case VCHI_FLAGS_NONE:
+- mode = VCHIQ_BULK_MODE_NOCALLBACK;
+- break;
+- default:
+- vcos_assert(0);
+- return vchiq_status_to_vchi(VCHIQ_ERROR);
+- }
+-
+- status = vchiq_bulk_transmit(service->handle, data_src, data_size,
+- bulk_handle, mode);
+-
+- // On some platforms, like linux kernel, vchiq_bulk_transmit() may return
+- // VCHIQ_RETRY, so we need to implment a retry mechanism since this
+- // function is supposed to block until queued
+- while ( status == VCHIQ_RETRY )
+- {
+- vcos_sleep( 1 );
+- status = vchiq_bulk_transmit(service->handle, data_src, data_size,
+- bulk_handle, mode);
+- }
+-
+- return vchiq_status_to_vchi(status);
+-}
+-
+-/***********************************************************
+- * Name: vchi_bulk_queue_transmit_reloc
+- *
+- * Arguments: VCHI_BULK_HANDLE_T handle,
+- * VCHI_MEM_HANDLE_T h_src,
+- * uint32_t offset,
+- * uint32_t data_size,
+- * VCHI_FLAGS_T flags,
+- * void *bulk_handle
+- *
+- * Description: Routine to transmit some data from a relocatable buffer
+- *
+- * Returns: int32_t - success == 0
+- *
+- ***********************************************************/
+-
+-int32_t vchi_bulk_queue_transmit_reloc( VCHI_SERVICE_HANDLE_T handle,
+- VCHI_MEM_HANDLE_T h_src,
+- uint32_t offset,
+- uint32_t data_size,
+- VCHI_FLAGS_T flags,
+- void * const bulk_handle )
+-{
+- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+- VCHIQ_BULK_MODE_T mode;
+- VCHIQ_STATUS_T status;
+-
+- switch ((int)flags) {
+- case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+- vcos_assert(service->callback);
+- mode = VCHIQ_BULK_MODE_CALLBACK;
+- break;
+- case VCHI_FLAGS_BLOCK_UNTIL_DATA_READ:
+- case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
+- mode = VCHIQ_BULK_MODE_BLOCKING;
+- break;
+- case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
+- case VCHI_FLAGS_NONE:
+- mode = VCHIQ_BULK_MODE_NOCALLBACK;
+- break;
+- default:
+- vcos_assert(0);
+- return vchiq_status_to_vchi(VCHIQ_ERROR);
+- }
+-
+- status = vchiq_bulk_transmit_handle(service->handle, h_src, (void*)offset,
+- data_size, bulk_handle, mode);
+-
+- // On some platforms, like linux kernel, vchiq_bulk_transmit_handle() may
+- // return VCHIQ_RETRY, so we need to implment a retry mechanism since this
+- // function is supposed to block until queued
+- while ( status == VCHIQ_RETRY )
+- {
+- vcos_sleep( 1 );
+- status = vchiq_bulk_transmit_handle(service->handle, h_src, (void*)offset,
+- data_size, bulk_handle, mode);
+- }
+-
+- return vchiq_status_to_vchi(status);
++int32_t vchi_bulk_queue_transmit(VCHI_SERVICE_HANDLE_T handle,
++ const void *data_src,
++ uint32_t data_size,
++ VCHI_FLAGS_T flags,
++ void *bulk_handle)
++{
++ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
++ VCHIQ_BULK_MODE_T mode;
++ VCHIQ_STATUS_T status;
++
++ switch ((int)flags) {
++ case VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE
++ | VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
++ WARN_ON(!service->callback);
++ mode = VCHIQ_BULK_MODE_CALLBACK;
++ break;
++ case VCHI_FLAGS_BLOCK_UNTIL_DATA_READ:
++ case VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE:
++ mode = VCHIQ_BULK_MODE_BLOCKING;
++ break;
++ case VCHI_FLAGS_BLOCK_UNTIL_QUEUED:
++ case VCHI_FLAGS_NONE:
++ mode = VCHIQ_BULK_MODE_NOCALLBACK;
++ break;
++ default:
++ WARN(1, "unsupported message\n");
++ return vchiq_status_to_vchi(VCHIQ_ERROR);
++ }
++
++ status = vchiq_bulk_transmit(service->handle, data_src, data_size,
++ bulk_handle, mode);
++
++ /* vchiq_bulk_transmit() may return VCHIQ_RETRY, so we need to
++ ** implement a retry mechanism since this function is supposed
++ ** to block until queued
++ */
++ while (status == VCHIQ_RETRY) {
++ msleep(1);
++ status = vchiq_bulk_transmit(service->handle, data_src,
++ data_size, bulk_handle, mode);
++ }
++
++ return vchiq_status_to_vchi(status);
+ }
++EXPORT_SYMBOL(vchi_bulk_queue_transmit);
+
+ /***********************************************************
+ * Name: vchi_msg_dequeue
+@@ -425,38 +305,41 @@ int32_t vchi_bulk_queue_transmit_reloc( VCHI_SERVICE_HANDLE_T handle,
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+-int32_t vchi_msg_dequeue( VCHI_SERVICE_HANDLE_T handle,
+- void *data,
+- uint32_t max_data_size_to_read,
+- uint32_t *actual_msg_size,
+- VCHI_FLAGS_T flags )
++int32_t vchi_msg_dequeue(VCHI_SERVICE_HANDLE_T handle,
++ void *data,
++ uint32_t max_data_size_to_read,
++ uint32_t *actual_msg_size,
++ VCHI_FLAGS_T flags)
+ {
+- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+- VCHIQ_HEADER_T *header;
++ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
++ VCHIQ_HEADER_T *header;
+
+- vcos_assert(flags == VCHI_FLAGS_NONE || flags == VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE);
++ WARN_ON((flags != VCHI_FLAGS_NONE) &&
++ (flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));
+
+- if (flags == VCHI_FLAGS_NONE)
+- if (vchiu_queue_is_empty(&service->queue))
+- return -1;
++ if (flags == VCHI_FLAGS_NONE)
++ if (vchiu_queue_is_empty(&service->queue))
++ return -1;
+
+- header = vchiu_queue_pop(&service->queue);
++ header = vchiu_queue_pop(&service->queue);
+
+- memcpy(data, header->data, header->size < max_data_size_to_read ? header->size : max_data_size_to_read);
++ memcpy(data, header->data, header->size < max_data_size_to_read ?
++ header->size : max_data_size_to_read);
+
+- *actual_msg_size = header->size;
++ *actual_msg_size = header->size;
+
+- vchiq_release_message(service->handle, header);
++ vchiq_release_message(service->handle, header);
+
+- return 0;
++ return 0;
+ }
++EXPORT_SYMBOL(vchi_msg_dequeue);
+
+ /***********************************************************
+ * Name: vchi_msg_queuev
+ *
+ * Arguments: VCHI_SERVICE_HANDLE_T handle,
+- * const void *data,
+- * uint32_t data_size,
++ * VCHI_MSG_VECTOR_T *vector,
++ * uint32_t count,
+ * VCHI_FLAGS_T flags,
+ * void *msg_handle
+ *
+@@ -466,151 +349,46 @@ int32_t vchi_msg_dequeue( VCHI_SERVICE_HANDLE_T handle,
+ *
+ ***********************************************************/
+
+-vcos_static_assert(sizeof(VCHI_MSG_VECTOR_T) == sizeof(VCHIQ_ELEMENT_T));
+-vcos_static_assert(offsetof(VCHI_MSG_VECTOR_T, vec_base) == offsetof(VCHIQ_ELEMENT_T, data));
+-vcos_static_assert(offsetof(VCHI_MSG_VECTOR_T, vec_len) == offsetof(VCHIQ_ELEMENT_T, size));
++vchiq_static_assert(sizeof(VCHI_MSG_VECTOR_T) == sizeof(VCHIQ_ELEMENT_T));
++vchiq_static_assert(offsetof(VCHI_MSG_VECTOR_T, vec_base) ==
++ offsetof(VCHIQ_ELEMENT_T, data));
++vchiq_static_assert(offsetof(VCHI_MSG_VECTOR_T, vec_len) ==
++ offsetof(VCHIQ_ELEMENT_T, size));
+
+-int32_t vchi_msg_queuev( VCHI_SERVICE_HANDLE_T handle,
+- VCHI_MSG_VECTOR_T * vector,
+- uint32_t count,
+- VCHI_FLAGS_T flags,
+- void *msg_handle )
++int32_t vchi_msg_queuev(VCHI_SERVICE_HANDLE_T handle,
++ VCHI_MSG_VECTOR_T *vector,
++ uint32_t count,
++ VCHI_FLAGS_T flags,
++ void *msg_handle)
+ {
+- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
++ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+
+- vcos_unused(msg_handle);
++ (void)msg_handle;
+
+- vcos_assert(flags == VCHI_FLAGS_BLOCK_UNTIL_QUEUED);
++ WARN_ON(flags != VCHI_FLAGS_BLOCK_UNTIL_QUEUED);
+
+- return vchiq_status_to_vchi(vchiq_queue_message(service->handle, (const VCHIQ_ELEMENT_T *)vector, count));
++ return vchiq_status_to_vchi(vchiq_queue_message(service->handle,
++ (const VCHIQ_ELEMENT_T *)vector, count));
+ }
+-
+-#ifdef USE_MEMMGR
+-
+-/***********************************************************
+- * Name: vchi_msg_queuev_ex
+- *
+- * Arguments: VCHI_SERVICE_HANDLE_T handle,
+- * VCHI_MSG_VECTOR_EX_T *vector
+- * uint32_t count
+- * VCHI_FLAGS_T flags,
+- * void *msg_handle
+- *
+- * Description: Thin wrapper to queue an array of messages onto a connection
+- * Supports resolving MEM_HANDLE's at last possible moment to avoid deadlocks.
+- *
+- * Currently just a shim, so deadlocks are still possible!
+- *
+- * Returns: int32_t - success == 0
+- *
+- ***********************************************************/
+-int32_t vchi_msg_queuev_ex( const VCHI_SERVICE_HANDLE_T handle,
+- VCHI_MSG_VECTOR_EX_T * const vector,
+- const uint32_t count,
+- const VCHI_FLAGS_T flags,
+- void * const msg_handle )
+-{
+- int32_t success = -1;
+- // For now, we don't actually support sending anything other than
+- // a pointer, so handles have to be patched up; this is likely
+- // to cause deadlocks. This code is not designed to be either
+- // pretty, efficient, or deadlock-free.
+-
+- #define max_vecs 16
+- VCHI_MSG_VECTOR_T copy[max_vecs];
+- const uint8_t *orig[max_vecs];
+-
+- int i;
+- vcos_unused(msg_handle);
+-
+- if (count > sizeof(copy)/sizeof(copy[0]))
+- {
+- vcos_assert(0);
+- return -1;
+- }
+-
+- for (i=0; i<count; i++)
+- {
+- VCHI_MSG_VECTOR_EX_T *v = vector+i;
+-
+- switch (vector[i].type)
+- {
+- case VCHI_VEC_POINTER:
+- copy[i].vec_base = v->u.ptr.vec_base;
+- copy[i].vec_len = v->u.ptr.vec_len;
+- break;
+- case VCHI_VEC_HANDLE:
+- vcos_assert(v->u.handle.offset+v->u.handle.vec_len <= mem_get_size(v->u.handle.handle));
+- copy[i].vec_base = (uint8_t*)mem_lock(v->u.handle.handle) + v->u.handle.offset;
+- orig[i] = copy[i].vec_base;
+- copy[i].vec_len = v->u.handle.vec_len;
+- break;
+- case VCHI_VEC_LIST:
+- vcos_assert(0); // FIXME: implement this
+- break;
+- default:
+- vcos_assert(0);
+- }
+- }
+- success = vchi_msg_queuev( handle,
+- copy,
+- count,
+- flags &~ VCHI_FLAGS_INTERNAL,
+- msg_handle );
+- if (vcos_verify(success == 0))
+- {
+- // now we need to patch up the vectors if any have been only partially consumed, and
+- // unlock memory handles.
+-
+- for (i=0; i<count; i++)
+- {
+- VCHI_MSG_VECTOR_EX_T *v = vector+i;
+-
+- switch (vector[i].type)
+- {
+- case VCHI_VEC_POINTER:
+- if (flags & VCHI_FLAGS_ALLOW_PARTIAL)
+- {
+- v->u.ptr.vec_base = copy[i].vec_base;
+- v->u.ptr.vec_len = copy[i].vec_len;
+- }
+- break;
+- case VCHI_VEC_HANDLE:
+- mem_unlock(v->u.handle.handle);
+- if (flags & VCHI_FLAGS_ALLOW_PARTIAL)
+- {
+- const uint8_t *old = orig[i];
+- uint32_t change = (const uint8_t*)copy[i].vec_base-old;
+- v->u.handle.offset += change;
+- v->u.handle.vec_len -= change;
+- }
+- break;
+- default:
+- vcos_assert(0);
+- }
+- }
+- }
+-
+- return vchiq_status_to_vchi(success);
+-}
+-
+-#endif
++EXPORT_SYMBOL(vchi_msg_queuev);
+
+ /***********************************************************
+ * Name: vchi_held_msg_release
+ *
+ * Arguments: VCHI_HELD_MSG_T *message
+ *
+- * Description: Routine to release a held message (after it has been read with vchi_msg_hold)
++ * Description: Routine to release a held message (after it has been read with
++ * vchi_msg_hold)
+ *
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+-int32_t vchi_held_msg_release( VCHI_HELD_MSG_T *message )
++int32_t vchi_held_msg_release(VCHI_HELD_MSG_T *message)
+ {
+- vchiq_release_message((VCHIQ_SERVICE_HANDLE_T)message->service, (VCHIQ_HEADER_T *)message->message);
++ vchiq_release_message((VCHIQ_SERVICE_HANDLE_T)message->service,
++ (VCHIQ_HEADER_T *)message->message);
+
+- return 0;
++ return 0;
+ }
+
+ /***********************************************************
+@@ -622,37 +400,40 @@ int32_t vchi_held_msg_release( VCHI_HELD_MSG_T *message )
+ * VCHI_FLAGS_T flags,
+ * VCHI_HELD_MSG_T *message_handle
+ *
+- * Description: Routine to return a pointer to the current message (to allow in place processing)
+- * The message is dequeued - don't forget to release the message using
+- * vchi_held_msg_release when you're finished
++ * Description: Routine to return a pointer to the current message (to allow
++ * in place processing). The message is dequeued - don't forget
++ * to release the message using vchi_held_msg_release when you're
++ * finished.
+ *
+ * Returns: int32_t - success == 0
+ *
+ ***********************************************************/
+-int32_t vchi_msg_hold( VCHI_SERVICE_HANDLE_T handle,
+- void **data,
+- uint32_t *msg_size,
+- VCHI_FLAGS_T flags,
+- VCHI_HELD_MSG_T *message_handle )
++int32_t vchi_msg_hold(VCHI_SERVICE_HANDLE_T handle,
++ void **data,
++ uint32_t *msg_size,
++ VCHI_FLAGS_T flags,
++ VCHI_HELD_MSG_T *message_handle)
+ {
+- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+- VCHIQ_HEADER_T *header;
++ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
++ VCHIQ_HEADER_T *header;
+
+- vcos_assert(flags == VCHI_FLAGS_NONE || flags == VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE);
++ WARN_ON((flags != VCHI_FLAGS_NONE) &&
++ (flags != VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE));
+
+- if (flags == VCHI_FLAGS_NONE)
+- if (vchiu_queue_is_empty(&service->queue))
+- return -1;
++ if (flags == VCHI_FLAGS_NONE)
++ if (vchiu_queue_is_empty(&service->queue))
++ return -1;
+
+- header = vchiu_queue_pop(&service->queue);
++ header = vchiu_queue_pop(&service->queue);
+
+- *data = header->data;
+- *msg_size = header->size;
++ *data = header->data;
++ *msg_size = header->size;
+
+- message_handle->service = (struct opaque_vchi_service_t *)service->handle;
+- message_handle->message = header;
++ message_handle->service =
++ (struct opaque_vchi_service_t *)service->handle;
++ message_handle->message = header;
+
+- return 0;
++ return 0;
+ }
+
+ /***********************************************************
+@@ -670,24 +451,25 @@ int32_t vchi_msg_hold( VCHI_SERVICE_HANDLE_T handle,
+ *
+ ***********************************************************/
+
+-int32_t vchi_initialise( VCHI_INSTANCE_T *instance_handle )
++int32_t vchi_initialise(VCHI_INSTANCE_T *instance_handle)
+ {
+- VCHIQ_INSTANCE_T instance;
+- VCHIQ_STATUS_T status;
++ VCHIQ_INSTANCE_T instance;
++ VCHIQ_STATUS_T status;
+
+- status = vchiq_initialise(&instance);
++ status = vchiq_initialise(&instance);
+
+- *instance_handle = (VCHI_INSTANCE_T)instance;
++ *instance_handle = (VCHI_INSTANCE_T)instance;
+
+- return vchiq_status_to_vchi(status);
++ return vchiq_status_to_vchi(status);
+ }
++EXPORT_SYMBOL(vchi_initialise);
+
+ /***********************************************************
+ * Name: vchi_connect
+ *
+ * Arguments: VCHI_CONNECTION_T **connections
+ * const uint32_t num_connections
+- * VCHI_INSTANCE_T instance_handle )
++ * VCHI_INSTANCE_T instance_handle)
+ *
+ * Description: Starts the command service on each connection,
+ * causing INIT messages to be pinged back and forth
+@@ -695,17 +477,18 @@ int32_t vchi_initialise( VCHI_INSTANCE_T *instance_handle )
+ * Returns: 0 if successful, failure otherwise
+ *
+ ***********************************************************/
+-int32_t vchi_connect( VCHI_CONNECTION_T **connections,
+- const uint32_t num_connections,
+- VCHI_INSTANCE_T instance_handle )
++int32_t vchi_connect(VCHI_CONNECTION_T **connections,
++ const uint32_t num_connections,
++ VCHI_INSTANCE_T instance_handle)
+ {
+- VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
++ VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
+
+- vcos_unused(connections);
+- vcos_unused(num_connections);
++ (void)connections;
++ (void)num_connections;
+
+- return vchiq_connect(instance);
++ return vchiq_connect(instance);
+ }
++EXPORT_SYMBOL(vchi_connect);
+
+
+ /***********************************************************
+@@ -719,11 +502,12 @@ int32_t vchi_connect( VCHI_CONNECTION_T **connections,
+ * Returns: 0 if successful, failure otherwise
+ *
+ ***********************************************************/
+-int32_t vchi_disconnect( VCHI_INSTANCE_T instance_handle )
++int32_t vchi_disconnect(VCHI_INSTANCE_T instance_handle)
+ {
+- VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
+- return vchiq_status_to_vchi(vchiq_shutdown(instance));
++ VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
++ return vchiq_status_to_vchi(vchiq_shutdown(instance));
+ }
++EXPORT_SYMBOL(vchi_disconnect);
+
+
+ /***********************************************************
+@@ -740,168 +524,188 @@ int32_t vchi_disconnect( VCHI_INSTANCE_T instance_handle )
+ *
+ ***********************************************************/
+
+-static VCHIQ_STATUS_T shim_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header, VCHIQ_SERVICE_HANDLE_T handle, void *bulk_user)
+-{
+- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)VCHIQ_GET_SERVICE_USERDATA(handle);
+-
+- switch (reason) {
+- case VCHIQ_MESSAGE_AVAILABLE:
+- vchiu_queue_push(&service->queue, header);
+-
+- if (service->callback)
+- service->callback(service->callback_param, VCHI_CALLBACK_MSG_AVAILABLE, NULL);
+- break;
+- case VCHIQ_BULK_TRANSMIT_DONE:
+- if (service->callback)
+- service->callback(service->callback_param, VCHI_CALLBACK_BULK_SENT, bulk_user);
+- break;
+- case VCHIQ_BULK_RECEIVE_DONE:
+- if (service->callback)
+- service->callback(service->callback_param, VCHI_CALLBACK_BULK_RECEIVED, bulk_user);
+- break;
+- case VCHIQ_SERVICE_CLOSED:
+- if (service->callback)
+- service->callback(service->callback_param, VCHI_CALLBACK_SERVICE_CLOSED, NULL);
+- break;
+- case VCHIQ_SERVICE_OPENED:
+- /* No equivalent VCHI reason */
+- break;
+- case VCHIQ_BULK_TRANSMIT_ABORTED:
+- if (service->callback)
+- service->callback(service->callback_param, VCHI_CALLBACK_BULK_TRANSMIT_ABORTED, bulk_user);
+- break;
+- case VCHIQ_BULK_RECEIVE_ABORTED:
+- if (service->callback)
+- service->callback(service->callback_param, VCHI_CALLBACK_BULK_RECEIVE_ABORTED, bulk_user);
+- break;
+- default:
+- vcos_assert(0);
+- break;
+- }
+-
+- return VCHIQ_SUCCESS;
++static VCHIQ_STATUS_T shim_callback(VCHIQ_REASON_T reason,
++ VCHIQ_HEADER_T *header, VCHIQ_SERVICE_HANDLE_T handle, void *bulk_user)
++{
++ SHIM_SERVICE_T *service =
++ (SHIM_SERVICE_T *)VCHIQ_GET_SERVICE_USERDATA(handle);
++
++ switch (reason) {
++ case VCHIQ_MESSAGE_AVAILABLE:
++ vchiu_queue_push(&service->queue, header);
++
++ if (service->callback)
++ service->callback(service->callback_param,
++ VCHI_CALLBACK_MSG_AVAILABLE, NULL);
++ break;
++ case VCHIQ_BULK_TRANSMIT_DONE:
++ if (service->callback)
++ service->callback(service->callback_param,
++ VCHI_CALLBACK_BULK_SENT, bulk_user);
++ break;
++ case VCHIQ_BULK_RECEIVE_DONE:
++ if (service->callback)
++ service->callback(service->callback_param,
++ VCHI_CALLBACK_BULK_RECEIVED, bulk_user);
++ break;
++ case VCHIQ_SERVICE_CLOSED:
++ if (service->callback)
++ service->callback(service->callback_param,
++ VCHI_CALLBACK_SERVICE_CLOSED, NULL);
++ break;
++ case VCHIQ_SERVICE_OPENED:
++ /* No equivalent VCHI reason */
++ break;
++ case VCHIQ_BULK_TRANSMIT_ABORTED:
++ if (service->callback)
++ service->callback(service->callback_param,
++ VCHI_CALLBACK_BULK_TRANSMIT_ABORTED, bulk_user);
++ break;
++ case VCHIQ_BULK_RECEIVE_ABORTED:
++ if (service->callback)
++ service->callback(service->callback_param,
++ VCHI_CALLBACK_BULK_RECEIVE_ABORTED, bulk_user);
++ break;
++ default:
++ WARN(1, "not supported\n");
++ break;
++ }
++
++ return VCHIQ_SUCCESS;
+ }
+
+ static SHIM_SERVICE_T *service_alloc(VCHIQ_INSTANCE_T instance,
+- SERVICE_CREATION_T *setup)
++ SERVICE_CREATION_T *setup)
+ {
+- SHIM_SERVICE_T *service = vcos_calloc(1, sizeof(SHIM_SERVICE_T), "vchiq_shim");
+-
+- vcos_unused(instance);
+-
+- if (service)
+- {
+- if (vchiu_queue_init(&service->queue, 64))
+- {
+- service->callback = setup->callback;
+- service->callback_param = setup->callback_param;
+- }
+- else
+- {
+- vcos_free(service);
+- service = NULL;
+- }
+- }
+-
+- return service;
++ SHIM_SERVICE_T *service = kzalloc(sizeof(SHIM_SERVICE_T), GFP_KERNEL);
++
++ (void)instance;
++
++ if (service) {
++ if (vchiu_queue_init(&service->queue, 64)) {
++ service->callback = setup->callback;
++ service->callback_param = setup->callback_param;
++ } else {
++ kfree(service);
++ service = NULL;
++ }
++ }
++
++ return service;
+ }
+
+ static void service_free(SHIM_SERVICE_T *service)
+ {
+- if (service)
+- {
+- vchiu_queue_delete(&service->queue);
+- vcos_free((void*)service);
+- }
++ if (service) {
++ vchiu_queue_delete(&service->queue);
++ kfree(service);
++ }
+ }
+
+-int32_t vchi_service_open( VCHI_INSTANCE_T instance_handle,
+- SERVICE_CREATION_T *setup,
+- VCHI_SERVICE_HANDLE_T *handle)
++int32_t vchi_service_open(VCHI_INSTANCE_T instance_handle,
++ SERVICE_CREATION_T *setup,
++ VCHI_SERVICE_HANDLE_T *handle)
+ {
+- VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
+- SHIM_SERVICE_T *service = service_alloc(instance, setup);
+- if (service)
+- {
+- VCHIQ_STATUS_T status = vchiq_open_service(instance, setup->service_id, shim_callback, service, &service->handle);
+- if (status != VCHIQ_SUCCESS)
+- {
+- service_free(service);
+- service = NULL;
+- }
+- }
+-
+- *handle = (VCHI_SERVICE_HANDLE_T)service;
+-
+- return (service != NULL) ? 0 : -1;
++ VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
++ SHIM_SERVICE_T *service = service_alloc(instance, setup);
++ if (service) {
++ VCHIQ_SERVICE_PARAMS_T params;
++ VCHIQ_STATUS_T status;
++
++ memset(&params, 0, sizeof(params));
++ params.fourcc = setup->service_id;
++ params.callback = shim_callback;
++ params.userdata = service;
++ params.version = setup->version.version;
++ params.version_min = setup->version.version_min;
++
++ status = vchiq_open_service(instance, &params,
++ &service->handle);
++ if (status != VCHIQ_SUCCESS) {
++ service_free(service);
++ service = NULL;
++ }
++ }
++
++ *handle = (VCHI_SERVICE_HANDLE_T)service;
++
++ return (service != NULL) ? 0 : -1;
+ }
++EXPORT_SYMBOL(vchi_service_open);
+
+-int32_t vchi_service_create( VCHI_INSTANCE_T instance_handle,
+- SERVICE_CREATION_T *setup,
+- VCHI_SERVICE_HANDLE_T *handle )
++int32_t vchi_service_create(VCHI_INSTANCE_T instance_handle,
++ SERVICE_CREATION_T *setup,
++ VCHI_SERVICE_HANDLE_T *handle)
+ {
+- VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
+- SHIM_SERVICE_T *service = service_alloc(instance, setup);
+- if (service)
+- {
+- VCHIQ_STATUS_T status = vchiq_add_service(instance, setup->service_id, shim_callback, service, &service->handle);
+- if (status != VCHIQ_SUCCESS)
+- {
+- service_free(service);
+- service = NULL;
+- }
+- }
+-
+- *handle = (VCHI_SERVICE_HANDLE_T)service;
+-
+- return (service != NULL) ? 0 : -1;
++ VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
++ SHIM_SERVICE_T *service = service_alloc(instance, setup);
++ if (service) {
++ VCHIQ_SERVICE_PARAMS_T params;
++ VCHIQ_STATUS_T status;
++
++ memset(&params, 0, sizeof(params));
++ params.fourcc = setup->service_id;
++ params.callback = shim_callback;
++ params.userdata = service;
++ params.version = setup->version.version;
++ params.version_min = setup->version.version_min;
++ status = vchiq_add_service(instance, &params, &service->handle);
++
++ if (status != VCHIQ_SUCCESS) {
++ service_free(service);
++ service = NULL;
++ }
++ }
++
++ *handle = (VCHI_SERVICE_HANDLE_T)service;
++
++ return (service != NULL) ? 0 : -1;
+ }
++EXPORT_SYMBOL(vchi_service_create);
+
+-int32_t vchi_service_close( const VCHI_SERVICE_HANDLE_T handle )
++int32_t vchi_service_close(const VCHI_SERVICE_HANDLE_T handle)
+ {
+- int32_t ret = -1;
+- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+- if(service)
+- {
+- VCHIQ_STATUS_T status = vchiq_close_service(service->handle);
+- if (status == VCHIQ_SUCCESS)
+- {
+- service_free(service);
+- service = NULL;
+- }
+-
+- ret = vchiq_status_to_vchi( status );
+- }
+- return ret;
++ int32_t ret = -1;
++ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
++ if (service) {
++ VCHIQ_STATUS_T status = vchiq_close_service(service->handle);
++ if (status == VCHIQ_SUCCESS) {
++ service_free(service);
++ service = NULL;
++ }
++
++ ret = vchiq_status_to_vchi(status);
++ }
++ return ret;
+ }
++EXPORT_SYMBOL(vchi_service_close);
+
+-int32_t vchi_service_destroy( const VCHI_SERVICE_HANDLE_T handle )
++int32_t vchi_service_destroy(const VCHI_SERVICE_HANDLE_T handle)
+ {
+- int32_t ret = -1;
+- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+- if(service)
+- {
+- VCHIQ_STATUS_T status = vchiq_remove_service(service->handle);
+- if (status == VCHIQ_SUCCESS)
+- {
+- service_free(service);
+- service = NULL;
+- }
+-
+- ret = vchiq_status_to_vchi( status );
+- }
+- return ret;
++ int32_t ret = -1;
++ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
++ if (service) {
++ VCHIQ_STATUS_T status = vchiq_remove_service(service->handle);
++ if (status == VCHIQ_SUCCESS) {
++ service_free(service);
++ service = NULL;
++ }
++
++ ret = vchiq_status_to_vchi(status);
++ }
++ return ret;
+ }
++EXPORT_SYMBOL(vchi_service_destroy);
+
+ /* ----------------------------------------------------------------------
+ * read a uint32_t from buffer.
+ * network format is defined to be little endian
+ * -------------------------------------------------------------------- */
+ uint32_t
+-vchi_readbuf_uint32( const void *_ptr )
++vchi_readbuf_uint32(const void *_ptr)
+ {
+- const unsigned char *ptr = _ptr;
+- return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
++ const unsigned char *ptr = _ptr;
++ return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
+ }
+
+ /* ----------------------------------------------------------------------
+@@ -909,13 +713,13 @@ vchi_readbuf_uint32( const void *_ptr )
+ * network format is defined to be little endian
+ * -------------------------------------------------------------------- */
+ void
+-vchi_writebuf_uint32( void *_ptr, uint32_t value )
++vchi_writebuf_uint32(void *_ptr, uint32_t value)
+ {
+- unsigned char *ptr = _ptr;
+- ptr[0] = (unsigned char)((value >> 0) & 0xFF);
+- ptr[1] = (unsigned char)((value >> 8) & 0xFF);
+- ptr[2] = (unsigned char)((value >> 16) & 0xFF);
+- ptr[3] = (unsigned char)((value >> 24) & 0xFF);
++ unsigned char *ptr = _ptr;
++ ptr[0] = (unsigned char)((value >> 0) & 0xFF);
++ ptr[1] = (unsigned char)((value >> 8) & 0xFF);
++ ptr[2] = (unsigned char)((value >> 16) & 0xFF);
++ ptr[3] = (unsigned char)((value >> 24) & 0xFF);
+ }
+
+ /* ----------------------------------------------------------------------
+@@ -923,10 +727,10 @@ vchi_writebuf_uint32( void *_ptr, uint32_t value )
+ * network format is defined to be little endian
+ * -------------------------------------------------------------------- */
+ uint16_t
+-vchi_readbuf_uint16( const void *_ptr )
++vchi_readbuf_uint16(const void *_ptr)
+ {
+- const unsigned char *ptr = _ptr;
+- return ptr[0] | (ptr[1] << 8);
++ const unsigned char *ptr = _ptr;
++ return ptr[0] | (ptr[1] << 8);
+ }
+
+ /* ----------------------------------------------------------------------
+@@ -934,11 +738,11 @@ vchi_readbuf_uint16( const void *_ptr )
+ * network format is defined to be little endian
+ * -------------------------------------------------------------------- */
+ void
+-vchi_writebuf_uint16( void *_ptr, uint16_t value )
++vchi_writebuf_uint16(void *_ptr, uint16_t value)
+ {
+- unsigned char *ptr = _ptr;
+- ptr[0] = (value >> 0) & 0xFF;
+- ptr[1] = (value >> 8) & 0xFF;
++ unsigned char *ptr = _ptr;
++ ptr[0] = (value >> 0) & 0xFF;
++ ptr[1] = (value >> 8) & 0xFF;
+ }
+
+ /***********************************************************
+@@ -951,16 +755,15 @@ vchi_writebuf_uint16( void *_ptr, uint16_t value )
+ * Returns: void
+ *
+ ***********************************************************/
+-int32_t vchi_service_use( const VCHI_SERVICE_HANDLE_T handle )
++int32_t vchi_service_use(const VCHI_SERVICE_HANDLE_T handle)
+ {
+- int32_t ret = -1;
+- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+- if(service)
+- {
+- ret = vchiq_status_to_vchi(vchiq_use_service(service->handle));
+- }
+- return ret;
++ int32_t ret = -1;
++ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
++ if (service)
++ ret = vchiq_status_to_vchi(vchiq_use_service(service->handle));
++ return ret;
+ }
++EXPORT_SYMBOL(vchi_service_use);
+
+ /***********************************************************
+ * Name: vchi_service_release
+@@ -972,30 +775,13 @@ int32_t vchi_service_use( const VCHI_SERVICE_HANDLE_T handle )
+ * Returns: void
+ *
+ ***********************************************************/
+-int32_t vchi_service_release( const VCHI_SERVICE_HANDLE_T handle )
++int32_t vchi_service_release(const VCHI_SERVICE_HANDLE_T handle)
+ {
+- int32_t ret = -1;
+- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+- if(service)
+- {
+- ret = vchiq_status_to_vchi(vchiq_release_service(service->handle));
+- }
+- return ret;
++ int32_t ret = -1;
++ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
++ if (service)
++ ret = vchiq_status_to_vchi(
++ vchiq_release_service(service->handle));
++ return ret;
+ }
+-
+-#if defined(__KERNEL__)
+-EXPORT_SYMBOL(vchi_initialise);
+-EXPORT_SYMBOL(vchi_connect);
+-EXPORT_SYMBOL(vchi_bulk_queue_transmit);
+-EXPORT_SYMBOL(vchi_msg_dequeue);
+-EXPORT_SYMBOL(vchi_msg_queue);
+-EXPORT_SYMBOL(vchi_msg_queuev);
+-EXPORT_SYMBOL(vchi_msg_peek);
+-EXPORT_SYMBOL(vchi_msg_remove);
+-EXPORT_SYMBOL(vchi_service_close);
+-EXPORT_SYMBOL(vchi_service_open);
+-EXPORT_SYMBOL(vchi_service_create);
+-EXPORT_SYMBOL(vchi_service_destroy);
+-EXPORT_SYMBOL(vchi_service_use);
+ EXPORT_SYMBOL(vchi_service_release);
+-#endif
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c
+index 20b67c3..8ea8bea 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c
+@@ -18,80 +18,88 @@
+
+ #include "vchiq_util.h"
+
+-#if !defined(__KERNEL__)
+-#include <stdlib.h>
+-#endif
+-
+-static __inline int is_pow2(int i)
++static inline int is_pow2(int i)
+ {
+- return i && !(i & (i - 1));
++ return i && !(i & (i - 1));
+ }
+
+ int vchiu_queue_init(VCHIU_QUEUE_T *queue, int size)
+ {
+- vcos_assert(is_pow2(size));
+-
+- queue->size = size;
+- queue->read = 0;
+- queue->write = 0;
+-
+- vcos_event_create(&queue->pop, "vchiu");
+- vcos_event_create(&queue->push, "vchiu");
+-
+- queue->storage = vcos_malloc(size * sizeof(VCHIQ_HEADER_T *), VCOS_FUNCTION);
+- if (queue->storage == NULL)
+- {
+- vchiu_queue_delete(queue);
+- return 0;
+- }
+- return 1;
++ WARN_ON(!is_pow2(size));
++
++ queue->size = size;
++ queue->read = 0;
++ queue->write = 0;
++
++ sema_init(&queue->pop, 0);
++ sema_init(&queue->push, 0);
++
++ queue->storage = kzalloc(size * sizeof(VCHIQ_HEADER_T *), GFP_KERNEL);
++ if (queue->storage == NULL) {
++ vchiu_queue_delete(queue);
++ return 0;
++ }
++ return 1;
+ }
+
+ void vchiu_queue_delete(VCHIU_QUEUE_T *queue)
+ {
+- vcos_event_delete(&queue->pop);
+- vcos_event_delete(&queue->push);
+- if (queue->storage != NULL)
+- vcos_free(queue->storage);
++ if (queue->storage != NULL)
++ kfree(queue->storage);
+ }
+
+ int vchiu_queue_is_empty(VCHIU_QUEUE_T *queue)
+ {
+- return queue->read == queue->write;
++ return queue->read == queue->write;
++}
++
++int vchiu_queue_is_full(VCHIU_QUEUE_T *queue)
++{
++ return queue->write == queue->read + queue->size;
+ }
+
+ void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header)
+ {
+- while (queue->write == queue->read + queue->size)
+- vcos_event_wait(&queue->pop);
++ while (queue->write == queue->read + queue->size) {
++ if (down_interruptible(&queue->pop) != 0) {
++ flush_signals(current);
++ }
++ }
+
+- queue->storage[queue->write & (queue->size - 1)] = header;
++ queue->storage[queue->write & (queue->size - 1)] = header;
+
+- queue->write++;
++ queue->write++;
+
+- vcos_event_signal(&queue->push);
++ up(&queue->push);
+ }
+
+ VCHIQ_HEADER_T *vchiu_queue_peek(VCHIU_QUEUE_T *queue)
+ {
+- while (queue->write == queue->read)
+- vcos_event_wait(&queue->push);
+-
+- return queue->storage[queue->read & (queue->size - 1)];
++ while (queue->write == queue->read) {
++ if (down_interruptible(&queue->push) != 0) {
++ flush_signals(current);
++ }
++ }
++
++ up(&queue->push); // We haven't removed anything from the queue.
++ return queue->storage[queue->read & (queue->size - 1)];
+ }
+
+ VCHIQ_HEADER_T *vchiu_queue_pop(VCHIU_QUEUE_T *queue)
+ {
+- VCHIQ_HEADER_T *header;
++ VCHIQ_HEADER_T *header;
+
+- while (queue->write == queue->read)
+- vcos_event_wait(&queue->push);
++ while (queue->write == queue->read) {
++ if (down_interruptible(&queue->push) != 0) {
++ flush_signals(current);
++ }
++ }
+
+- header = queue->storage[queue->read & (queue->size - 1)];
++ header = queue->storage[queue->read & (queue->size - 1)];
+
+- queue->read++;
++ queue->read++;
+
+- vcos_event_signal(&queue->pop);
++ up(&queue->pop);
+
+- return header;
++ return header;
+ }
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h
+index 6e0c84b..948503d 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h
+@@ -19,24 +19,44 @@
+ #ifndef VCHIQ_UTIL_H
+ #define VCHIQ_UTIL_H
+
++#include <linux/types.h>
++#include <linux/semaphore.h>
++#include <linux/mutex.h>
++#include <linux/bitops.h>
++#include <linux/kthread.h>
++#include <linux/wait.h>
++#include <linux/vmalloc.h>
++#include <linux/jiffies.h>
++#include <linux/delay.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/interrupt.h>
++#include <linux/random.h>
++#include <linux/sched.h>
++#include <linux/ctype.h>
++#include <linux/uaccess.h>
++#include <linux/time.h> /* for time_t */
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++
+ #include "vchiq_if.h"
+-#include "interface/vcos/vcos.h"
+
+ typedef struct {
+- int size;
+- int read;
+- int write;
++ int size;
++ int read;
++ int write;
+
+- VCOS_EVENT_T pop;
+- VCOS_EVENT_T push;
++ struct semaphore pop;
++ struct semaphore push;
+
+- VCHIQ_HEADER_T **storage;
++ VCHIQ_HEADER_T **storage;
+ } VCHIU_QUEUE_T;
+
+ extern int vchiu_queue_init(VCHIU_QUEUE_T *queue, int size);
+ extern void vchiu_queue_delete(VCHIU_QUEUE_T *queue);
+
+ extern int vchiu_queue_is_empty(VCHIU_QUEUE_T *queue);
++extern int vchiu_queue_is_full(VCHIU_QUEUE_T *queue);
+
+ extern void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header);
+
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_cmd.c b/drivers/misc/vc04_services/interface/vcos/generic/vcos_cmd.c
+deleted file mode 100644
+index 447d577..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_cmd.c
++++ /dev/null
+@@ -1,681 +0,0 @@
+-/*****************************************************************************
+-* Copyright 2009 - 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.
+-*****************************************************************************/
+-
+-/*****************************************************************************
+-*
+-* This file provides a generic command line interface which allows
+-* vcos internals to be manipulated and/or displayed.
+-*
+-*****************************************************************************/
+-
+-/* ---- Include Files ---------------------------------------------------- */
+-
+-#include "interface/vcos/vcos.h"
+-
+-#ifdef HAVE_VCOS_VERSION
+-#include "interface/vcos/vcos_build_info.h"
+-#endif
+-
+- #ifdef _VIDEOCORE
+-#include vcfw/logging/logging.h
+-#endif
+-
+-/* ---- Public Variables ------------------------------------------------- */
+-
+-/* ---- Private Constants and Types -------------------------------------- */
+-
+-#define VCOS_LOG_CATEGORY (&vcos_cmd_log_category)
+-VCOS_LOG_CAT_T vcos_cmd_log_category;
+-
+-/* ---- Private Variables ------------------------------------------------ */
+-
+-static struct VCOS_CMD_GLOBALS_T
+-{
+- VCOS_MUTEX_T lock;
+- VCOS_ONCE_T initialized;
+-
+- unsigned num_cmd_entries;
+- unsigned num_cmd_alloc;
+- VCOS_CMD_T *cmd_entry;
+-
+- VCOS_LOG_CAT_T *log_category;
+-} cmd_globals;
+-
+-/* ---- Private Function Prototypes -------------------------------------- */
+-
+-static VCOS_STATUS_T help_cmd( VCOS_CMD_PARAM_T *param );
+-
+-/* ---- Functions ------------------------------------------------------- */
+-
+-/*****************************************************************************
+-*
+-* Walks through the commands looking for a particular command
+-*
+-*****************************************************************************/
+-
+-static VCOS_CMD_T *find_cmd( VCOS_CMD_T *cmd_entry, const char *name )
+-{
+- VCOS_CMD_T *scan_entry = cmd_entry;
+-
+- while ( scan_entry->name != NULL )
+- {
+- if ( vcos_strcmp( scan_entry->name, name ) == 0 )
+- {
+- return scan_entry;
+- }
+- scan_entry++;
+- }
+-
+- return NULL;
+-}
+-
+-/*****************************************************************************
+-*
+-* Saves away
+-* each line individually.
+-*
+-*****************************************************************************/
+-
+-void vcos_cmd_always_log_output( VCOS_LOG_CAT_T *log_category )
+-{
+- cmd_globals.log_category = log_category;
+-}
+-
+-/*****************************************************************************
+-*
+-* Walks through a buffer containing newline separated lines, and logs
+-* each line individually.
+-*
+-*****************************************************************************/
+-
+-static void cmd_log_results( VCOS_CMD_PARAM_T *param )
+-{
+- char *start;
+- char *end;
+-
+- start = end = param->result_buf;
+-
+- while ( *start != '\0' )
+- {
+- while (( *end != '\0' ) && ( *end != '\n' ))
+- end++;
+-
+- if ( *end == '\n' )
+- {
+- *end++ = '\0';
+- }
+-
+- if ( cmd_globals.log_category != NULL )
+- {
+- if ( vcos_is_log_enabled( cmd_globals.log_category, VCOS_LOG_INFO ))
+- {
+- vcos_log_impl( cmd_globals.log_category, VCOS_LOG_INFO, "%s", start );
+- }
+- }
+- else
+- {
+- vcos_log_info( "%s", start );
+- }
+-
+- start = end;
+- }
+-
+- /* Since we logged the buffer, reset the pointer back to the beginning. */
+-
+- param->result_ptr = param->result_buf;
+- param->result_buf[0] = '\0';
+-}
+-
+-/*****************************************************************************
+-*
+-* Since we may have limited output space, we create a generic routine
+-* which tries to use the result space, but will switch over to using
+-* logging if the output is too large.
+-*
+-*****************************************************************************/
+-
+-void vcos_cmd_vprintf( VCOS_CMD_PARAM_T *param, const char *fmt, va_list args )
+-{
+- int bytes_written;
+- int bytes_remaining;
+-
+- bytes_remaining = (int)(param->result_size - ( param->result_ptr - param->result_buf ));
+-
+- bytes_written = vcos_vsnprintf( param->result_ptr, bytes_remaining, fmt, args );
+-
+- if ( cmd_globals.log_category != NULL )
+- {
+- /* We're going to log each line as we encounter it. If the buffer
+- * doesn't end in a newline, then we'll wait for one first.
+- */
+-
+- if ( (( bytes_written + 1 ) >= bytes_remaining )
+- || ( param->result_ptr[ bytes_written - 1 ] == '\n' ))
+- {
+- cmd_log_results( param );
+- }
+- else
+- {
+- param->result_ptr += bytes_written;
+- }
+- }
+- else
+- {
+- if (( bytes_written + 1 ) >= bytes_remaining )
+- {
+- /* Output doesn't fit - switch over to logging */
+-
+- param->use_log = 1;
+-
+- *param->result_ptr = '\0'; /* Zap the partial line that didn't fit above. */
+-
+- cmd_log_results( param ); /* resets result_ptr */
+-
+- bytes_written = vcos_vsnprintf( param->result_ptr, bytes_remaining, fmt, args );
+- }
+- param->result_ptr += bytes_written;
+- }
+-}
+-
+-/*****************************************************************************
+-*
+-* Prints the output.
+-*
+-*****************************************************************************/
+-
+-void vcos_cmd_printf( VCOS_CMD_PARAM_T *param, const char *fmt, ... )
+-{
+- va_list args;
+-
+- va_start( args, fmt );
+- vcos_cmd_vprintf( param, fmt, args );
+- va_end( args );
+-}
+-
+-/*****************************************************************************
+-*
+-* Prints the arguments which were on the command line prior to ours.
+-*
+-*****************************************************************************/
+-
+-static void print_argument_prefix( VCOS_CMD_PARAM_T *param )
+-{
+- int arg_idx;
+-
+- for ( arg_idx = 0; &param->argv_orig[arg_idx] != param->argv; arg_idx++ )
+- {
+- vcos_cmd_printf( param, "%s ", param->argv_orig[arg_idx] );
+- }
+-}
+-
+-/*****************************************************************************
+-*
+-* Prints an error message, prefixed by the command chain required to get
+-* to where we're at.
+-*
+-*****************************************************************************/
+-
+-void vcos_cmd_error( VCOS_CMD_PARAM_T *param, const char *fmt, ... )
+-{
+- va_list args;
+-
+- print_argument_prefix( param );
+-
+- va_start( args, fmt );
+- vcos_cmd_vprintf( param, fmt, args );
+- va_end( args );
+- vcos_cmd_printf( param, "\n" );
+-}
+-
+-/****************************************************************************
+-*
+-* usage - prints command usage for an array of commands.
+-*
+-***************************************************************************/
+-
+-static void usage( VCOS_CMD_PARAM_T *param, VCOS_CMD_T *cmd_entry )
+-{
+- int cmd_idx;
+- int nameWidth = 0;
+- int argsWidth = 0;
+- VCOS_CMD_T *scan_entry;
+-
+- vcos_cmd_printf( param, "Usage: " );
+- print_argument_prefix( param );
+- vcos_cmd_printf( param, "command [args ...]\n" );
+- vcos_cmd_printf( param, "\n" );
+- vcos_cmd_printf( param, "Where command is one of the following:\n" );
+-
+- for ( cmd_idx = 0; cmd_entry[cmd_idx].name != NULL; cmd_idx++ )
+- {
+- int aw;
+- int nw;
+-
+- scan_entry = &cmd_entry[cmd_idx];
+-
+- nw = vcos_strlen( scan_entry->name );
+- aw = vcos_strlen( scan_entry->args );
+-
+- if ( nw > nameWidth )
+- {
+- nameWidth = nw;
+- }
+- if ( aw > argsWidth )
+- {
+- argsWidth = aw;
+- }
+- }
+-
+- for ( cmd_idx = 0; cmd_entry[cmd_idx].name != NULL; cmd_idx++ )
+- {
+- scan_entry = &cmd_entry[cmd_idx];
+-
+- vcos_cmd_printf( param, " %-*s %-*s - %s\n",
+- nameWidth, scan_entry->name,
+- argsWidth, scan_entry->args,
+- scan_entry->descr );
+- }
+-}
+-
+-/****************************************************************************
+-*
+-* Prints the usage for the current command.
+-*
+-***************************************************************************/
+-
+-void vcos_cmd_usage( VCOS_CMD_PARAM_T *param )
+-{
+- VCOS_CMD_T *cmd_entry;
+-
+- cmd_entry = param->cmd_entry;
+-
+- if ( cmd_entry->sub_cmd_entry != NULL )
+- {
+- /* This command is command with sub-commands */
+-
+- usage( param, param->cmd_entry->sub_cmd_entry );
+- }
+- else
+- {
+- vcos_cmd_printf( param, "Usage: " );
+- print_argument_prefix( param );
+- vcos_cmd_printf( param, "%s - %s\n",
+- param->cmd_entry->args,
+- param->cmd_entry->descr );
+- }
+-}
+-
+-/*****************************************************************************
+-*
+-* Command to print out the help
+-*
+-* This help command is only called from the main menu.
+-*
+-*****************************************************************************/
+-
+-static VCOS_STATUS_T help_cmd( VCOS_CMD_PARAM_T *param )
+-{
+- VCOS_CMD_T *found_entry;
+-
+-#if 0
+- {
+- int arg_idx;
+-
+- vcos_log_trace( "%s: argc = %d", __func__, param->argc );
+- for ( arg_idx = 0; arg_idx < param->argc; arg_idx++ )
+- {
+- vcos_log_trace( "%s: argv[%d] = '%s'", __func__, arg_idx, param->argv[arg_idx] );
+- }
+- }
+-#endif
+-
+- /* If there is an argument after the word help, then we want to print
+- * help for that command.
+- */
+-
+- if ( param->argc == 1 )
+- {
+- if ( param->cmd_parent_entry == cmd_globals.cmd_entry )
+- {
+- /* Bare help - print the command usage for the root */
+-
+- usage( param, cmd_globals.cmd_entry );
+- return VCOS_SUCCESS;
+- }
+-
+- /* For all other cases help requires an argument */
+-
+- vcos_cmd_error( param, "%s requires an argument", param->argv[0] );
+- return VCOS_EINVAL;
+- }
+-
+- /* We were given an argument. */
+-
+- if (( found_entry = find_cmd( param->cmd_parent_entry, param->argv[1] )) != NULL )
+- {
+- /* Make it look like the command that was specified is the one that's
+- * currently running
+- */
+-
+- param->cmd_entry = found_entry;
+- param->argv[0] = param->argv[1];
+- param->argv++;
+- param->argc--;
+-
+- vcos_cmd_usage( param );
+- return VCOS_SUCCESS;
+- }
+-
+- vcos_cmd_error( param, "- unrecognized command: '%s'", param->argv[1] );
+- return VCOS_ENOENT;
+-}
+-
+-/*****************************************************************************
+-*
+-* Command to print out the version/build information.
+-*
+-*****************************************************************************/
+-
+-#ifdef HAVE_VCOS_VERSION
+-
+-static VCOS_STATUS_T version_cmd( VCOS_CMD_PARAM_T *param )
+-{
+- static const char* copyright = "Copyright (c) 2011 Broadcom";
+-
+- vcos_cmd_printf( param, "%s %s\n%s\nversion %s\n",
+- vcos_get_build_date(),
+- vcos_get_build_time(),
+- copyright,
+- vcos_get_build_version() );
+-
+- return VCOS_SUCCESS;
+-}
+-
+-#endif
+-
+-/*****************************************************************************
+-*
+-* Internal commands
+-*
+-*****************************************************************************/
+-
+-static VCOS_CMD_T cmd_help = { "help", "[command]", help_cmd, NULL, "Prints command help information" };
+-
+-#ifdef HAVE_VCOS_VERSION
+-static VCOS_CMD_T cmd_version = { "version", "", version_cmd, NULL, "Prints build/version information" };
+-#endif
+-
+-/*****************************************************************************
+-*
+-* Walks the command table and executes the commands
+-*
+-*****************************************************************************/
+-
+-static VCOS_STATUS_T execute_cmd( VCOS_CMD_PARAM_T *param, VCOS_CMD_T *cmd_entry )
+-{
+- const char *cmdStr;
+- VCOS_CMD_T *found_entry;
+-
+-#if 0
+- {
+- int arg_idx;
+-
+- vcos_cmd_printf( param, "%s: argc = %d", __func__, param->argc );
+- for ( arg_idx = 0; arg_idx < param->argc; arg_idx++ )
+- {
+- vcos_cmd_printf( param, " argv[%d] = '%s'", arg_idx, param->argv[arg_idx] );
+- }
+- vcos_cmd_printf( param, "\n" );
+- }
+-#endif
+-
+- if ( param->argc <= 1 )
+- {
+- /* No command specified */
+-
+- vcos_cmd_error( param, "%s - no command specified", param->argv[0] );
+- return VCOS_EINVAL;
+- }
+-
+- /* argv[0] is the command/program that caused us to get invoked, so we strip
+- * it off.
+- */
+-
+- param->argc--;
+- param->argv++;
+- param->cmd_parent_entry = cmd_entry;
+-
+- /* Not the help command, scan for the command and execute it. */
+-
+- cmdStr = param->argv[0];
+-
+- if (( found_entry = find_cmd( cmd_entry, cmdStr )) != NULL )
+- {
+- if ( found_entry->sub_cmd_entry != NULL )
+- {
+- return execute_cmd( param, found_entry->sub_cmd_entry );
+- }
+-
+- param->cmd_entry = found_entry;
+- return found_entry->cmd_fn( param );
+- }
+-
+- /* Unrecognized command - check to see if it was the help command */
+-
+- if ( vcos_strcmp( cmdStr, cmd_help.name ) == 0 )
+- {
+- return help_cmd( param );
+- }
+-
+- vcos_cmd_error( param, "- unrecognized command: '%s'", cmdStr );
+- return VCOS_ENOENT;
+-}
+-
+-/*****************************************************************************
+-*
+-* Initializes the command line parser.
+-*
+-*****************************************************************************/
+-
+-static void vcos_cmd_init( void )
+-{
+- vcos_mutex_create( &cmd_globals.lock, "vcos_cmd" );
+-
+- cmd_globals.num_cmd_entries = 0;
+- cmd_globals.num_cmd_alloc = 0;
+- cmd_globals.cmd_entry = NULL;
+-}
+-
+-/*****************************************************************************
+-*
+-* Command line processor.
+-*
+-*****************************************************************************/
+-
+-VCOS_STATUS_T vcos_cmd_execute( int argc, char **argv, size_t result_size, char *result_buf )
+-{
+- VCOS_STATUS_T rc = VCOS_EINVAL;
+- VCOS_CMD_PARAM_T param;
+-
+- vcos_once( &cmd_globals.initialized, vcos_cmd_init );
+-
+- param.argc = argc;
+- param.argv = param.argv_orig = argv;
+-
+- param.use_log = 0;
+- param.result_size = result_size;
+- param.result_ptr = result_buf;
+- param.result_buf = result_buf;
+-
+- result_buf[0] = '\0';
+-
+- vcos_mutex_lock( &cmd_globals.lock );
+-
+- rc = execute_cmd( &param, cmd_globals.cmd_entry );
+-
+- if ( param.use_log )
+- {
+- cmd_log_results( &param );
+- vcos_snprintf( result_buf, result_size, "results logged" );
+- }
+- else
+- if ( cmd_globals.log_category != NULL )
+- {
+- if ( result_buf[0] != '\0' )
+- {
+- /* There is a partial line still buffered. */
+-
+- vcos_cmd_printf( &param, "\n" );
+- }
+- }
+-
+- vcos_mutex_unlock( &cmd_globals.lock );
+-
+- return rc;
+-}
+-
+-/*****************************************************************************
+-*
+-* Registers a command entry with the command line processor
+-*
+-*****************************************************************************/
+-
+-VCOS_STATUS_T vcos_cmd_register( VCOS_CMD_T *cmd_entry )
+-{
+- VCOS_STATUS_T rc;
+- VCOS_UNSIGNED new_num_cmd_alloc;
+- VCOS_CMD_T *new_cmd_entry;
+- VCOS_CMD_T *old_cmd_entry;
+- VCOS_CMD_T *scan_entry;
+-
+- vcos_once( &cmd_globals.initialized, vcos_cmd_init );
+-
+- vcos_assert( cmd_entry != NULL );
+- vcos_assert( cmd_entry->name != NULL );
+-
+- vcos_log_trace( "%s: cmd '%s'", __FUNCTION__, cmd_entry->name );
+-
+- vcos_assert( cmd_entry->args != NULL );
+- vcos_assert(( cmd_entry->cmd_fn != NULL ) || ( cmd_entry->sub_cmd_entry != NULL ));
+- vcos_assert( cmd_entry->descr != NULL );
+-
+- /* We expect vcos_cmd_init to be called before vcos_logging_init, so we
+- * need to defer registering our logging category until someplace
+- * like right here.
+- */
+-
+- if ( vcos_cmd_log_category.name == NULL )
+- {
+- /*
+- * If you're using the command interface, you pretty much always want
+- * log messages from this file to show up. So we change the default
+- * from ERROR to be the more reasonable INFO level.
+- */
+-
+- vcos_log_set_level(&vcos_cmd_log_category, VCOS_LOG_INFO);
+- vcos_log_register("vcos_cmd", &vcos_cmd_log_category);
+-
+- /* We register a help command so that it shows up in the usage. */
+-
+- vcos_cmd_register( &cmd_help );
+-#ifdef HAVE_VCOS_VERSION
+- vcos_cmd_register( &cmd_version );
+-#endif
+- }
+-
+- vcos_mutex_lock( &cmd_globals.lock );
+-
+- if ( cmd_globals.num_cmd_entries >= cmd_globals.num_cmd_alloc )
+- {
+- if ( cmd_globals.num_cmd_alloc == 0 )
+- {
+- /* We haven't allocated a table yet */
+- }
+-
+- /* The number 8 is rather arbitrary. */
+-
+- new_num_cmd_alloc = cmd_globals.num_cmd_alloc + 8;
+-
+- /* The + 1 is to ensure that we always have a NULL entry at the end. */
+-
+- new_cmd_entry = (VCOS_CMD_T *)vcos_calloc( new_num_cmd_alloc + 1, sizeof( *cmd_entry ), "vcos_cmd_entries" );
+- if ( new_cmd_entry == NULL )
+- {
+- rc = VCOS_ENOMEM;
+- goto out;
+- }
+- memcpy( new_cmd_entry, cmd_globals.cmd_entry, cmd_globals.num_cmd_entries * sizeof( *cmd_entry ));
+- cmd_globals.num_cmd_alloc = new_num_cmd_alloc;
+- old_cmd_entry = cmd_globals.cmd_entry;
+- cmd_globals.cmd_entry = new_cmd_entry;
+- vcos_free( old_cmd_entry );
+- }
+-
+- if ( cmd_globals.num_cmd_entries == 0 )
+- {
+- /* This is the first command being registered */
+-
+- cmd_globals.cmd_entry[0] = *cmd_entry;
+- }
+- else
+- {
+- /* Keep the list in alphabetical order. We start at the end and work backwards
+- * shuffling entries up one until we find an insertion point.
+- */
+-
+- for ( scan_entry = &cmd_globals.cmd_entry[cmd_globals.num_cmd_entries - 1];
+- scan_entry >= cmd_globals.cmd_entry; scan_entry-- )
+- {
+- if ( vcos_strcmp( cmd_entry->name, scan_entry->name ) > 0 )
+- {
+- /* We found an insertion point. */
+-
+- break;
+- }
+-
+- scan_entry[1] = scan_entry[0];
+- }
+- scan_entry[1] = *cmd_entry;
+- }
+- cmd_globals.num_cmd_entries++;
+-
+- rc = VCOS_SUCCESS;
+-
+-out:
+-
+- vcos_mutex_unlock( &cmd_globals.lock );
+- return rc;
+-}
+-
+-/*****************************************************************************
+-*
+-* Registers multiple commands.
+-*
+-*****************************************************************************/
+-
+-VCOS_STATUS_T vcos_cmd_register_multiple( VCOS_CMD_T *cmd_entry )
+-{
+- VCOS_STATUS_T status;
+-
+- while ( cmd_entry->name != NULL )
+- {
+- if (( status = vcos_cmd_register( cmd_entry )) != VCOS_SUCCESS )
+- {
+- return status;
+- }
+- cmd_entry++;
+- }
+- return VCOS_SUCCESS;
+-}
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_common.h b/drivers/misc/vc04_services/interface/vcos/generic/vcos_common.h
+deleted file mode 100644
+index ce7816957..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_common.h
++++ /dev/null
+@@ -1,87 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - common postamble code
+-=============================================================================*/
+-
+-/** \file
+- *
+- * Postamble code included by the platform-specific header files
+- */
+-
+-#define VCOS_THREAD_PRI_DEFAULT VCOS_THREAD_PRI_NORMAL
+-
+-#if !defined(VCOS_THREAD_PRI_INCREASE)
+-#error Which way to thread priorities go?
+-#endif
+-
+-#if VCOS_THREAD_PRI_INCREASE < 0
+-/* smaller numbers are higher priority */
+-#define VCOS_THREAD_PRI_LESS(x) ((x)<VCOS_THREAD_PRI_MAX?(x)+1:VCOS_THREAD_PRI_MAX)
+-#define VCOS_THREAD_PRI_MORE(x) ((x)>VCOS_THREAD_PRI_MIN?(x)-1:VCOS_THREAD_PRI_MIN)
+-#else
+-/* bigger numbers are lower priority */
+-#define VCOS_THREAD_PRI_MORE(x) ((x)<VCOS_THREAD_PRI_MAX?(x)+1:VCOS_THREAD_PRI_MAX)
+-#define VCOS_THREAD_PRI_LESS(x) ((x)>VCOS_THREAD_PRI_MIN?(x)-1:VCOS_THREAD_PRI_MIN)
+-#endif
+-
+-/* Convenience for Brits: */
+-#define VCOS_APPLICATION_INITIALISE VCOS_APPLICATION_INITIALIZE
+-
+-/*
+- * Check for constant definitions
+- */
+-#ifndef VCOS_TICKS_PER_SECOND
+-#error VCOS_TICKS_PER_SECOND not defined
+-#endif
+-
+-#if !defined(VCOS_THREAD_PRI_MIN) || !defined(VCOS_THREAD_PRI_MAX)
+-#error Priority range not defined
+-#endif
+-
+-#if !defined(VCOS_THREAD_PRI_HIGHEST) || !defined(VCOS_THREAD_PRI_LOWEST) || !defined(VCOS_THREAD_PRI_NORMAL)
+-#error Priority ordering not defined
+-#endif
+-
+-#if !defined(VCOS_CAN_SET_STACK_ADDR)
+-#error Can stack addresses be set on this platform? Please set this macro to either 0 or 1.
+-#endif
+-
+-#if (_VCOS_AFFINITY_CPU0|_VCOS_AFFINITY_CPU1) & (~_VCOS_AFFINITY_MASK)
+-#error _VCOS_AFFINITY_CPUxxx values are not consistent with _VCOS_AFFINITY_MASK
+-#endif
+-
+-/** Append to the end of a singly-linked queue, O(1). Works with
+- * any structure where list has members 'head' and 'tail' and
+- * item has a 'next' pointer.
+- */
+-#define VCOS_QUEUE_APPEND_TAIL(list, item) {\
+- (item)->next = NULL;\
+- if (!(list)->head) {\
+- (list)->head = (list)->tail = (item); \
+- } else {\
+- (list)->tail->next = (item); \
+- (list)->tail = (item); \
+- } \
+-}
+-
+-#ifndef VCOS_HAVE_TIMER
+-VCOSPRE_ void VCOSPOST_ vcos_timer_init(void);
+-#endif
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_blockpool.h b/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_blockpool.h
+deleted file mode 100644
+index 154b200..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_blockpool.h
++++ /dev/null
+@@ -1,271 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - event flags implemented via a semaphore
+-=============================================================================*/
+-
+-#ifndef VCOS_GENERIC_BLOCKPOOL_H
+-#define VCOS_GENERIC_BLOCKPOOL_H
+-
+-/**
+- * \file
+- *
+- * This provides a generic, thread safe implementation of a VCOS block pool
+- * fixed size memory allocator.
+- */
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-
+-/** Bits 0 to (VCOS_BLOCKPOOL_SUBPOOL_BITS - 1) are used to store the
+- * subpool id. */
+-#define VCOS_BLOCKPOOL_SUBPOOL_BITS 3
+-#define VCOS_BLOCKPOOL_MAX_SUBPOOLS (1 << VCOS_BLOCKPOOL_SUBPOOL_BITS)
+-
+-/* Make zero an invalid handle at the cost of decreasing the maximum
+- * number of blocks (2^28) by 1. Alternatively, a spare bit could be
+- * used to indicated valid blocks but there are likely to be better
+- * uses for spare bits. e.g. allowing more subpools
+- */
+-#define INDEX_OFFSET 1
+-
+-#define VCOS_BLOCKPOOL_HANDLE_GET_INDEX(h) \
+- (((h) >> VCOS_BLOCKPOOL_SUBPOOL_BITS) - INDEX_OFFSET)
+-
+-#define VCOS_BLOCKPOOL_HANDLE_GET_SUBPOOL(h) \
+- ((h) & ((1 << VCOS_BLOCKPOOL_SUBPOOL_BITS) - 1))
+-
+-#define VCOS_BLOCKPOOL_HANDLE_CREATE(i,s) \
+- ((((i) + INDEX_OFFSET) << VCOS_BLOCKPOOL_SUBPOOL_BITS) | (s))
+-
+-#define VCOS_BLOCKPOOL_INVALID_HANDLE 0
+-
+-typedef struct VCOS_BLOCKPOOL_HEADER_TAG
+-{
+- /* Blocks either refer to to the pool if they are allocated
+- * or the free list if they are available.
+- */
+- union {
+- struct VCOS_BLOCKPOOL_HEADER_TAG *next;
+- struct VCOS_BLOCKPOOL_SUBPOOL_TAG* subpool;
+- } owner;
+-} VCOS_BLOCKPOOL_HEADER_T;
+-
+-typedef struct VCOS_BLOCKPOOL_SUBPOOL_TAG
+-{
+- /** VCOS_BLOCKPOOL_SUBPOOL_MAGIC */
+- uint32_t magic;
+- VCOS_BLOCKPOOL_HEADER_T* free_list;
+- /* The start of the pool memory */
+- void *mem;
+- /* Address of the first block header */
+- void *start;
+- /** The number of blocks in this sub-pool */
+- VCOS_UNSIGNED num_blocks;
+- /** Current number of available blocks in this sub-pool */
+- VCOS_UNSIGNED available_blocks;
+- /** Pointers to the pool that owns this sub-pool */
+- struct VCOS_BLOCKPOOL_TAG* owner;
+- /** Define properties such as memory ownership */
+- uint32_t flags;
+-} VCOS_BLOCKPOOL_SUBPOOL_T;
+-
+-typedef struct VCOS_BLOCKPOOL_TAG
+-{
+- /** VCOS_BLOCKPOOL_MAGIC */
+- uint32_t magic;
+- /** Thread safety for Alloc, Free, Delete, Stats */
+- VCOS_MUTEX_T mutex;
+- /** The size of the block data */
+- size_t block_data_size;
+- /** Block size inc overheads */
+- size_t block_size;
+- /** Name for debugging */
+- const char *name;
+- /* The number of subpools that may be used */
+- VCOS_UNSIGNED num_subpools;
+- /** Number of blocks in each dynamically allocated subpool */
+- VCOS_UNSIGNED num_extension_blocks;
+- /** Array of subpools. Subpool zero is is not deleted until the pool is
+- * destroed. If the index of the pool is < num_subpools and
+- * subpool[index.mem] is null then the subpool entry is valid but
+- * "not currently allocated" */
+- VCOS_BLOCKPOOL_SUBPOOL_T subpools[VCOS_BLOCKPOOL_MAX_SUBPOOLS];
+-} VCOS_BLOCKPOOL_T;
+-
+-#define VCOS_BLOCKPOOL_ROUND_UP(x,s) (((x) + ((s) - 1)) & ~((s) - 1))
+-/**
+- * Calculates the size in bytes required for a block pool containing
+- * num_blocks of size block_size plus any overheads.
+- *
+- * The block pool header (VCOS_BLOCKPOOL_T) is allocated separately
+- *
+- * Overheads:
+- * block_size + header must be a multiple of sizeof(void*)
+- * The start of the first block may need to be up to wordsize - 1 bytes
+- * into the given buffer because statically allocated buffers within structures
+- * are not guaranteed to be word aligned.
+- */
+-#define VCOS_BLOCKPOOL_SIZE(num_blocks, block_size) \
+- ((VCOS_BLOCKPOOL_ROUND_UP((block_size) + sizeof(VCOS_BLOCKPOOL_HEADER_T), \
+- sizeof(void*)) * (num_blocks)) + sizeof(void*))
+-
+-/**
+- * Sanity check to verify whether a handle is potentially a blockpool handle
+- * when the pool pointer is not available.
+- *
+- * If the pool pointer is availabe use vcos_blockpool_elem_to_handle instead.
+- *
+- * @param handle the handle to verify
+- * @param max_blocks the expected maximum number of block in the pool
+- * that the handle belongs to.
+- */
+-#define VCOS_BLOCKPOOL_IS_VALID_HANDLE_FORMAT(handle, max_blocks) \
+- ((handle) != VCOS_BLOCKPOOL_INVALID_HANDLE \
+- && VCOS_BLOCKPOOL_HANDLE_GET_INDEX((handle)) < (max_blocks))
+-
+-VCOSPRE_
+- VCOS_STATUS_T VCOSPOST_ vcos_generic_blockpool_init(VCOS_BLOCKPOOL_T *pool,
+- VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size,
+- void *start, VCOS_UNSIGNED pool_size, const char *name);
+-
+-VCOSPRE_
+- VCOS_STATUS_T VCOSPOST_ vcos_generic_blockpool_create_on_heap(
+- VCOS_BLOCKPOOL_T *pool, VCOS_UNSIGNED num_blocks,
+- VCOS_UNSIGNED block_size, const char *name);
+-
+-VCOSPRE_
+- VCOS_STATUS_T VCOSPOST_ vcos_generic_blockpool_extend(VCOS_BLOCKPOOL_T *pool,
+- VCOS_UNSIGNED num_extensions, VCOS_UNSIGNED num_blocks);
+-
+-VCOSPRE_ void VCOSPOST_ *vcos_generic_blockpool_alloc(VCOS_BLOCKPOOL_T *pool);
+-
+-VCOSPRE_ void VCOSPOST_ *vcos_generic_blockpool_calloc(VCOS_BLOCKPOOL_T *pool);
+-
+-VCOSPRE_ void VCOSPOST_ vcos_generic_blockpool_free(void *block);
+-
+-VCOSPRE_
+- VCOS_UNSIGNED VCOSPOST_ vcos_generic_blockpool_available_count(
+- VCOS_BLOCKPOOL_T *pool);
+-
+-VCOSPRE_
+- VCOS_UNSIGNED VCOSPOST_ vcos_generic_blockpool_used_count(
+- VCOS_BLOCKPOOL_T *pool);
+-
+-VCOSPRE_ void VCOSPOST_ vcos_generic_blockpool_delete(VCOS_BLOCKPOOL_T *pool);
+-
+-VCOSPRE_ uint32_t VCOSPOST_ vcos_generic_blockpool_elem_to_handle(void *block);
+-
+-VCOSPRE_ void VCOSPOST_
+- *vcos_generic_blockpool_elem_from_handle(
+- VCOS_BLOCKPOOL_T *pool, uint32_t handle);
+-
+-VCOSPRE_ uint32_t VCOSPOST_
+- vcos_generic_blockpool_is_valid_elem(
+- VCOS_BLOCKPOOL_T *pool, const void *block);
+-#if defined(VCOS_INLINE_BODIES)
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_blockpool_init(VCOS_BLOCKPOOL_T *pool,
+- VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size,
+- void *start, VCOS_UNSIGNED pool_size, const char *name)
+-{
+- return vcos_generic_blockpool_init(pool, num_blocks, block_size,
+- start, pool_size, name);
+-}
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_blockpool_create_on_heap(VCOS_BLOCKPOOL_T *pool,
+- VCOS_UNSIGNED num_blocks, VCOS_UNSIGNED block_size, const char *name)
+-{
+- return vcos_generic_blockpool_create_on_heap(
+- pool, num_blocks, block_size, name);
+-}
+-
+-VCOS_INLINE_IMPL
+- VCOS_STATUS_T VCOSPOST_ vcos_blockpool_extend(VCOS_BLOCKPOOL_T *pool,
+- VCOS_UNSIGNED num_extensions, VCOS_UNSIGNED num_blocks)
+-{
+- return vcos_generic_blockpool_extend(pool, num_extensions, num_blocks);
+-}
+-
+-VCOS_INLINE_IMPL
+-void *vcos_blockpool_alloc(VCOS_BLOCKPOOL_T *pool)
+-{
+- return vcos_generic_blockpool_alloc(pool);
+-}
+-
+-VCOS_INLINE_IMPL
+-void *vcos_blockpool_calloc(VCOS_BLOCKPOOL_T *pool)
+-{
+- return vcos_generic_blockpool_calloc(pool);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_blockpool_free(void *block)
+-{
+- vcos_generic_blockpool_free(block);
+-}
+-
+-VCOS_INLINE_IMPL
+-VCOS_UNSIGNED vcos_blockpool_available_count(VCOS_BLOCKPOOL_T *pool)
+-{
+- return vcos_generic_blockpool_available_count(pool);
+-}
+-
+-VCOS_INLINE_IMPL
+-VCOS_UNSIGNED vcos_blockpool_used_count(VCOS_BLOCKPOOL_T *pool)
+-{
+- return vcos_generic_blockpool_used_count(pool);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_blockpool_delete(VCOS_BLOCKPOOL_T *pool)
+-{
+- vcos_generic_blockpool_delete(pool);
+-}
+-
+-VCOS_INLINE_IMPL
+-uint32_t vcos_blockpool_elem_to_handle(void *block)
+-{
+- return vcos_generic_blockpool_elem_to_handle(block);
+-}
+-
+-VCOS_INLINE_IMPL
+-void *vcos_blockpool_elem_from_handle(VCOS_BLOCKPOOL_T *pool, uint32_t handle)
+-{
+- return vcos_generic_blockpool_elem_from_handle(pool, handle);
+-}
+-
+-VCOS_INLINE_IMPL
+-uint32_t vcos_blockpool_is_valid_elem(VCOS_BLOCKPOOL_T *pool, const void *block)
+-{
+- return vcos_generic_blockpool_is_valid_elem(pool, block);
+-}
+-#endif /* VCOS_INLINE_BODIES */
+-
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif /* VCOS_GENERIC_BLOCKPOOL_H */
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_event_flags.c b/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_event_flags.c
+deleted file mode 100644
+index 3948a57..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_event_flags.c
++++ /dev/null
+@@ -1,311 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - event flags implemented via mutexes
+-=============================================================================*/
+-
+-#include "interface/vcos/vcos.h"
+-#include "interface/vcos/generic/vcos_generic_event_flags.h"
+-
+-#include <stddef.h>
+-
+-/** A structure created by a thread that waits on the event flags
+- * for a particular combination of flags to arrive.
+- */
+-typedef struct VCOS_EVENT_WAITER_T
+-{
+- VCOS_UNSIGNED requested_events; /**< The events wanted */
+- VCOS_UNSIGNED actual_events; /**< Actual events found */
+- VCOS_UNSIGNED op; /**< The event operation to be used */
+- VCOS_STATUS_T return_status; /**< The return status the waiter should pass back */
+- VCOS_EVENT_FLAGS_T *flags; /**< Pointer to the original 'flags' structure */
+- VCOS_THREAD_T *thread; /**< Thread waiting */
+- struct VCOS_EVENT_WAITER_T *next;
+-} VCOS_EVENT_WAITER_T;
+-
+-#ifndef NDEBUG
+-static int waiter_list_valid(VCOS_EVENT_FLAGS_T *flags);
+-#endif
+-static void event_flags_timer_expired(void *cxt);
+-
+-VCOS_STATUS_T vcos_generic_event_flags_create(VCOS_EVENT_FLAGS_T *flags, const char *name)
+-{
+- VCOS_STATUS_T rc;
+- if ((rc=vcos_mutex_create(&flags->lock, name)) != VCOS_SUCCESS)
+- {
+- return rc;
+- }
+-
+- flags->events = 0;
+- flags->waiters.head = flags->waiters.tail = 0;
+- return rc;
+-}
+-
+-void vcos_generic_event_flags_set(VCOS_EVENT_FLAGS_T *flags,
+- VCOS_UNSIGNED bitmask,
+- VCOS_OPTION op)
+-{
+- vcos_assert(flags);
+- vcos_mutex_lock(&flags->lock);
+- if (op == VCOS_OR)
+- {
+- flags->events |= bitmask;
+- }
+- else if (op == VCOS_AND)
+- {
+- flags->events &= bitmask;
+- }
+- else
+- {
+- vcos_assert(0);
+- }
+-
+- /* Now wake up any threads that have now become signalled. */
+- if (flags->waiters.head != NULL)
+- {
+- VCOS_UNSIGNED consumed_events = 0;
+- VCOS_EVENT_WAITER_T **pcurrent_waiter = &flags->waiters.head;
+- VCOS_EVENT_WAITER_T *prev_waiter = NULL;
+-
+- /* Walk the chain of tasks suspend on this event flag group to determine
+- * if any of their requests can be satisfied.
+- */
+- while ((*pcurrent_waiter) != NULL)
+- {
+- VCOS_EVENT_WAITER_T *curr_waiter = *pcurrent_waiter;
+-
+- /* Determine if this request has been satisfied */
+-
+- /* First, find the event flags in common. */
+- VCOS_UNSIGNED waiter_satisfied = flags->events & curr_waiter->requested_events;
+-
+- /* Second, determine if all the event flags must match */
+- if (curr_waiter->op & VCOS_AND)
+- {
+- /* All requested events must be present */
+- waiter_satisfied = (waiter_satisfied == curr_waiter->requested_events);
+- }
+-
+- /* Wake this one up? */
+- if (waiter_satisfied)
+- {
+-
+- if (curr_waiter->op & VCOS_CONSUME)
+- {
+- consumed_events |= curr_waiter->requested_events;
+- }
+-
+- /* remove this block from the list, taking care at the end */
+- *pcurrent_waiter = curr_waiter->next;
+- if (curr_waiter->next == NULL)
+- flags->waiters.tail = prev_waiter;
+-
+- vcos_assert(waiter_list_valid(flags));
+-
+- curr_waiter->return_status = VCOS_SUCCESS;
+- curr_waiter->actual_events = flags->events;
+-
+- _vcos_thread_sem_post(curr_waiter->thread);
+- }
+- else
+- {
+- /* move to next element in the list */
+- prev_waiter = *pcurrent_waiter;
+- pcurrent_waiter = &(curr_waiter->next);
+- }
+- }
+-
+- flags->events &= ~consumed_events;
+-
+- }
+-
+- vcos_mutex_unlock(&flags->lock);
+-}
+-
+-void vcos_generic_event_flags_delete(VCOS_EVENT_FLAGS_T *flags)
+-{
+- vcos_mutex_delete(&flags->lock);
+-}
+-
+-extern VCOS_STATUS_T vcos_generic_event_flags_get(VCOS_EVENT_FLAGS_T *flags,
+- VCOS_UNSIGNED bitmask,
+- VCOS_OPTION op,
+- VCOS_UNSIGNED suspend,
+- VCOS_UNSIGNED *retrieved_bits)
+-{
+- VCOS_EVENT_WAITER_T waitreq;
+- VCOS_STATUS_T rc = VCOS_EAGAIN;
+- int satisfied = 0;
+-
+- vcos_assert(flags);
+-
+- /* default retrieved bits to 0 */
+- *retrieved_bits = 0;
+-
+- vcos_mutex_lock(&flags->lock);
+- switch (op & VCOS_EVENT_FLAG_OP_MASK)
+- {
+- case VCOS_AND:
+- if ((flags->events & bitmask) == bitmask)
+- {
+- *retrieved_bits = flags->events;
+- rc = VCOS_SUCCESS;
+- satisfied = 1;
+- if (op & VCOS_CONSUME)
+- flags->events &= ~bitmask;
+- }
+- break;
+-
+- case VCOS_OR:
+- if (flags->events & bitmask)
+- {
+- *retrieved_bits = flags->events;
+- rc = VCOS_SUCCESS;
+- satisfied = 1;
+- if (op & VCOS_CONSUME)
+- flags->events &= ~bitmask;
+- }
+- break;
+-
+- default:
+- vcos_assert(0);
+- rc = VCOS_EINVAL;
+- break;
+- }
+-
+- if (!satisfied && suspend)
+- {
+- /* Have to go to sleep.
+- *
+- * Append to tail so we get FIFO ordering.
+- */
+- waitreq.requested_events = bitmask;
+- waitreq.op = op;
+- waitreq.return_status = VCOS_EAGAIN;
+- waitreq.flags = flags;
+- waitreq.actual_events = 0;
+- waitreq.thread = vcos_thread_current();
+- waitreq.next = 0;
+- vcos_assert(waitreq.thread != (VCOS_THREAD_T*)-1);
+- VCOS_QUEUE_APPEND_TAIL(&flags->waiters, &waitreq);
+-
+- if (suspend != (VCOS_UNSIGNED)-1)
+- _vcos_task_timer_set(event_flags_timer_expired, &waitreq, suspend);
+-
+- vcos_mutex_unlock(&flags->lock);
+- /* go to sleep and wait to be signalled or timeout */
+-
+- _vcos_thread_sem_wait();
+-
+- *retrieved_bits = waitreq.actual_events;
+- rc = waitreq.return_status;
+-
+- /* cancel the timer - do not do this while holding the mutex as it
+- * might be waiting for the timeout function to complete, which will
+- * try to take the mutex.
+- */
+- if (suspend != (VCOS_UNSIGNED)-1)
+- _vcos_task_timer_cancel();
+- }
+- else
+- {
+- vcos_mutex_unlock(&flags->lock);
+- }
+-
+- return rc;
+-}
+-
+-
+-/** Called when a get call times out. Remove this thread's
+- * entry from the waiting queue, then resume the thread.
+- */
+-static void event_flags_timer_expired(void *cxt)
+-{
+- VCOS_EVENT_WAITER_T *waitreq = (VCOS_EVENT_WAITER_T *)cxt;
+- VCOS_EVENT_FLAGS_T *flags = waitreq->flags;
+- VCOS_EVENT_WAITER_T **plist;
+- VCOS_EVENT_WAITER_T *prev = NULL;
+- VCOS_THREAD_T *thread = 0;
+-
+- vcos_assert(flags);
+-
+- vcos_mutex_lock(&flags->lock);
+-
+- /* walk the list of waiting threads on this event group, and remove
+- * the one that has expired.
+- *
+- * FIXME: could use doubly-linked list if lots of threads are found
+- * to be waiting on a single event flag instance.
+- */
+- plist = &flags->waiters.head;
+- while (*plist != NULL)
+- {
+- if (*plist == waitreq)
+- {
+- int at_end;
+- /* found it */
+- thread = (*plist)->thread;
+- at_end = ((*plist)->next == NULL);
+-
+- /* link past */
+- *plist = (*plist)->next;
+- if (at_end)
+- flags->waiters.tail = prev;
+-
+- break;
+- }
+- prev = *plist;
+- plist = &(*plist)->next;
+- }
+- vcos_assert(waiter_list_valid(flags));
+-
+- vcos_mutex_unlock(&flags->lock);
+-
+- if (thread)
+- {
+- _vcos_thread_sem_post(thread);
+- }
+-}
+-
+-#ifndef NDEBUG
+-
+-static int waiter_list_valid(VCOS_EVENT_FLAGS_T *flags)
+-{
+- int valid;
+- /* Either both head and tail are NULL, or neither are NULL */
+- if (flags->waiters.head == NULL)
+- {
+- valid = (flags->waiters.tail == NULL);
+- }
+- else
+- {
+- valid = (flags->waiters.tail != NULL);
+- }
+-
+- /* If head and tail point at the same non-NULL element, then there
+- * is only one element in the list.
+- */
+- if (flags->waiters.head && (flags->waiters.head == flags->waiters.tail))
+- {
+- valid = (flags->waiters.head->next == NULL);
+- }
+- return valid;
+-}
+-
+-#endif
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_event_flags.h b/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_event_flags.h
+deleted file mode 100644
+index 8776ebe..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_event_flags.h
++++ /dev/null
+@@ -1,118 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - event flags implemented via a semaphore
+-=============================================================================*/
+-
+-#ifndef VCOS_GENERIC_EVENT_FLAGS_H
+-#define VCOS_GENERIC_EVENT_FLAGS_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-
+-/**
+- * \file
+- *
+- * This provides event flags (as per Nucleus Event Groups) based on a
+- * mutex, a semaphore (per waiting thread) and a timer (per waiting
+- * thread).
+- *
+- * The data structure is a 32 bit unsigned int (the current set of
+- * flags) and a linked list of clients waiting to be 'satisfied'.
+- *
+- * The mutex merely locks access to the data structure. If a client
+- * calls vcos_event_flags_get() and the requested bits are not already
+- * present, it then sleeps on its per-thread semaphore after adding
+- * this semaphore to the queue waiting. It also sets up a timer.
+- *
+- * The per-thread semaphore and timer are actually stored in the
+- * thread context (joinable thread). In future it may become necessary
+- * to support non-VCOS threads by using thread local storage to
+- * create these objects and associate them with the thread.
+- */
+-
+-struct VCOS_EVENT_WAITER_T;
+-
+-typedef struct VCOS_EVENT_FLAGS_T
+-{
+- VCOS_UNSIGNED events; /**< Events currently set */
+- VCOS_MUTEX_T lock; /**< Serialize access */
+- struct
+- {
+- struct VCOS_EVENT_WAITER_T *head; /**< List of threads waiting */
+- struct VCOS_EVENT_WAITER_T *tail; /**< List of threads waiting */
+- } waiters;
+-} VCOS_EVENT_FLAGS_T;
+-
+-#define VCOS_OR 1
+-#define VCOS_AND 2
+-#define VCOS_CONSUME 4
+-#define VCOS_OR_CONSUME (VCOS_OR | VCOS_CONSUME)
+-#define VCOS_AND_CONSUME (VCOS_AND | VCOS_CONSUME)
+-#define VCOS_EVENT_FLAG_OP_MASK (VCOS_OR|VCOS_AND)
+-
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_generic_event_flags_create(VCOS_EVENT_FLAGS_T *flags, const char *name);
+-VCOSPRE_ void VCOSPOST_ vcos_generic_event_flags_set(VCOS_EVENT_FLAGS_T *flags,
+- VCOS_UNSIGNED events,
+- VCOS_OPTION op);
+-VCOSPRE_ void VCOSPOST_ vcos_generic_event_flags_delete(VCOS_EVENT_FLAGS_T *);
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_generic_event_flags_get(VCOS_EVENT_FLAGS_T *flags,
+- VCOS_UNSIGNED requested_events,
+- VCOS_OPTION op,
+- VCOS_UNSIGNED suspend,
+- VCOS_UNSIGNED *retrieved_events);
+-
+-#ifdef VCOS_INLINE_BODIES
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_event_flags_create(VCOS_EVENT_FLAGS_T *flags, const char *name) {
+- return vcos_generic_event_flags_create(flags, name);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_event_flags_set(VCOS_EVENT_FLAGS_T *flags,
+- VCOS_UNSIGNED events,
+- VCOS_OPTION op) {
+- vcos_generic_event_flags_set(flags, events, op);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_event_flags_delete(VCOS_EVENT_FLAGS_T *f) {
+- vcos_generic_event_flags_delete(f);
+-}
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_event_flags_get(VCOS_EVENT_FLAGS_T *flags,
+- VCOS_UNSIGNED requested_events,
+- VCOS_OPTION op,
+- VCOS_UNSIGNED suspend,
+- VCOS_UNSIGNED *retrieved_events) {
+- return vcos_generic_event_flags_get(flags, requested_events, op, suspend, retrieved_events);
+-}
+-
+-#endif /* VCOS_INLINE_BODIES */
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_named_sem.h b/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_named_sem.h
+deleted file mode 100644
+index 370562d..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_named_sem.h
++++ /dev/null
+@@ -1,92 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - named semaphores
+-=============================================================================*/
+-
+-#ifndef VCOS_GENERIC_NAMED_SEM_H
+-#define VCOS_GENERIC_NAMED_SEM_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-
+-/**
+- * \file
+- *
+- * Generic support for named semaphores, using regular ones. This is only
+- * suitable for emulating them on an embedded MMUless system, since there is
+- * no support for opening semaphores across process boundaries.
+- *
+- */
+-
+-#define VCOS_NAMED_SEMAPHORE_NAMELEN 64
+-
+-/* In theory we could use the name facility provided within Nucleus. However, this
+- * is hard to do as semaphores are constantly being created and destroyed; we
+- * would need to stop everything while allocating the memory for the semaphore
+- * list and then walking it. So keep our own list.
+- */
+-typedef struct VCOS_NAMED_SEMAPHORE_T
+-{
+- struct VCOS_NAMED_SEMAPHORE_IMPL_T *actual; /**< There are 'n' named semaphores per 1 actual semaphore */
+- VCOS_SEMAPHORE_T *sem; /**< Pointer to actual underlying semaphore */
+-} VCOS_NAMED_SEMAPHORE_T;
+-
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_
+-vcos_generic_named_semaphore_create(VCOS_NAMED_SEMAPHORE_T *sem, const char *name, VCOS_UNSIGNED count);
+-
+-VCOSPRE_ void VCOSPOST_ vcos_named_semaphore_delete(VCOS_NAMED_SEMAPHORE_T *sem);
+-
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ _vcos_named_semaphore_init(void);
+-VCOSPRE_ void VCOSPOST_ _vcos_named_semaphore_deinit(void);
+-
+-#if defined(VCOS_INLINE_BODIES)
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_named_semaphore_create(VCOS_NAMED_SEMAPHORE_T *sem, const char *name, VCOS_UNSIGNED count) {
+- return vcos_generic_named_semaphore_create(sem, name, count);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_named_semaphore_wait(VCOS_NAMED_SEMAPHORE_T *sem) {
+- vcos_semaphore_wait(sem->sem);
+-}
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_named_semaphore_trywait(VCOS_NAMED_SEMAPHORE_T *sem) {
+- return vcos_semaphore_trywait(sem->sem);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_named_semaphore_post(VCOS_NAMED_SEMAPHORE_T *sem) {
+- vcos_semaphore_post(sem->sem);
+-}
+-
+-
+-#endif
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+-
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_quickslow_mutex.h b/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_quickslow_mutex.h
+deleted file mode 100644
+index bf7945c..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_quickslow_mutex.h
++++ /dev/null
+@@ -1,86 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - reentrant mutexes created from regular ones.
+-=============================================================================*/
+-
+-#ifndef VCOS_GENERIC_QUICKSLOW_MUTEX_H
+-#define VCOS_GENERIC_QUICKSLOW_MUTEX_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-
+-/**
+- * \file
+- *
+- * Quickslow Mutexes implemented as regular ones (i.e. quick and slow modes are the same).
+- *
+- */
+-
+-typedef VCOS_MUTEX_T VCOS_QUICKSLOW_MUTEX_T;
+-
+-#if defined(VCOS_INLINE_BODIES)
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_quickslow_mutex_create(VCOS_QUICKSLOW_MUTEX_T *m, const char *name)
+-{
+- return vcos_mutex_create(m, name);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_quickslow_mutex_delete(VCOS_QUICKSLOW_MUTEX_T *m)
+-{
+- vcos_mutex_delete(m);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_quickslow_mutex_lock(VCOS_QUICKSLOW_MUTEX_T *m)
+-{
+- while (vcos_mutex_lock(m) == VCOS_EAGAIN);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_quickslow_mutex_unlock(VCOS_QUICKSLOW_MUTEX_T *m)
+-{
+- vcos_mutex_unlock(m);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_quickslow_mutex_lock_quick(VCOS_QUICKSLOW_MUTEX_T *m)
+-{
+- while (vcos_mutex_lock(m) == VCOS_EAGAIN);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_quickslow_mutex_unlock_quick(VCOS_QUICKSLOW_MUTEX_T *m)
+-{
+- vcos_mutex_unlock(m);
+-}
+-
+-#endif
+-
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+-
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_reentrant_mtx.h b/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_reentrant_mtx.h
+deleted file mode 100644
+index 27563ea..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_reentrant_mtx.h
++++ /dev/null
+@@ -1,86 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - reentrant mutexes created from regular ones.
+-=============================================================================*/
+-
+-#ifndef VCOS_GENERIC_REENTRANT_MUTEX_H
+-#define VCOS_GENERIC_REENTRANT_MUTEX_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-
+-/**
+- * \file
+- *
+- * Reentrant Mutexes from regular ones.
+- *
+- */
+-
+-typedef struct VCOS_REENTRANT_MUTEX_T
+-{
+- VCOS_MUTEX_T mutex;
+- VCOS_THREAD_T *owner;
+- unsigned count;
+-} VCOS_REENTRANT_MUTEX_T;
+-
+-/* Extern definitions of functions that do the actual work */
+-
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_generic_reentrant_mutex_create(VCOS_REENTRANT_MUTEX_T *m, const char *name);
+-
+-VCOSPRE_ void VCOSPOST_ vcos_generic_reentrant_mutex_delete(VCOS_REENTRANT_MUTEX_T *m);
+-
+-VCOSPRE_ void VCOSPOST_ vcos_generic_reentrant_mutex_lock(VCOS_REENTRANT_MUTEX_T *m);
+-
+-VCOSPRE_ void VCOSPOST_ vcos_generic_reentrant_mutex_unlock(VCOS_REENTRANT_MUTEX_T *m);
+-
+-/* Inline forwarding functions */
+-
+-#if defined(VCOS_INLINE_BODIES)
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_reentrant_mutex_create(VCOS_REENTRANT_MUTEX_T *m, const char *name) {
+- return vcos_generic_reentrant_mutex_create(m,name);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_reentrant_mutex_delete(VCOS_REENTRANT_MUTEX_T *m) {
+- vcos_generic_reentrant_mutex_delete(m);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_reentrant_mutex_lock(VCOS_REENTRANT_MUTEX_T *m) {
+- vcos_generic_reentrant_mutex_lock(m);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_reentrant_mutex_unlock(VCOS_REENTRANT_MUTEX_T *m) {
+- vcos_generic_reentrant_mutex_unlock(m);
+-}
+-#endif
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+-
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_tls.h b/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_tls.h
+deleted file mode 100644
+index 22c059a..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_generic_tls.h
++++ /dev/null
+@@ -1,155 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - generic thread local storage
+-=============================================================================*/
+-
+-#ifndef VCOS_GENERIC_TLS_H
+-#define VCOS_GENERIC_TLS_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-
+-/**
+- * \file
+- *
+- * Do an emulation of Thread Local Storage. The platform needs to
+- * provide a way to set and get a per-thread pointer which is
+- * where the TLS data itself is stored.
+- *
+- *
+- * Each thread that wants to join in this scheme needs to call
+- * vcos_tls_thread_register().
+- *
+- * The platform needs to support the macros/functions
+- * _vcos_tls_thread_ptr_set() and _vcos_tls_thread_ptr_get().
+- */
+-
+-#ifndef VCOS_WANT_TLS_EMULATION
+-#error Should not be included unless TLS emulation is defined
+-#endif
+-
+-/** Number of slots to reserve per thread. This results in an overhead
+- * of this many words per thread.
+- */
+-#define VCOS_TLS_MAX_SLOTS 4
+-
+-/** TLS key. Allocating one of these reserves the client one of the
+- * available slots.
+- */
+-typedef VCOS_UNSIGNED VCOS_TLS_KEY_T;
+-
+-/** TLS per-thread structure. Each thread gets one of these
+- * if TLS emulation (rather than native TLS support) is
+- * being used.
+- */
+-typedef struct VCOS_TLS_THREAD_T
+-{
+- void *slots[VCOS_TLS_MAX_SLOTS];
+-} VCOS_TLS_THREAD_T;
+-
+-/*
+- * Internal APIs
+- */
+-
+-/** Register this thread's TLS storage area. */
+-VCOSPRE_ void VCOSPOST_ vcos_tls_thread_register(VCOS_TLS_THREAD_T *);
+-
+-/** Create a new TLS key */
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_generic_tls_create(VCOS_TLS_KEY_T *key);
+-
+-/** Delete a TLS key */
+-VCOSPRE_ void VCOSPOST_ vcos_generic_tls_delete(VCOS_TLS_KEY_T tls);
+-
+-/** Initialise the TLS library */
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_tls_init(void);
+-
+-/** Deinitialise the TLS library */
+-VCOSPRE_ void VCOSPOST_ vcos_tls_deinit(void);
+-
+-#if defined(VCOS_INLINE_BODIES)
+-
+-#undef VCOS_ASSERT_LOGGING_DISABLE
+-#define VCOS_ASSERT_LOGGING_DISABLE 1
+-
+-/*
+- * Implementations of public API functions
+- */
+-
+-/** Set the given value. Since everything is per-thread, there is no need
+- * for any locking.
+- */
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_tls_set(VCOS_TLS_KEY_T tls, void *v) {
+- VCOS_TLS_THREAD_T *tlsdata = _vcos_tls_thread_ptr_get();
+- vcos_assert(tlsdata); /* Fires if this thread has not been registered */
+- if (tls<VCOS_TLS_MAX_SLOTS)
+- {
+- tlsdata->slots[tls] = v;
+- return VCOS_SUCCESS;
+- }
+- else
+- {
+- vcos_assert(0);
+- return VCOS_EINVAL;
+- }
+-}
+-
+-/** Get the given value. No locking required.
+- */
+-VCOS_INLINE_IMPL
+-void *vcos_tls_get(VCOS_TLS_KEY_T tls) {
+- VCOS_TLS_THREAD_T *tlsdata = _vcos_tls_thread_ptr_get();
+- vcos_assert(tlsdata); /* Fires if this thread has not been registered */
+- if (tls<VCOS_TLS_MAX_SLOTS)
+- {
+- return tlsdata->slots[tls];
+- }
+- else
+- {
+- vcos_assert(0);
+- return NULL;
+- }
+-}
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_tls_create(VCOS_TLS_KEY_T *key) {
+- return vcos_generic_tls_create(key);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_tls_delete(VCOS_TLS_KEY_T tls) {
+- vcos_generic_tls_delete(tls);
+-}
+-
+-#undef VCOS_ASSERT_LOGGING_DISABLE
+-#define VCOS_ASSERT_LOGGING_DISABLE 0
+-
+-#endif /* VCOS_INLINE_BODIES */
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-
+-#endif
+-
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_joinable_thread_from_plain.h b/drivers/misc/vc04_services/interface/vcos/generic/vcos_joinable_thread_from_plain.h
+deleted file mode 100644
+index fd0e198..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_joinable_thread_from_plain.h
++++ /dev/null
+@@ -1,214 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - implementation: joinable thread from plain
+-=============================================================================*/
+-
+-/** \file
+- *
+- * Header file for platforms creating the joinable thread from a lowlevel
+- * thread.
+- *
+- * In addition to the actual thread, the following are also created:
+- *
+- * - a semaphore to wait on when joining the thread
+- * - a semaphore to support counted suspend/resume (used by event group)
+- * - a per-thread timer (used by event group, but could be removed)
+- */
+-
+-#ifndef VCOS_JOINABLE_THREAD_FROM_PLAIN_H
+-#define VCOS_JOINABLE_THREAD_FROM_PLAIN_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_semaphore.h"
+-#include "interface/vcos/vcos_lowlevel_thread.h"
+-#include "interface/vcos/vcos_timer.h"
+-
+-#ifdef VCOS_WANT_TLS_EMULATION
+-#include "interface/vcos/generic/vcos_generic_tls.h"
+-#endif
+-
+-#define VCOS_THREAD_MAGIC 0x56436a74
+-
+-#define VCOS_THREAD_VALID(t) (t->magic == VCOS_THREAD_MAGIC)
+-#define VCOS_HAVE_THREAD_AT_EXIT 1
+-
+-/** Thread attribute structure. Clients should not manipulate this directly, but
+- * should instead use the provided functions.
+- */
+-typedef struct VCOS_THREAD_ATTR_T
+-{
+- void *ta_stackaddr;
+- VCOS_UNSIGNED ta_stacksz;
+- VCOS_UNSIGNED ta_priority;
+- VCOS_UNSIGNED ta_affinity;
+- VCOS_UNSIGNED ta_timeslice;
+- VCOS_UNSIGNED legacy;
+- VCOS_UNSIGNED ta_autostart;
+-} VCOS_THREAD_ATTR_T;
+-
+-/** Each thread gets a timer, which is for internal VCOS use.
+- */
+-typedef struct _VCOS_THREAD_TIMER_T
+-{
+- VCOS_TIMER_T timer;
+- void (*pfn)(void *);
+- void *cxt;
+-} _VCOS_THREAD_TIMER_T;
+-
+-typedef void (*VCOS_THREAD_EXIT_HANDLER_T)(void *);
+-/** Called at thread exit.
+- */
+-typedef struct VCOS_THREAD_EXIT_T
+-{
+- VCOS_THREAD_EXIT_HANDLER_T pfn;
+- void *cxt;
+-} VCOS_THREAD_EXIT_T;
+-#define VCOS_MAX_EXIT_HANDLERS 8
+-
+-/* The name field isn't used for anything, so we can just copy the
+- * the pointer. Nucleus makes its own copy.
+- */
+-typedef const char * VCOS_LLTHREAD_T_NAME;
+-#define _VCOS_LLTHREAD_NAME(dst,src) (dst)=(src)
+-
+-/*
+- * Simulated TLS support
+- */
+-
+-
+-/** Thread structure.
+- *
+- * \warning Do not access the members of this structure directly!
+- */
+-typedef struct VCOS_THREAD_T
+-{
+- VCOS_LLTHREAD_T thread; /**< The underlying thread */
+- char name[16]; /**< The name */
+- unsigned int magic; /**< For debug */
+- void *exit_data; /**< Exit data passed out in vcos_joinable_thread_exit() */
+- void *stack; /**< Stack, if not supplied by caller */
+- VCOS_SEMAPHORE_T wait; /**< Semaphore to wait on at join */
+- VCOS_SEMAPHORE_T suspend; /**< Semaphore to wait on for counted suspend */
+- int16_t joined; /**< Joined yet? For debug. */
+- VCOS_UNSIGNED legacy; /**< Use (argc,argv) for entry point arguments */
+- void *(*entry)(void*); /**< Entry point */
+- void *arg; /**< Argument passed to entry point */
+- void *(*term)(void*); /**< Termination function, used by reaper */
+- void *term_arg; /**< Argument passed to termination function */
+- _VCOS_THREAD_TIMER_T _timer; /**< Internal timer, mainly for event groups */
+-#ifdef VCOS_WANT_TLS_EMULATION
+- VCOS_TLS_THREAD_T _tls; /**< TLS data when native TLS not available, or NULL */
+-#endif
+- /** Array of functions to call at thread exit */
+- VCOS_THREAD_EXIT_T at_exit[VCOS_MAX_EXIT_HANDLERS];
+-
+- struct VCOS_THREAD_T *next; /**< For linked lists of threads */
+-} VCOS_THREAD_T;
+-
+-#if defined(VCOS_INLINE_BODIES)
+-
+-VCOS_INLINE_IMPL
+-void vcos_thread_attr_setstack(VCOS_THREAD_ATTR_T *attrs, void *addr, VCOS_UNSIGNED stacksz) {
+- attrs->ta_stackaddr = addr;
+- attrs->ta_stacksz = stacksz;
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_thread_attr_setstacksize(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED stacksz) {
+- attrs->ta_stacksz = stacksz;
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_thread_attr_setpriority(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED pri) {
+- attrs->ta_priority = pri;
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_thread_attr_setaffinity(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED affinity) {
+- attrs->ta_affinity = affinity;
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_thread_attr_settimeslice(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED ts) {
+- attrs->ta_timeslice = ts;
+-}
+-
+-VCOS_INLINE_IMPL
+-void _vcos_thread_attr_setlegacyapi(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED legacy) {
+- attrs->legacy = legacy;
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_thread_attr_setautostart(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED autostart) {
+- attrs->ta_autostart = autostart;
+-}
+-
+-VCOS_INLINE_IMPL
+-VCOS_THREAD_T *vcos_thread_current(void) {
+- VCOS_THREAD_T *ret = (VCOS_THREAD_T*)vcos_llthread_current();
+- /*If we're called from a non-vcos thread, this assert will fail.
+- *XXX FIXME why is this commented out?
+- *vcos_assert(ret->magic == VCOS_THREAD_MAGIC);
+- */
+- return ret;
+-}
+-
+-VCOS_INLINE_IMPL
+-int vcos_thread_running(VCOS_THREAD_T *thread) {
+- return vcos_llthread_running(&thread->thread);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_thread_resume(VCOS_THREAD_T *thread) {
+- vcos_llthread_resume(&thread->thread);
+-}
+-
+-#endif /* VCOS_INLINE_BODIES */
+-
+-/**
+- * \brief Create a VCOS_THREAD_T for the current thread. This is so we can have
+- * VCOS_THREAD_Ts even for threads not originally created by VCOS (eg the
+- * thread that calls vcos_init)
+- */
+-extern VCOS_STATUS_T _vcos_thread_create_attach(VCOS_THREAD_T *thread,
+- const char *name);
+-
+-/**
+- * \brief Deletes the VCOS_THREAD_T, but does not wait for the underlying
+- * thread to exit. This will cleanup everything created by
+- * _vcos_thread_create_attach
+- */
+-extern void _vcos_thread_delete(VCOS_THREAD_T *thread);
+-
+-/** Register a function to be called when the current thread exits.
+- */
+-extern VCOS_STATUS_T vcos_thread_at_exit(void (*pfn)(void*), void *cxt);
+-
+-/** Deregister a previously registered at-exit function.
+- */
+-extern void vcos_thread_deregister_at_exit(void (*pfn)(void*), void *cxt);
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif /* VCOS_JOINABLE_THREAD_FROM_PLAIN_H */
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_latch_from_sem.h b/drivers/misc/vc04_services/interface/vcos/generic/vcos_latch_from_sem.h
+deleted file mode 100644
+index ec9e07b..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_latch_from_sem.h
++++ /dev/null
+@@ -1,59 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - Construct a latch from a semaphore
+-=============================================================================*/
+-
+-/** FIXME: rename to vcos_mutex_from_sem.c
+- */
+-
+-typedef struct VCOS_MUTEX_T {
+- VCOS_SEMAPHORE_T sem;
+- struct VCOS_THREAD_T *owner;
+-} VCOS_MUTEX_T;
+-
+-extern VCOS_STATUS_T vcos_generic_mutex_create(VCOS_MUTEX_T *latch, const char *name);
+-extern void vcos_generic_mutex_delete(VCOS_MUTEX_T *latch);
+-extern VCOS_STATUS_T vcos_generic_mutex_lock(VCOS_MUTEX_T *latch);
+-extern void vcos_generic_mutex_unlock(VCOS_MUTEX_T *latch);
+-
+-#if defined(VCOS_INLINE_BODIES)
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_mutex_create(VCOS_MUTEX_T *latch, const char *name) {
+- return vcos_generic_mutex_create(latch,name);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_mutex_delete(VCOS_MUTEX_T *latch) {
+- vcos_generic_mutex_delete(latch);
+-}
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_mutex_lock(VCOS_MUTEX_T *latch) {
+- return vcos_generic_mutex_lock(latch);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_mutex_unlock(VCOS_MUTEX_T *latch) {
+- vcos_generic_mutex_unlock(latch);
+-}
+-
+-#endif /* VCOS_INLINE_BODIES */
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_logcat.c b/drivers/misc/vc04_services/interface/vcos/generic/vcos_logcat.c
+deleted file mode 100644
+index 8b05179..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_logcat.c
++++ /dev/null
+@@ -1,560 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-Categorized logging for VCOS - a generic implementation.
+-=============================================================================*/
+-
+-#include "interface/vcos/vcos.h"
+-#include "interface/vcos/vcos_ctype.h"
+-#include "interface/vcos/vcos_string.h"
+-
+-static VCOS_MUTEX_T lock;
+-static int warned_loglevel; /* only warn about invalid log level once */
+-static VCOS_VLOG_IMPL_FUNC_T vcos_vlog_impl_func = vcos_vlog_default_impl;
+-
+-#define VCOS_LOG_CATEGORY (&dflt_log_category)
+-static VCOS_LOG_CAT_T dflt_log_category;
+-VCOS_LOG_CAT_T *vcos_logging_categories = NULL;
+-static int inited;
+-
+-#if VCOS_HAVE_CMD
+-
+-/*
+- * For kernel or videocore purposes, we generally want the log command. For
+- * user-space apps, they might want to provide their own log command, so we
+- * don't include the built in on.
+- *
+- * So pthreads/vcos_platform.h defines VCOS_WANT_LOG_CMD to be 0. It is
+- * undefined elsewhere.
+- */
+-
+-# if !defined( VCOS_WANT_LOG_CMD )
+-# define VCOS_WANT_LOG_CMD 1
+-# endif
+-#else
+-# define VCOS_WANT_LOG_CMD 0
+-#endif
+-
+-#if VCOS_WANT_LOG_CMD
+-
+-/*****************************************************************************
+-*
+-* Does a vcos_assert(0), which is useful to test logging.
+-*
+-*****************************************************************************/
+-
+-VCOS_STATUS_T vcos_log_assert_cmd( VCOS_CMD_PARAM_T *param )
+-{
+- (void)param;
+-
+-#if defined( NDEBUG ) && !defined( VCOS_RELEASE_ASSERTS )
+- vcos_log_error( "vcos_asserts have been compiled out" );
+- vcos_cmd_printf( param, "vcos_asserts have been compiled out - did a vcos_log_error instead\n" );
+-#else
+- vcos_assert(0);
+- vcos_cmd_printf( param, "Executed vcos_assert(0)\n" );
+-#endif
+-
+- return VCOS_SUCCESS;
+-}
+-
+-/*****************************************************************************
+-*
+-* Sets a vcos logging level
+-*
+-*****************************************************************************/
+-
+-VCOS_STATUS_T vcos_log_set_cmd( VCOS_CMD_PARAM_T *param )
+-{
+- VCOS_LOG_CAT_T *cat;
+- char *name;
+- char *levelStr;
+- VCOS_LOG_LEVEL_T level;
+- VCOS_STATUS_T status;
+-
+- if ( param->argc != 3 )
+- {
+- vcos_cmd_usage( param );
+- return VCOS_EINVAL;
+- }
+-
+- name = param->argv[1];
+- levelStr = param->argv[2];
+-
+- if ( vcos_string_to_log_level( levelStr, &level ) != VCOS_SUCCESS )
+- {
+- vcos_cmd_printf( param, "Unrecognized logging level: '%s'\n", levelStr );
+- return VCOS_EINVAL;
+- }
+-
+- vcos_mutex_lock(&lock);
+-
+- status = VCOS_SUCCESS;
+- for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next )
+- {
+- if ( vcos_strcmp( name, cat->name ) == 0 )
+- {
+- cat->level = level;
+- vcos_cmd_printf( param, "Category %s level set to %s\n", name, levelStr );
+- break;
+- }
+- }
+- if ( cat == NULL )
+- {
+- vcos_cmd_printf( param, "Unrecognized category: '%s'\n", name );
+- status = VCOS_ENOENT;
+- }
+-
+- vcos_mutex_unlock(&lock);
+-
+- return status;
+-}
+-
+-/*****************************************************************************
+-*
+-* Prints out the current settings for a given category (or all cvategories)
+-*
+-*****************************************************************************/
+-
+-VCOS_STATUS_T vcos_log_status_cmd( VCOS_CMD_PARAM_T *param )
+-{
+- VCOS_LOG_CAT_T *cat;
+- VCOS_STATUS_T status;
+-
+- vcos_mutex_lock(&lock);
+-
+- if ( param->argc == 1)
+- {
+- int nw;
+- int nameWidth = 0;
+-
+- /* Print information about all of the categories. */
+-
+- for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next )
+- {
+- nw = (int)strlen( cat->name );
+-
+- if ( nw > nameWidth )
+- {
+- nameWidth = nw;
+- }
+- }
+-
+- for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next )
+- {
+- vcos_cmd_printf( param, "%-*s - %s\n", nameWidth, cat->name, vcos_log_level_to_string( cat->level ));
+- }
+- }
+- else
+- {
+- /* Print information about a particular category */
+-
+- for ( cat = vcos_logging_categories; cat != NULL; cat = cat->next )
+- {
+- if ( vcos_strcmp( cat->name, param->argv[1] ) == 0 )
+- {
+- vcos_cmd_printf( param, "%s - %s\n", cat->name, vcos_log_level_to_string( cat->level ));
+- break;
+- }
+- }
+- if ( cat == NULL )
+- {
+- vcos_cmd_printf( param, "Unrecognized logging category: '%s'\n", param->argv[1] );
+- status = VCOS_ENOENT;
+- goto out;
+- }
+- }
+-
+- status = VCOS_SUCCESS;
+-out:
+- vcos_mutex_unlock(&lock);
+-
+- return status;
+-}
+-
+-/*****************************************************************************
+-*
+-* Prints out the current settings for a given category (or all cvategories)
+-*
+-*****************************************************************************/
+-
+-VCOS_STATUS_T vcos_log_test_cmd( VCOS_CMD_PARAM_T *param )
+-{
+- if ( param->argc == 1 )
+- {
+- static int seq_num = 100;
+-
+- /* No additional arguments - generate a message with an incrementing number */
+-
+- vcos_log_error( "Test message %d", seq_num );
+-
+- seq_num++;
+- vcos_cmd_printf( param, "Logged 'Test message %d'\n", seq_num );
+- }
+- else
+- {
+- int arg_idx;
+-
+- /* Arguments supplied - log these */
+-
+- for ( arg_idx = 0; arg_idx < param->argc; arg_idx++ )
+- {
+- vcos_log_error( "argv[%d] = '%s'", arg_idx, param->argv[arg_idx] );
+- }
+- vcos_cmd_printf( param, "Logged %d line(s) of test data\n", param->argc );
+- }
+- return VCOS_SUCCESS;
+-}
+-
+-/*****************************************************************************
+-*
+-* Internal commands
+-*
+-*****************************************************************************/
+-
+-static VCOS_CMD_T log_cmd_entry[] =
+-{
+- { "assert", "", vcos_log_assert_cmd, NULL, "Does a vcos_assert(0) to test logging" },
+- { "set", "category level", vcos_log_set_cmd, NULL, "Sets the vcos logging level for a category" },
+- { "status", "[category]", vcos_log_status_cmd, NULL, "Prints the vcos log status for a (or all) categories" },
+- { "test", "[arbitrary text]", vcos_log_test_cmd, NULL, "Does a vcos_log to test logging" },
+-
+- { NULL, NULL, NULL, NULL, NULL }
+-};
+-
+-static VCOS_CMD_T cmd_log =
+- { "log", "command [args]", NULL, log_cmd_entry, "Commands related to vcos logging" };
+-
+-#endif
+-
+-void vcos_logging_init(void)
+-{
+- if (inited)
+- {
+- /* FIXME: should print a warning or something here */
+- return;
+- }
+- vcos_mutex_create(&lock, "vcos_log");
+-
+- vcos_log_platform_init();
+-
+- vcos_log_register("default", &dflt_log_category);
+-
+-#if VCOS_WANT_LOG_CMD
+- vcos_cmd_register( &cmd_log );
+-#endif
+-
+- vcos_assert(!inited);
+- inited = 1;
+-}
+-
+-/** Read an alphanumeric token, returning True if we succeeded.
+- */
+-
+-static int read_tok(char *tok, size_t toklen, const char **pstr, char sep)
+-{
+- const char *str = *pstr;
+- size_t n = 0;
+- char ch;
+-
+- /* skip past any whitespace */
+- while (str[0] && isspace((int)(str[0])))
+- str++;
+-
+- while ((ch = *str) != '\0' &&
+- ch != sep &&
+- (isalnum((int)ch) || (ch == '_')) &&
+- n != toklen-1)
+- {
+- tok[n++] = ch;
+- str++;
+- }
+-
+- /* did it work out? */
+- if (ch == '\0' || ch == sep)
+- {
+- if (ch) str++; /* move to next token if not at end */
+- /* yes */
+- tok[n] = '\0';
+- *pstr = str;
+- return 1;
+- }
+- else
+- {
+- /* no */
+- return 0;
+- }
+-}
+-
+-const char *vcos_log_level_to_string( VCOS_LOG_LEVEL_T level )
+-{
+- switch (level)
+- {
+- case VCOS_LOG_UNINITIALIZED: return "uninit";
+- case VCOS_LOG_NEVER: return "never";
+- case VCOS_LOG_ERROR: return "error";
+- case VCOS_LOG_WARN: return "warn";
+- case VCOS_LOG_INFO: return "info";
+- case VCOS_LOG_TRACE: return "trace";
+- }
+- return "???";
+-}
+-
+-VCOS_STATUS_T vcos_string_to_log_level( const char *str, VCOS_LOG_LEVEL_T *level )
+-{
+- if (strcmp(str,"error") == 0)
+- *level = VCOS_LOG_ERROR;
+- else if (strcmp(str,"never") == 0)
+- *level = VCOS_LOG_NEVER;
+- else if (strcmp(str,"warn") == 0)
+- *level = VCOS_LOG_WARN;
+- else if (strcmp(str,"warning") == 0)
+- *level = VCOS_LOG_WARN;
+- else if (strcmp(str,"info") == 0)
+- *level = VCOS_LOG_INFO;
+- else if (strcmp(str,"trace") == 0)
+- *level = VCOS_LOG_TRACE;
+- else
+- return VCOS_EINVAL;
+-
+- return VCOS_SUCCESS;
+-}
+-
+-static int read_level(VCOS_LOG_LEVEL_T *level, const char **pstr, char sep)
+-{
+- char buf[16];
+- int ret = 1;
+- if (read_tok(buf,sizeof(buf),pstr,sep))
+- {
+- if (vcos_string_to_log_level(buf,level) != VCOS_SUCCESS)
+- {
+- vcos_log("Invalid trace level '%s'\n", buf);
+- ret = 0;
+- }
+- }
+- else
+- {
+- ret = 0;
+- }
+- return ret;
+-}
+-
+-void vcos_log_register(const char *name, VCOS_LOG_CAT_T *category)
+-{
+- const char *env;
+- VCOS_LOG_CAT_T *i;
+-
+- category->name = name;
+- if ( category->level == VCOS_LOG_UNINITIALIZED )
+- {
+- category->level = VCOS_LOG_ERROR;
+- }
+- category->flags.want_prefix = (category != &dflt_log_category );
+-
+- vcos_mutex_lock(&lock);
+-
+- /* is it already registered? */
+- for (i = vcos_logging_categories; i ; i = i->next )
+- {
+- if (i == category)
+- {
+- i->refcount++;
+- break;
+- }
+- }
+-
+- if (!i)
+- {
+- /* not yet registered */
+- category->next = vcos_logging_categories;
+- vcos_logging_categories = category;
+- category->refcount++;
+-
+- vcos_log_platform_register(category);
+- }
+-
+- vcos_mutex_unlock(&lock);
+-
+- /* Check to see if this log level has been enabled. Look for
+- * (<category:level>,)*
+- *
+- * VC_LOGLEVEL=ilcs:info,vchiq:warn
+- */
+-
+- env = _VCOS_LOG_LEVEL();
+- if (env)
+- {
+- do
+- {
+- char env_name[64];
+- VCOS_LOG_LEVEL_T level;
+- if (read_tok(env_name, sizeof(env_name), &env, ':') &&
+- read_level(&level, &env, ','))
+- {
+- if (strcmp(env_name, name) == 0)
+- {
+- category->level = level;
+- break;
+- }
+- }
+- else
+- {
+- if (!warned_loglevel)
+- {
+- vcos_log("VC_LOGLEVEL format invalid at %s\n", env);
+- warned_loglevel = 1;
+- }
+- return;
+- }
+- } while (env[0] != '\0');
+- }
+-
+- vcos_log_info( "Registered log category '%s' with level %s",
+- category->name,
+- vcos_log_level_to_string( category->level ));
+-}
+-
+-void vcos_log_unregister(VCOS_LOG_CAT_T *category)
+-{
+- VCOS_LOG_CAT_T **pcat;
+- vcos_mutex_lock(&lock);
+- category->refcount--;
+- if (category->refcount == 0)
+- {
+- pcat = &vcos_logging_categories;
+- while (*pcat != category)
+- {
+- if (!*pcat)
+- break; /* possibly deregistered twice? */
+- if ((*pcat)->next == NULL)
+- {
+- vcos_assert(0); /* already removed! */
+- vcos_mutex_unlock(&lock);
+- return;
+- }
+- pcat = &(*pcat)->next;
+- }
+- if (*pcat)
+- *pcat = category->next;
+-
+- vcos_log_platform_unregister(category);
+- }
+- vcos_mutex_unlock(&lock);
+-}
+-
+-VCOSPRE_ const VCOS_LOG_CAT_T * VCOSPOST_ vcos_log_get_default_category(void)
+-{
+- return &dflt_log_category;
+-}
+-
+-void vcos_set_log_options(const char *opt)
+-{
+- (void)opt;
+-}
+-
+-void vcos_log_dump_mem_impl( const VCOS_LOG_CAT_T *cat,
+- const char *label,
+- uint32_t addr,
+- const void *voidMem,
+- size_t numBytes )
+-{
+- const uint8_t *mem = (const uint8_t *)voidMem;
+- size_t offset;
+- char lineBuf[ 100 ];
+- char *s;
+-
+- while ( numBytes > 0 )
+- {
+- s = lineBuf;
+-
+- for ( offset = 0; offset < 16; offset++ )
+- {
+- if ( offset < numBytes )
+- {
+- s += vcos_snprintf( s, 4, "%02x ", mem[ offset ]);
+- }
+- else
+- {
+- s += vcos_snprintf( s, 4, " " );
+- }
+- }
+-
+- for ( offset = 0; offset < 16; offset++ )
+- {
+- if ( offset < numBytes )
+- {
+- uint8_t ch = mem[ offset ];
+-
+- if (( ch < ' ' ) || ( ch > '~' ))
+- {
+- ch = '.';
+- }
+- *s++ = (char)ch;
+- }
+- }
+- *s++ = '\0';
+-
+- if (( label != NULL ) && ( *label != '\0' ))
+- {
+- vcos_log_impl( cat, VCOS_LOG_INFO, "%s: %08x: %s", label, addr, lineBuf );
+- }
+- else
+- {
+- vcos_log_impl( cat, VCOS_LOG_INFO, "%08x: %s", addr, lineBuf );
+- }
+-
+- addr += 16;
+- mem += 16;
+- if ( numBytes > 16 )
+- {
+- numBytes -= 16;
+- }
+- else
+- {
+- numBytes = 0;
+- }
+- }
+-
+-}
+-
+-void vcos_log_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, ...)
+-{
+- va_list ap;
+- va_start(ap,fmt);
+- vcos_vlog_impl( cat, _level, fmt, ap );
+- va_end(ap);
+-}
+-
+-void vcos_vlog_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args)
+-{
+- vcos_vlog_impl_func( cat, _level, fmt, args );
+-}
+-
+-void vcos_set_vlog_impl( VCOS_VLOG_IMPL_FUNC_T vlog_impl_func )
+-{
+- if ( vlog_impl_func == NULL )
+- {
+- vcos_vlog_impl_func = vcos_vlog_default_impl;
+- }
+- else
+- {
+- vcos_vlog_impl_func = vlog_impl_func;
+- }
+-}
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_mem_from_malloc.c b/drivers/misc/vc04_services/interface/vcos/generic/vcos_mem_from_malloc.c
+deleted file mode 100644
+index dd0574a..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_mem_from_malloc.c
++++ /dev/null
+@@ -1,84 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - memory alloc implementation
+-=============================================================================*/
+-
+-#include "interface/vcos/vcos.h"
+-
+-#ifndef _vcos_platform_malloc
+-#include <stdlib.h>
+-#define _vcos_platform_malloc malloc
+-#define _vcos_platform_free free
+-#endif
+-
+-typedef struct malloc_header_s {
+- uint32_t guardword;
+- uint32_t size;
+- const char *description;
+- void *ptr;
+-} MALLOC_HEADER_T;
+-
+-
+-#define MIN_ALIGN sizeof(MALLOC_HEADER_T)
+-
+-#define GUARDWORDHEAP 0xa55a5aa5
+-
+-void *vcos_generic_mem_alloc_aligned(VCOS_UNSIGNED size, VCOS_UNSIGNED align, const char *desc)
+-{
+- int local_align = align == 0 ? 1 : align;
+- int required_size = size + local_align + sizeof(MALLOC_HEADER_T);
+- void *ptr = _vcos_platform_malloc(required_size);
+- void *ret = (void *)VCOS_ALIGN_UP(((char *)ptr)+sizeof(MALLOC_HEADER_T), local_align);
+- MALLOC_HEADER_T *h = ((MALLOC_HEADER_T *)ret)-1;
+-
+- h->size = size;
+- h->description = desc;
+- h->guardword = GUARDWORDHEAP;
+- h->ptr = ptr;
+-
+- return ret;
+-}
+-
+-void *vcos_generic_mem_alloc(VCOS_UNSIGNED size, const char *desc)
+-{
+- return vcos_generic_mem_alloc_aligned(size,MIN_ALIGN,desc);
+-}
+-
+-void *vcos_generic_mem_calloc(VCOS_UNSIGNED count, VCOS_UNSIGNED sz, const char *desc)
+-{
+- uint32_t size = count*sz;
+- void *ptr = vcos_generic_mem_alloc_aligned(size,MIN_ALIGN,desc);
+- if (ptr)
+- {
+- memset(ptr, 0, size);
+- }
+- return ptr;
+-}
+-
+-void vcos_generic_mem_free(void *ptr)
+-{
+- MALLOC_HEADER_T *h;
+- if (! ptr) return;
+-
+- h = ((MALLOC_HEADER_T *)ptr)-1;
+- vcos_assert(h->guardword == GUARDWORDHEAP);
+- _vcos_platform_free(h->ptr);
+-}
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_mem_from_malloc.h b/drivers/misc/vc04_services/interface/vcos/generic/vcos_mem_from_malloc.h
+deleted file mode 100644
+index 8e2a18e..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_mem_from_malloc.h
++++ /dev/null
+@@ -1,65 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-Create the vcos_malloc API from the regular system malloc/free
+-=============================================================================*/
+-
+-/**
+- * \file
+- *
+- * Create the vcos malloc API from a regular system malloc/free library.
+- *
+- * The API lets callers specify an alignment.
+- *
+- * Under VideoCore this is not needed, as we can simply use the rtos_malloc routines.
+- * But on host platforms that won't be the case.
+- *
+- */
+-
+-VCOSPRE_ void * VCOSPOST_ vcos_generic_mem_alloc(VCOS_UNSIGNED sz, const char *desc);
+-VCOSPRE_ void * VCOSPOST_ vcos_generic_mem_calloc(VCOS_UNSIGNED count, VCOS_UNSIGNED sz, const char *descr);
+-VCOSPRE_ void VCOSPOST_ vcos_generic_mem_free(void *ptr);
+-VCOSPRE_ void * VCOSPOST_ vcos_generic_mem_alloc_aligned(VCOS_UNSIGNED sz, VCOS_UNSIGNED align, const char *desc);
+-
+-#ifdef VCOS_INLINE_BODIES
+-
+-VCOS_INLINE_IMPL
+-void *vcos_malloc(VCOS_UNSIGNED size, const char *description) {
+- return vcos_generic_mem_alloc(size, description);
+-}
+-
+-VCOS_INLINE_IMPL
+-void *vcos_calloc(VCOS_UNSIGNED num, VCOS_UNSIGNED size, const char *description) {
+- return vcos_generic_mem_calloc(num, size, description);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_free(void *ptr) {
+- vcos_generic_mem_free(ptr);
+-}
+-
+-VCOS_INLINE_IMPL
+-void * vcos_malloc_aligned(VCOS_UNSIGNED size, VCOS_UNSIGNED align, const char *description) {
+- return vcos_generic_mem_alloc_aligned(size, align, description);
+-}
+-
+-
+-#endif /* VCOS_INLINE_BODIES */
+-
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_mutexes_are_reentrant.h b/drivers/misc/vc04_services/interface/vcos/generic/vcos_mutexes_are_reentrant.h
+deleted file mode 100644
+index a6a52b4..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_mutexes_are_reentrant.h
++++ /dev/null
+@@ -1,79 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - reentrant mutexes mapped directly to regular ones
+-=============================================================================*/
+-
+-#ifndef VCOS_GENERIC_REENTRANT_MUTEX_H
+-#define VCOS_GENERIC_REENTRANT_MUTEX_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "interface/vcos/vcos_mutex.h"
+-
+-/**
+- * \file
+- *
+- * Reentrant Mutexes directly using the native re-entrant mutex.
+- *
+- */
+-
+-typedef VCOS_MUTEX_T VCOS_REENTRANT_MUTEX_T;
+-
+-/* Inline forwarding functions */
+-
+-#if defined(VCOS_INLINE_BODIES)
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_reentrant_mutex_create(VCOS_REENTRANT_MUTEX_T *m, const char *name) {
+- return vcos_mutex_create(m,name);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_reentrant_mutex_delete(VCOS_REENTRANT_MUTEX_T *m) {
+- vcos_mutex_delete(m);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_reentrant_mutex_lock(VCOS_REENTRANT_MUTEX_T *m) {
+- vcos_mutex_lock(m);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_reentrant_mutex_unlock(VCOS_REENTRANT_MUTEX_T *m) {
+- vcos_mutex_unlock(m);
+-}
+-
+-VCOS_INLINE_IMPL
+-int vcos_reentrant_mutex_is_locked(VCOS_REENTRANT_MUTEX_T *m) {
+- return vcos_mutex_is_locked(m);
+-}
+-
+-#endif
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+-
+-
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/generic/vcos_thread_reaper.h b/drivers/misc/vc04_services/interface/vcos/generic/vcos_thread_reaper.h
+deleted file mode 100644
+index 655dc25..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/generic/vcos_thread_reaper.h
++++ /dev/null
+@@ -1,46 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - thread reaping
+-=============================================================================*/
+-
+-#ifndef VCOS_THREAD_REAPER_H
+-#define VCOS_THREAD_REAPER_H
+-
+-#define VCOS_HAVE_THREAD_REAPER
+-
+-/** Initialise the thread reaper.
+- */
+-VCOS_STATUS_T vcos_thread_reaper_init(void);
+-
+-/** Reap a thread. Arranges for the thread to be automatically
+- * joined.
+- *
+- * @sa vcos_thread_join().
+- *
+- * @param thread the thread to terminate
+- * @param on_terminated called after the thread has exited
+- * @param cxt pass back to the callback
+- *
+- */
+-void vcos_thread_reap(VCOS_THREAD_T *thread, void (*on_terminated)(void*), void *cxt);
+-
+-#endif
+-
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/linuxkernel/stdint.h b/drivers/misc/vc04_services/interface/vcos/linuxkernel/stdint.h
+deleted file mode 100644
+index 1db1ecb..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/linuxkernel/stdint.h
++++ /dev/null
+@@ -1,31 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS fAbstraction Layer - stdint.h C standard header
+-=============================================================================*/
+-
+-#ifndef _VCOS_PLATFORM_LINUX_STDINT_H
+-#define _VCOS_PLATFORM_LINUX_STDINT_H
+-
+-/* The Linux kernel does not have a <stdint.h> so we have to provide one of
+- our own. */
+-
+-#include <linux/types.h> /* includes integer types */
+-
+-#endif /* _VCOS_PLATFORM_LINUX_STDINT_H */
+diff --git a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel.c b/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel.c
+deleted file mode 100644
+index 0385540..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel.c
++++ /dev/null
+@@ -1,627 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - pthreads types
+-=============================================================================*/
+-
+-#define VCOS_INLINE_BODIES
+-#include <linux/module.h>
+-#include <linux/kernel.h>
+-#include <linux/time.h>
+-#include <linux/pid.h>
+-#include <linux/mm.h>
+-#include <linux/version.h>
+-
+-#if defined( CONFIG_BCM_KNLLOG_SUPPORT )
+-#include <linux/broadcom/knllog.h>
+-#endif
+-#include "interface/vcos/vcos.h"
+-#ifdef HAVE_VCOS_VERSION
+-#include "interface/vcos/vcos_build_info.h"
+-#endif
+-
+-VCOS_CFG_ENTRY_T vcos_cfg_dir;
+-VCOS_CFG_ENTRY_T vcos_logging_cfg_dir;
+-VCOS_CFG_ENTRY_T vcos_version_cfg;
+-
+-#ifndef VCOS_DEFAULT_STACK_SIZE
+-#define VCOS_DEFAULT_STACK_SIZE 4096
+-#endif
+-
+-static VCOS_THREAD_ATTR_T default_attrs = {
+- 0,
+- VCOS_DEFAULT_STACK_SIZE,
+-};
+-
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
+-static DEFINE_SEMAPHORE(lock);
+-#else
+-static DECLARE_MUTEX(lock);
+-#endif
+-
+-typedef void (*LEGACY_ENTRY_FN_T)(int, void *);
+-
+-/** Wrapper function around the real thread function. Posts the semaphore
+- * when completed.
+- */
+-static int vcos_thread_wrapper(void *arg)
+-{
+- void *ret;
+- VCOS_THREAD_T *thread = arg;
+-
+- vcos_assert(thread->magic == VCOS_THREAD_MAGIC);
+-
+- thread->thread.thread = current;
+-
+- vcos_add_thread(thread);
+-
+-#ifdef VCOS_WANT_TLS_EMULATION
+- vcos_tls_thread_register(&thread->_tls);
+-#endif
+-
+- if (thread->legacy)
+- {
+- LEGACY_ENTRY_FN_T fn = (LEGACY_ENTRY_FN_T)thread->entry;
+- fn(0,thread->arg);
+- ret = 0;
+- }
+- else
+- {
+- ret = thread->entry(thread->arg);
+- }
+-
+- thread->exit_data = ret;
+-
+- vcos_remove_thread(current);
+-
+- /* For join and cleanup */
+- vcos_semaphore_post(&thread->wait);
+-
+- return 0;
+-}
+-
+-VCOS_STATUS_T vcos_thread_create(VCOS_THREAD_T *thread,
+- const char *name,
+- VCOS_THREAD_ATTR_T *attrs,
+- VCOS_THREAD_ENTRY_FN_T entry,
+- void *arg)
+-{
+- VCOS_STATUS_T st;
+- struct task_struct *kthread;
+-
+- memset(thread, 0, sizeof(*thread));
+- thread->magic = VCOS_THREAD_MAGIC;
+- strlcpy( thread->name, name, sizeof( thread->name ));
+- thread->legacy = attrs ? attrs->legacy : 0;
+- thread->entry = entry;
+- thread->arg = arg;
+-
+- if (!name)
+- {
+- vcos_assert(0);
+- return VCOS_EINVAL;
+- }
+-
+- st = vcos_semaphore_create(&thread->wait, NULL, 0);
+- if (st != VCOS_SUCCESS)
+- {
+- return st;
+- }
+-
+- st = vcos_semaphore_create(&thread->suspend, NULL, 0);
+- if (st != VCOS_SUCCESS)
+- {
+- return st;
+- }
+-
+- /*required for event groups */
+- vcos_timer_create(&thread->_timer.timer, thread->name, NULL, NULL);
+-
+- kthread = kthread_create((int (*)(void *))vcos_thread_wrapper, (void*)thread, name);
+- vcos_assert(kthread != NULL);
+- set_user_nice(kthread, attrs->ta_priority);
+- thread->thread.thread = kthread;
+- wake_up_process(kthread);
+- return VCOS_SUCCESS;
+-}
+-
+-void vcos_thread_join(VCOS_THREAD_T *thread,
+- void **pData)
+-{
+- vcos_assert(thread);
+- vcos_assert(thread->magic == VCOS_THREAD_MAGIC);
+-
+- thread->joined = 1;
+-
+- vcos_semaphore_wait(&thread->wait);
+-
+- if (pData)
+- {
+- *pData = thread->exit_data;
+- }
+-
+- /* Clean up */
+- if (thread->stack)
+- vcos_free(thread->stack);
+-
+- vcos_semaphore_delete(&thread->wait);
+- vcos_semaphore_delete(&thread->suspend);
+-
+-}
+-
+-uint32_t vcos_getmicrosecs( void )
+-{
+- struct timeval tv;
+-/*XXX FIX ME! switch to ktime_get_ts to use MONOTONIC clock */
+- do_gettimeofday(&tv);
+- return (tv.tv_sec*1000000) + tv.tv_usec;
+-}
+-
+-VCOS_STATUS_T vcos_timer_init(void)
+-{
+- return VCOS_SUCCESS;
+-}
+-
+-static const char *log_prefix[] =
+-{
+- "", /* VCOS_LOG_UNINITIALIZED */
+- "", /* VCOS_LOG_NEVER */
+- KERN_ERR, /* VCOS_LOG_ERROR */
+- KERN_WARNING, /* VCOS_LOG_WARN */
+- KERN_INFO, /* VCOS_LOG_INFO */
+- KERN_INFO /* VCOS_LOG_TRACE */
+-};
+-
+-void vcos_vlog_default_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args)
+-{
+- char *newline = strchr( fmt, '\n' );
+- const char *prefix;
+- const char *real_fmt;
+-
+- preempt_disable();
+- {
+- if ( *fmt == '<' )
+- {
+- prefix = fmt;
+- real_fmt= &fmt[3];
+- }
+- else
+- {
+- prefix = log_prefix[_level];
+- real_fmt = fmt;
+- }
+-#if defined( CONFIG_BCM_KNLLOG_SUPPORT )
+- knllog_ventry( "vcos", real_fmt, args );
+-#endif
+- printk( "%.3svcos: [%d]: ", prefix, current->pid );
+- vprintk( real_fmt, args );
+-
+- if ( newline == NULL )
+- {
+- printk("\n");
+- }
+- }
+- preempt_enable();
+-}
+-
+-
+-const char * _vcos_log_level(void)
+-{
+- return NULL;
+-}
+-
+-/*****************************************************************************
+-*
+-* Displays the version information in /proc/vcos/version
+-*
+-*****************************************************************************/
+-
+-#ifdef HAVE_VCOS_VERSION
+-
+-static void show_version( VCOS_CFG_BUF_T buf, void *data )
+-{
+- static const char* copyright = "Copyright (c) 2011 Broadcom";
+-
+- vcos_cfg_buf_printf( buf, "Built %s %s on %s\n%s\nversion %s\n",
+- vcos_get_build_date(),
+- vcos_get_build_time(),
+- vcos_get_build_hostname(),
+- copyright,
+- vcos_get_build_version() );
+-}
+-
+-#endif
+-
+-/*****************************************************************************
+-*
+-* Initialises vcos
+-*
+-*****************************************************************************/
+-
+-VCOS_STATUS_T vcos_init(void)
+-{
+- if ( vcos_cfg_mkdir( &vcos_cfg_dir, NULL, "vcos" ) != VCOS_SUCCESS )
+- {
+- printk( KERN_ERR "%s: Unable to create vcos cfg entry\n", __func__ );
+- }
+- vcos_logging_init();
+-
+-#ifdef HAVE_VCOS_VERSION
+- if ( vcos_cfg_create_entry( &vcos_version_cfg, &vcos_cfg_dir, "version",
+- show_version, NULL, NULL ) != VCOS_SUCCESS )
+- {
+- printk( KERN_ERR "%s: Unable to create vcos cfg entry 'version'\n", __func__ );
+- }
+-#endif
+-
+- return VCOS_SUCCESS;
+-}
+-
+-/*****************************************************************************
+-*
+-* Deinitializes vcos
+-*
+-*****************************************************************************/
+-
+-void vcos_deinit(void)
+-{
+-#ifdef HAVE_VCOS_VERSION
+- vcos_cfg_remove_entry( &vcos_version_cfg );
+-#endif
+- vcos_cfg_remove_entry( &vcos_cfg_dir );
+-}
+-
+-void vcos_global_lock(void)
+-{
+- down(&lock);
+-}
+-
+-void vcos_global_unlock(void)
+-{
+- up(&lock);
+-}
+-
+-/* vcos_thread_exit() doesn't really stop this thread here
+- *
+- * At the moment, call to do_exit() will leak task_struct for
+- * current thread, so we let the vcos_thread_wrapper() do the
+- * cleanup and exit job, and we return w/o actually stopping the thread.
+- *
+- * ToDo: Kernel v2.6.31 onwards, it is considered safe to call do_exit()
+- * from kthread, the implementation of which is combined in 2 patches
+- * with commit-ids "63706172" and "cdd140bd" in oss Linux kernel tree
+- */
+-
+-void vcos_thread_exit(void *arg)
+-{
+- VCOS_THREAD_T *thread = vcos_thread_current();
+-
+- vcos_assert(thread);
+- vcos_assert(thread->magic == VCOS_THREAD_MAGIC);
+-
+- thread->exit_data = arg;
+-}
+-
+-void vcos_thread_attr_init(VCOS_THREAD_ATTR_T *attrs)
+-{
+- *attrs = default_attrs;
+-}
+-
+-void _vcos_task_timer_set(void (*pfn)(void *), void *cxt, VCOS_UNSIGNED ms)
+-{
+- VCOS_THREAD_T *self = vcos_thread_current();
+- vcos_assert(self);
+- vcos_assert(self->_timer.pfn == NULL);
+-
+- vcos_timer_create( &self->_timer.timer, "TaskTimer", pfn, cxt );
+- vcos_timer_set(&self->_timer.timer, ms);
+-}
+-
+-void _vcos_task_timer_cancel(void)
+-{
+- VCOS_THREAD_T *self = vcos_thread_current();
+- if (self->_timer.timer.linux_timer.function)
+- {
+- vcos_timer_cancel(&self->_timer.timer);
+- vcos_timer_delete(&self->_timer.timer);
+- }
+-}
+-
+-int vcos_vsnprintf( char *buf, size_t buflen, const char *fmt, va_list ap )
+-{
+- return vsnprintf( buf, buflen, fmt, ap );
+-}
+-
+-int vcos_snprintf(char *buf, size_t buflen, const char *fmt, ...)
+-{
+- int ret;
+- va_list ap;
+- va_start(ap,fmt);
+- ret = vsnprintf(buf, buflen, fmt, ap);
+- va_end(ap);
+- return ret;
+-}
+-
+-int vcos_llthread_running(VCOS_LLTHREAD_T *t) {
+- vcos_assert(0); /* this function only exists as a nasty hack for the video codecs! */
+- return 1;
+-}
+-
+-static int vcos_verify_bkpts = 1;
+-
+-int vcos_verify_bkpts_enabled(void)
+-{
+- return vcos_verify_bkpts;
+-}
+-
+-/*****************************************************************************
+-*
+-* _vcos_log_platform_init is called from vcos_logging_init
+-*
+-*****************************************************************************/
+-
+-void _vcos_log_platform_init(void)
+-{
+- if ( vcos_cfg_mkdir( &vcos_logging_cfg_dir, &vcos_cfg_dir, "logging" ) != VCOS_SUCCESS )
+- {
+- printk( KERN_ERR "%s: Unable to create logging cfg entry\n", __func__ );
+- }
+-}
+-
+-/*****************************************************************************
+-*
+-* Called to display the contents of a logging category.
+-*
+-*****************************************************************************/
+-
+-static void logging_show_category( VCOS_CFG_BUF_T buf, void *data )
+-{
+- VCOS_LOG_CAT_T *category = data;
+-
+- vcos_cfg_buf_printf( buf, "%s\n", vcos_log_level_to_string( category->level ));
+-}
+-
+-/*****************************************************************************
+-*
+-* Called to parse content for a logging category.
+-*
+-*****************************************************************************/
+-
+-static void logging_parse_category( VCOS_CFG_BUF_T buf, void *data )
+-{
+- VCOS_LOG_CAT_T *category = data;
+- const char *str = vcos_cfg_buf_get_str( buf );
+- VCOS_LOG_LEVEL_T level;
+-
+- if ( vcos_string_to_log_level( str, &level ) == VCOS_SUCCESS )
+- {
+- category->level = level;
+- }
+- else
+- {
+- printk( KERN_ERR "%s: Unrecognized logging level: '%s'\n",
+- __func__, str );
+- }
+-}
+-
+-/*****************************************************************************
+-*
+-* _vcos_log_platform_register is called from vcos_log_register whenever
+-* a new category is registered.
+-*
+-*****************************************************************************/
+-
+-void _vcos_log_platform_register(VCOS_LOG_CAT_T *category)
+-{
+- VCOS_CFG_ENTRY_T entry;
+-
+- if ( vcos_cfg_create_entry( &entry, &vcos_logging_cfg_dir, category->name,
+- logging_show_category, logging_parse_category,
+- category ) != VCOS_SUCCESS )
+- {
+- printk( KERN_ERR "%s: Unable to create cfg entry for logging category '%s'\n",
+- __func__, category->name );
+- category->platform_data = NULL;
+- }
+- else
+- {
+- category->platform_data = entry;
+- }
+-}
+-
+-/*****************************************************************************
+-*
+-* _vcos_log_platform_unregister is called from vcos_log_unregister whenever
+-* a new category is unregistered.
+-*
+-*****************************************************************************/
+-
+-void _vcos_log_platform_unregister(VCOS_LOG_CAT_T *category)
+-{
+- VCOS_CFG_ENTRY_T entry;
+-
+- entry = category->platform_data;
+- if ( entry != NULL )
+- {
+- if ( vcos_cfg_remove_entry( &entry ) != VCOS_SUCCESS )
+- {
+- printk( KERN_ERR "%s: Unable to remove cfg entry for logging category '%s'\n",
+- __func__, category->name );
+- }
+- }
+-}
+-
+-/*****************************************************************************
+-*
+-* Allocate memory.
+-*
+-*****************************************************************************/
+-
+-void *vcos_platform_malloc( VCOS_UNSIGNED required_size )
+-{
+- if ( required_size >= ( 2 * PAGE_SIZE ))
+- {
+- /* For larger allocations, use vmalloc, whose underlying allocator
+- * returns pages
+- */
+-
+- return vmalloc( required_size );
+- }
+-
+- /* For smaller allocation, use kmalloc */
+-
+- return kmalloc( required_size, GFP_KERNEL );
+-}
+-
+-/*****************************************************************************
+-*
+-* Free previously allocated memory
+-*
+-*****************************************************************************/
+-
+-void vcos_platform_free( void *ptr )
+-{
+- if (((unsigned long)ptr >= VMALLOC_START )
+- && ((unsigned long)ptr < VMALLOC_END ))
+- {
+- vfree( ptr );
+- }
+- else
+- {
+- kfree( ptr );
+- }
+-}
+-
+-/*****************************************************************************
+-*
+-* Execute a routine exactly once.
+-*
+-*****************************************************************************/
+-
+-VCOS_STATUS_T vcos_once(VCOS_ONCE_T *once_control,
+- void (*init_routine)(void))
+-{
+- /* In order to be thread-safe we need to re-test *once_control
+- * inside the lock. The outer test is basically an optimization
+- * so that once it is initialized we don't need to waste time
+- * trying to acquire the lock.
+- */
+-
+- if ( *once_control == 0 )
+- {
+- vcos_global_lock();
+- if ( *once_control == 0 )
+- {
+- init_routine();
+- *once_control = 1;
+- }
+- vcos_global_unlock();
+- }
+-
+- return VCOS_SUCCESS;
+-}
+-
+-/*****************************************************************************
+-*
+-* String duplication routine.
+-*
+-*****************************************************************************/
+-
+-char *vcos_strdup(const char *str)
+-{
+- return kstrdup(str, GFP_KERNEL);
+-}
+-
+-
+-/* Export functions for modules to use */
+-EXPORT_SYMBOL( vcos_init );
+-
+-EXPORT_SYMBOL( vcos_semaphore_trywait );
+-EXPORT_SYMBOL( vcos_semaphore_post );
+-EXPORT_SYMBOL( vcos_semaphore_create );
+-EXPORT_SYMBOL( vcos_semaphore_wait );
+-EXPORT_SYMBOL( vcos_semaphore_delete );
+-
+-EXPORT_SYMBOL( vcos_log_impl );
+-EXPORT_SYMBOL( vcos_vlog_impl );
+-EXPORT_SYMBOL( vcos_vlog_default_impl );
+-EXPORT_SYMBOL( vcos_log_get_default_category );
+-EXPORT_SYMBOL( vcos_log_register );
+-EXPORT_SYMBOL( vcos_log_unregister );
+-EXPORT_SYMBOL( vcos_logging_init );
+-EXPORT_SYMBOL( vcos_log_level_to_string );
+-EXPORT_SYMBOL( vcos_string_to_log_level );
+-EXPORT_SYMBOL( vcos_log_dump_mem_impl );
+-
+-EXPORT_SYMBOL( vcos_event_create );
+-EXPORT_SYMBOL( vcos_event_delete );
+-EXPORT_SYMBOL( vcos_event_flags_set );
+-EXPORT_SYMBOL( vcos_event_signal );
+-EXPORT_SYMBOL( vcos_event_wait );
+-EXPORT_SYMBOL( vcos_event_try );
+-
+-EXPORT_SYMBOL( vcos_getmicrosecs );
+-
+-EXPORT_SYMBOL( vcos_strcasecmp );
+-EXPORT_SYMBOL( vcos_snprintf );
+-EXPORT_SYMBOL( vcos_vsnprintf );
+-
+-EXPORT_SYMBOL( vcos_thread_current );
+-EXPORT_SYMBOL( vcos_thread_join );
+-EXPORT_SYMBOL( vcos_thread_create );
+-EXPORT_SYMBOL( vcos_thread_set_priority );
+-EXPORT_SYMBOL( vcos_thread_exit );
+-EXPORT_SYMBOL( vcos_once );
+-
+-EXPORT_SYMBOL( vcos_thread_attr_init );
+-EXPORT_SYMBOL( vcos_thread_attr_setpriority );
+-EXPORT_SYMBOL( vcos_thread_attr_settimeslice );
+-EXPORT_SYMBOL( vcos_thread_attr_setstacksize );
+-EXPORT_SYMBOL( _vcos_thread_attr_setlegacyapi );
+-
+-EXPORT_SYMBOL( vcos_event_flags_create );
+-EXPORT_SYMBOL( vcos_event_flags_delete );
+-EXPORT_SYMBOL( vcos_event_flags_get );
+-
+-EXPORT_SYMBOL( vcos_sleep );
+-
+-EXPORT_SYMBOL( vcos_calloc );
+-EXPORT_SYMBOL( vcos_malloc );
+-EXPORT_SYMBOL( vcos_malloc_aligned );
+-EXPORT_SYMBOL( vcos_free );
+-
+-EXPORT_SYMBOL( vcos_mutex_create );
+-EXPORT_SYMBOL( vcos_mutex_delete );
+-EXPORT_SYMBOL( vcos_mutex_lock );
+-EXPORT_SYMBOL( vcos_mutex_unlock );
+-EXPORT_SYMBOL( vcos_mutex_trylock );
+-
+-EXPORT_SYMBOL( vcos_timer_cancel );
+-EXPORT_SYMBOL( vcos_timer_create );
+-EXPORT_SYMBOL( vcos_timer_delete );
+-EXPORT_SYMBOL( vcos_timer_set );
+-
+-EXPORT_SYMBOL( vcos_atomic_flags_create );
+-EXPORT_SYMBOL( vcos_atomic_flags_delete );
+-EXPORT_SYMBOL( vcos_atomic_flags_or );
+-EXPORT_SYMBOL( vcos_atomic_flags_get_and_clear );
+-
+-EXPORT_SYMBOL( vcos_verify_bkpts_enabled );
+-
+-EXPORT_SYMBOL( vcos_strdup );
+diff --git a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel_cfg.c b/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel_cfg.c
+deleted file mode 100644
+index e3f0840..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel_cfg.c
++++ /dev/null
+@@ -1,332 +0,0 @@
+-/*****************************************************************************
+-* Copyright 2009 - 2010 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 "interface/vcos/vcos.h"
+-#include <linux/module.h>
+-#include <linux/proc_fs.h>
+-#include <linux/seq_file.h>
+-#include <asm/uaccess.h>
+-
+-struct opaque_vcos_cfg_buf_t
+-{
+- struct seq_file *seq;
+- char *charBuf;
+-};
+-
+-struct opaque_vcos_cfg_entry_t
+-{
+- struct proc_dir_entry *pde;
+- struct proc_dir_entry *parent_pde;
+- VCOS_CFG_SHOW_FPTR showFunc;
+- VCOS_CFG_PARSE_FPTR parseFunc;
+- void *data;
+- const char *name;
+-};
+-
+-/*****************************************************************************
+-*
+-* cfg_proc_show
+-*
+-*****************************************************************************/
+-
+-static int cfg_proc_show( struct seq_file *s, void *v )
+-{
+- VCOS_CFG_ENTRY_T entry;
+- struct opaque_vcos_cfg_buf_t buf;
+-
+- entry = s->private;
+-
+- if ( entry->showFunc )
+- {
+- memset( &buf, 0, sizeof( buf ));
+- buf.seq = s;
+-
+- entry->showFunc( &buf, entry->data );
+- }
+-
+- return 0;
+-}
+-
+-/*****************************************************************************
+-*
+-* cfg_proc_write
+-*
+-*****************************************************************************/
+-
+-static ssize_t cfg_proc_write( struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
+-{
+- VCOS_CFG_ENTRY_T entry = PDE(file->f_path.dentry->d_inode)->data;
+- char *charBuf;
+- struct opaque_vcos_cfg_buf_t buf;
+- size_t len;
+-
+- if ( entry->parseFunc != NULL )
+- {
+- /* The number 4000 is rather arbitrary. It just needs to be bigger than any input
+- * string we expect to use.
+- */
+-
+- len = count;
+- if ( count > 4000 )
+- {
+- len = 4000;
+- }
+-
+- /* Allocate a kernel buffer to contain the string being written. */
+-
+- charBuf = kmalloc( len + 1, GFP_KERNEL );
+- if ( copy_from_user( charBuf, buffer, len ))
+- {
+- kfree( charBuf );
+- return -EFAULT;
+- }
+-
+- /* echo puts a trailing newline in the buffer - strip it out. */
+-
+- if (( len > 0 ) && ( charBuf[ len - 1 ] == '\n' ))
+- {
+- len--;
+- }
+- charBuf[len] = '\0';
+-
+- memset( &buf, 0, sizeof( buf ));
+- buf.charBuf = charBuf;
+-
+- entry->parseFunc( &buf, entry->data );
+- kfree( charBuf );
+- }
+- return count;
+-}
+-
+-/*****************************************************************************
+-*
+-* cfg_proc_open
+-*
+-*****************************************************************************/
+-
+-static int cfg_proc_open( struct inode *inode, struct file *file )
+-{
+- return single_open( file, cfg_proc_show, PDE(inode)->data );
+-}
+-
+-static const struct file_operations cfg_proc_fops =
+-{
+- .open = cfg_proc_open,
+- .read = seq_read,
+- .llseek = seq_lseek,
+- .release = single_release,
+- .write = cfg_proc_write,
+-};
+-
+-/*****************************************************************************
+-*
+-* vcos_cfg_mkdir
+-*
+-*****************************************************************************/
+-
+-VCOS_STATUS_T vcos_cfg_mkdir( VCOS_CFG_ENTRY_T *entryp,
+- VCOS_CFG_ENTRY_T *parent,
+- const char *dirName )
+-{
+- VCOS_CFG_ENTRY_T entry;
+-
+- if (( entry = kzalloc( sizeof( *entry ), GFP_KERNEL )) == NULL )
+- {
+- return VCOS_ENOMEM;
+- }
+-
+- if ( parent == NULL )
+- {
+- entry->pde = proc_mkdir( dirName, NULL );
+- }
+- else
+- {
+- entry->pde = proc_mkdir( dirName, (*parent)->pde );
+- entry->parent_pde = (*parent)->pde;
+- }
+- if ( entry->pde == NULL )
+- {
+- kfree( entry );
+- return VCOS_ENOMEM;
+- }
+-
+- entry->name = dirName;
+-
+- *entryp = entry;
+- return VCOS_SUCCESS;
+-}
+-
+-/*****************************************************************************
+-*
+-* vcos_cfg_create_entry
+-*
+-*****************************************************************************/
+-
+-VCOS_STATUS_T vcos_cfg_create_entry( VCOS_CFG_ENTRY_T *entryp,
+- VCOS_CFG_ENTRY_T *parent,
+- const char *entryName,
+- VCOS_CFG_SHOW_FPTR showFunc,
+- VCOS_CFG_PARSE_FPTR parseFunc,
+- void *data )
+-{
+- VCOS_CFG_ENTRY_T entry;
+- mode_t mode;
+-
+- *entryp = NULL;
+-
+- if (( entry = kzalloc( sizeof( *entry ), GFP_KERNEL )) == NULL )
+- {
+- return VCOS_ENOMEM;
+- }
+-
+- mode = 0;
+- if ( showFunc != NULL )
+- {
+- mode |= 0444;
+- }
+- if ( parseFunc != NULL )
+- {
+- mode |= 0200;
+- }
+-
+- if ( parent == NULL )
+- {
+- entry->pde = create_proc_entry( entryName, mode, NULL );
+- }
+- else
+- {
+- entry->pde = create_proc_entry( entryName, mode, (*parent)->pde );
+- entry->parent_pde = (*parent)->pde;
+- }
+- if ( entry->pde == NULL )
+- {
+- kfree( entry );
+- return -ENOMEM;
+- }
+- entry->showFunc = showFunc;
+- entry->parseFunc = parseFunc;
+- entry->data = data;
+- entry->name = entryName;
+-
+- entry->pde->data = entry;
+- entry->pde->proc_fops = &cfg_proc_fops;
+-
+- *entryp = entry;
+- return VCOS_SUCCESS;
+-}
+-
+-/*****************************************************************************
+-*
+-* vcos_cfg_remove_entry
+-*
+-*****************************************************************************/
+-
+-VCOS_STATUS_T vcos_cfg_remove_entry( VCOS_CFG_ENTRY_T *entryp )
+-{
+- if (( entryp != NULL ) && ( *entryp != NULL ))
+- {
+- remove_proc_entry( (*entryp)->name, (*entryp)->parent_pde );
+-
+- kfree( *entryp );
+- *entryp = NULL;
+- }
+-
+- return VCOS_SUCCESS;
+-}
+-
+-/*****************************************************************************
+-*
+-* vcos_cfg_is_entry_created
+-*
+-*****************************************************************************/
+-
+-int vcos_cfg_is_entry_created( VCOS_CFG_ENTRY_T entry )
+-{
+- return ( entry != NULL ) && ( entry->pde != NULL );
+-}
+-
+-/*****************************************************************************
+-*
+-* vcos_cfg_buf_printf
+-*
+-*****************************************************************************/
+-
+-void vcos_cfg_buf_printf( VCOS_CFG_BUF_T buf, const char *fmt, ... )
+-{
+- struct seq_file *m = buf->seq;
+-
+- /* Bah - there is no seq_vprintf */
+-
+- va_list args;
+- int len;
+-
+- if (m->count < m->size) {
+- va_start(args, fmt);
+- len = vsnprintf(m->buf + m->count, m->size - m->count, fmt, args);
+- va_end(args);
+- if (m->count + len < m->size) {
+- m->count += len;
+- return;
+- }
+- }
+- m->count = m->size;
+-}
+-
+-/*****************************************************************************
+-*
+-* vcos_cfg_buf_get_str
+-*
+-*****************************************************************************/
+-
+-char *vcos_cfg_buf_get_str( VCOS_CFG_BUF_T buf )
+-{
+- return buf->charBuf;
+-}
+-
+-/*****************************************************************************
+-*
+-* vcos_cfg_get_proc_entry
+-*
+-* This function is only created for a couple of backwards compatibility '
+-* issues and shouldn't normally be used.
+-*
+-*****************************************************************************/
+-
+-void *vcos_cfg_get_proc_entry( VCOS_CFG_ENTRY_T entry )
+-{
+- return entry->pde;
+-}
+-
+-/*****************************************************************************
+-*
+-* vcos_cfg_get_entry_name
+-*
+-*****************************************************************************/
+-
+-const char *vcos_cfg_get_entry_name( VCOS_CFG_ENTRY_T entry )
+-{
+- return entry->pde->name;
+-}
+-
+-
+-EXPORT_SYMBOL( vcos_cfg_mkdir );
+-EXPORT_SYMBOL( vcos_cfg_create_entry );
+-EXPORT_SYMBOL( vcos_cfg_remove_entry );
+-EXPORT_SYMBOL( vcos_cfg_get_entry_name );
+-EXPORT_SYMBOL( vcos_cfg_is_entry_created );
+-EXPORT_SYMBOL( vcos_cfg_buf_printf );
+-EXPORT_SYMBOL( vcos_cfg_buf_get_str );
+-
+-EXPORT_SYMBOL_GPL( vcos_cfg_get_proc_entry );
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel_misc.c b/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel_misc.c
+deleted file mode 100644
+index 4a9cedf..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_linuxkernel_misc.c
++++ /dev/null
+@@ -1,111 +0,0 @@
+-/*****************************************************************************
+-* Copyright 2009 - 2010 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 "interface/vcos/vcos.h"
+-#include <linux/sched.h>
+-#include <linux/module.h>
+-#include <linux/freezer.h>
+-#include <linux/string.h>
+-#include <linux/slab.h>
+-
+-/*****************************************************************************
+-*
+-* vcos_semaphore_wait_freezable
+-*
+-*****************************************************************************/
+-
+-VCOS_STATUS_T vcos_semaphore_wait_freezable(VCOS_SEMAPHORE_T *sem)
+-{
+- int rval, sig_pended = 0;
+- unsigned long flags;
+- struct task_struct *task = current;
+-
+- while (1) {
+- rval = down_interruptible((struct semaphore *)sem);
+- if (rval == 0) { /* down now */
+- break;
+- } else {
+- if (freezing(current)) {
+- try_to_freeze();
+- } else {
+- spin_lock_irqsave(&task->sighand->siglock, flags);
+- if (test_tsk_thread_flag(task, TIF_SIGPENDING)) {
+- clear_tsk_thread_flag(task, TIF_SIGPENDING);
+- sig_pended = 1;
+- }
+- spin_unlock_irqrestore(&task->sighand->siglock, flags);
+- }
+- }
+- }
+-
+- if (sig_pended) {
+- spin_lock_irqsave(&task->sighand->siglock, flags);
+- set_tsk_thread_flag(task, TIF_SIGPENDING);
+- spin_unlock_irqrestore(&task->sighand->siglock, flags);
+- }
+-
+- return 0;
+-}
+-
+-EXPORT_SYMBOL( vcos_semaphore_wait_freezable );
+-
+-/*****************************************************************************
+-*
+-* vcos_kmalloc
+-*
+-* We really need to convert malloc to do kmalloc or vmalloc based on the
+-* size, but for now we'll add a separate function.
+-*
+-*****************************************************************************/
+-
+-void *vcos_kmalloc(VCOS_UNSIGNED size, const char *description)
+-{
+- (void)description;
+-
+- return kmalloc( size, GFP_KERNEL );
+-}
+-
+-/*****************************************************************************
+-*
+-* vcos_kmalloc
+-*
+-* We really need to convert malloc to do kmalloc or vmalloc based on the
+-* size, but for now we'll add a separate function.
+-*
+-*****************************************************************************/
+-
+-void *vcos_kcalloc(VCOS_UNSIGNED num, VCOS_UNSIGNED size, const char *description)
+-{
+- (void)description;
+-
+- return kzalloc( num * size, GFP_KERNEL );
+-}
+-
+-/*****************************************************************************
+-*
+-* vcos_kfree
+-*
+-*****************************************************************************/
+-
+-void vcos_kfree(void *ptr)
+-{
+- kfree( ptr );
+-}
+-
+-EXPORT_SYMBOL( vcos_kmalloc );
+-EXPORT_SYMBOL( vcos_kcalloc );
+-EXPORT_SYMBOL( vcos_kfree );
+-
+-// END #########################################################################
+-// #############################################################################
+diff --git a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_mod_init.c b/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_mod_init.c
+deleted file mode 100644
+index 6ffd755..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_mod_init.c
++++ /dev/null
+@@ -1,64 +0,0 @@
+-/*****************************************************************************
+-* Copyright 2006 - 2008 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 Files ---------------------------------------------------- */
+-
+-#include "interface/vcos/vcos.h"
+-#include <linux/module.h>
+-
+-/* ---- Public Variables ------------------------------------------------- */
+-
+-/* ---- Private Constants and Types -------------------------------------- */
+-
+-/* ---- Private Variables ------------------------------------------------ */
+-
+-/* ---- Private Function Prototypes -------------------------------------- */
+-
+-/* ---- Functions -------------------------------------------------------- */
+-
+-/****************************************************************************
+-*
+-* Called to perform module initialization when the module is loaded
+-*
+-***************************************************************************/
+-
+-static int __init vcos_mod_init( void )
+-{
+- printk( KERN_INFO "VCOS Module\n" );
+-
+- vcos_init();
+- return 0;
+-}
+-
+-/****************************************************************************
+-*
+-* Called to perform module cleanup when the module is unloaded.
+-*
+-***************************************************************************/
+-
+-static void __exit vcos_mod_exit( void )
+-{
+- vcos_deinit();
+-}
+-
+-/****************************************************************************/
+-
+-module_init( vcos_mod_init );
+-module_exit( vcos_mod_exit );
+-
+-MODULE_AUTHOR("Broadcom");
+-MODULE_DESCRIPTION( "VCOS Module Functions" );
+-MODULE_LICENSE( "GPL" );
+-MODULE_VERSION( "1.0" );
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_platform.h b/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_platform.h
+deleted file mode 100644
+index 381688e..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_platform.h
++++ /dev/null
+@@ -1,507 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - Linux kernel (partial) implementation.
+-=============================================================================*/
+-
+-/* Do not include this file directly - instead include it via vcos.h */
+-
+-/** @file
+- *
+- * Linux kernel (partial) implementation of VCOS.
+- *
+- */
+-
+-#ifndef VCOS_PLATFORM_H
+-#define VCOS_PLATFORM_H
+-
+-#include <linux/types.h>
+-#include <linux/semaphore.h>
+-#include <linux/mutex.h>
+-#include <asm/bitops.h>
+-#include <linux/kthread.h>
+-#include <linux/wait.h>
+-#include <linux/vmalloc.h>
+-#include <linux/jiffies.h>
+-#include <linux/delay.h>
+-#include <linux/string.h>
+-#include <linux/types.h>
+-#include <linux/interrupt.h>
+-#include <linux/random.h>
+-#include <linux/sched.h>
+-#include <linux/ctype.h>
+-#include <linux/uaccess.h>
+-#include <linux/time.h> /* for time_t */
+-#include <linux/slab.h>
+-#include <linux/vmalloc.h>
+-
+-#define VCOS_HAVE_RTOS 1
+-#define VCOS_HAVE_SEMAPHORE 1
+-#define VCOS_HAVE_EVENT 1
+-#define VCOS_HAVE_QUEUE 0
+-#define VCOS_HAVE_LEGACY_ISR 0
+-#define VCOS_HAVE_TIMER 1
+-#define VCOS_HAVE_CANCELLATION_SAFE_TIMER 0
+-#define VCOS_HAVE_MEMPOOL 0
+-#define VCOS_HAVE_ISR 0
+-#define VCOS_HAVE_ATOMIC_FLAGS 1
+-#define VCOS_HAVE_BLOCK_POOL 0
+-#define VCOS_HAVE_ONCE 1
+-#define VCOS_HAVE_FILE 0
+-#define VCOS_HAVE_USER_BUF 0
+-#define VCOS_HAVE_CFG 1
+-#define VCOS_HAVE_SPINLOCK 0
+-#define VCOS_HAVE_CMD 1
+-#define VCOS_HAVE_EVENT_FLAGS 1
+-
+-/* Exclude many VCOS classes which don't have predicates */
+-#define VCOS_TLS_H
+-#define VCOS_NAMED_MUTEX_H
+-#define VCOS_REENTRANT_MUTEX_H
+-#define VCOS_NAMED_SEMAPHORE_H
+-#define VCOS_QUICKSLOW_MUTEX_H
+-/*#define VCOS_INIT_H */
+-/*#define VCOS_MEM_H */
+-/*#define VCOS_STRING_H */
+-
+-typedef struct semaphore VCOS_SEMAPHORE_T;
+-typedef struct semaphore VCOS_EVENT_T;
+-typedef struct mutex VCOS_MUTEX_T;
+-typedef volatile int VCOS_ONCE_T;
+-
+-typedef unsigned int VCOS_UNSIGNED;
+-typedef unsigned int VCOS_OPTION;
+-typedef atomic_t VCOS_ATOMIC_FLAGS_T;
+-
+-typedef struct
+-{
+- struct timer_list linux_timer;
+- void *context;
+- void (*expiration_routine)(void *context);
+-
+-} VCOS_TIMER_T;
+-
+-typedef struct VCOS_LLTHREAD_T
+-{
+- struct task_struct *thread; /**< The thread itself */
+- VCOS_SEMAPHORE_T suspend; /**< For support event groups and similar - a per thread semaphore */
+-} VCOS_LLTHREAD_T;
+-
+-typedef enum
+-{
+- VCOS_O_RDONLY = 00000000,
+- VCOS_O_WRONLY = 00000001,
+- VCOS_O_RDWR = 00000002,
+- VCOS_O_TRUNC = 00001000,
+-} VCOS_FILE_FLAGS_T;
+-
+-typedef struct file *VCOS_FILE_T;
+-
+-#define VCOS_SUSPEND -1
+-#define VCOS_NO_SUSPEND 0
+-
+-#define VCOS_START 1
+-#define VCOS_NO_START 0
+-
+-#define VCOS_THREAD_PRI_MIN -20
+-#define VCOS_THREAD_PRI_MAX 19
+-
+-#define VCOS_THREAD_PRI_INCREASE -1
+-#define VCOS_THREAD_PRI_HIGHEST VCOS_THREAD_PRI_MIN
+-#define VCOS_THREAD_PRI_LOWEST VCOS_THREAD_PRI_MAX
+-#define VCOS_THREAD_PRI_NORMAL ((VCOS_THREAD_PRI_MAX+VCOS_THREAD_PRI_MIN)/2)
+-#define VCOS_THREAD_PRI_ABOVE_NORMAL (VCOS_THREAD_PRI_NORMAL + VCOS_THREAD_PRI_INCREASE)
+-#define VCOS_THREAD_PRI_REALTIME VCOS_THREAD_PRI_HIGHEST
+-
+-#define _VCOS_AFFINITY_DEFAULT 0
+-#define _VCOS_AFFINITY_CPU0 0
+-#define _VCOS_AFFINITY_CPU1 0
+-#define _VCOS_AFFINITY_MASK 0
+-#define VCOS_CAN_SET_STACK_ADDR 0
+-
+-#define VCOS_TICKS_PER_SECOND HZ
+-
+-#include "interface/vcos/generic/vcos_generic_event_flags.h"
+-#include "interface/vcos/generic/vcos_mem_from_malloc.h"
+-#include "interface/vcos/generic/vcos_joinable_thread_from_plain.h"
+-
+-/***********************************************************
+- *
+- * Memory allcoation
+- *
+- ***********************************************************/
+-
+-#define _vcos_platform_malloc vcos_platform_malloc
+-#define _vcos_platform_free vcos_platform_free
+-
+-void *vcos_platform_malloc( VCOS_UNSIGNED required_size );
+-void vcos_platform_free( void *ptr );
+-
+-#if defined(VCOS_INLINE_BODIES)
+-
+-#undef VCOS_ASSERT_LOGGING_DISABLE
+-#define VCOS_ASSERT_LOGGING_DISABLE 1
+-
+-/***********************************************************
+- *
+- * Counted Semaphores
+- *
+- ***********************************************************/
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_semaphore_wait(VCOS_SEMAPHORE_T *sem) {
+- int ret = down_interruptible(sem);
+- if ( ret == 0 )
+- /* Success */
+- return VCOS_SUCCESS;
+- else if ( ret == -EINTR )
+- /* Interrupted */
+- return VCOS_EINTR;
+- else
+- /* Default (timeout) */
+- return VCOS_EAGAIN;
+-}
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_semaphore_trywait(VCOS_SEMAPHORE_T *sem) {
+- if (down_trylock(sem) != 0)
+- return VCOS_EAGAIN;
+- return VCOS_SUCCESS;
+-}
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_semaphore_create(VCOS_SEMAPHORE_T *sem,
+- const char *name,
+- VCOS_UNSIGNED initial_count) {
+- sema_init(sem, initial_count);
+- return VCOS_SUCCESS;
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_semaphore_delete(VCOS_SEMAPHORE_T *sem) {
+-}
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_semaphore_post(VCOS_SEMAPHORE_T *sem) {
+- up(sem);
+- return VCOS_SUCCESS;
+-}
+-
+-/***********************************************************
+- *
+- * Threads
+- *
+- ***********************************************************/
+-
+-#include "vcos_thread_map.h"
+-
+-VCOS_INLINE_IMPL
+-VCOS_LLTHREAD_T *vcos_llthread_current(void) {
+- return &vcos_kthread_current()->thread;
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_llthread_resume(VCOS_LLTHREAD_T *thread) {
+- vcos_assert(0);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_sleep(uint32_t ms) {
+- msleep(ms);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_thread_set_priority(VCOS_THREAD_T *thread, VCOS_UNSIGNED p) {
+- /* not implemented */
+-}
+-VCOS_INLINE_IMPL
+-VCOS_UNSIGNED vcos_thread_get_priority(VCOS_THREAD_T *thread) {
+- /* not implemented */
+- return 0;
+-}
+-
+-/***********************************************************
+- *
+- * Miscellaneous
+- *
+- ***********************************************************/
+-
+-VCOS_INLINE_IMPL
+-int vcos_strcasecmp(const char *s1, const char *s2) {
+- return strcasecmp(s1,s2);
+-}
+-
+-
+-/***********************************************************
+- *
+- * Mutexes
+- *
+- ***********************************************************/
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_mutex_create(VCOS_MUTEX_T *m, const char *name) {
+- mutex_init(m);
+- return VCOS_SUCCESS;
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_mutex_delete(VCOS_MUTEX_T *m) {
+-}
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_mutex_lock(VCOS_MUTEX_T *m) {
+- int ret = mutex_lock_interruptible(m);
+- if ( ret == 0 )
+- /* Success */
+- return VCOS_SUCCESS;
+- else if ( ret == -EINTR )
+- /* Interrupted */
+- return VCOS_EINTR;
+- else
+- /* Default */
+- return VCOS_EAGAIN;
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_mutex_unlock(VCOS_MUTEX_T *m) {
+- mutex_unlock(m);
+-}
+-
+-VCOS_INLINE_IMPL
+-int vcos_mutex_is_locked(VCOS_MUTEX_T *m) {
+- if (mutex_trylock(m) != 0)
+- return 1; /* it was locked */
+- mutex_unlock(m);
+- /* it wasn't locked */
+- return 0;
+-}
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_mutex_trylock(VCOS_MUTEX_T *m) {
+- if (mutex_trylock(m) == 0)
+- return VCOS_SUCCESS;
+- else
+- return VCOS_EAGAIN;
+-}
+-
+-/* For supporting event groups - per thread semaphore */
+-VCOS_INLINE_IMPL
+-void _vcos_thread_sem_wait(void) {
+- VCOS_THREAD_T *t = vcos_thread_current();
+- vcos_semaphore_wait(&t->suspend);
+-}
+-
+-VCOS_INLINE_IMPL
+-void _vcos_thread_sem_post(VCOS_THREAD_T *target) {
+- vcos_semaphore_post(&target->suspend);
+-}
+-
+-/***********************************************************
+- *
+- * Events
+- *
+- ***********************************************************/
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_event_create(VCOS_EVENT_T *event, const char *debug_name)
+-{
+- sema_init(event, 0);
+- return VCOS_SUCCESS;
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_event_signal(VCOS_EVENT_T *event)
+-{
+- up(event);
+-}
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_event_wait(VCOS_EVENT_T *event)
+-{
+- int ret = down_interruptible(event);
+- if ( ret == -EINTR )
+- /* Interrupted */
+- return VCOS_EINTR;
+- else if (ret != 0)
+- /* Default (timeout) */
+- return VCOS_EAGAIN;
+- /* Emulate a maximum count of 1 by removing any extra upness */
+- while (down_trylock(event) == 0) continue;
+- return VCOS_SUCCESS;
+-}
+-
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_event_try(VCOS_EVENT_T *event)
+-{
+- return (down_trylock(event) == 0) ? VCOS_SUCCESS : VCOS_EAGAIN;
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_event_delete(VCOS_EVENT_T *event)
+-{
+-}
+-
+-/***********************************************************
+- *
+- * Timers
+- *
+- ***********************************************************/
+-
+-VCOS_INLINE_DECL
+-void vcos_timer_linux_func(unsigned long data)
+-{
+- VCOS_TIMER_T *vcos_timer = (VCOS_TIMER_T *)data;
+-
+- vcos_timer->expiration_routine( vcos_timer->context );
+-}
+-
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_timer_create(VCOS_TIMER_T *timer,
+- const char *name,
+- void (*expiration_routine)(void *context),
+- void *context) {
+- init_timer(&timer->linux_timer);
+- timer->linux_timer.data = (unsigned long)timer;
+- timer->linux_timer.function = vcos_timer_linux_func;
+-
+- timer->context = context;
+- timer->expiration_routine = expiration_routine;
+-
+- return VCOS_SUCCESS;
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_timer_set(VCOS_TIMER_T *timer, VCOS_UNSIGNED delay_ms) {
+- timer->linux_timer.expires = jiffies + msecs_to_jiffies(delay_ms);
+- add_timer(&timer->linux_timer);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_timer_cancel(VCOS_TIMER_T *timer) {
+- del_timer(&timer->linux_timer);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_timer_reset(VCOS_TIMER_T *timer, VCOS_UNSIGNED delay_ms) {
+- del_timer_sync(&timer->linux_timer);
+- timer->linux_timer.expires = jiffies + msecs_to_jiffies(delay_ms);
+- add_timer(&timer->linux_timer);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_timer_delete(VCOS_TIMER_T *timer) {
+- timer->context = NULL;
+- timer->expiration_routine = NULL;
+- timer->linux_timer.function = NULL;
+- timer->linux_timer.data = 0;
+- return;
+-}
+-
+-VCOS_INLINE_IMPL
+-VCOS_UNSIGNED vcos_process_id_current(void) {
+- return (VCOS_UNSIGNED)current->pid;
+-}
+-
+-
+-VCOS_INLINE_IMPL
+-int vcos_in_interrupt(void) {
+- return in_interrupt();
+-}
+-
+-/***********************************************************
+- *
+- * Atomic flags
+- *
+- ***********************************************************/
+-
+-VCOS_INLINE_IMPL
+-VCOS_STATUS_T vcos_atomic_flags_create(VCOS_ATOMIC_FLAGS_T *atomic_flags)
+-{
+- atomic_set(atomic_flags, 0);
+- return VCOS_SUCCESS;
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_atomic_flags_or(VCOS_ATOMIC_FLAGS_T *atomic_flags, uint32_t flags)
+-{
+- uint32_t value;
+- do {
+- value = atomic_read(atomic_flags);
+- } while (atomic_cmpxchg(atomic_flags, value, value | flags) != value);
+-}
+-
+-VCOS_INLINE_IMPL
+-uint32_t vcos_atomic_flags_get_and_clear(VCOS_ATOMIC_FLAGS_T *atomic_flags)
+-{
+- return atomic_xchg(atomic_flags, 0);
+-}
+-
+-VCOS_INLINE_IMPL
+-void vcos_atomic_flags_delete(VCOS_ATOMIC_FLAGS_T *atomic_flags)
+-{
+-}
+-
+-#undef VCOS_ASSERT_LOGGING_DISABLE
+-#define VCOS_ASSERT_LOGGING_DISABLE 0
+-
+-#endif /* VCOS_INLINE_BODIES */
+-
+-VCOS_INLINE_DECL void _vcos_thread_sem_wait(void);
+-VCOS_INLINE_DECL void _vcos_thread_sem_post(VCOS_THREAD_T *);
+-
+-/***********************************************************
+- *
+- * Misc
+- *
+- ***********************************************************/
+-VCOS_INLINE_DECL char *vcos_strdup(const char *str);
+-
+-/***********************************************************
+- *
+- * Logging
+- *
+- ***********************************************************/
+-
+-VCOSPRE_ const char * VCOSPOST_ _vcos_log_level(void);
+-#define _VCOS_LOG_LEVEL() _vcos_log_level()
+-
+-#define vcos_log_platform_init() _vcos_log_platform_init()
+-#define vcos_log_platform_register(category) _vcos_log_platform_register(category)
+-#define vcos_log_platform_unregister(category) _vcos_log_platform_unregister(category)
+-
+-struct VCOS_LOG_CAT_T; /* Forward declaration since vcos_logging.h hasn't been included yet */
+-
+-void _vcos_log_platform_init(void);
+-void _vcos_log_platform_register(struct VCOS_LOG_CAT_T *category);
+-void _vcos_log_platform_unregister(struct VCOS_LOG_CAT_T *category);
+-
+-/***********************************************************
+- *
+- * Memory barriers
+- *
+- ***********************************************************/
+-
+-#define vcos_wmb(x) wmb()
+-#define vcos_rmb() rmb()
+-
+-#include "interface/vcos/generic/vcos_common.h"
+-/*#include "interface/vcos/generic/vcos_generic_quickslow_mutex.h" */
+-
+-#endif /* VCOS_PLATFORM_H */
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_platform_types.h b/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_platform_types.h
+deleted file mode 100644
+index 5f82aaf..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_platform_types.h
++++ /dev/null
+@@ -1,59 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - platform-specific types and defines
+-=============================================================================*/
+-
+-#ifndef VCOS_PLATFORM_TYPES_H
+-#define VCOS_PLATFORM_TYPES_H
+-
+-#include <stddef.h>
+-#include <linux/types.h>
+-#include <linux/bug.h>
+-#include <linux/kernel.h>
+-
+-#define VCOSPRE_ extern
+-#define VCOSPOST_
+-
+-#if defined(__GNUC__) && (( __GNUC__ > 2 ) || (( __GNUC__ == 2 ) && ( __GNUC_MINOR__ >= 3 )))
+-#define VCOS_FORMAT_ATTR_(ARCHETYPE, STRING_INDEX, FIRST_TO_CHECK) __attribute__ ((format (ARCHETYPE, STRING_INDEX, FIRST_TO_CHECK)))
+-#else
+-#define VCOS_FORMAT_ATTR_(ARCHETYPE, STRING_INDEX, FIRST_TO_CHECK)
+-#endif
+-
+-#if !defined( __STDC_VERSION__ )
+-#define __STDC_VERSION__ 199901L
+-#endif
+-
+-#if !defined( __STDC_VERSION )
+-#define __STDC_VERSION __STDC_VERSION__
+-#endif
+-
+-static inline void __vcos_bkpt( void ) { BUG(); }
+-#define VCOS_BKPT __vcos_bkpt()
+-
+-#define VCOS_ASSERT_MSG(...) printk( KERN_ERR "vcos_assert: " __VA_ARGS__ )
+-
+-#define PRId64 "lld"
+-#define PRIi64 "lli"
+-#define PRIo64 "llo"
+-#define PRIu64 "llu"
+-#define PRIx64 "llx"
+-
+-#endif
+diff --git a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_thread_map.c b/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_thread_map.c
+deleted file mode 100644
+index 2d62589..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_thread_map.c
++++ /dev/null
+@@ -1,129 +0,0 @@
+-/*****************************************************************************
+-* Copyright 2009 - 2010 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.
+-*****************************************************************************/
+-
+-/** Support to allow VCOS thread-related functions to be called from
+- * threads that were not created by VCOS.
+- */
+-
+-#include <linux/semaphore.h>
+-#include <linux/vmalloc.h>
+-#include <linux/list.h>
+-#include <linux/sched.h>
+-
+-#include "vcos_thread_map.h"
+-#include "interface/vcos/vcos_logging.h"
+-
+-/*
+- * Store the vcos_thread pointer at the end of
+- * current kthread stack, right after the thread_info
+- * structure.
+- *
+- * I belive we should be safe here to steal these 4 bytes
+- * from the stack, as long as the vcos thread does not use up
+- * all the stack available
+- *
+- * NOTE: This scheme will not work on architectures with stack growing up
+- */
+-
+-/* Shout, if we are not being compiled for ARM kernel */
+-
+-#ifndef CONFIG_ARM
+-#error " **** The vcos kthread implementation may not work for non-ARM kernel ****"
+-#endif
+-
+-static inline void *to_current_vcos_thread(void)
+-{
+- unsigned long *vcos_data;
+-
+- vcos_data = (unsigned long *)((char *)current_thread_info() + sizeof(struct thread_info));
+-
+- return (void *)vcos_data;
+-}
+-
+-
+-static inline void *to_vcos_thread(struct task_struct *tsk)
+-{
+- unsigned long *vcos_data;
+-
+- vcos_data = (unsigned long *)((char *)tsk->stack + sizeof(struct thread_info));
+-
+- return (void *)vcos_data;
+-}
+-
+-/**
+- @fn uint32_t vcos_add_thread(THREAD_MAP_T *vcos_thread);
+-*/
+-uint32_t vcos_add_thread(VCOS_THREAD_T *vcos_thread)
+-{
+- VCOS_THREAD_T **vcos_thread_storage = (VCOS_THREAD_T **)to_current_vcos_thread();
+-
+- *vcos_thread_storage = vcos_thread;
+-
+- return(0);
+-}
+-
+-
+-/**
+- @fn uint32_t vcos_remove_thread(struct task_struct * thread_id);
+-*/
+-uint32_t vcos_remove_thread(struct task_struct *thread_id)
+-{
+- /* Remove thread_id -> VCOS_THREAD_T relationship */
+- VCOS_THREAD_T **vcos_thread_storage;
+-
+- /*
+- * We want to be able to build vcos as a loadable module, which
+- * means that we can't call get_task_struct. So we assert if we're
+- * ever called with thread_id != current.
+- */
+-
+- BUG_ON( thread_id != current );
+-
+- vcos_thread_storage = (VCOS_THREAD_T **)to_vcos_thread(thread_id);
+-
+- *(unsigned long *)vcos_thread_storage = 0xCAFEBABE;
+-
+- return(0);
+-}
+-
+-
+-VCOS_THREAD_T *vcos_kthread_current(void)
+-{
+- VCOS_THREAD_T **vcos_thread_storage = (VCOS_THREAD_T **)to_current_vcos_thread();
+-
+- /* If we find this, either the thread is already dead or stack pages of a
+- * dead vcos thread are re-allocated to this one.
+- *
+- * Since there's no way to differentiate between these 2 cases, we just dump
+- * the current task name to the log.
+- *
+- * If the current thread is created using VCOS API, you should *never* see this
+- * print.
+- *
+- * If its a non-VCOS thread, just let it go ...
+- *
+- * To debug VCOS, uncomment printk's under the "if" condition below
+- *
+- */
+- if (*vcos_thread_storage == (void *)0xCAFEBABE)
+- {
+- #if 0
+- printk(KERN_DEBUG"****************************************************\n");
+- printk(KERN_DEBUG"%s : You have a problem, if \"%s\" is a VCOS thread\n",__func__, current->comm);
+- printk(KERN_DEBUG"****************************************************\n");
+- #endif
+- }
+-
+- return *vcos_thread_storage;
+-}
+diff --git a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_thread_map.h b/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_thread_map.h
+deleted file mode 100644
+index 62963c1..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/linuxkernel/vcos_thread_map.h
++++ /dev/null
+@@ -1,39 +0,0 @@
+-/*****************************************************************************
+-* Copyright 2009 - 2010 Broadcom Corporation. All rights reserved.
+-*
+-* Unless you and Broadcom execute a separate written software license
+-* agreement governing use of this software, this software is licensed to you
+-* under the terms of the GNU General Public License version 2, available at
+-* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+-*
+-* Notwithstanding the above, under no circumstances may you combine this
+-* software in any way with any other Broadcom software provided under a
+-* license other than the GPL, without Broadcom's express prior written
+-* consent.
+-*****************************************************************************/
+-
+-
+-#ifndef VCOS_THREAD_MAP_H
+-#define VCOS_THREAD_MAP_H
+-
+-#include <linux/string.h>
+-
+-#include "vcos_platform.h"
+-
+-static inline void vcos_thread_map_init(void)
+-{
+- return;
+-}
+-
+-static inline void vcos_thread_map_cleanup(void)
+-{
+- return;
+-}
+-
+-uint32_t vcos_add_thread(VCOS_THREAD_T *vcos_thread);
+-
+-uint32_t vcos_remove_thread(struct task_struct *thread_id);
+-
+-VCOS_THREAD_T *vcos_kthread_current(void);
+-
+-#endif /*VCOS_THREAD_MAP_H */
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos.h b/drivers/misc/vc04_services/interface/vcos/vcos.h
+deleted file mode 100644
+index e37d795..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos.h
++++ /dev/null
+@@ -1,212 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - public header file
+-=============================================================================*/
+-
+-/**
+- * \mainpage OS Abstraction Layer
+- *
+- * \section intro Introduction
+- *
+- * This abstraction layer is here to allow the underlying OS to be easily changed (e.g. from
+- * Nucleus to ThreadX) and to aid in porting host applications to new targets.
+- *
+- * \subsection error Error handling
+- *
+- * Wherever possible, VCOS functions assert internally and return void. The only exceptions
+- * are creation functions (which might fail due to lack of resources) and functions that
+- * might timeout or fail due to lack of space. Errors that might be reported by the underlying
+- * OS API (e.g. invalid mutex) are treated as a programming error, and are merely asserted on.
+- *
+- * \section thread_synch Threads and synchronisation
+- *
+- * \subsection thread Threads
+- *
+- * The thread API is somewhat different to that found in Nucleus. In particular, threads
+- * cannot just be destroyed at arbitrary times and nor can they merely exit. This is so
+- * that the same API can be implemented across all interesting platforms without too much
+- * difficulty. See vcos_thread.h for details. Thread attributes are configured via
+- * the VCOS_THREAD_ATTR_T structure, found in vcos_thread_attr.h.
+- *
+- * \subsection sema Semaphores
+- *
+- * Counted semaphores (c.f. Nucleus NU_SEMAPHORE) are created with VCOS_SEMAPHORE_T.
+- * Under ThreadX on VideoCore, semaphores are implemented using VideoCore spinlocks, and
+- * so are quite a lot faster than ordinary ThreadX semaphores. See vcos_semaphore.h.
+- *
+- * \subsection mtx Mutexes
+- *
+- * Mutexes are used for locking. Attempts to take a mutex twice, or to unlock it
+- * in a different thread to the one in which it was locked should be expected to fail.
+- * Mutexes are not re-entrant (see vcos_reentrant_mutex.h for a slightly slower
+- * re-entrant mutex).
+- *
+- * \subsection evflags Event flags
+- *
+- * Event flags (the ThreadX name - also known as event groups under Nucleus) provide
+- * 32 flags which can be waited on by multiple clients, and signalled by multiple clients.
+- * A timeout can be specified. See vcos_event_flags.h. An alternative to this is the
+- * VCOS_EVENT_T (see vcos_event.h) which is akin to the Win32 auto-reset event, or a
+- * saturating counted semaphore.
+- *
+- * \subsection event Events
+- *
+- * A VCOS_EVENT_T is a bit like a saturating semaphore. No matter how many times it
+- * is signalled, the waiter will only wake up once. See vcos_event.h. You might think this
+- * is useful if you suspect that the cost of reading the semaphore count (perhaps via a
+- * system call) is expensive on your platform.
+- *
+- * \subsection tls Thread local storage
+- *
+- * Thread local storage is supported using vcos_tls.h. This is emulated on Nucleus
+- * and ThreadX.
+- *
+- * \section int Interrupts
+- *
+- * The legacy LISR/HISR scheme found in Nucleus is supported via the legacy ISR API,
+- * which is also supported on ThreadX. New code should avoid this, and old code should
+- * be migrated away from it, since it is slow. See vcos_legacy_isr.h.
+- *
+- * Registering an interrupt handler, and disabling/restoring interrupts, is handled
+- * using the functions in vcos_isr.h.
+- *
+- */
+-
+-/**
+- * \file vcos.h
+- *
+- * This is the top level header file. Clients include this. It pulls in the platform-specific
+- * header file (vcos_platform.h) together with header files defining the expected APIs, such
+- * as vcos_mutex.h, vcos_semaphore.h, etc. It is also possible to include these header files
+- * directly.
+- *
+- */
+-
+-#ifndef VCOS_H
+-#define VCOS_H
+-
+-#include "interface/vcos/vcos_assert.h"
+-#include "vcos_types.h"
+-#include "vcos_platform.h"
+-
+-#ifndef VCOS_INIT_H
+-#include "interface/vcos/vcos_init.h"
+-#endif
+-
+-#ifndef VCOS_SEMAPHORE_H
+-#include "interface/vcos/vcos_semaphore.h"
+-#endif
+-
+-#ifndef VCOS_THREAD_H
+-#include "interface/vcos/vcos_thread.h"
+-#endif
+-
+-#ifndef VCOS_MUTEX_H
+-#include "interface/vcos/vcos_mutex.h"
+-#endif
+-
+-#ifndef VCOS_MEM_H
+-#include "interface/vcos/vcos_mem.h"
+-#endif
+-
+-#ifndef VCOS_LOGGING_H
+-#include "interface/vcos/vcos_logging.h"
+-#endif
+-
+-#ifndef VCOS_STRING_H
+-#include "interface/vcos/vcos_string.h"
+-#endif
+-
+-#ifndef VCOS_EVENT_H
+-#include "interface/vcos/vcos_event.h"
+-#endif
+-
+-#ifndef VCOS_THREAD_ATTR_H
+-#include "interface/vcos/vcos_thread_attr.h"
+-#endif
+-
+-#ifndef VCOS_TLS_H
+-#include "interface/vcos/vcos_tls.h"
+-#endif
+-
+-#ifndef VCOS_REENTRANT_MUTEX_H
+-#include "interface/vcos/vcos_reentrant_mutex.h"
+-#endif
+-
+-#ifndef VCOS_NAMED_SEMAPHORE_H
+-#include "interface/vcos/vcos_named_semaphore.h"
+-#endif
+-
+-#ifndef VCOS_QUICKSLOW_MUTEX_H
+-#include "interface/vcos/vcos_quickslow_mutex.h"
+-#endif
+-
+-/* Headers with predicates */
+-
+-#if VCOS_HAVE_EVENT_FLAGS
+-#include "interface/vcos/vcos_event_flags.h"
+-#endif
+-
+-#if VCOS_HAVE_QUEUE
+-#include "interface/vcos/vcos_queue.h"
+-#endif
+-
+-#if VCOS_HAVE_LEGACY_ISR
+-#include "interface/vcos/vcos_legacy_isr.h"
+-#endif
+-
+-#if VCOS_HAVE_TIMER
+-#include "interface/vcos/vcos_timer.h"
+-#endif
+-
+-#if VCOS_HAVE_MEMPOOL
+-#include "interface/vcos/vcos_mempool.h"
+-#endif
+-
+-#if VCOS_HAVE_ISR
+-#include "interface/vcos/vcos_isr.h"
+-#endif
+-
+-#if VCOS_HAVE_ATOMIC_FLAGS
+-#include "interface/vcos/vcos_atomic_flags.h"
+-#endif
+-
+-#if VCOS_HAVE_ONCE
+-#include "interface/vcos/vcos_once.h"
+-#endif
+-
+-#if VCOS_HAVE_BLOCK_POOL
+-#include "interface/vcos/vcos_blockpool.h"
+-#endif
+-
+-#if VCOS_HAVE_FILE
+-#include "interface/vcos/vcos_file.h"
+-#endif
+-
+-#if VCOS_HAVE_CFG
+-#include "interface/vcos/vcos_cfg.h"
+-#endif
+-
+-#if VCOS_HAVE_CMD
+-#include "interface/vcos/vcos_cmd.h"
+-#endif
+-
+-#endif /* VCOS_H */
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_assert.h b/drivers/misc/vc04_services/interface/vcos/vcos_assert.h
+deleted file mode 100644
+index 1e72dff..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_assert.h
++++ /dev/null
+@@ -1,280 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - Assertion and error-handling macros.
+-=============================================================================*/
+-
+-
+-#ifndef VCOS_ASSERT_H
+-#define VCOS_ASSERT_H
+-
+-/*
+- * Macro:
+- * vcos_assert(cond)
+- * vcos_assert_msg(cond, fmt, ...)
+- * Use:
+- * Detecting programming errors by ensuring that assumptions are correct.
+- * On failure:
+- * Performs a platform-dependent "breakpoint", usually with an assert-style
+- * message. The '_msg' variant expects a printf-style format string and
+- * parameters.
+- * If a failure is detected, the code should be fixed and rebuilt.
+- * In release builds:
+- * Generates no code, i.e. does not evaluate 'cond'.
+- * Returns:
+- * Nothing.
+- *
+- * Macro:
+- * vcos_demand(cond)
+- * vcos_demand_msg(cond, fmt, ...)
+- * Use:
+- * Detecting fatal system errors that require a reboot.
+- * On failure:
+- * Performs a platform-dependent "breakpoint", usually with an assert-style
+- * message, then calls vcos_abort (see below).
+- * In release builds:
+- * Calls vcos_abort() if 'cond' is false.
+- * Returns:
+- * Nothing (never, on failure).
+- *
+- * Macro:
+- * vcos_verify(cond)
+- * vcos_verify_msg(cond, fmt, ...)
+- * Use:
+- * Detecting run-time errors and interesting conditions, normally within an
+- * 'if' statement to catch the failures, i.e.
+- * if (!vcos_verify(cond)) handle_error();
+- * On failure:
+- * Generates a message and optionally stops at a platform-dependent
+- * "breakpoint" (usually disabled). See vcos_verify_bkpts_enable below.
+- * In release builds:
+- * Just evaluates and returns 'cond'.
+- * Returns:
+- * Non-zero if 'cond' is true, otherwise zero.
+- *
+- * Macro:
+- * vcos_static_assert(cond)
+- * Use:
+- * Detecting compile-time errors.
+- * On failure:
+- * Generates a compiler error.
+- * In release builds:
+- * Generates a compiler error.
+- *
+- * Function:
+- * void vcos_abort(void)
+- * Use:
+- * Invokes the fatal error handling mechanism, alerting the host where
+- * applicable.
+- * Returns:
+- * Never.
+- *
+- * Macro:
+- * VCOS_VERIFY_BKPTS
+- * Use:
+- * Define in a module (before including vcos.h) to specify an alternative
+- * flag to control breakpoints on vcos_verify() failures.
+- * Returns:
+- * Non-zero values enable breakpoints.
+- *
+- * Function:
+- * int vcos_verify_bkpts_enable(int enable);
+- * Use:
+- * Sets the global flag controlling breakpoints on vcos_verify failures,
+- * enabling the breakpoints iff 'enable' is non-zero.
+- * Returns:
+- * The previous state of the flag.
+- *
+- * Function:
+- * int vcos_verify_bkpts_enabled(void);
+- * Use:
+- * Queries the state of the global flag enabling breakpoints on vcos_verify
+- * failures.
+- * Returns:
+- * The current state of the flag.
+- *
+- * Examples:
+- *
+- * int my_breakpoint_enable_flag = 1;
+- *
+- * #define VCOS_VERIFY_BKPTS my_breakpoint_enable_flag
+- *
+- * #include "interface/vcos/vcos.h"
+- *
+- * vcos_static_assert((sizeof(object) % 32) == 0);
+- *
+- * // ...
+- *
+- * vcos_assert_msg(postcondition_is_true, "Coding error");
+- *
+- * if (!vcos_verify_msg(buf, "Buffer allocation failed (%d bytes)", size))
+- * {
+- * // Tidy up
+- * // ...
+- * return OUT_OF_MEMORY;
+- * }
+- *
+- * vcos_demand(*p++==GUARDWORDHEAP);
+- */
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-
+-#ifdef __COVERITY__
+-#undef VCOS_ASSERT_BKPT
+-#define VCOS_ASSERT_BKPT __coverity_panic__()
+-#endif
+-
+-#ifndef VCOS_VERIFY_BKPTS
+-#define VCOS_VERIFY_BKPTS vcos_verify_bkpts_enabled()
+-#endif
+-
+-#ifndef VCOS_BKPT
+-#if defined(__VIDEOCORE__) && !defined(VCOS_ASSERT_NO_BKPTS)
+-#define VCOS_BKPT _bkpt()
+-#else
+-#define VCOS_BKPT (void )0
+-#endif
+-#endif
+-
+-#ifndef VCOS_ASSERT_BKPT
+-#define VCOS_ASSERT_BKPT VCOS_BKPT
+-#endif
+-
+-#ifndef VCOS_VERIFY_BKPT
+-#define VCOS_VERIFY_BKPT (VCOS_VERIFY_BKPTS ? VCOS_BKPT : (void)0)
+-#endif
+-
+-VCOSPRE_ int VCOSPOST_ vcos_verify_bkpts_enabled(void);
+-VCOSPRE_ int VCOSPOST_ vcos_verify_bkpts_enable(int enable);
+-VCOSPRE_ void VCOSPOST_ vcos_abort(void);
+-
+-#ifndef VCOS_ASSERT_MSG
+-#ifdef LOGGING
+-extern void logging_assert(const char *file, const char *func, int line, const char *format, ...);
+-#define VCOS_ASSERT_MSG(...) ((VCOS_ASSERT_LOGGING && !VCOS_ASSERT_LOGGING_DISABLE) ? logging_assert(__FILE__, __func__, __LINE__, __VA_ARGS__) : (void)0)
+-#else
+-#define VCOS_ASSERT_MSG(...) ((void)0)
+-#endif
+-#endif
+-
+-#ifndef VCOS_VERIFY_MSG
+-#define VCOS_VERIFY_MSG(...) VCOS_ASSERT_MSG(__VA_ARGS__)
+-#endif
+-
+-#ifndef VCOS_ASSERT_LOGGING
+-#define VCOS_ASSERT_LOGGING 0
+-#endif
+-
+-#ifndef VCOS_ASSERT_LOGGING_DISABLE
+-#define VCOS_ASSERT_LOGGING_DISABLE 0
+-#endif
+-
+-#if !defined(NDEBUG) || defined(VCOS_RELEASE_ASSERTS)
+-
+-#ifndef vcos_assert
+-#define vcos_assert(cond) \
+- ( (cond) ? (void)0 : (VCOS_ASSERT_MSG("%s", #cond), VCOS_ASSERT_BKPT) )
+-#endif
+-
+-#ifndef vcos_assert_msg
+-#define vcos_assert_msg(cond, ...) \
+- ( (cond) ? (void)0 : (VCOS_ASSERT_MSG(__VA_ARGS__), VCOS_ASSERT_BKPT) )
+-#endif
+-
+-#else /* !defined(NDEBUG) || defined(VCOS_RELEASE_ASSERTS) */
+-
+-#ifndef vcos_assert
+-#define vcos_assert(cond) (void)0
+-#endif
+-
+-#ifndef vcos_assert_msg
+-#define vcos_assert_msg(cond, ...) (void)0
+-#endif
+-
+-#endif /* !defined(NDEBUG) || defined(VCOS_RELEASE_ASSERTS) */
+-
+-#if !defined(NDEBUG)
+-
+-#ifndef vcos_demand
+-#define vcos_demand(cond) \
+- ( (cond) ? (void)0 : (VCOS_ASSERT_MSG("%s", #cond), VCOS_ASSERT_BKPT, vcos_abort()) )
+-#endif
+-
+-#ifndef vcos_demand_msg
+-#define vcos_demand_msg(cond, ...) \
+- ( (cond) ? (void)0 : (VCOS_ASSERT_MSG(__VA_ARGS__), VCOS_ASSERT_BKPT, vcos_abort()) )
+-#endif
+-
+-#ifndef vcos_verify
+-#define vcos_verify(cond) \
+- ( (cond) ? 1 : (VCOS_VERIFY_MSG("%s", #cond), VCOS_VERIFY_BKPT, 0) )
+-#endif
+-
+-#ifndef vcos_verify_msg
+-#define vcos_verify_msg(cond, ...) \
+- ( (cond) ? 1 : (VCOS_VERIFY_MSG(__VA_ARGS__), VCOS_VERIFY_BKPT, 0) )
+-#endif
+-
+-#else /* !defined(NDEBUG) */
+-
+-#ifndef vcos_demand
+-#define vcos_demand(cond) \
+- ( (cond) ? (void)0 : vcos_abort() )
+-#endif
+-
+-#ifndef vcos_demand_msg
+-#define vcos_demand_msg(cond, ...) \
+- ( (cond) ? (void)0 : vcos_abort() )
+-#endif
+-
+-#ifndef vcos_verify
+-#define vcos_verify(cond) (cond)
+-#endif
+-
+-#ifndef vcos_verify_msg
+-#define vcos_verify_msg(cond, ...) (cond)
+-#endif
+-
+-#endif /* !defined(NDEBUG) */
+-
+-#ifndef vcos_static_assert
+-#if defined(__GNUC__)
+-#define vcos_static_assert(cond) __attribute__((unused)) extern int vcos_static_assert[(cond)?1:-1]
+-#else
+-#define vcos_static_assert(cond) extern int vcos_static_assert[(cond)?1:-1]
+-#endif
+-#endif
+-
+-#ifndef vc_assert
+-#define vc_assert(cond) vcos_assert(cond)
+-#endif
+-
+-/** Print out a backtrace, on supported platforms.
+- */
+-extern void vcos_backtrace_self(void);
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-
+-#endif /* VCOS_ASSERT_H */
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_atomic_flags.h b/drivers/misc/vc04_services/interface/vcos/vcos_atomic_flags.h
+deleted file mode 100644
+index 317abf3..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_atomic_flags.h
++++ /dev/null
+@@ -1,83 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - public header file
+-=============================================================================*/
+-
+-#ifndef VCOS_ATOMIC_FLAGS_H
+-#define VCOS_ATOMIC_FLAGS_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-/**
+- * \file vcos_atomic_flags.h
+- *
+- * Defines atomic flags API.
+- *
+- * 32 flags. Atomic "or" and "get and clear" operations
+- */
+-
+-/**
+- * Create an atomic flags instance.
+- *
+- * @param atomic_flags Pointer to atomic flags instance, filled in on return
+- *
+- * @return VCOS_SUCCESS if succeeded.
+- */
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_atomic_flags_create(VCOS_ATOMIC_FLAGS_T *atomic_flags);
+-
+-/**
+- * Atomically set the specified flags.
+- *
+- * @param atomic_flags Instance to set flags on
+- * @param flags Mask of flags to set
+- */
+-VCOS_INLINE_DECL
+-void vcos_atomic_flags_or(VCOS_ATOMIC_FLAGS_T *atomic_flags, uint32_t flags);
+-
+-/**
+- * Retrieve the current flags and then clear them. The entire operation is
+- * atomic.
+- *
+- * @param atomic_flags Instance to get/clear flags from/on
+- *
+- * @return Mask of flags which were set (and we cleared)
+- */
+-VCOS_INLINE_DECL
+-uint32_t vcos_atomic_flags_get_and_clear(VCOS_ATOMIC_FLAGS_T *atomic_flags);
+-
+-/**
+- * Delete an atomic flags instance.
+- *
+- * @param atomic_flags Instance to delete
+- */
+-VCOS_INLINE_DECL
+-void vcos_atomic_flags_delete(VCOS_ATOMIC_FLAGS_T *atomic_flags);
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-
+-#endif
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_build_info.h b/drivers/misc/vc04_services/interface/vcos/vcos_build_info.h
+deleted file mode 100644
+index f3817f6..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_build_info.h
++++ /dev/null
+@@ -1,23 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-const char *vcos_get_build_hostname( void );
+-const char *vcos_get_build_version( void );
+-const char *vcos_get_build_time( void );
+-const char *vcos_get_build_date( void );
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_cfg.h b/drivers/misc/vc04_services/interface/vcos/vcos_cfg.h
+deleted file mode 100644
+index 4423051..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_cfg.h
++++ /dev/null
+@@ -1,113 +0,0 @@
+-/*****************************************************************************
+-* Copyright 2009 - 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( VCOS_CFG_H )
+-#define VCOS_CFG_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-typedef struct opaque_vcos_cfg_buf_t *VCOS_CFG_BUF_T;
+-typedef struct opaque_vcos_cfg_entry_t *VCOS_CFG_ENTRY_T;
+-
+-/** \file vcos_file.h
+- *
+- * API for accessing configuration/statistics information. This
+- * is loosely modelled on the linux proc entries.
+- */
+-
+-typedef void (*VCOS_CFG_SHOW_FPTR)( VCOS_CFG_BUF_T buf, void *data );
+-typedef void (*VCOS_CFG_PARSE_FPTR)( VCOS_CFG_BUF_T buf, void *data );
+-
+-/** Create a configuration directory.
+- *
+- * @param entry Place to store the created config entry.
+- * @param parent Parent entry (for directory like config
+- * options).
+- * @param entryName Name of the directory.
+- */
+-
+-VCOS_STATUS_T vcos_cfg_mkdir( VCOS_CFG_ENTRY_T *entry,
+- VCOS_CFG_ENTRY_T *parent,
+- const char *dirName );
+-
+-/** Create a configuration entry.
+- *
+- * @param entry Place to store the created config entry.
+- * @param parent Parent entry (for directory like config
+- * options).
+- * @param entryName Name of the configuration entry.
+- * @param showFunc Function pointer to show configuration
+- * data.
+- * @param parseFunc Function pointer to parse new data.
+- */
+-
+-VCOS_STATUS_T vcos_cfg_create_entry( VCOS_CFG_ENTRY_T *entry,
+- VCOS_CFG_ENTRY_T *parent,
+- const char *entryName,
+- VCOS_CFG_SHOW_FPTR showFunc,
+- VCOS_CFG_PARSE_FPTR parseFunc,
+- void *data );
+-
+-/** Determines if a configuration entry has been created or not.
+- *
+- * @param entry Configuration entry to query.
+- */
+-
+-int vcos_cfg_is_entry_created( VCOS_CFG_ENTRY_T entry );
+-
+-/** Returns the name of a configuration entry.
+- *
+- * @param entry Configuration entry to query.
+- */
+-
+-const char *vcos_cfg_get_entry_name( VCOS_CFG_ENTRY_T entry );
+-
+-/** Removes a configuration entry.
+- *
+- * @param entry Configuration entry to remove.
+- */
+-
+-VCOS_STATUS_T vcos_cfg_remove_entry( VCOS_CFG_ENTRY_T *entry );
+-
+-
+-/** Writes data into a configuration buffer. Only valid inside
+- * the show function.
+- *
+- * @param buf Buffer to write data into.
+- * @param fmt printf style format string.
+- */
+-
+-void vcos_cfg_buf_printf( VCOS_CFG_BUF_T buf, const char *fmt, ... );
+-
+-/** Retrieves a null terminated string of the data associated
+- * with the buffer. Only valid inside the parse function.
+- *
+- * @param buf Buffer to get data from.
+- * @param fmt printf style format string.
+- */
+-
+-char *vcos_cfg_buf_get_str( VCOS_CFG_BUF_T buf );
+-
+-void *vcos_cfg_get_proc_entry( VCOS_CFG_ENTRY_T entry );
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_cmd.h b/drivers/misc/vc04_services/interface/vcos/vcos_cmd.h
+deleted file mode 100644
+index 29d5315..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_cmd.h
++++ /dev/null
+@@ -1,98 +0,0 @@
+-/*****************************************************************************
+-* Copyright 2009 - 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( VCOS_CMD_H )
+-#define VCOS_CMD_H
+-
+-/* ---- Include Files ----------------------------------------------------- */
+-
+-#include "interface/vcos/vcos.h"
+-#include "interface/vcos/vcos_stdint.h"
+-
+-
+-/* ---- Constants and Types ---------------------------------------------- */
+-
+-struct VCOS_CMD_S;
+-typedef struct VCOS_CMD_S VCOS_CMD_T;
+-
+-typedef struct
+-{
+- int argc; /* Number of arguments (includes the command/sub-command) */
+- char **argv; /* Array of arguments */
+- char **argv_orig; /* Original array of arguments */
+-
+- VCOS_CMD_T *cmd_entry;
+- VCOS_CMD_T *cmd_parent_entry;
+-
+- int use_log; /* Output being logged? */
+- size_t result_size; /* Size of result buffer. */
+- char *result_ptr; /* Next place to put output. */
+- char *result_buf; /* Start of the buffer. */
+-
+-} VCOS_CMD_PARAM_T;
+-
+-typedef VCOS_STATUS_T (*VCOS_CMD_FUNC_T)( VCOS_CMD_PARAM_T *param );
+-
+-struct VCOS_CMD_S
+-{
+- const char *name;
+- const char *args;
+- VCOS_CMD_FUNC_T cmd_fn;
+- VCOS_CMD_T *sub_cmd_entry;
+- const char *descr;
+-
+-};
+-
+-/* ---- Variable Externs ------------------------------------------------- */
+-
+-/* ---- Function Prototypes ---------------------------------------------- */
+-
+-/*
+- * Common printing routine for generating command output.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_cmd_error( VCOS_CMD_PARAM_T *param, const char *fmt, ... ) VCOS_FORMAT_ATTR_(printf, 2, 3);
+-VCOSPRE_ void VCOSPOST_ vcos_cmd_printf( VCOS_CMD_PARAM_T *param, const char *fmt, ... ) VCOS_FORMAT_ATTR_(printf, 2, 3);
+-VCOSPRE_ void VCOSPOST_ vcos_cmd_vprintf( VCOS_CMD_PARAM_T *param, const char *fmt, va_list args ) VCOS_FORMAT_ATTR_(printf, 2, 0);
+-
+-/*
+- * Cause vcos_cmd_error, printf and vprintf to always log to the provided
+- * category. When this call is made, the results buffer passed into
+- * vcos_cmd_execute is used as a line buffer and does not need to be
+- * output by the caller.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_cmd_always_log_output( VCOS_LOG_CAT_T *log_category );
+-
+-/*
+- * Prints command usage for the current command.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_cmd_usage( VCOS_CMD_PARAM_T *param );
+-
+-/*
+- * Register commands to be processed
+- */
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_cmd_register( VCOS_CMD_T *cmd_entry );
+-
+-/*
+- * Registers multiple commands to be processed. The array should
+- * be terminated by an entry with all zeros.
+- */
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_cmd_register_multiple( VCOS_CMD_T *cmd_entry );
+-
+-/*
+- * Executes a command based on a command line.
+- */
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_cmd_execute( int argc, char **argv, size_t result_size, char *result_buf );
+-
+-#endif /* VCOS_CMD_H */
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_ctype.h b/drivers/misc/vc04_services/interface/vcos/vcos_ctype.h
+deleted file mode 100644
+index a270de8..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_ctype.h
++++ /dev/null
+@@ -1,40 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - public header file
+-=============================================================================*/
+-
+-#ifndef VCOS_CTYPE_H
+-#define VCOS_CTYPE_H
+-
+-/**
+- * \file
+- *
+- * ctype functions.
+- *
+- */
+-
+-#ifdef __KERNEL__
+-#include <linux/ctype.h>
+-#else
+-#include <ctype.h>
+-#endif
+-
+-#endif
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_dlfcn.h b/drivers/misc/vc04_services/interface/vcos/vcos_dlfcn.h
+deleted file mode 100644
+index 0a683c0b..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_dlfcn.h
++++ /dev/null
+@@ -1,80 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VCOS - abstraction over dynamic library opening
+-=============================================================================*/
+-
+-#ifndef VCOS_DLFCN_H
+-#define VCOS_DLFCN_H
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#define VCOS_DL_LAZY 1
+-#define VCOS_DL_NOW 2
+-
+-/**
+- * \file
+- *
+- * Loading dynamic libraries. See also dlfcn.h.
+- */
+-
+-/** Open a dynamic library.
+- *
+- * @param name name of the library
+- * @param mode Load lazily or immediately (VCOS_DL_LAZY, VCOS_DL_NOW).
+- *
+- * @return A handle for use in subsequent calls.
+- */
+-VCOSPRE_ void * VCOSPOST_ vcos_dlopen(const char *name, int mode);
+-
+-/** Look up a symbol.
+- *
+- * @param handle Handle to open
+- * @param name Name of function
+- *
+- * @return Function pointer, or NULL.
+- */
+-VCOSPRE_ void VCOSPOST_ (*vcos_dlsym(void *handle, const char *name))(void);
+-
+-/** Close a library
+- *
+- * @param handle Handle to close
+- */
+-VCOSPRE_ int VCOSPOST_ vcos_dlclose (void *handle);
+-
+-/** Return error message from library.
+- *
+- * @param err On return, set to non-zero if an error has occurred
+- * @param buf Buffer to write error to
+- * @param len Size of buffer (including terminating NUL).
+- */
+-VCOSPRE_ int VCOSPOST_ vcos_dlerror(int *err, char *buf, size_t buflen);
+-
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+-
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_event.h b/drivers/misc/vc04_services/interface/vcos/vcos_event.h
+deleted file mode 100644
+index 38612f9..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_event.h
++++ /dev/null
+@@ -1,108 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - public header file for events
+-=============================================================================*/
+-
+-#ifndef VCOS_EVENT_H
+-#define VCOS_EVENT_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-/**
+- * \file
+- *
+- * An event is akin to the Win32 auto-reset event.
+- *
+- *
+- * Signalling an event will wake up one waiting thread only. Once one
+- * thread has been woken the event atomically returns to the unsignalled
+- * state.
+- *
+- * If no threads are waiting on the event when it is signalled it remains
+- * signalled.
+- *
+- * This is almost, but not quite, completely unlike the "event flags"
+- * object based on Nucleus event groups and ThreadX event flags.
+- *
+- * In particular, it should be similar in speed to a semaphore, unlike
+- * the event flags.
+- */
+-
+-/**
+- * Create an event instance.
+- *
+- * @param event Filled in with constructed event.
+- * @param name Name of the event (for debugging)
+- *
+- * @return VCOS_SUCCESS on success, or error code.
+- */
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_event_create(VCOS_EVENT_T *event, const char *name);
+-
+-#ifndef vcos_event_signal
+-
+-/**
+- * Signal the event. The event will return to being unsignalled
+- * after exactly one waiting thread has been woken up. If no
+- * threads are waiting it remains signalled.
+- *
+- * @param event The event to signal
+- */
+-VCOS_INLINE_DECL
+-void vcos_event_signal(VCOS_EVENT_T *event);
+-
+-/**
+- * Wait for the event.
+- *
+- * @param event The event to wait for
+- * @return VCOS_SUCCESS on success, VCOS_EAGAIN if the wait was interrupted.
+- */
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_event_wait(VCOS_EVENT_T *event);
+-
+-/**
+- * Try event, but don't block.
+- *
+- * @param event The event to try
+- * @return VCOS_SUCCESS on success, VCOS_EAGAIN if the event is not currently signalled
+- */
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_event_try(VCOS_EVENT_T *event);
+-
+-#endif
+-
+-/*
+- * Destroy an event.
+- */
+-VCOS_INLINE_DECL
+-void vcos_event_delete(VCOS_EVENT_T *event);
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-
+-#endif
+-
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_event_flags.h b/drivers/misc/vc04_services/interface/vcos/vcos_event_flags.h
+deleted file mode 100644
+index 9eee410..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_event_flags.h
++++ /dev/null
+@@ -1,109 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - public header file
+-=============================================================================*/
+-
+-#ifndef VCOS_EVENT_FLAGS_H
+-#define VCOS_EVENT_FLAGS_H
+-
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-#define VCOS_EVENT_FLAGS_SUSPEND VCOS_SUSPEND
+-#define VCOS_EVENT_FLAGS_NO_SUSPEND VCOS_NO_SUSPEND
+-typedef VCOS_OPTION VCOS_EVENTGROUP_OPERATION_T;
+-
+-/**
+- * \file vcos_event_flags.h
+- *
+- * Defines event flags API.
+- *
+- * Similar to Nucleus event groups.
+- *
+- * These have the same semantics as Nucleus event groups and ThreadX event
+- * flags. As such, they are quite complex internally; if speed is important
+- * they might not be your best choice.
+- *
+- */
+-
+-/**
+- * Create an event flags instance.
+- *
+- * @param flags Pointer to event flags instance, filled in on return.
+- * @param name Name for the event flags, used for debug.
+- *
+- * @return VCOS_SUCCESS if succeeded.
+- */
+-
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_event_flags_create(VCOS_EVENT_FLAGS_T *flags, const char *name);
+-
+-/**
+- * Set some events.
+- *
+- * @param flags Instance to set flags on
+- * @param events Bitmask of the flags to actually set
+- * @param op How the flags should be set. VCOS_OR will OR in the flags; VCOS_AND
+- * will AND them in, possibly clearing existing flags.
+- */
+-VCOS_INLINE_DECL
+-void vcos_event_flags_set(VCOS_EVENT_FLAGS_T *flags,
+- VCOS_UNSIGNED events,
+- VCOS_OPTION op);
+-
+-/**
+- * Retrieve some events.
+- *
+- * Waits until the specified events have been set.
+- *
+- * @param flags Instance to wait on
+- * @param requested_events The bitmask to wait for
+- * @param op VCOS_OR - get any; VCOS_AND - get all.
+- * @param ms_suspend How long to wait, in milliseconds
+- * @param retrieved_events the events actually retrieved.
+- *
+- * @return VCOS_SUCCESS if events were retrieved. VCOS_EAGAIN if the
+- * timeout expired.
+- */
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_event_flags_get(VCOS_EVENT_FLAGS_T *flags,
+- VCOS_UNSIGNED requested_events,
+- VCOS_OPTION op,
+- VCOS_UNSIGNED ms_suspend,
+- VCOS_UNSIGNED *retrieved_events);
+-
+-
+-/**
+- * Delete an event flags instance.
+- */
+-VCOS_INLINE_DECL
+-void vcos_event_flags_delete(VCOS_EVENT_FLAGS_T *);
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-
+-#endif
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_init.h b/drivers/misc/vc04_services/interface/vcos/vcos_init.h
+deleted file mode 100644
+index 9fc5eca..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_init.h
++++ /dev/null
+@@ -1,54 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - initialization routines
+-=============================================================================*/
+-
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-/** \file
+- *
+- * Some OS support libraries need some initialization. To support this, call this
+- * function at the start of day.
+- */
+-
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_init(void);
+-VCOSPRE_ void VCOSPOST_ vcos_deinit(void);
+-VCOSPRE_ void VCOSPOST_ vcos_global_lock(void);
+-VCOSPRE_ void VCOSPOST_ vcos_global_unlock(void);
+-
+-/** Pass in the argv/argc arguments passed to main() */
+-VCOSPRE_ void VCOSPOST_ vcos_set_args(int argc, const char **argv);
+-
+-/** Return argc. */
+-VCOSPRE_ int VCOSPOST_ vcos_get_argc(void);
+-
+-/** Return argv. */
+-VCOSPRE_ const char ** VCOSPOST_ vcos_get_argv(void);
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_logging.h b/drivers/misc/vc04_services/interface/vcos/vcos_logging.h
+deleted file mode 100644
+index 9702822..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_logging.h
++++ /dev/null
+@@ -1,290 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - logging support
+-=============================================================================*/
+-
+-#ifndef VCOS_LOGGING_H
+-#define VCOS_LOGGING_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include <stdarg.h>
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-/**
+- * \file
+- *
+- * Logging support
+- *
+- * This provides categorised logging. Clients register
+- * a category, and then get a number of logging levels for
+- * that category.
+- *
+- * The logging level flag is tested using a flag *before* the
+- * function call, which makes logging very fast when disabled - there
+- * is no function call overhead just to find out that this log
+- * message is disabled.
+- *
+- * \section VCOS_LOG_CATEGORY
+- *
+- * As a convenience, clients define VCOS_LOG_CATEGORY to point to
+- * their category; the various vcos_log_xxx() macros then expand to
+- * use this.
+- *
+- * e.g.
+- *
+- * #define VCOS_LOG_CATEGORY (&my_category)
+- *
+- * #include <interface/vcos/vcos.h>
+- *
+- * VCOS_LOG_CAT_T my_category;
+- *
+- * ....
+- *
+- * vcos_log_trace("Stuff happened: %d", n_stuff);
+- *
+- */
+-
+-/** Logging levels */
+-typedef enum VCOS_LOG_LEVEL_T
+-{
+- VCOS_LOG_UNINITIALIZED = 0,
+- VCOS_LOG_NEVER,
+- VCOS_LOG_ERROR,
+- VCOS_LOG_WARN,
+- VCOS_LOG_INFO,
+- VCOS_LOG_TRACE,
+-} VCOS_LOG_LEVEL_T;
+-
+-
+-/** Initialize a logging category without going through vcos_log_register().
+- *
+- * This is useful for the case where there is no obvious point to do the
+- * registration (no initialization function for the module). However, it
+- * means that your logging category is not registered, so cannot be easily
+- * changed at run-time.
+- */
+-#define VCOS_LOG_INIT(n,l) { l, n, 0, {0}, 0, 0 }
+-
+-/** A registered logging category.
+- */
+-typedef struct VCOS_LOG_CAT_T
+-{
+- VCOS_LOG_LEVEL_T level; /** Which levels are enabled for this category */
+- const char *name; /** Name for this category. */
+- struct VCOS_LOG_CAT_T *next;
+- struct {
+- unsigned int want_prefix:1;
+- } flags;
+- unsigned int refcount;
+- void *platform_data; /** platform specific data */
+-} VCOS_LOG_CAT_T;
+-
+-typedef void (*VCOS_VLOG_IMPL_FUNC_T)(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args);
+-
+-/** Convert a VCOS_LOG_LEVEL_T into a printable string.
+- * The platform needs to implement this function.
+- */
+-VCOSPRE_ const char * VCOSPOST_ vcos_log_level_to_string( VCOS_LOG_LEVEL_T level );
+-
+-/** Convert a string into a VCOS_LOG_LEVEL_T
+- * The platform needs to implement this function.
+- */
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_string_to_log_level( const char *str, VCOS_LOG_LEVEL_T *level );
+-
+-/** Log a message. Basic API. Normal code should not use this.
+- * The platform needs to implement this function.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_log_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, ...) VCOS_FORMAT_ATTR_(printf, 3, 4);
+-
+-/** Log a message using a varargs parameter list. Normal code should
+- * not use this.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_vlog_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args) VCOS_FORMAT_ATTR_(printf, 3, 0);
+-
+-/** Set the function which does the actual logging output.
+- * Passing in NULL causes the default logging function to be
+- * used.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_set_vlog_impl( VCOS_VLOG_IMPL_FUNC_T vlog_impl_func );
+-
+-/** The default logging function, which is provided by each
+- * platform.
+- */
+-
+-VCOSPRE_ void VCOSPOST_ vcos_vlog_default_impl(const VCOS_LOG_CAT_T *cat, VCOS_LOG_LEVEL_T _level, const char *fmt, va_list args) VCOS_FORMAT_ATTR_(printf, 3, 0);
+-
+-/*
+- * Initialise the logging subsystem. This is called from
+- * vcos_init() so you don't normally need to call it.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_logging_init(void);
+-
+-/** Register a logging category.
+- *
+- * @param name the name of this category.
+- * @param category the category to register.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_log_register(const char *name, VCOS_LOG_CAT_T *category);
+-
+-/** Unregister a logging category.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_log_unregister(VCOS_LOG_CAT_T *category);
+-
+-/** Return a default logging category, for people too lazy to create their own.
+- *
+- * Using the default category will be slow (there's an extra function
+- * call overhead). Don't do this in normal code.
+- */
+-VCOSPRE_ const VCOS_LOG_CAT_T * VCOSPOST_ vcos_log_get_default_category(void);
+-
+-VCOSPRE_ void VCOSPOST_ vcos_set_log_options(const char *opt);
+-
+-/** Set the logging level for a category at run time. Without this, the level
+- * will be that set by vcos_log_register from a platform-specific source.
+- *
+- * @param category the category to modify.
+- * @param level the new logging level for this category.
+- */
+-VCOS_STATIC_INLINE void vcos_log_set_level(VCOS_LOG_CAT_T *category, VCOS_LOG_LEVEL_T level)
+-{
+- category->level = level;
+-}
+-
+-#define vcos_log_dump_mem(cat,label,addr,voidMem,numBytes) do { if (vcos_is_log_enabled(cat,VCOS_LOG_TRACE)) vcos_log_dump_mem_impl(cat,label,addr,voidMem,numBytes); } while (0)
+-
+-void vcos_log_dump_mem_impl( const VCOS_LOG_CAT_T *cat,
+- const char *label,
+- uint32_t addr,
+- const void *voidMem,
+- size_t numBytes );
+-
+-/*
+- * Platform specific hooks (optional).
+- */
+-#ifndef vcos_log_platform_init
+-#define vcos_log_platform_init() (void)0
+-#endif
+-
+-#ifndef vcos_log_platform_register
+-#define vcos_log_platform_register(category) (void)0
+-#endif
+-
+-#ifndef vcos_log_platform_unregister
+-#define vcos_log_platform_unregister(category) (void)0
+-#endif
+-
+-/* VCOS_TRACE() - deprecated macro which just outputs in a debug build and
+- * is a no-op in a release build.
+- *
+- * _VCOS_LOG_X() - internal macro which outputs if the current level for the
+- * particular category is higher than the supplied message level.
+- */
+-
+-#define VCOS_LOG_DFLT_CATEGORY vcos_log_get_default_category()
+-
+-#define _VCOS_LEVEL(x) (x)
+-
+-#define vcos_is_log_enabled(cat,_level) (_VCOS_LEVEL((cat)->level) >= _VCOS_LEVEL(_level))
+-
+-#if defined(_VCOS_METAWARE) || defined(__GNUC__)
+-
+-# if !defined(NDEBUG) || defined(VCOS_ALWAYS_WANT_LOGGING)
+-# define VCOS_LOGGING_ENABLED
+-# define _VCOS_LOG_X(cat, _level, fmt...) do { if (vcos_is_log_enabled(cat,_level)) vcos_log_impl(cat,_level,fmt); } while (0)
+-# define _VCOS_VLOG_X(cat, _level, fmt, ap) do { if (vcos_is_log_enabled(cat,_level)) vcos_vlog_impl(cat,_level,fmt,ap); } while (0)
+-# else
+-# define _VCOS_LOG_X(cat, _level, fmt...) (void)0
+-# define _VCOS_VLOG_X(cat, _level, fmt, ap) (void)0
+-# endif
+-
+-
+-
+-# define vcos_log_error(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_ERROR, __VA_ARGS__)
+-# define vcos_log_warn(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_WARN, __VA_ARGS__)
+-# define vcos_log_info(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_INFO, __VA_ARGS__)
+-# define vcos_log_trace(...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_TRACE, __VA_ARGS__)
+-
+-# define vcos_vlog_error(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_ERROR, fmt, ap)
+-# define vcos_vlog_warn(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_WARN, fmt, ap)
+-# define vcos_vlog_info(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_INFO, fmt, ap)
+-# define vcos_vlog_trace(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_TRACE, fmt, ap)
+-
+-# define vcos_log(...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, __VA_ARGS__)
+-# define vcos_vlog(fmt,ap) _VCOS_VLOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, fmt, ap)
+-# define VCOS_ALERT(...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_ERROR, __VA_ARGS__)
+-# define VCOS_TRACE(...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, __VA_ARGS__)
+-
+-/*
+- * MS Visual Studio - pre 2005 does not grok variadic macros
+- */
+-#elif defined(_MSC_VER)
+-
+-# if _MSC_VER >= 1400
+-
+-# if !defined(NDEBUG) || defined(VCOS_ALWAYS_WANT_LOGGING)
+-# define VCOS_LOGGING_ENABLED
+-# define _VCOS_LOG_X(cat, _level, fmt,...) do { if (vcos_is_log_enabled(cat,_level)) vcos_log_impl(cat, _level, fmt, __VA_ARGS__); } while (0)
+-# else
+-# define _VCOS_LOG_X(cat, _level, fmt,...) (void)0
+-# endif
+-
+-# define vcos_log_error(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_ERROR, fmt, __VA_ARGS__)
+-# define vcos_log_warn(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_WARN, fmt, __VA_ARGS__)
+-# define vcos_log_info(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_INFO, fmt, __VA_ARGS__)
+-# define vcos_log_trace(fmt,...) _VCOS_LOG_X(VCOS_LOG_CATEGORY, VCOS_LOG_TRACE, fmt, __VA_ARGS__)
+-
+-# define vcos_log(fmt,...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, fmt)
+-# define VCOS_ALERT(fmt,...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_ERROR, fmt)
+-# define VCOS_TRACE(fmt,...) _VCOS_LOG_X(VCOS_LOG_DFLT_CATEGORY, VCOS_LOG_INFO, fmt)
+-
+-# else /* _MSC_VER >= 1400 */
+-
+-/* do not define these */
+-
+-# endif /* _MSC_VER >= 1400 */
+-
+-#endif
+-
+-#if VCOS_HAVE_CMD
+-
+-#include "interface/vcos/vcos_cmd.h"
+-
+-/*
+- * These are the log sub-commands. They're exported here for user-mode apps which
+- * may want to call these, since the "log" command isn't registered for user-mode
+- * apps (vcdbg for example, has its own log command).
+- */
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_assert_cmd( VCOS_CMD_PARAM_T *param );
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_set_cmd( VCOS_CMD_PARAM_T *param );
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_status_cmd( VCOS_CMD_PARAM_T *param );
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_log_test_cmd( VCOS_CMD_PARAM_T *param );
+-#endif
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif /* VCOS_LOGGING_H */
+-
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_lowlevel_thread.h b/drivers/misc/vc04_services/interface/vcos/vcos_lowlevel_thread.h
+deleted file mode 100644
+index 9473cec..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_lowlevel_thread.h
++++ /dev/null
+@@ -1,118 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - low level thread support
+-=============================================================================*/
+-
+-#ifndef VCOS_LOWLEVEL_THREAD_H
+-#define VCOS_LOWLEVEL_THREAD_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-/**
+- * \file
+- *
+- * This defines a low level thread API that is supported by *some* operating systems
+- * and can be used to construct the regular "joinable thread" API on those operating
+- * systems.
+- *
+- * Most clients will not need to use this code.
+- *
+- * \sa vcos_joinable_thread.h
+- */
+-
+-/**
+- * \brief Create a thread.
+- *
+- * This creates a thread which can be stopped either by returning from the
+- * entry point function or by calling vcos_llthread_exit from within the entry
+- * point function. The thread must be cleaned up by calling
+- * vcos_llthread_delete. vcos_llthread_delete may or may not terminate the
+- * thread.
+- *
+- * The preemptible parameter familiar from Nucleus is removed, as it is unused in
+- * VideoCore code. Affinity is added, since we do use this.
+- *
+- * @param thread Filled in with thread instance
+- * @param name An optional name for the thread. "" may be used (but
+- * a name will aid in debugging).
+- * @param entry Entry point
+- * @param arg A single argument passed to the entry point function
+- * @param stack Pointer to stack address
+- * @param stacksz Size of stack in bytes
+- * @param priority Priority of task, between VCOS_PRI_LOW and VCOS_PRI_HIGH
+- * @param affinity CPU affinity
+- *
+- * @sa vcos_llthread_terminate vcos_llthread_delete
+- */
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_llthread_create(VCOS_LLTHREAD_T *thread,
+- const char *name,
+- VCOS_LLTHREAD_ENTRY_FN_T entry,
+- void *arg,
+- void *stack,
+- VCOS_UNSIGNED stacksz,
+- VCOS_UNSIGNED priority,
+- VCOS_UNSIGNED affinity,
+- VCOS_UNSIGNED timeslice,
+- VCOS_UNSIGNED autostart);
+-
+-/**
+- * \brief Exits the current thread.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_llthread_exit(void);
+-
+-/**
+- * \brief Delete a thread. This must be called to cleanup after
+- * vcos_llthread_create. This may or may not terminate the thread.
+- * It does not clean up any resources that may have been
+- * allocated by the thread.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_llthread_delete(VCOS_LLTHREAD_T *thread);
+-
+-/**
+- * \brief Return current lowlevel thread pointer.
+- */
+-VCOS_INLINE_DECL
+-VCOS_LLTHREAD_T *vcos_llthread_current(void);
+-
+-/**
+- * Resume a thread.
+- */
+-VCOS_INLINE_DECL
+-void vcos_llthread_resume(VCOS_LLTHREAD_T *thread);
+-
+-VCOSPRE_ int VCOSPOST_ vcos_llthread_running(VCOS_LLTHREAD_T *thread);
+-
+-/**
+- * \brief Create a VCOS_LLTHREAD_T for the current thread. This is so we can
+- * have VCOS_LLTHREAD_Ts even for threads not originally created by VCOS (eg
+- * the thread that calls vcos_init).
+- */
+-extern VCOS_STATUS_T _vcos_llthread_create_attach(VCOS_LLTHREAD_T *thread);
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_mem.h b/drivers/misc/vc04_services/interface/vcos/vcos_mem.h
+deleted file mode 100644
+index af16208..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_mem.h
++++ /dev/null
+@@ -1,92 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - memory support
+-=============================================================================*/
+-
+-#ifndef VCOS_MEM_H
+-#define VCOS_MEM_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-/** \file
+- *
+- * Memory allocation api (malloc/free equivalents) is for benefit of host
+- * applications. VideoCore code should use rtos_XXX functions.
+- *
+- */
+-
+-
+-/** Allocate memory
+- *
+- * @param size Size of memory to allocate
+- * @param description Description, to aid in debugging. May be ignored internally on some platforms.
+- */
+-VCOS_INLINE_DECL
+-void *vcos_malloc(VCOS_UNSIGNED size, const char *description);
+-
+-void *vcos_kmalloc(VCOS_UNSIGNED size, const char *description);
+-void *vcos_kcalloc(VCOS_UNSIGNED num, VCOS_UNSIGNED size, const char *description);
+-
+-/** Allocate cleared memory
+- *
+- * @param num Number of items to allocate.
+- * @param size Size of each item in bytes.
+- * @param description Description, to aid in debugging. May be ignored internally on some platforms.
+- */
+-VCOS_INLINE_DECL
+-void *vcos_calloc(VCOS_UNSIGNED num, VCOS_UNSIGNED size, const char *description);
+-
+-/** Free memory
+- *
+- * Free memory that has been allocated.
+- */
+-VCOS_INLINE_DECL
+-void vcos_free(void *ptr);
+-
+-void vcos_kfree(void *ptr);
+-
+-/** Allocate aligned memory
+- *
+- * Allocate memory aligned on the specified boundary.
+- *
+- * @param size Size of memory to allocate
+- * @param description Description, to aid in debugging. May be ignored internally on some platforms.
+- */
+-VCOS_INLINE_DECL
+-void *vcos_malloc_aligned(VCOS_UNSIGNED size, VCOS_UNSIGNED align, const char *description);
+-
+-/** Return the amount of free heap memory
+- *
+- */
+-VCOS_INLINE_DECL
+-unsigned long vcos_get_free_mem(void);
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-
+-#endif
+-
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_msgqueue.h b/drivers/misc/vc04_services/interface/vcos/vcos_msgqueue.h
+deleted file mode 100644
+index f0ef70b..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_msgqueue.h
++++ /dev/null
+@@ -1,168 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VCOS - packet-like messages, based loosely on those found in TRIPOS.
+-=============================================================================*/
+-
+-#ifndef VCOS_MSGQUEUE_H
+-#define VCOS_MSGQUEUE_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-/**
+- * \file
+- *
+- * Packet-like messages, based loosely on those found in TRIPOS and
+- * derivatives thereof.
+- *
+- * A task can send a message *pointer* to another task, where it is
+- * queued on a linked list and the task woken up. The receiving task
+- * consumes all of the messages on its input queue, and optionally
+- * sends back replies using the original message memory.
+- *
+- * A caller can wait for the reply to a specific message - any other
+- * messages that arrive in the meantime are queued separately.
+- *
+- *
+- * All messages have a standard common layout, but the payload area can
+- * be used freely to extend this.
+- */
+-
+-/** Map the payload portion of a message to a structure pointer.
+- */
+-#define VCOS_MSG_DATA(_msg) (void*)((_msg)->data)
+-
+-/** Standard message ids - FIXME - these need to be done properly! */
+-#define VCOS_MSG_N_QUIT 1
+-#define VCOS_MSG_N_OPEN 2
+-#define VCOS_MSG_N_CLOSE 3
+-#define VCOS_MSG_N_PRIVATE (1<<20)
+-
+-#define VCOS_MSG_REPLY_BIT (1<<31)
+-
+-/** Make gnuc compiler be happy about pointer punning */
+-#ifdef __GNUC__
+-#define __VCOS_MAY_ALIAS __attribute__((__may_alias__))
+-#else
+-#define __VCOS_MAY_ALIAS
+-#endif
+-
+-/** A single message queue.
+- */
+-typedef struct VCOS_MSGQUEUE_T
+-{
+- struct VCOS_MSG_T *head; /**< head of linked list of messages waiting on this queue */
+- struct VCOS_MSG_T *tail; /**< tail of message queue */
+- VCOS_SEMAPHORE_T sem; /**< thread waits on this for new messages */
+- VCOS_MUTEX_T lock; /**< locks the messages list */
+-} VCOS_MSGQUEUE_T;
+-
+-/** A single message
+- */
+-typedef struct VCOS_MSG_T
+-{
+- uint32_t code; /**< message code */
+- int error; /**< error status signalled back to caller */
+- VCOS_MSGQUEUE_T *dst; /**< destination queue */
+- VCOS_MSGQUEUE_T *src; /**< source; replies go back to here */
+- struct VCOS_MSG_T *next; /**< next in queue */
+- VCOS_THREAD_T *src_thread; /**< for debug */
+- uint32_t data[25]; /**< payload area */
+-} VCOS_MSG_T;
+-
+-/** An endpoint
+- */
+-typedef struct VCOS_MSG_ENDPOINT_T
+-{
+- VCOS_MSGQUEUE_T primary; /**< incoming messages */
+- VCOS_MSGQUEUE_T secondary; /**< this is used for waitspecific */
+- char name[32]; /**< name of this endpoint, for find() */
+- struct VCOS_MSG_ENDPOINT_T *next; /**< next in global list of endpoints */
+-} VCOS_MSG_ENDPOINT_T;
+-#define MSG_REPLY_BIT (1<<31)
+-
+-/** Initalise the library. Normally called from vcos_init().
+- */
+-extern VCOS_STATUS_T vcos_msgq_init(void);
+-
+-/** Find a message queue by name and get a handle to it.
+- *
+- * @param name the name of the queue to find
+- *
+- * @return The message queue, or NULL if not found.
+- */
+-VCOSPRE_ VCOS_MSGQUEUE_T VCOSPOST_ *vcos_msgq_find(const char *name);
+-
+-/** Wait for a message queue to come into existence. If it already exists,
+- * return immediately, otherwise block.
+- *
+- * On the whole, if you find yourself using this, it is probably a sign
+- * of poor design, since you should create all the server threads first,
+- * and then the client threads. But it is sometimes useful.
+- *
+- * @param name the name of the queue to find
+- * @return The message queue
+- */
+-VCOSPRE_ VCOS_MSGQUEUE_T VCOSPOST_ *vcos_msgq_wait(const char *name);
+-
+-/** Send a message.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_msg_send(VCOS_MSGQUEUE_T *dest, uint32_t code, VCOS_MSG_T *msg);
+-
+-/** Send a message and wait for a reply.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_msg_sendwait(VCOS_MSGQUEUE_T *queue, uint32_t code, VCOS_MSG_T *msg);
+-
+-/** Wait for a message on this thread's endpoint.
+- */
+-VCOSPRE_ VCOS_MSG_T * VCOSPOST_ vcos_msg_wait(void);
+-
+-/** Wait for a specific message.
+- */
+-VCOS_MSG_T * vcos_msg_wait_specific(VCOS_MSGQUEUE_T *queue, VCOS_MSG_T *msg);
+-
+-/** Peek for a message on this thread's endpoint, if a message is not available, NULL is
+- returned. If a message is available it will be removed from the endpoint and returned.
+- */
+-VCOSPRE_ VCOS_MSG_T * VCOSPOST_ vcos_msg_peek(void);
+-
+-/** Send a reply to a message
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_msg_reply(VCOS_MSG_T *msg);
+-
+-/** Create an endpoint. Each thread should need no more than one of these - if you
+- * find yourself needing a second one, you've done something wrong.
+- */
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_msgq_endpoint_create(VCOS_MSG_ENDPOINT_T *ep, const char *name);
+-
+-/** Destroy an endpoint.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_msgq_endpoint_delete(VCOS_MSG_ENDPOINT_T *ep);
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+-
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_mutex.h b/drivers/misc/vc04_services/interface/vcos/vcos_mutex.h
+deleted file mode 100644
+index 14387a8..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_mutex.h
++++ /dev/null
+@@ -1,103 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - mutex public header file
+-=============================================================================*/
+-
+-#ifndef VCOS_MUTEX_H
+-#define VCOS_MUTEX_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-/**
+- * \file vcos_mutex.h
+- *
+- * Mutex API. Mutexes are not re-entrant, as supporting this adds extra code
+- * that slows down clients which have been written sensibly.
+- *
+- * \sa vcos_reentrant_mutex.h
+- *
+- */
+-
+-/** Create a mutex.
+- *
+- * @param m Filled in with mutex on return
+- * @param name A non-null name for the mutex, used for diagnostics.
+- *
+- * @return VCOS_SUCCESS if mutex was created, or error code.
+- */
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_mutex_create(VCOS_MUTEX_T *m, const char *name);
+-
+-/** Delete the mutex.
+- */
+-VCOS_INLINE_DECL
+-void vcos_mutex_delete(VCOS_MUTEX_T *m);
+-
+-/**
+- * \brief Wait to claim the mutex.
+- *
+- * On most platforms this always returns VCOS_SUCCESS, and so would ideally be
+- * a void function, however some platforms allow a wait to be interrupted so
+- * it remains non-void.
+- *
+- * Try to obtain the mutex.
+- * @param m Mutex to wait on
+- * @return VCOS_SUCCESS - mutex was taken.
+- * VCOS_EAGAIN - could not take mutex.
+- */
+-#ifndef vcos_mutex_lock
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_mutex_lock(VCOS_MUTEX_T *m);
+-
+-/** Release the mutex.
+- */
+-VCOS_INLINE_DECL
+-void vcos_mutex_unlock(VCOS_MUTEX_T *m);
+-#endif
+-
+-/** Test if the mutex is already locked.
+- *
+- * @return 1 if mutex is locked, 0 if it is unlocked.
+- */
+-VCOS_INLINE_DECL
+-int vcos_mutex_is_locked(VCOS_MUTEX_T *m);
+-
+-/** Obtain the mutex if possible.
+- *
+- * @param m the mutex to try to obtain
+- *
+- * @return VCOS_SUCCESS if mutex is succesfully obtained, or VCOS_EAGAIN
+- * if it is already in use by another thread.
+- */
+-#ifndef vcos_mutex_trylock
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_mutex_trylock(VCOS_MUTEX_T *m);
+-#endif
+-
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_once.h b/drivers/misc/vc04_services/interface/vcos/vcos_once.h
+deleted file mode 100644
+index 0533c10..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_once.h
++++ /dev/null
+@@ -1,53 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - 'once'
+-=============================================================================*/
+-
+-#ifndef VCOS_ONCE_H
+-#define VCOS_ONCE_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-/**
+- * \file vcos_once.h
+- *
+- * Ensure something is called only once.
+- *
+- * Initialize once_control to VCOS_ONCE_INIT. The first
+- * time this is called, the init_routine will be called. Thereafter
+- * it won't.
+- *
+- * \sa pthread_once()
+- *
+- */
+-
+-VCOS_STATUS_T vcos_once(VCOS_ONCE_T *once_control,
+- void (*init_routine)(void));
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_semaphore.h b/drivers/misc/vc04_services/interface/vcos/vcos_semaphore.h
+deleted file mode 100644
+index 2760dd7..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_semaphore.h
++++ /dev/null
+@@ -1,126 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - public header file
+-=============================================================================*/
+-
+-#ifndef VCOS_SEMAPHORE_H
+-#define VCOS_SEMAPHORE_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-/**
+- * \file vcos_semaphore.h
+- *
+- * \section sem Semaphores
+- *
+- * This provides counting semaphores. Semaphores are not re-entrant. On sensible
+- * operating systems a semaphore can always be posted but can only be taken in
+- * thread (not interrupt) context. Under Nucleus, a LISR cannot post a semaphore,
+- * although it would not be hard to lift this restriction.
+- *
+- * \subsection timeout Timeout
+- *
+- * On both Nucleus and ThreadX a semaphore can be taken with a timeout. This is
+- * not supported by VCOS because it makes the non-timeout code considerably more
+- * complicated (and hence slower). In the unlikely event that you need a timeout
+- * with a semaphore, and you cannot simply redesign your code to avoid it, use
+- * an event flag (vcos_event_flags.h).
+- *
+- * \subsection sem_nucleus Changes from Nucleus:
+- *
+- * Semaphores are always "FIFO" - i.e. sleeping threads are woken in FIFO order. That's
+- * because:
+- * \arg there's no support for NU_PRIORITY in threadx (though it can be emulated, slowly)
+- * \arg we don't appear to actually consciously use it - for example, Dispmanx uses
+- * it, but all threads waiting are the same priority.
+- *
+- */
+-
+-/**
+- * \brief Create a semaphore.
+- *
+- * Create a semaphore.
+- *
+- * @param sem Pointer to memory to be initialized
+- * @param name A name for this semaphore. The name may be truncated internally.
+- * @param count The initial count for the semaphore.
+- *
+- * @return VCOS_SUCCESS if the semaphore was created.
+- *
+- */
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_semaphore_create(VCOS_SEMAPHORE_T *sem, const char *name, VCOS_UNSIGNED count);
+-
+-/**
+- * \brief Wait on a semaphore.
+- *
+- * There is no timeout option on a semaphore, as adding this will slow down
+- * implementations on some platforms. If you need that kind of behaviour, use
+- * an event group.
+- *
+- * On most platforms this always returns VCOS_SUCCESS, and so would ideally be
+- * a void function, however some platforms allow a wait to be interrupted so
+- * it remains non-void.
+- *
+- * @param sem Semaphore to wait on
+- * @return VCOS_SUCCESS - semaphore was taken.
+- * VCOS_EAGAIN - could not take semaphore
+- *
+- */
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_semaphore_wait(VCOS_SEMAPHORE_T *sem);
+-
+-/**
+- * \brief Try to wait for a semaphore.
+- *
+- * Try to obtain the semaphore. If it is already taken, return VCOS_TIMEOUT.
+- * @param sem Semaphore to wait on
+- * @return VCOS_SUCCESS - semaphore was taken.
+- * VCOS_EAGAIN - could not take semaphore
+- */
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_semaphore_trywait(VCOS_SEMAPHORE_T *sem);
+-
+-/**
+- * \brief Post a semaphore.
+- *
+- * @param sem Semaphore to wait on
+- */
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_semaphore_post(VCOS_SEMAPHORE_T *sem);
+-
+-/**
+- * \brief Delete a semaphore, releasing any resources consumed by it.
+- *
+- * @param sem Semaphore to wait on
+- */
+-VCOS_INLINE_DECL
+-void vcos_semaphore_delete(VCOS_SEMAPHORE_T *sem);
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_stdbool.h b/drivers/misc/vc04_services/interface/vcos/vcos_stdbool.h
+deleted file mode 100644
+index 3c7669d..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_stdbool.h
++++ /dev/null
+@@ -1,34 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-#ifndef VCOS_STDBOOL_H
+-#define VCOS_STDBOOL_H
+-
+-#ifndef __cplusplus
+-
+-#if defined(__STDC__) && (__STDC_VERSION__ >= 199901L)
+-#include <stdbool.h>
+-#else
+-typedef enum {
+- false,
+- true
+-} bool;
+-#endif
+-
+-#endif /* __cplusplus */
+-
+-#endif
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_stdint.h b/drivers/misc/vc04_services/interface/vcos/vcos_stdint.h
+deleted file mode 100644
+index c9a3e02..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_stdint.h
++++ /dev/null
+@@ -1,203 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-#ifndef VCOS_STDINT_H
+-#define VCOS_STDINT_H
+-
+-/* Attempt to provide the types defined in stdint.h.
+- *
+- * Ideally this would either call out to a platform-specific
+- * header file (e.g. stdint.h) or define the types on a
+- * per-architecture/compiler basis. But for now we just
+- * use #ifdefs.
+- */
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#ifdef __SYMBIAN32__
+-
+-typedef signed char int8_t;
+-typedef unsigned char uint8_t;
+-
+-typedef signed short int16_t;
+-typedef unsigned short uint16_t;
+-
+-typedef int16_t int_least16_t;
+-
+-typedef signed long int32_t;
+-typedef unsigned long uint32_t;
+-
+-typedef signed long long int64_t;
+-typedef unsigned long long uint64_t;
+-
+-typedef int32_t intptr_t;
+-typedef uint32_t uintptr_t;
+-
+-typedef int64_t intmax_t;
+-typedef uint64_t uintmax_t;
+-
+-#define INT8_MIN SCHAR_MIN
+-#define INT8_MAX SCHAR_MAX
+-#define UINT8_MAX UCHAR_MAX
+-#define INT16_MIN SHRT_MIN
+-#define INT16_MAX SHRT_MAX
+-#define UINT16_MAX USHRT_MAX
+-#define INT32_MIN LONG_MIN
+-#define INT32_MAX LONG_MAX
+-#define UINT32_MAX ULONG_MAX
+-#define INT64_MIN LLONG_MIN
+-#define INT64_MAX LLONG_MAX
+-#define UINT64_MAX ULLONG_MAX
+-
+-#define INTPTR_MIN INT32_MIN
+-#define INTPTR_MAX INT32_MAX
+-#define UINTPTR_MAX UINT32_MAX
+-#define INTMAX_MIN INT64_MIN
+-#define INTMAX_MAX INT64_MAX
+-#define INT_LEAST16_MAX INT16_MAX
+-#define INT_LEAST16_MAX INT16_MAX
+-
+-/*{{{ C99 types - THIS WHOLE SECTION IS INCOMPATIBLE WITH C99. IT SHOULD RESIDE IN A STDINT.H SINCE THIS FILE GETS USED ON HOST SIDE */
+-
+-#elif defined( __STDC__ ) && __STDC_VERSION__ >= 199901L
+-
+-#include <stdint.h>
+-
+-#elif defined( __GNUC__ )
+-
+-#include <stdint.h>
+-
+-#elif defined(_MSC_VER) /* Visual C define equivalent types */
+-
+-#include <stddef.h> /* Avoids intptr_t being defined in vadefs.h */
+-
+-typedef __int8 int8_t;
+-typedef unsigned __int8 uint8_t;
+-
+-typedef __int16 int16_t;
+-typedef unsigned __int16 uint16_t;
+-
+-typedef __int32 int32_t;
+-typedef unsigned __int32 uint32_t;
+-
+-typedef __int64 int64_t;
+-typedef unsigned __int64 uint64_t;
+-typedef uint32_t uintptr_t;
+-typedef int64_t intmax_t;
+-typedef uint64_t uintmax_t;
+-typedef int16_t int_least16_t;
+-
+-#elif defined (VCMODS_LCC)
+-#include <limits.h>
+-
+-typedef signed char int8_t;
+-typedef unsigned char uint8_t;
+-
+-typedef signed short int16_t;
+-typedef unsigned short uint16_t;
+-
+-typedef signed long int32_t;
+-typedef unsigned long uint32_t;
+-
+-typedef signed long int64_t; /*!!!! PFCD, this means code using 64bit numbers will be broken on the VCE */
+-typedef unsigned long uint64_t; /* !!!! PFCD */
+-
+-typedef int32_t intptr_t;
+-typedef uint32_t uintptr_t;
+-typedef int64_t intmax_t;
+-typedef uint64_t uintmax_t;
+-typedef int16_t int_least16_t;
+-
+-#define INT8_MIN SCHAR_MIN
+-#define INT8_MAX SCHAR_MAX
+-#define UINT8_MAX UCHAR_MAX
+-#define INT16_MIN SHRT_MIN
+-#define INT16_MAX SHRT_MAX
+-#define UINT16_MAX USHRT_MAX
+-#define INT32_MIN LONG_MIN
+-#define INT32_MAX LONG_MAX
+-#define UINT32_MAX ULONG_MAX
+-#define INT64_MIN LONG_MIN /* !!!! PFCD */
+-#define INT64_MAX LONG_MAX /* !!!! PFCD */
+-#define UINT64_MAX ULONG_MAX /* !!!! PFCD */
+-
+-#define INTPTR_MIN INT32_MIN
+-#define INTPTR_MAX INT32_MAX
+-#define UINTPTR_MAX UINT32_MAX
+-#define INTMAX_MIN INT64_MIN
+-#define INTMAX_MIN INT64_MIN
+-#define INT_LEAST16_MAX INT16_MAX
+-#define INT_LEAST16_MAX INT16_MAX
+-
+-#elif defined(__VIDEOCORE__)
+-
+-typedef signed char int8_t;
+-typedef unsigned char uint8_t;
+-
+-typedef signed short int16_t;
+-typedef unsigned short uint16_t;
+-
+-typedef signed long int32_t;
+-typedef unsigned long uint32_t;
+-
+-typedef signed long long int64_t;
+-typedef unsigned long long uint64_t;
+-
+-typedef int32_t intptr_t;
+-typedef uint32_t uintptr_t;
+-typedef int64_t intmax_t;
+-typedef uint64_t uintmax_t;
+-typedef int16_t int_least16_t;
+-
+-#define INT8_MIN SCHAR_MIN
+-#define INT8_MAX SCHAR_MAX
+-#define UINT8_MAX UCHAR_MAX
+-#define INT16_MIN SHRT_MIN
+-#define INT16_MAX SHRT_MAX
+-#define UINT16_MAX USHRT_MAX
+-#define INT32_MIN LONG_MIN
+-#define INT32_MAX LONG_MAX
+-#define UINT32_MAX ULONG_MAX
+-#define INT64_MIN LLONG_MIN
+-#define INT64_MAX LLONG_MAX
+-#define UINT64_MAX ULLONG_MAX
+-
+-#define INTPTR_MIN INT32_MIN
+-#define INTPTR_MAX INT32_MAX
+-#define UINTPTR_MAX UINT32_MAX
+-#define INTMAX_MIN INT64_MIN
+-#define INTMAX_MAX INT64_MAX
+-#define INT_LEAST16_MAX INT16_MAX
+-#define INT_LEAST16_MAX INT16_MAX
+-
+-#elif defined (__HIGHC__) && defined(_I386)
+-
+-#include <stdint.h>
+-
+-#else
+-#error Unknown platform
+-#endif
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif /* VCOS_STDINT_H */
+-
+-
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_string.h b/drivers/misc/vc04_services/interface/vcos/vcos_string.h
+deleted file mode 100644
+index c3d875f..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_string.h
++++ /dev/null
+@@ -1,84 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - public header file
+-=============================================================================*/
+-
+-#ifndef VCOS_STRING_H
+-#define VCOS_STRING_H
+-
+-/**
+- * \file
+- *
+- * String functions.
+- *
+- */
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-#ifdef __KERNEL__
+-#include <linux/string.h>
+-#else
+-#include <string.h>
+-#endif
+-
+-/** Case insensitive string comparison.
+- *
+- */
+-
+-VCOS_INLINE_DECL
+-int vcos_strcasecmp(const char *s1, const char *s2);
+-
+-VCOS_INLINE_DECL
+-int vcos_strncasecmp(const char *s1, const char *s2, size_t n);
+-
+-VCOSPRE_ int VCOSPOST_ vcos_vsnprintf( char *buf, size_t buflen, const char *fmt, va_list ap );
+-
+-VCOSPRE_ int VCOSPOST_ vcos_snprintf(char *buf, size_t buflen, const char *fmt, ...);
+-
+-VCOS_STATIC_INLINE
+-int vcos_strlen(const char *s) { return (int)strlen(s); }
+-
+-VCOS_STATIC_INLINE
+-int vcos_strcmp(const char *s1, const char *s2) { return strcmp(s1,s2); }
+-
+-VCOS_STATIC_INLINE
+-int vcos_strncmp(const char *cs, const char *ct, size_t count) { return strncmp(cs, ct, count); }
+-
+-VCOS_STATIC_INLINE
+-char *vcos_strcpy(char *dst, const char *src) { return strcpy(dst, src); }
+-
+-VCOS_STATIC_INLINE
+-char *vcos_strncpy(char *dst, const char *src, size_t count) { return strncpy(dst, src, count); }
+-
+-VCOS_STATIC_INLINE
+-void *vcos_memcpy(void *dst, const void *src, size_t n) { memcpy(dst, src, n); return dst; }
+-
+-VCOS_STATIC_INLINE
+-void *vcos_memset(void *p, int c, size_t n) { return memset(p, c, n); }
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_thread.h b/drivers/misc/vc04_services/interface/vcos/vcos_thread.h
+deleted file mode 100644
+index ee34648..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_thread.h
++++ /dev/null
+@@ -1,270 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - public header file
+-=============================================================================*/
+-
+-#ifndef VCOS_THREAD_H
+-#define VCOS_THREAD_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-/**
+- * \file vcos_thread.h
+- *
+- * \section thread Threads
+- *
+- * Under Nucleus, a thread is created by NU_Create_Task, passing in the stack
+- * and various other parameters. To stop the thread, NU_Terminate_Thread() and
+- * NU_Delete_Thread() are called.
+- *
+- * Unfortunately it's not possible to emulate this API under some fairly common
+- * operating systems. Under Windows you can't pass in the stack, and you can't
+- * safely terminate a thread.
+- *
+- * Therefore, an API which is similar to the pthreads API is used instead. This
+- * API can (mostly) be emulated under all interesting operating systems.
+- *
+- * Obviously this makes the code somewhat more complicated on VideoCore than it
+- * would otherwise be - we end up with an extra mutex per thread, and some code
+- * that waits for it. The benefit is that we have a single way of creating
+- * threads that works consistently on all platforms (apart from stack supplying).
+- *
+- * \subsection stack Stack
+- *
+- * It's still not possible to pass in the stack address, but this can be made
+- * much more obvious in the API: the relevant function is missing and the
+- * CPP symbol VCOS_CAN_SET_STACK_ADDR is zero rather than one.
+- *
+- * \subsection thr_create Creating a thread
+- *
+- * The simplest way to create a thread is with vcos_thread_create() passing in a
+- * NULL thread parameter argument. To wait for the thread to exit, call
+- * vcos_thread_join().
+- *
+- * \subsection back Backward compatibility
+- *
+- * To ease migration, a "classic" thread creation API is provided for code
+- * that used to make use of Nucleus, vcos_thread_create_classic(). The
+- * arguments are not exactly the same, as the PREEMPT parameter is dropped.
+- *
+- */
+-
+-#define VCOS_AFFINITY_CPU0 _VCOS_AFFINITY_CPU0
+-#define VCOS_AFFINITY_CPU1 _VCOS_AFFINITY_CPU1
+-#define VCOS_AFFINITY_MASK _VCOS_AFFINITY_MASK
+-#define VCOS_AFFINITY_DEFAULT _VCOS_AFFINITY_DEFAULT
+-#define VCOS_AFFINITY_THISCPU _VCOS_AFFINITY_THISCPU
+-
+-/** Report whether or not we have an RTOS at all, and hence the ability to
+- * create threads.
+- */
+-VCOSPRE_ int VCOSPOST_ vcos_have_rtos(void);
+-
+-/** Create a thread. It must be cleaned up by calling vcos_thread_join().
+- *
+- * @param thread Filled in on return with thread
+- * @param name A name for the thread. May be the empty string.
+- * @param attrs Attributes; default attributes will be used if this is NULL.
+- * @param entry Entry point.
+- * @param arg Argument passed to the entry point.
+- */
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_thread_create(VCOS_THREAD_T *thread,
+- const char *name,
+- VCOS_THREAD_ATTR_T *attrs,
+- VCOS_THREAD_ENTRY_FN_T entry,
+- void *arg);
+-
+-/** Exit the thread from within the thread function itself.
+- * Resources must still be cleaned up via a call to thread_join().
+- *
+- * The thread can also be terminated by simply exiting the thread function.
+- *
+- * @param data Data passed to thread_join. May be NULL.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_thread_exit(void *data);
+-
+-/** Wait for a thread to terminate and then clean up its resources.
+- *
+- * @param thread Thread to wait for
+- * @param pData Updated to point at data provided in vcos_thread_exit or exit
+- * code of thread function.
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_thread_join(VCOS_THREAD_T *thread,
+- void **pData);
+-
+-
+-/**
+- * \brief Create a thread using an API similar to the one "traditionally"
+- * used under Nucleus.
+- *
+- * This creates a thread which must be cleaned up by calling vcos_thread_join().
+- * The thread cannot be simply terminated (as in Nucleus and ThreadX) as thread
+- * termination is not universally supported.
+- *
+- * @param thread Filled in with thread instance
+- * @param name An optional name for the thread. NULL or "" may be used (but
+- * a name will aid in debugging).
+- * @param entry Entry point
+- * @param arg A single argument passed to the entry point function
+- * @param stack Pointer to stack address
+- * @param stacksz Size of stack in bytes
+- * @param priaff Priority of task, between VCOS_PRI_LOW and VCOS_PRI_HIGH, ORed with the CPU affinity
+- * @param autostart If non-zero the thread will start immediately.
+- * @param timeslice Timeslice (system ticks) for this thread.
+- *
+- * @sa vcos_thread_terminate vcos_thread_delete
+- */
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_thread_create_classic(VCOS_THREAD_T *thread,
+- const char *name,
+- void *(*entry)(void *arg),
+- void *arg,
+- void *stack,
+- VCOS_UNSIGNED stacksz,
+- VCOS_UNSIGNED priaff,
+- VCOS_UNSIGNED timeslice,
+- VCOS_UNSIGNED autostart);
+-
+-/**
+- * \brief Set a thread's priority
+- *
+- * Set the priority for a thread.
+- *
+- * @param thread The thread
+- * @param pri Thread priority in VCOS_PRI_MASK bits; affinity in VCOS_AFFINITY_MASK bits.
+- */
+-VCOS_INLINE_DECL
+-void vcos_thread_set_priority(VCOS_THREAD_T *thread, VCOS_UNSIGNED pri);
+-
+-/**
+- * \brief Return the currently executing thread.
+- *
+- */
+-VCOS_INLINE_DECL
+-VCOS_THREAD_T *vcos_thread_current(void);
+-
+-/**
+- * \brief Return the thread's priority.
+- */
+-VCOS_INLINE_DECL
+-VCOS_UNSIGNED vcos_thread_get_priority(VCOS_THREAD_T *thread);
+-
+-/**
+- * \brief Return the thread's cpu affinity.
+- */
+-VCOS_INLINE_DECL
+-VCOS_UNSIGNED vcos_thread_get_affinity(VCOS_THREAD_T *thread);
+-
+-/**
+- * \brief Set the thread's cpu affinity.
+- */
+-
+-VCOS_INLINE_DECL
+-void vcos_thread_set_affinity(VCOS_THREAD_T *thread, VCOS_UNSIGNED affinity);
+-
+-/**
+- * \brief Query whether we are in an interrupt.
+- *
+- * @return 1 if in interrupt context.
+- */
+-VCOS_INLINE_DECL
+-int vcos_in_interrupt(void);
+-
+-/**
+- * \brief Sleep a while.
+- *
+- * @param ms Number of milliseconds to sleep for
+- *
+- * This may actually sleep a whole number of ticks.
+- */
+-VCOS_INLINE_DECL
+-void vcos_sleep(uint32_t ms);
+-
+-/**
+- * \brief Return the value of the hardware microsecond counter.
+- *
+- */
+-VCOS_INLINE_DECL
+-uint32_t vcos_getmicrosecs(void);
+-
+-#define vcos_get_ms() (vcos_getmicrosecs()/1000)
+-
+-/**
+- * \brief Return a unique identifier for the current process
+- *
+- */
+-VCOS_INLINE_DECL
+-VCOS_UNSIGNED vcos_process_id_current(void);
+-
+-/** Relinquish this time slice. */
+-VCOS_INLINE_DECL
+-void vcos_thread_relinquish(void);
+-
+-/** Return the name of the given thread.
+- */
+-VCOSPRE_ const char * VCOSPOST_ vcos_thread_get_name(const VCOS_THREAD_T *thread);
+-
+-/** Change preemption. This is almost certainly not what you want, as it won't
+- * work reliably in a multicore system: although you can affect the preemption
+- * on *this* core, you won't affect what's happening on the other core(s).
+- *
+- * It's mainly here to ease migration. If you're using it in new code, you
+- * probably need to think again.
+- *
+- * @param pe New preemption, VCOS_PREEMPT or VCOS_NO_PREEMPT
+- * @return Old value of preemption.
+- */
+-VCOS_INLINE_DECL
+-VCOS_UNSIGNED vcos_change_preemption(VCOS_UNSIGNED pe);
+-
+-/** Is a thread still running, or has it exited?
+- *
+- * Note: this exists for some fairly scary code in the video codec tests. Don't
+- * try to use it for anything else, as it may well not do what you expect.
+- *
+- * @param thread thread to query
+- * @return non-zero if thread is running, or zero if it has exited.
+- */
+-VCOS_INLINE_DECL
+-int vcos_thread_running(VCOS_THREAD_T *thread);
+-
+-/** Resume a thread.
+- *
+- * @param thread thread to resume
+- */
+-VCOS_INLINE_DECL
+-void vcos_thread_resume(VCOS_THREAD_T *thread);
+-
+-/*
+- * Internal APIs - may not always be present and should not be used in
+- * client code.
+- */
+-
+-extern void _vcos_task_timer_set(void (*pfn)(void*), void *, VCOS_UNSIGNED ms);
+-extern void _vcos_task_timer_cancel(void);
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_thread_attr.h b/drivers/misc/vc04_services/interface/vcos/vcos_thread_attr.h
+deleted file mode 100644
+index 375dd01..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_thread_attr.h
++++ /dev/null
+@@ -1,87 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - thread attributes
+-=============================================================================*/
+-
+-#ifndef VCOS_THREAD_ATTR_H
+-#define VCOS_THREAD_ATTR_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-/**
+- * \file
+- *
+- * Attributes for thread creation.
+- *
+- */
+-
+-/** Initialize thread attribute struct. This call does not allocate memory,
+- * and so cannot fail.
+- *
+- */
+-VCOSPRE_ void VCOSPOST_ vcos_thread_attr_init(VCOS_THREAD_ATTR_T *attrs);
+-
+-/** Set the stack address and size. If not set, a stack will be allocated automatically.
+- *
+- * This can only be set on some platforms. It will always be possible to set the stack
+- * address on VideoCore, but on host platforms, support may well not be available.
+- */
+-#if VCOS_CAN_SET_STACK_ADDR
+-VCOS_INLINE_DECL
+-void vcos_thread_attr_setstack(VCOS_THREAD_ATTR_T *attrs, void *addr, VCOS_UNSIGNED sz);
+-#endif
+-
+-/** Set the stack size. If not set, a default size will be used. Attempting to call this after having
+- * set the stack location with vcos_thread_attr_setstack() will result in undefined behaviour.
+- */
+-VCOS_INLINE_DECL
+-void vcos_thread_attr_setstacksize(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED sz);
+-
+-/** Set the task priority. If not set, a default value will be used.
+- */
+-VCOS_INLINE_DECL
+-void vcos_thread_attr_setpriority(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED pri);
+-
+-/** Set the task cpu affinity. If not set, the default will be used.
+- */
+-VCOS_INLINE_DECL
+-void vcos_thread_attr_setaffinity(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED aff);
+-
+-/** Set the timeslice. If not set the default will be used.
+- */
+-VCOS_INLINE_DECL
+-void vcos_thread_attr_settimeslice(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED ts);
+-
+-/** The thread entry function takes (argc,argv), as per Nucleus, with
+- * argc being 0. This may be withdrawn in a future release and should not
+- * be used in new code.
+- */
+-VCOS_INLINE_DECL
+-void _vcos_thread_attr_setlegacyapi(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED legacy);
+-
+-VCOS_INLINE_DECL
+-void vcos_thread_attr_setautostart(VCOS_THREAD_ATTR_T *attrs, VCOS_UNSIGNED autostart);
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_timer.h b/drivers/misc/vc04_services/interface/vcos/vcos_timer.h
+deleted file mode 100644
+index 1612334..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_timer.h
++++ /dev/null
+@@ -1,106 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - timer support
+-=============================================================================*/
+-
+-#ifndef VCOS_TIMER_H
+-#define VCOS_TIMER_H
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#include "interface/vcos/vcos_types.h"
+-#include "vcos_platform.h"
+-
+-/** \file vcos_timer.h
+- *
+- * Timers are single shot.
+- *
+- * Timer times are in milliseconds.
+- *
+- * \note that timer callback functions are called from an arbitrary thread
+- * context. The expiration function should do its work as quickly as possible;
+- * blocking should be avoided.
+- *
+- * \note On Windows, the separate function vcos_timer_init() must be called
+- * as timer initialization from DllMain is not possible.
+- */
+-
+-/** Perform timer subsystem initialization. This function is not needed
+- * on non-Windows platforms but is still present so that it can be
+- * called. On Windows it is needed because vcos_init() gets called
+- * from DLL initialization where it is not possible to create a
+- * time queue (deadlock occurs if you try).
+- *
+- * @return VCOS_SUCCESS on success. VCOS_EEXIST if this has already been called
+- * once. VCOS_ENOMEM if resource allocation failed.
+- */
+-VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_timer_init(void);
+-
+-/** Create a timer in a disabled state.
+- *
+- * The timer is initially disabled.
+- *
+- * @param timer timer handle
+- * @param name name for timer
+- * @param expiration_routine function to call when timer expires
+- * @param context context passed to expiration routine
+- *
+- */
+-VCOS_INLINE_DECL
+-VCOS_STATUS_T vcos_timer_create(VCOS_TIMER_T *timer,
+- const char *name,
+- void (*expiration_routine)(void *context),
+- void *context);
+-
+-
+-
+-/** Start a timer running.
+- *
+- * Timer must be stopped.
+- *
+- * @param timer timer handle
+- * @param delay Delay to wait for, in ms
+- */
+-VCOS_INLINE_DECL
+-void vcos_timer_set(VCOS_TIMER_T *timer, VCOS_UNSIGNED delay);
+-
+-/** Stop an already running timer.
+- *
+- * @param timer timer handle
+- */
+-VCOS_INLINE_DECL
+-void vcos_timer_cancel(VCOS_TIMER_T *timer);
+-
+-/** Stop a timer and restart it.
+- * @param timer timer handle
+- * @param delay delay in ms
+- */
+-VCOS_INLINE_DECL
+-void vcos_timer_reset(VCOS_TIMER_T *timer, VCOS_UNSIGNED delay);
+-
+-VCOS_INLINE_DECL
+-void vcos_timer_delete(VCOS_TIMER_T *timer);
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-#endif
+diff --git a/drivers/misc/vc04_services/interface/vcos/vcos_types.h b/drivers/misc/vc04_services/interface/vcos/vcos_types.h
+deleted file mode 100644
+index 25de671..0000000
+--- a/drivers/misc/vc04_services/interface/vcos/vcos_types.h
++++ /dev/null
+@@ -1,211 +0,0 @@
+-/*
+- * Copyright (c) 2010-2011 Broadcom. All rights reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-/*=============================================================================
+-VideoCore OS Abstraction Layer - basic types
+-=============================================================================*/
+-
+-#ifndef VCOS_TYPES_H
+-#define VCOS_TYPES_H
+-
+-#define VCOS_VERSION 1
+-
+-#include "vcos_platform_types.h"
+-
+-#if !defined(VCOSPRE_) || !defined(VCOSPOST_)
+-#error VCOSPRE_ and VCOSPOST_ not defined!
+-#endif
+-
+-/* Redefine these here; this means that existing header files can carry on
+- * using the VCHPOST/VCHPRE macros rather than having huge changes, which
+- * could cause nasty merge problems.
+- */
+-#ifndef VCHPOST_
+-#define VCHPOST_ VCOSPOST_
+-#endif
+-#ifndef VCHPRE_
+-#define VCHPRE_ VCOSPRE_
+-#endif
+-
+-/** Entry function for a lowlevel thread.
+- *
+- * Returns void for consistency with Nucleus/ThreadX.
+- */
+-typedef void (*VCOS_LLTHREAD_ENTRY_FN_T)(void *);
+-
+-/** Thread entry point. Returns a void* for consistency
+- * with pthreads.
+- */
+-typedef void *(*VCOS_THREAD_ENTRY_FN_T)(void*);
+-
+-
+-/* Error return codes - chosen to be similar to errno values */
+-typedef enum
+-{
+- VCOS_SUCCESS,
+- VCOS_EAGAIN,
+- VCOS_ENOENT,
+- VCOS_ENOSPC,
+- VCOS_EINVAL,
+- VCOS_EACCESS,
+- VCOS_ENOMEM,
+- VCOS_ENOSYS,
+- VCOS_EEXIST,
+- VCOS_ENXIO,
+- VCOS_EINTR
+-} VCOS_STATUS_T;
+-
+-/* Some compilers (MetaWare) won't inline with -g turned on, which then results
+- * in a lot of code bloat. To overcome this, inline functions are forward declared
+- * with the prefix VCOS_INLINE_DECL, and implemented with the prefix VCOS_INLINE_IMPL.
+- *
+- * That then means that in a release build, "static inline" can be used in the obvious
+- * way, but in a debug build the implementations can be skipped in all but one file,
+- * by using VCOS_INLINE_BODIES.
+- *
+- * VCOS_INLINE_DECL - put this at the start of an inline forward declaration of a VCOS
+- * function.
+- *
+- * VCOS_INLINE_IMPL - put this at the start of an inlined implementation of a VCOS
+- * function.
+- *
+- */
+-
+-/* VCOS_EXPORT - it turns out that in some circumstances we need the implementation of
+- * a function even if it is usually inlined.
+- *
+- * In particular, if we have a codec that is usually provided in object form, if it
+- * was built for a debug build it will be full of calls to vcos_XXX(). If this is used
+- * in a *release* build, then there won't be any of these calls around in the main image
+- * as they will all have been inlined. The problem also exists for vcos functions called
+- * from assembler.
+- *
+- * VCOS_EXPORT ensures that the named function will be emitted as a regular (not static-inline)
+- * function inside vcos_<platform>.c so that it can be linked against. Doing this for every
+- * VCOS function would be a bit code-bloat-tastic, so it is only done for those that need it.
+- *
+- */
+-
+-#ifdef __cplusplus
+-#define _VCOS_INLINE inline
+-#else
+-#define _VCOS_INLINE __inline
+-#endif
+-
+-#if defined(NDEBUG)
+-
+-#ifdef __GNUC__
+-# define VCOS_INLINE_DECL extern __inline__
+-# define VCOS_INLINE_IMPL static __inline__
+-#else
+-# define VCOS_INLINE_DECL static _VCOS_INLINE /* declare a func */
+-# define VCOS_INLINE_IMPL static _VCOS_INLINE /* implement a func inline */
+-#endif
+-
+-# if defined(VCOS_WANT_IMPL)
+-# define VCOS_EXPORT
+-# else
+-# define VCOS_EXPORT VCOS_INLINE_IMPL
+-# endif /* VCOS_WANT_IMPL */
+-
+-#define VCOS_INLINE_BODIES
+-
+-#else /* NDEBUG */
+-
+-#if !defined(VCOS_INLINE_DECL)
+- #define VCOS_INLINE_DECL extern
+-#endif
+-#if !defined(VCOS_INLINE_IMPL)
+- #define VCOS_INLINE_IMPL
+-#endif
+-#define VCOS_EXPORT VCOS_INLINE_IMPL
+-#endif
+-
+-#define VCOS_STATIC_INLINE static _VCOS_INLINE
+-
+-#if defined(__HIGHC__) || defined(__HIGHC_ANSI__)
+-#define _VCOS_METAWARE
+-#endif
+-
+-/** It seems that __FUNCTION__ isn't standard!
+- */
+-#if __STDC_VERSION__ < 199901L
+-# if __GNUC__ >= 2 || defined(__VIDEOCORE__)
+-# define VCOS_FUNCTION __FUNCTION__
+-# else
+-# define VCOS_FUNCTION "<unknown>"
+-# endif
+-#else
+-# define VCOS_FUNCTION __func__
+-#endif
+-
+-#define _VCOS_MS_PER_TICK (1000/VCOS_TICKS_PER_SECOND)
+-
+-/* Convert a number of milliseconds to a tick count. Internal use only - fails to
+- * convert VCOS_SUSPEND correctly.
+- */
+-#define _VCOS_MS_TO_TICKS(ms) (((ms)+_VCOS_MS_PER_TICK-1)/_VCOS_MS_PER_TICK)
+-
+-#define VCOS_TICKS_TO_MS(ticks) ((ticks) * _VCOS_MS_PER_TICK)
+-
+-/** VCOS version of DATESTR, from pcdisk.h. Used by the hostreq service.
+- */
+-typedef struct vcos_datestr
+-{
+- uint8_t cmsec; /**< Centesimal mili second */
+- uint16_t date; /**< Date */
+- uint16_t time; /**< Time */
+-
+-} VCOS_DATESTR;
+-
+-/* Compile-time assert - declares invalid array length if condition
+- * not met, or array of length one if OK.
+- */
+-#define VCOS_CASSERT(e) extern char vcos_compile_time_check[1/(e)]
+-
+-#define vcos_min(x,y) ((x) < (y) ? (x) : (y))
+-#define vcos_max(x,y) ((x) > (y) ? (x) : (y))
+-
+-/** Return the count of an array. FIXME: under gcc we could make
+- * this report an error for pointers using __builtin_types_compatible().
+- */
+-#define vcos_countof(x) (sizeof((x)) / sizeof((x)[0]))
+-
+-/* for backward compatibility */
+-#define countof(x) (sizeof((x)) / sizeof((x)[0]))
+-
+-#define VCOS_ALIGN_DOWN(p,n) (((ptrdiff_t)(p)) & ~((n)-1))
+-#define VCOS_ALIGN_UP(p,n) VCOS_ALIGN_DOWN((ptrdiff_t)(p)+(n)-1,(n))
+-
+-/** bool_t is not a POSIX type so cannot rely on it. Define it here.
+- * It's not even defined in stdbool.h.
+- */
+-typedef int32_t vcos_bool_t;
+-typedef int32_t vcos_fourcc_t;
+-
+-#define VCOS_FALSE 0
+-#define VCOS_TRUE (!VCOS_FALSE)
+-
+-/** Mark unused arguments to keep compilers quiet */
+-#define vcos_unused(x) (void)(x)
+-
+-/** For backward compatibility */
+-typedef vcos_fourcc_t fourcc_t;
+-typedef vcos_fourcc_t FOURCC_T;
+-
+-#endif
+diff --git a/sound/arm/bcm2835-vchiq.c b/sound/arm/bcm2835-vchiq.c
+index 3b7ed1e..14ca707 100755
+--- a/sound/arm/bcm2835-vchiq.c
++++ b/sound/arm/bcm2835-vchiq.c
+@@ -226,6 +226,7 @@ static AUDIO_INSTANCE_T *vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance,
+ /* Open the VCHI service connections */
+ for (i = 0; i < num_connections; i++) {
+ SERVICE_CREATION_T params = {
++ VCHI_VERSION(VC_AUDIOSERV_VER), // version
+ VC_AUDIO_SERVER_NAME, // 4cc service code
+ vchi_connections[i], // passed in fn pointers
+ 0, // rx fifo size (unused)
+diff --git a/sound/arm/vc_vchi_audioserv_defs.h b/sound/arm/vc_vchi_audioserv_defs.h
+index d610734..2020ce4 100644
+--- a/sound/arm/vc_vchi_audioserv_defs.h
++++ b/sound/arm/vc_vchi_audioserv_defs.h
+@@ -15,6 +15,8 @@
+ #ifndef _VC_AUDIO_DEFS_H_
+ #define _VC_AUDIO_DEFS_H_
+
++#define VC_AUDIOSERV_VER 1
++
+ // FourCC code used for VCHI connection
+ #define VC_AUDIO_SERVER_NAME MAKE_FOURCC("AUDS")
+
diff --git a/patches/linux-3.6.7/0156-Add-in-missed-vchiq-files.patch b/patches/linux-3.6.7/0156-Add-in-missed-vchiq-files.patch
new file mode 100644
index 0000000..2f9e1a4
--- /dev/null
+++ b/patches/linux-3.6.7/0156-Add-in-missed-vchiq-files.patch
@@ -0,0 +1,398 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Fri, 5 Oct 2012 17:44:36 +0100
+Subject: [PATCH] Add in missed vchiq files
+
+---
+ .../interface/vchiq_arm/vchiq_build_info.h | 22 ++
+ .../interface/vchiq_arm/vchiq_genversion | 87 ++++++++
+ .../vc04_services/interface/vchiq_arm/vchiq_proc.c | 223 +++++++++++++++++++++
+ .../interface/vchiq_arm/vchiq_version.c | 27 +++
+ 4 files changed, 359 insertions(+)
+ create mode 100644 drivers/misc/vc04_services/interface/vchiq_arm/vchiq_build_info.h
+ create mode 100644 drivers/misc/vc04_services/interface/vchiq_arm/vchiq_genversion
+ create mode 100644 drivers/misc/vc04_services/interface/vchiq_arm/vchiq_proc.c
+ create mode 100644 drivers/misc/vc04_services/interface/vchiq_arm/vchiq_version.c
+
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_build_info.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_build_info.h
+new file mode 100644
+index 0000000..7c3ab94
+--- /dev/null
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_build_info.h
+@@ -0,0 +1,22 @@
++/*
++ * Copyright (c) 2010-2011 Broadcom. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++const char *vchiq_get_build_hostname(void);
++const char *vchiq_get_build_version(void);
++const char *vchiq_get_build_time(void);
++const char *vchiq_get_build_date(void);
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_genversion b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_genversion
+new file mode 100644
+index 0000000..9f5b634
+--- /dev/null
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_genversion
+@@ -0,0 +1,87 @@
++#!/usr/bin/perl -w
++
++use strict;
++
++#
++# Generate a version from available information
++#
++
++my $prefix = shift @ARGV;
++my $root = shift @ARGV;
++
++
++if ( not defined $root ) {
++ die "usage: $0 prefix root-dir\n";
++}
++
++if ( ! -d $root ) {
++ die "root directory $root not found\n";
++}
++
++my $version = "unknown";
++my $tainted = "";
++
++if ( -d "$root/.git" ) {
++ # attempt to work out git version. only do so
++ # on a linux build host, as cygwin builds are
++ # already slow enough
++
++ if ( -f "/usr/bin/git" || -f "/usr/local/bin/git" ) {
++ if (not open(F, "git --git-dir $root/.git rev-parse --verify HEAD|")) {
++ $version = "no git version";
++ }
++ else {
++ $version = <F>;
++ $version =~ s/[ \r\n]*$//; # chomp may not be enough (cygwin).
++ $version =~ s/^[ \r\n]*//; # chomp may not be enough (cygwin).
++ }
++
++ if (open(G, "git --git-dir $root/.git status --porcelain|")) {
++ $tainted = <G>;
++ $tainted =~ s/[ \r\n]*$//; # chomp may not be enough (cygwin).
++ $tainted =~ s/^[ \r\n]*//; # chomp may not be enough (cygwin).
++ if (length $tainted) {
++ $version = join ' ', $version, "(tainted)";
++ }
++ else {
++ $version = join ' ', $version, "(clean)";
++ }
++ }
++ }
++}
++
++my $hostname = `hostname`;
++$hostname =~ s/[ \r\n]*$//; # chomp may not be enough (cygwin).
++$hostname =~ s/^[ \r\n]*//; # chomp may not be enough (cygwin).
++
++
++print STDERR "Version $version\n";
++print <<EOF;
++#include "${prefix}_build_info.h"
++#include <linux/broadcom/vc_debug_sym.h>
++
++VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_hostname, "$hostname" );
++VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_version, "$version" );
++VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_time, __TIME__ );
++VC_DEBUG_DECLARE_STRING_VAR( ${prefix}_build_date, __DATE__ );
++
++const char *vchiq_get_build_hostname( void )
++{
++ return vchiq_build_hostname;
++}
++
++const char *vchiq_get_build_version( void )
++{
++ return vchiq_build_version;
++}
++
++const char *vchiq_get_build_date( void )
++{
++ return vchiq_build_date;
++}
++
++const char *vchiq_get_build_time( void )
++{
++ return vchiq_build_time;
++}
++EOF
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_proc.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_proc.c
+new file mode 100644
+index 0000000..6e06c3b
+--- /dev/null
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_proc.c
+@@ -0,0 +1,223 @@
++/*
++ * Copyright (c) 2012 Broadcom Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++
++#include <linux/proc_fs.h>
++#include "vchiq_core.h"
++#include "vchiq_arm.h"
++
++struct vchiq_proc_info {
++ /* Global 'vc' proc entry used by all instances */
++ struct proc_dir_entry *vc_cfg_dir;
++
++ /* one entry per client process */
++ struct proc_dir_entry *clients;
++
++ /* log categories */
++ struct proc_dir_entry *log_categories;
++};
++
++static struct vchiq_proc_info proc_info;
++
++struct proc_dir_entry *vchiq_proc_top(void)
++{
++ BUG_ON(proc_info.vc_cfg_dir == NULL);
++ return proc_info.vc_cfg_dir;
++}
++
++/****************************************************************************
++*
++* log category entries
++*
++***************************************************************************/
++#define PROC_WRITE_BUF_SIZE 256
++
++#define VCHIQ_LOG_ERROR_STR "error"
++#define VCHIQ_LOG_WARNING_STR "warning"
++#define VCHIQ_LOG_INFO_STR "info"
++#define VCHIQ_LOG_TRACE_STR "trace"
++
++static int log_cfg_read(char *buffer,
++ char **start,
++ off_t off,
++ int count,
++ int *eof,
++ void *data)
++{
++ int len = 0;
++ char *log_value = NULL;
++
++ switch (*((int *)data)) {
++ case VCHIQ_LOG_ERROR:
++ log_value = VCHIQ_LOG_ERROR_STR;
++ break;
++ case VCHIQ_LOG_WARNING:
++ log_value = VCHIQ_LOG_WARNING_STR;
++ break;
++ case VCHIQ_LOG_INFO:
++ log_value = VCHIQ_LOG_INFO_STR;
++ break;
++ case VCHIQ_LOG_TRACE:
++ log_value = VCHIQ_LOG_TRACE_STR;
++ break;
++ default:
++ break;
++ }
++
++ len += sprintf(buffer + len,
++ "%s\n",
++ log_value ? log_value : "(null)");
++
++ return len;
++}
++
++
++static int log_cfg_write(struct file *file,
++ const char __user *buffer,
++ unsigned long count,
++ void *data)
++{
++ int *log_module = data;
++ char kbuf[PROC_WRITE_BUF_SIZE + 1];
++
++ (void)file;
++
++ memset(kbuf, 0, PROC_WRITE_BUF_SIZE + 1);
++ if (count >= PROC_WRITE_BUF_SIZE)
++ count = PROC_WRITE_BUF_SIZE;
++
++ if (copy_from_user(kbuf,
++ buffer,
++ count) != 0)
++ return -EFAULT;
++ kbuf[count - 1] = 0;
++
++ if (strncmp("error", kbuf, strlen("error")) == 0)
++ *log_module = VCHIQ_LOG_ERROR;
++ else if (strncmp("warning", kbuf, strlen("warning")) == 0)
++ *log_module = VCHIQ_LOG_WARNING;
++ else if (strncmp("info", kbuf, strlen("info")) == 0)
++ *log_module = VCHIQ_LOG_INFO;
++ else if (strncmp("trace", kbuf, strlen("trace")) == 0)
++ *log_module = VCHIQ_LOG_TRACE;
++ else
++ *log_module = VCHIQ_LOG_DEFAULT;
++
++ return count;
++}
++
++/* Log category proc entries */
++struct vchiq_proc_log_entry {
++ const char *name;
++ int *plevel;
++ struct proc_dir_entry *dir;
++};
++
++static struct vchiq_proc_log_entry vchiq_proc_log_entries[] = {
++ { "core", &vchiq_core_log_level },
++ { "msg", &vchiq_core_msg_log_level },
++ { "sync", &vchiq_sync_log_level },
++ { "arm", &vchiq_arm_log_level },
++};
++static int n_log_entries =
++ sizeof(vchiq_proc_log_entries)/sizeof(vchiq_proc_log_entries[0]);
++
++/* create an entry under /proc/vc/log for each log category */
++static int vchiq_proc_create_log_entries(struct proc_dir_entry *top)
++{
++ struct proc_dir_entry *dir;
++ size_t i;
++ int ret = 0;
++
++ dir = proc_mkdir("log", proc_info.vc_cfg_dir);
++ if (!dir)
++ return -ENOMEM;
++ proc_info.log_categories = dir;
++
++ for (i = 0; i < n_log_entries; i++) {
++ dir = create_proc_entry(vchiq_proc_log_entries[i].name,
++ 0644,
++ proc_info.log_categories);
++ if (!dir) {
++ ret = -ENOMEM;
++ break;
++ }
++
++ dir->read_proc = &log_cfg_read;
++ dir->write_proc = &log_cfg_write;
++ dir->data = (void *)vchiq_proc_log_entries[i].plevel;
++
++ vchiq_proc_log_entries[i].dir = dir;
++ }
++ return ret;
++}
++
++
++int vchiq_proc_init(void)
++{
++ BUG_ON(proc_info.vc_cfg_dir != NULL);
++
++ proc_info.vc_cfg_dir = proc_mkdir("vc", NULL);
++ if (proc_info.vc_cfg_dir == NULL)
++ goto fail;
++
++ proc_info.clients = proc_mkdir("clients",
++ proc_info.vc_cfg_dir);
++ if (!proc_info.clients)
++ goto fail;
++
++ if (vchiq_proc_create_log_entries(proc_info.vc_cfg_dir) != 0)
++ goto fail;
++
++ return 0;
++
++fail:
++ vchiq_proc_deinit();
++ vchiq_log_error(vchiq_arm_log_level,
++ "%s: failed to create proc directory",
++ __func__);
++
++ return -ENOMEM;
++}
++
++/* remove all the proc entries */
++void vchiq_proc_deinit(void)
++{
++ /* log category entries */
++ if (proc_info.log_categories) {
++ size_t i;
++ for (i = 0; i < n_log_entries; i++)
++ if (vchiq_proc_log_entries[i].dir)
++ remove_proc_entry(
++ vchiq_proc_log_entries[i].name,
++ proc_info.log_categories);
++
++ remove_proc_entry(proc_info.log_categories->name,
++ proc_info.vc_cfg_dir);
++ }
++ if (proc_info.clients)
++ remove_proc_entry(proc_info.clients->name,
++ proc_info.vc_cfg_dir);
++ if (proc_info.vc_cfg_dir)
++ remove_proc_entry(proc_info.vc_cfg_dir->name, NULL);
++}
++
++struct proc_dir_entry *vchiq_clients_top(void)
++{
++ return proc_info.clients;
++}
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_version.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_version.c
+new file mode 100644
+index 0000000..87bea8b
+--- /dev/null
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_version.c
+@@ -0,0 +1,27 @@
++#include "vchiq_build_info.h"
++#include <linux/broadcom/vc_debug_sym.h>
++
++VC_DEBUG_DECLARE_STRING_VAR( vchiq_build_hostname, "dc4-arm-01" );
++VC_DEBUG_DECLARE_STRING_VAR( vchiq_build_version, "9245b4c35b99b3870e1f7dc598c5692b3c66a6f0 (tainted)" );
++VC_DEBUG_DECLARE_STRING_VAR( vchiq_build_time, __TIME__ );
++VC_DEBUG_DECLARE_STRING_VAR( vchiq_build_date, __DATE__ );
++
++const char *vchiq_get_build_hostname( void )
++{
++ return vchiq_build_hostname;
++}
++
++const char *vchiq_get_build_version( void )
++{
++ return vchiq_build_version;
++}
++
++const char *vchiq_get_build_date( void )
++{
++ return vchiq_build_date;
++}
++
++const char *vchiq_get_build_time( void )
++{
++ return vchiq_build_time;
++}
diff --git a/patches/linux-3.6.7/0157-Make-vchiq-enabled-by-default.-Tidy-Kconfig-file.patch b/patches/linux-3.6.7/0157-Make-vchiq-enabled-by-default.-Tidy-Kconfig-file.patch
new file mode 100644
index 0000000..2993506
--- /dev/null
+++ b/patches/linux-3.6.7/0157-Make-vchiq-enabled-by-default.-Tidy-Kconfig-file.patch
@@ -0,0 +1,119 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Fri, 5 Oct 2012 22:30:10 +0100
+Subject: [PATCH] Make vchiq enabled by default. Tidy Kconfig file.
+
+---
+ drivers/misc/vc04_services/Kconfig | 2 +-
+ drivers/misc/vc04_services/Makefile | 83 -------------------------------------
+ 2 files changed, 1 insertion(+), 84 deletions(-)
+
+diff --git a/drivers/misc/vc04_services/Kconfig b/drivers/misc/vc04_services/Kconfig
+index ff83aaa..b48a3f3 100644
+--- a/drivers/misc/vc04_services/Kconfig
++++ b/drivers/misc/vc04_services/Kconfig
+@@ -1,7 +1,7 @@
+ config BCM2708_VCHIQ
+ tristate "Videocore VCHIQ"
+ depends on MACH_BCM2708
+- default CONFIG_BCM_VC_SERVICES
++ default y
+ help
+ Kernel to VideoCore communication interface for the
+ BCM2708 family of products.
+diff --git a/drivers/misc/vc04_services/Makefile b/drivers/misc/vc04_services/Makefile
+index 85b6ba3..1aeb20a 100644
+--- a/drivers/misc/vc04_services/Makefile
++++ b/drivers/misc/vc04_services/Makefile
+@@ -1,11 +1,5 @@
+ ifeq ($(CONFIG_MACH_BCM2708),y)
+
+-##############################################################################
+-#
+-# This section is for building the RaspberryPi model
+-#
+-##############################################################################
+-
+ obj-$(CONFIG_BCM2708_VCHIQ) += vchiq.o
+
+ vchiq-objs := \
+@@ -22,80 +16,3 @@ EXTRA_CFLAGS += -DVCOS_VERIFY_BKPTS=1 -Idrivers/misc/vc04_services -DUSE_VCHIQ_A
+
+ endif
+
+-ifeq ($(CONFIG_ARCH_KONA),y)
+-
+-##############################################################################
+-#
+-# This section is for building the Capri/Island model
+-#
+-##############################################################################
+-
+-# Remove the quotes from the platform config name
+-VCHIQ_PLATFORM_CONFIG = $(patsubst "%",%,$(CONFIG_VCHIQ_PLATFORM_CFG_NAME))
+-
+-$(info VCHIQ_PLATFORM_CONFIG = $(VCHIQ_PLATFORM_CONFIG))
+-include $(srctree)/drivers/misc/vc04_services/interface/vchiq_arm/platform-cfg/$(VCHIQ_PLATFORM_CONFIG).mk
+-
+-$(info Building for MAP build system)
+-$(info CONFIG_ARCH_KONA = $(CONFIG_ARCH_KONA))
+-
+-EXTRA_CFLAGS += -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -Wno-declaration-after-statement -Wno-parentheses
+-
+-EXTRA_CFLAGS += -I"drivers/misc/vc04_services/"
+-EXTRA_CFLAGS += -I"drivers/misc/vc04_services/interface/vchiq_arm"
+-EXTRA_CFLAGS += -I"drivers/misc/vc04_services/interface/debug_sym"
+-EXTRA_CFLAGS += -I"include/linux/broadcom"
+-
+-EXTRA_CFLAGS += -Werror
+-
+-VCHIQ_HOST_BUS_ALIGNMENT = 3
+-
+-EXTRA_CFLAGS += -DOS_ASSERT_FAILURE
+-EXTRA_CFLAGS += -D__STDC_VERSION=199901L
+-EXTRA_CFLAGS += -D__STDC_VERSION__=199901L
+-EXTRA_CFLAGS += -D__VCCOREVER__=0
+-EXTRA_CFLAGS += -D__linux__
+-EXTRA_CFLAGS += -D__KERNEL__
+-EXTRA_CFLAGS += -DVCHIQ_HOST_BUS_ALIGNMENT=$(VCHIQ_HOST_BUS_ALIGNMENT)
+-EXTRA_CFLAGS += -DVCHIQ_SLOT_PADDING=16
+-EXTRA_CFLAGS += -DVCHIQ_ARM_SIDE
+-EXTRA_CFLAGS += -DUSE_VCHIQ_ARM
+-ifeq ($(VCHIQ_SM_ALLOC),vcddr)
+-EXTRA_CFLAGS += -DVCHIQ_SM_ALLOC_VCDDR
+-endif
+-
+-obj-$(CONFIG_KONA_VCHIQ) += vc-vchiq.o
+-vc-vchiq-objs := \
+- interface/vchiq_arm/vchiq_arm.o \
+- interface/vchiq_arm/vchiq_connected.o \
+- interface/vchiq_arm/vchiq_core.o \
+- interface/vchiq_arm/vchiq_kern_lib.o \
+- interface/vchiq_arm/vchiq_shim.o \
+- interface/vchiq_arm/vchiq_util.o \
+- interface/vchiq_arm/vchiq_kona_arm.o \
+- interface/vchiq_arm/vchiq_$(VCHIQ_PLATFORM)_arm.o \
+- interface/vchiq_arm/vchiq_version.o \
+- interface/vchiq_arm/vchiq_proc.o
+-ifeq ($(VCHIQ_SM_ALLOC),vcddr)
+-vc-vchiq-objs += \
+- interface/debug_sym/debug_sym.o
+-endif
+-
+-obj-$(CONFIG_KONA_VCHIQ_MEMDRV) += vc-vchiq-memdrv-kona.o
+-vc-vchiq-memdrv-kona-objs := \
+- interface/vchiq_arm/vchiq_memdrv_kona.o
+-
+-genversion = drivers/misc/vc04_services/interface/vchiq_arm/vchiq_genversion
+-
+-GENVERSION_SRC_ROOT_DIR = .
+-ifeq ($(CONFIG_ANDROID),y)
+-GENVERSION_SRC_ROOT_DIR = $(srctree)
+-endif
+-
+-$(obj)/interface/vchiq_arm/vchiq_version.c: $(genversion) FORCE
+- echo "(new) Generating $@ ..."
+- perl $(srctree)/$(genversion) vchiq $(GENVERSION_SRC_ROOT_DIR) > $@
+-
+-clean-files := vchiq_version.c
+-
+-endif
diff --git a/patches/linux-3.6.7/0158-Support-dummy-vc-mem-ioctl-used-by-vcdbg.patch b/patches/linux-3.6.7/0158-Support-dummy-vc-mem-ioctl-used-by-vcdbg.patch
new file mode 100644
index 0000000..7549236
--- /dev/null
+++ b/patches/linux-3.6.7/0158-Support-dummy-vc-mem-ioctl-used-by-vcdbg.patch
@@ -0,0 +1,46 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Fri, 5 Oct 2012 22:44:47 +0100
+Subject: [PATCH] Support dummy vc-mem ioctl used by vcdbg
+
+---
+ arch/arm/mach-bcm2708/include/mach/vc_mem.h | 1 +
+ arch/arm/mach-bcm2708/vc_mem.c | 14 ++++++++++++++
+ 2 files changed, 15 insertions(+)
+
+diff --git a/arch/arm/mach-bcm2708/include/mach/vc_mem.h b/arch/arm/mach-bcm2708/include/mach/vc_mem.h
+index 9d41c3a..d29125b 100644
+--- a/arch/arm/mach-bcm2708/include/mach/vc_mem.h
++++ b/arch/arm/mach-bcm2708/include/mach/vc_mem.h
+@@ -22,6 +22,7 @@
+ #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
+diff --git a/arch/arm/mach-bcm2708/vc_mem.c b/arch/arm/mach-bcm2708/vc_mem.c
+index 5c56b31..f12cb49 100644
+--- a/arch/arm/mach-bcm2708/vc_mem.c
++++ b/arch/arm/mach-bcm2708/vc_mem.c
+@@ -208,6 +208,20 @@ vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ }
+ break;
+ }
++ case VC_MEM_IOC_MEM_LOAD:
++ {
++ // Get the videocore memory base
++ vc_mem_get_base();
++
++ LOG_DBG("%s: VC_MEM_IOC_MEM_LOAD=%u", __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;
diff --git a/patches/linux-3.6.7/0159-Remove-BUG-call-from-vchiq-that-is-trigger-when-alsa.patch b/patches/linux-3.6.7/0159-Remove-BUG-call-from-vchiq-that-is-trigger-when-alsa.patch
new file mode 100644
index 0000000..d6794cd
--- /dev/null
+++ b/patches/linux-3.6.7/0159-Remove-BUG-call-from-vchiq-that-is-trigger-when-alsa.patch
@@ -0,0 +1,22 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Sat, 6 Oct 2012 16:18:27 +0100
+Subject: [PATCH] Remove BUG() call from vchiq that is trigger when alsa is
+ killed
+
+---
+ drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
+index 0b84988..b8675d8 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
+@@ -3180,7 +3180,7 @@ vchiq_bulk_transmit(VCHIQ_SERVICE_HANDLE_T handle, const void *data, int size,
+ mode, VCHIQ_BULK_TRANSMIT);
+
+ /* This call is for kernel thread use and should not be interrupted */
+- BUG_ON(status == VCHIQ_RETRY);
++ // dc4: remove as it does happen: BUG_ON(status == VCHIQ_RETRY);
+ return status;
+ }
+
diff --git a/patches/linux-3.6.7/0160-Fix-up-issues-with-rebase.patch b/patches/linux-3.6.7/0160-Fix-up-issues-with-rebase.patch
new file mode 100644
index 0000000..a689c59
--- /dev/null
+++ b/patches/linux-3.6.7/0160-Fix-up-issues-with-rebase.patch
@@ -0,0 +1,2470 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Sat, 13 Oct 2012 22:44:27 +0100
+Subject: [PATCH] Fix up issues with rebase
+
+---
+ arch/arm/lib/Makefile | 3 +-
+ arch/arm/mach-bcm2708/Kconfig | 2 +
+ arch/arm/mach-bcm2708/armctrl.c | 191 +----
+ arch/arm/mach-bcm2708/bcm2708.c | 94 ++-
+ arch/arm/mach-bcm2708/delay.S | 6 +-
+ arch/arm/mach-bcm2708/include/mach/memory.h | 7 -
+ arch/arm/tools/mach-types | 1 +
+ .../vc04_services/interface/vchiq_arm/vchiq_core.c | 193 +----
+ .../interface/vchiq_arm/vchiq_kern_lib.c | 185 ++++-
+ drivers/mmc/host/Kconfig | 8 -
+ drivers/mmc/host/Makefile | 1 -
+ drivers/mmc/host/bcm2708_mci.c | 889 ---------------------
+ drivers/mmc/host/bcm2708_mci.h | 101 ---
+ drivers/mmc/host/sdhci-bcm2708.c | 131 +--
+ drivers/mmc/host/sdhci.c | 44 -
+ drivers/mmc/host/sdhci.h | 5 -
+ drivers/thermal/bcm2835-thermal.c | 2 +-
+ drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c | 4 +-
+ sound/arm/Kconfig | 2 +-
+ 19 files changed, 278 insertions(+), 1591 deletions(-)
+ delete mode 100644 drivers/mmc/host/bcm2708_mci.c
+ delete mode 100644 drivers/mmc/host/bcm2708_mci.h
+
+diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
+index 0ade0ac..af72969 100644
+--- a/arch/arm/lib/Makefile
++++ b/arch/arm/lib/Makefile
+@@ -6,9 +6,8 @@
+
+ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
+ csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
+- delay.o findbit.o memchr.o memcpy.o \
++ delay.o delay-loop.o findbit.o memchr.o memcpy.o \
+ memmove.o memset.o memzero.o setbit.o \
+- strncpy_from_user.o strnlen_user.o \
+ strchr.o strrchr.o \
+ testchangebit.o testclearbit.o testsetbit.o \
+ ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
+diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig
+index 5593167..63bb76c 100644
+--- a/arch/arm/mach-bcm2708/Kconfig
++++ b/arch/arm/mach-bcm2708/Kconfig
+@@ -3,6 +3,8 @@ menu "Broadcom BCM2708 Implementations"
+
+ 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.
+diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c
+index cdaa761..f22fbba 100644
+--- a/arch/arm/mach-bcm2708/armctrl.c
++++ b/arch/arm/mach-bcm2708/armctrl.c
+@@ -21,11 +21,7 @@
+ #include <linux/list.h>
+ #include <linux/io.h>
+ #include <linux/version.h>
+-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39)
+ #include <linux/syscore_ops.h>
+-#else
+-#include <linux/sysdev.h>
+-#endif
+ #include <linux/interrupt.h>
+
+ #include <asm/mach/irq.h>
+@@ -47,11 +43,7 @@ static unsigned int remap_irqs[(INTERRUPT_ARASANSDIO + 1) - INTERRUPT_JPEG] = {
+ INTERRUPT_VC_ARASANSDIO
+ };
+
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+ static void armctrl_mask_irq(struct irq_data *d)
+-#else
+-static void armctrl_mask_irq(unsigned int irq)
+-#endif
+ {
+ static const unsigned int disables[4] = {
+ IO_ADDRESS(ARM_IRQ_DIBL1),
+@@ -66,20 +58,12 @@ static void armctrl_mask_irq(unsigned int irq)
+ }
+ else
+ {
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+ unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
+-#else
+- unsigned int data = (unsigned int)get_irq_chip_data(irq);
+-#endif
+ writel(1 << (data & 0x1f), __io(disables[(data >> 5) & 0x3]));
+ }
+ }
+
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+ static void armctrl_unmask_irq(struct irq_data *d)
+-#else
+-static void armctrl_unmask_irq(unsigned int irq)
+-#endif
+ {
+ static const unsigned int enables[4] = {
+ IO_ADDRESS(ARM_IRQ_ENBL1),
+@@ -95,11 +79,7 @@ static void armctrl_unmask_irq(unsigned int irq)
+ }
+ else
+ {
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+ unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
+-#else
+- unsigned int data = (unsigned int)get_irq_chip_data(irq);
+-#endif
+ writel(1 << (data & 0x1f), __io(enables[(data >> 5) & 0x3]));
+ }
+ }
+@@ -120,12 +100,7 @@ static void armctrl_unmask_irq(unsigned int irq)
+ * @soft_int: Save for VIC_INT_SOFT.
+ * @protect: Save for VIC_PROTECT.
+ */
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)
+-struct armctrl_device {
+- struct sys_device sysdev;
+-#else
+ struct armctrl_info {
+-#endif
+ void __iomem *base;
+ int irq;
+ u32 resume_sources;
+@@ -134,75 +109,8 @@ struct armctrl_device {
+ u32 int_enable;
+ u32 soft_int;
+ u32 protect;
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)
+-};
+-#else
+ } armctrl;
+-#endif
+-
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)
+-
+-static struct armctrl_device armctrl_devices[1];
+-
+-static inline struct armctrl_device *to_vic(struct sys_device *sys)
+-{
+- return container_of(sys, struct armctrl_device, sysdev);
+-}
+-
+-static int armctrl_id;
+-
+-static int armctrl_class_resume(struct sys_device *dev)
+-{
+-#if 0 // FIXME
+- struct armctrl_device *armctrl = to_vic(dev);
+- void __iomem *base = armctrl->base;
+-
+- printk(KERN_DEBUG "%s: resuming armctrl at %p\n", __func__, base);
+
+- writel(armctrl->int_select, base + VIC_INT_SELECT);
+- writel(armctrl->protect, base + VIC_PROTECT);
+-
+- /* set the enabled ints and then clear the non-enabled */
+- writel(armctrl->int_enable, base + VIC_INT_ENABLE);
+- writel(~armctrl->int_enable, base + VIC_INT_ENABLE_CLEAR);
+-
+- /* and the same for the soft-int register */
+-
+- writel(armctrl->soft_int, base + VIC_INT_SOFT);
+- writel(~armctrl->soft_int, base + VIC_INT_SOFT_CLEAR);
+-#endif
+- return 0;
+-}
+-
+-static int armctrl_class_suspend(struct sys_device *dev, pm_message_t state)
+-{
+-#if 0 // FIXME
+- struct armctrl_device *armctrl = to_vic(dev);
+- void __iomem *base = armctrl->base;
+-
+- printk(KERN_DEBUG "%s: suspending armctrl at %p\n", __func__, base);
+-
+- armctrl->int_select = readl(base + VIC_INT_SELECT);
+- armctrl->int_enable = readl(base + VIC_INT_ENABLE);
+- armctrl->soft_int = readl(base + VIC_INT_SOFT);
+- armctrl->protect = readl(base + VIC_PROTECT);
+-
+- /* set the interrupts (if any) that are used for
+- * resuming the system */
+-
+- writel(armctrl->resume_irqs, base + VIC_INT_ENABLE);
+- writel(~armctrl->resume_irqs, base + VIC_INT_ENABLE_CLEAR);
+-#endif
+- return 0;
+-}
+-
+-struct sysdev_class armctrl_class = {
+- .name = "armctrl",
+- .suspend = armctrl_class_suspend,
+- .resume = armctrl_class_resume,
+-};
+-
+-#endif // < 2.6.39
+
+ static int armctrl_suspend(void)
+ {
+@@ -229,98 +137,16 @@ static void armctrl_resume(void)
+ static void __init armctrl_pm_register(void __iomem * base, unsigned int irq,
+ u32 resume_sources)
+ {
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)
+- struct armctrl_device *v;
+-
+- if (armctrl_id >= ARRAY_SIZE(armctrl_devices))
+- printk(KERN_ERR
+- "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n",
+- __func__);
+- else {
+- v = &armctrl_devices[armctrl_id];
+- v->base = base;
+- v->resume_sources = resume_sources;
+- v->irq = irq;
+- armctrl_id++;
+- }
+-#else
+ armctrl.base = base;
+ armctrl.resume_sources = resume_sources;
+ armctrl.irq = irq;
+-#endif
+ }
+
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)
+-
+-/**
+- * armctrl_pm_init - initicall to register VIC pm
+- *
+- * 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_pm_init(void)
+-{
+- struct armctrl_device *dev = armctrl_devices;
+- int err;
+- int id;
+-
+- if (armctrl_id == 0)
+- return 0;
+-
+- err = sysdev_class_register(&armctrl_class);
+- if (err) {
+- printk(KERN_ERR "%s: cannot register class\n", __func__);
+- return err;
+- }
+-
+- for (id = 0; id < armctrl_id; id++, dev++) {
+- dev->sysdev.id = id;
+- dev->sysdev.cls = &armctrl_class;
+-
+- err = sysdev_register(&dev->sysdev);
+- if (err) {
+- printk(KERN_ERR "%s: failed to register device\n",
+- __func__);
+- return err;
+- }
+- }
+-
+- return 0;
+-}
+-
+-late_initcall(armctrl_pm_init);
+-
+-#endif // VERSION check
+-
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+ static int armctrl_set_wake(struct irq_data *d, unsigned int on)
+-#else
+-static int armctrl_set_wake(unsigned int irq, unsigned int on)
+-#endif
+ {
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)
+- struct armctrl_device *armctrl = &armctrl_devices[0];
+-#endif
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+ unsigned int off = d->irq & 31;
+-#else
+- unsigned int off = irq & 31;
+-#endif
+ u32 bit = 1 << off;
+
+-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)
+- if (!armctrl)
+- return -EINVAL;
+-
+- if (!(bit & armctrl->resume_sources))
+- return -EINVAL;
+-
+- if (on)
+- armctrl->resume_irqs |= bit;
+- else
+- armctrl->resume_irqs &= ~bit;
+-#else
+ if (!(bit & armctrl.resume_sources))
+ return -EINVAL;
+
+@@ -328,7 +154,6 @@ static int armctrl_set_wake(unsigned int irq, unsigned int on)
+ armctrl.resume_irqs |= bit;
+ else
+ armctrl.resume_irqs &= ~bit;
+-#endif
+
+ return 0;
+ }
+@@ -343,7 +168,6 @@ static inline void armctrl_pm_register(void __iomem *base, unsigned int irq,
+ #define armctrl_set_wake NULL
+ #endif /* CONFIG_PM */
+
+-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39)
+
+ static struct syscore_ops armctrl_syscore_ops = {
+ .suspend = armctrl_suspend,
+@@ -365,21 +189,13 @@ static int __init armctrl_syscore_init(void)
+
+ late_initcall(armctrl_syscore_init);
+
+-#endif
+
+ static struct irq_chip armctrl_chip = {
+ .name = "ARMCTRL",
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+ .irq_ack = armctrl_mask_irq,
+ .irq_mask = armctrl_mask_irq,
+ .irq_unmask = armctrl_unmask_irq,
+ .irq_set_wake = armctrl_set_wake,
+-#else
+- .ack = armctrl_mask_irq,
+- .mask = armctrl_mask_irq,
+- .unmask = armctrl_unmask_irq,
+- .set_wake = armctrl_set_wake,
+-#endif
+ };
+
+ /**
+@@ -399,18 +215,13 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start,
+ if (irq >= INTERRUPT_JPEG && irq <= INTERRUPT_ARASANSDIO)
+ data = remap_irqs[irq - INTERRUPT_JPEG];
+
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+ irq_set_chip(irq, &armctrl_chip);
+ irq_set_chip_data(irq, (void *)data);
+ irq_set_handler(irq, handle_level_irq);
+-#else
+- set_irq_chip(irq, &armctrl_chip);
+- set_irq_chip_data(irq, (void *)data);
+- set_irq_handler(irq, handle_level_irq);
+-#endif
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_DISABLED);
+ }
+
+ armctrl_pm_register(base, irq_start, resume_sources);
++ init_FIQ(FIQ_START);
+ return 0;
+ }
+diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
+index 93fb75d..02cb556 100644
+--- a/arch/arm/mach-bcm2708/bcm2708.c
++++ b/arch/arm/mach-bcm2708/bcm2708.c
+@@ -54,6 +54,8 @@
+ #include <mach/vcio.h>
+ #include <mach/system.h>
+
++#include <linux/delay.h>
++
+ #include "bcm2708.h"
+ #include "armctrl.h"
+ #include "clock.h"
+@@ -73,8 +75,6 @@
+ // use GPIO 4 for the one-wire GPIO pin, if enabled
+ #define W1_GPIO 4
+
+-static DEFINE_CLOCK_DATA(cd);
+-
+ /* command line parameters */
+ static unsigned boardrev, serial;
+ static unsigned uart_clock;
+@@ -149,30 +149,43 @@ void __init bcm2708_map_io(void)
+ /* The STC is a free running counter that increments at the rate of 1MHz */
+ #define STC_FREQ_HZ 1000000
+
+-/*
+- * Constants generated by clocks_calc_mult_shift(m, s, 1MHz, NSEC_PER_SEC, 60).
+- * This gives a resolution of about 1us and a wrap period of about 1h11min.
+- */
+-#define SC_MULT 4194304000u
+-#define SC_SHIFT 22
+-
+-static cycle_t stc_read_cycles(struct clocksource *cs)
++static inline uint32_t timer_read(void)
+ {
+ /* STC: a free running counter that increments at the rate of 1MHz */
+- return (cycle_t) readl(__io_address(ST_BASE + 0x04));
++ return readl(__io_address(ST_BASE + 0x04));
++}
++
++int read_current_timer(unsigned long *timer_val)
++{
++ *timer_val = timer_read();
++ return 0;
++}
++
++#ifdef CONFIG_ARM_ARCH_TIMER
++EXPORT_SYMBOL(read_current_timer);
++#endif
++
++static u32 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 = stc_read_cycles,
++ .read = clksrc_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ };
+
+ unsigned long frc_clock_ticks32(void)
+ {
+- return (unsigned long)stc_read_cycles(&clocksource_stc);
++ return timer_read();
+ }
+
+ static void __init bcm2708_clocksource_init(void)
+@@ -183,18 +196,6 @@ static void __init bcm2708_clocksource_init(void)
+ }
+ }
+
+-unsigned long long sched_clock(void)
+-{
+- u32 cyc = clocksource_stc.read(&clocksource_stc);
+- return cyc_to_fixed_sched_clock(&cd, cyc, clocksource_stc.mask,
+- SC_MULT, SC_SHIFT);
+-}
+-
+-static void notrace bcm2708_update_sched_clock(void)
+-{
+- u32 cyc = clocksource_stc.read(&clocksource_stc);
+- update_sched_clock(&cd, cyc, clocksource_stc.mask);
+-}
+
+ /*
+ * These are fixed clocks.
+@@ -247,7 +248,7 @@ static struct clk_lookup lookups[] = {
+ }
+ };
+
+-#define UART0_IRQ { IRQ_UART, NO_IRQ }
++#define UART0_IRQ { IRQ_UART, 0 /*NO_IRQ*/ }
+ #define UART0_DMA { 15, 14 }
+
+ AMBA_DEVICE(uart0, "dev:f1", UART0, NULL);
+@@ -580,6 +581,7 @@ static struct platform_device bcm2708_spi_device = {
+ .resource = bcm2708_spi_resources,
+ };
+
++#ifdef CONFIG_SPI
+ static struct spi_board_info bcm2708_spi_devices[] = {
+ {
+ .modalias = "spidev",
+@@ -595,6 +597,7 @@ static struct spi_board_info bcm2708_spi_devices[] = {
+ .mode = SPI_MODE_0,
+ }
+ };
++#endif
+
+ static struct resource bcm2708_bsc0_resources[] = {
+ {
+@@ -700,6 +703,7 @@ void __init bcm2708_init(void)
+ bcm_register_device(&bcm2708_usb_device);
+ bcm_register_device(&bcm2708_uart1_device);
+ bcm_register_device(&bcm2708_powerman_device);
++
+ #ifdef CONFIG_MMC_SDHCI_BCM2708
+ bcm_register_device(&bcm2708_emmc_device);
+ #endif
+@@ -805,8 +809,7 @@ static void __init bcm2708_timer_init(void)
+ */
+ setup_irq(IRQ_TIMER3, &bcm2708_timer_irq);
+
+- init_fixed_sched_clock(&cd, bcm2708_update_sched_clock, 32,
+- STC_FREQ_HZ, SC_MULT, SC_SHIFT);
++ setup_sched_clock(bcm2708_read_sched_clock, 32, STC_FREQ_HZ);
+
+ timer0_clockevent.mult =
+ div_sc(STC_FREQ_HZ, NSEC_PER_SEC, timer0_clockevent.shift);
+@@ -858,36 +861,55 @@ static inline void bcm2708_init_led(void)
+ }
+ #endif
+
+-
+ /* The assembly versions in delay.S don't account for core freq changing in cpufreq driver */
+ /* Use 1MHz system timer for busy waiting */
+-void __udelay(unsigned long usecs)
++void bcm2708_udelay(unsigned long usecs)
+ {
+- unsigned long start = readl(__io_address(ST_BASE + 0x04));
++ unsigned long start = timer_read();
+ unsigned long now;
+ do {
+- now = readl(__io_address(ST_BASE + 0x04));
++ now = timer_read();
+ } while ((long)(now - start) <= usecs);
+ }
+
+
+-void __const_udelay(unsigned long scaled_usecs)
++void bcm2708_const_udelay(unsigned long scaled_usecs)
+ {
+ /* want /107374, this is about 3% bigger. We know usecs is less than 2000, so shouldn't overflow */
+ const unsigned long usecs = scaled_usecs * 10 >> 20;
+- unsigned long start = readl(__io_address(ST_BASE + 0x04));
++ unsigned long start = timer_read();
+ unsigned long now;
+ do {
+- now = readl(__io_address(ST_BASE + 0x04));
++ now = timer_read();
+ } while ((long)(now - start) <= usecs);
+ }
+
++extern void bcm2708_delay(unsigned long cycles);
++
++struct arm_delay_ops arm_delay_ops = {
++ .delay = bcm2708_delay,
++ .const_udelay = bcm2708_const_udelay,
++ .udelay = bcm2708_udelay,
++};
++
++
++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_2M);
++}
++
+ MACHINE_START(BCM2708, "BCM2708")
+ /* Maintainer: Broadcom Europe Ltd. */
+ .map_io = bcm2708_map_io,
+ .init_irq = bcm2708_init_irq,
+ .timer =&bcm2708_timer,
+- .init_machine =bcm2708_init,
++ .init_machine = bcm2708_init,
++ .init_early = bcm2708_init_early,
+ MACHINE_END
+
+ module_param(boardrev, uint, 0644);
+diff --git a/arch/arm/mach-bcm2708/delay.S b/arch/arm/mach-bcm2708/delay.S
+index 4256d29..91754d6 100644
+--- a/arch/arm/mach-bcm2708/delay.S
++++ b/arch/arm/mach-bcm2708/delay.S
+@@ -13,8 +13,8 @@
+
+ .text
+ @ Delay routine
+-ENTRY(__delay)
++ENTRY(bcm2708_delay)
+ subs r0, r0, #1
+- bhi __delay
++ bhi bcm2708_delay
+ mov pc, lr
+-ENDPROC(__delay)
++ENDPROC(bcm2708_delay)
+diff --git a/arch/arm/mach-bcm2708/include/mach/memory.h b/arch/arm/mach-bcm2708/include/mach/memory.h
+index 5d47513..521540d 100644
+--- a/arch/arm/mach-bcm2708/include/mach/memory.h
++++ b/arch/arm/mach-bcm2708/include/mach/memory.h
+@@ -54,11 +54,4 @@
+ #define __pfn_to_bus(x) (__pfn_to_phys(x) + (BUS_OFFSET - PLAT_PHYS_OFFSET))
+ #define __bus_to_pfn(x) __phys_to_pfn((x) - (BUS_OFFSET - PLAT_PHYS_OFFSET))
+
+-/*
+- * Consistent DMA area set to 2M. Framebuffer now allocated on host
+- */
+-
+-
+-#define CONSISTENT_DMA_SIZE 0x00200000
+-
+ #endif
+diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
+index 2997e56..c166a40 100644
+--- a/arch/arm/tools/mach-types
++++ b/arch/arm/tools/mach-types
+@@ -519,6 +519,7 @@ 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
+ ag5evm MACH_AG5EVM AG5EVM 3189
+ tsunagi MACH_TSUNAGI TSUNAGI 3197
+ ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
+index b8675d8..0dc312b 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
+@@ -1448,8 +1448,6 @@ fail_open:
+ NULL, 0, 0, 0) == VCHIQ_RETRY)
+ goto bail_not_ready;
+
+- unlock_service(service);
+-
+ return 1;
+
+ bail_not_ready:
+@@ -1649,7 +1647,14 @@ parse_rx_slots(VCHIQ_STATE_T *state)
+ && (service->srvstate ==
+ VCHIQ_SRVSTATE_OPEN)) {
+ VCHIQ_BULK_T *bulk;
+- int resolved;
++ int resolved = 0;
++
++ DEBUG_TRACE(PARSE_LINE);
++ if (mutex_lock_interruptible(
++ &service->bulk_mutex) != 0) {
++ DEBUG_TRACE(PARSE_LINE);
++ goto bail_not_ready;
++ }
+
+ WARN_ON(!(queue->remote_insert < queue->remove +
+ VCHIQ_NUM_SERVICE_BULKS));
+@@ -1670,18 +1675,12 @@ parse_rx_slots(VCHIQ_STATE_T *state)
+
+ queue->remote_insert++;
+
+- if (state->conn_state !=
+- VCHIQ_CONNSTATE_CONNECTED)
+- break;
+-
+- DEBUG_TRACE(PARSE_LINE);
+- if (mutex_lock_interruptible(
+- &service->bulk_mutex) != 0) {
++ if (state->conn_state ==
++ VCHIQ_CONNSTATE_CONNECTED) {
+ DEBUG_TRACE(PARSE_LINE);
+- goto bail_not_ready;
++ resolved = resolve_bulks(service, queue);
+ }
+- DEBUG_TRACE(PARSE_LINE);
+- resolved = resolve_bulks(service, queue);
++
+ mutex_unlock(&service->bulk_mutex);
+ if (resolved)
+ notify_bulks(service, queue,
+@@ -1700,14 +1699,23 @@ parse_rx_slots(VCHIQ_STATE_T *state)
+ queue = (type == VCHIQ_MSG_BULK_RX_DONE) ?
+ &service->bulk_rx : &service->bulk_tx;
+
++ DEBUG_TRACE(PARSE_LINE);
++ if (mutex_lock_interruptible(
++ &service->bulk_mutex) != 0) {
++ DEBUG_TRACE(PARSE_LINE);
++ goto bail_not_ready;
++ }
+ if ((int)(queue->remote_insert -
+ queue->local_insert) >= 0) {
+ vchiq_log_error(vchiq_core_log_level,
+ "%d: prs %s@%x (%d->%d) "
+- "unexpected",
++ "unexpected (ri=%d,li=%d)",
+ state->id, msg_type_str(type),
+ (unsigned int)header,
+- remoteport, localport);
++ remoteport, localport,
++ queue->remote_insert,
++ queue->local_insert);
++ mutex_unlock(&service->bulk_mutex);
+ break;
+ }
+
+@@ -1735,12 +1743,6 @@ parse_rx_slots(VCHIQ_STATE_T *state)
+ queue->remote_insert, queue->process);
+
+ DEBUG_TRACE(PARSE_LINE);
+- if (mutex_lock_interruptible(
+- &service->bulk_mutex) != 0) {
+- DEBUG_TRACE(PARSE_LINE);
+- goto bail_not_ready;
+- }
+- DEBUG_TRACE(PARSE_LINE);
+ WARN_ON(queue->process == queue->local_insert);
+ vchiq_complete_bulk(bulk);
+ queue->process++;
+@@ -2971,7 +2973,6 @@ vchiq_remove_service(VCHIQ_SERVICE_HANDLE_T handle)
+ return status;
+ }
+
+-
+ /* This function may be called by kernel threads or user threads.
+ * User threads may receive VCHIQ_RETRY to indicate that a signal has been
+ * received and the call should be retried after being returned to user
+@@ -3120,154 +3121,6 @@ error_exit:
+ }
+
+ VCHIQ_STATUS_T
+-vchiq_queue_bulk_transmit(VCHIQ_SERVICE_HANDLE_T handle,
+- const void *data, int size, void *userdata)
+-{
+- return vchiq_bulk_transfer(handle,
+- VCHI_MEM_HANDLE_INVALID, (void *)data, size, userdata,
+- VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_TRANSMIT);
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_queue_bulk_receive(VCHIQ_SERVICE_HANDLE_T handle, void *data, int size,
+- void *userdata)
+-{
+- return vchiq_bulk_transfer(handle,
+- VCHI_MEM_HANDLE_INVALID, data, size, userdata,
+- VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_RECEIVE);
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_queue_bulk_transmit_handle(VCHIQ_SERVICE_HANDLE_T handle,
+- VCHI_MEM_HANDLE_T memhandle, const void *offset, int size,
+- void *userdata)
+-{
+- return vchiq_bulk_transfer(handle,
+- memhandle, (void *)offset, size, userdata,
+- VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_TRANSMIT);
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_queue_bulk_receive_handle(VCHIQ_SERVICE_HANDLE_T handle,
+- VCHI_MEM_HANDLE_T memhandle, void *offset, int size,
+- void *userdata)
+-{
+- return vchiq_bulk_transfer(handle,
+- memhandle, offset, size, userdata,
+- VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_RECEIVE);
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_bulk_transmit(VCHIQ_SERVICE_HANDLE_T handle, const void *data, int size,
+- void *userdata, VCHIQ_BULK_MODE_T mode)
+-{
+- struct bulk_waiter bulk_waiter;
+- VCHIQ_STATUS_T status;
+-
+- switch (mode) {
+- case VCHIQ_BULK_MODE_NOCALLBACK:
+- case VCHIQ_BULK_MODE_CALLBACK:
+- break;
+- case VCHIQ_BULK_MODE_BLOCKING:
+- userdata = &bulk_waiter;
+- break;
+- default:
+- return VCHIQ_ERROR;
+- }
+-
+- status = vchiq_bulk_transfer(handle,
+- VCHI_MEM_HANDLE_INVALID, (void *)data, size, userdata,
+- mode, VCHIQ_BULK_TRANSMIT);
+-
+- /* This call is for kernel thread use and should not be interrupted */
+- // dc4: remove as it does happen: BUG_ON(status == VCHIQ_RETRY);
+- return status;
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_bulk_receive(VCHIQ_SERVICE_HANDLE_T handle, void *data, int size,
+- void *userdata, VCHIQ_BULK_MODE_T mode)
+-{
+- struct bulk_waiter bulk_waiter;
+- VCHIQ_STATUS_T status;
+-
+- switch (mode) {
+- case VCHIQ_BULK_MODE_NOCALLBACK:
+- case VCHIQ_BULK_MODE_CALLBACK:
+- break;
+- case VCHIQ_BULK_MODE_BLOCKING:
+- userdata = &bulk_waiter;
+- break;
+- default:
+- return VCHIQ_ERROR;
+- }
+-
+- status = vchiq_bulk_transfer(handle,
+- VCHI_MEM_HANDLE_INVALID, data, size, userdata,
+- mode, VCHIQ_BULK_RECEIVE);
+-
+- /* This call is for kernel thread use and should not be interrupted */
+- BUG_ON(status == VCHIQ_RETRY);
+- return status;
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_bulk_transmit_handle(VCHIQ_SERVICE_HANDLE_T handle,
+- VCHI_MEM_HANDLE_T memhandle, const void *offset, int size,
+- void *userdata, VCHIQ_BULK_MODE_T mode)
+-{
+- struct bulk_waiter bulk_waiter;
+- VCHIQ_STATUS_T status;
+-
+- switch (mode) {
+- case VCHIQ_BULK_MODE_NOCALLBACK:
+- case VCHIQ_BULK_MODE_CALLBACK:
+- break;
+- case VCHIQ_BULK_MODE_BLOCKING:
+- userdata = &bulk_waiter;
+- break;
+- default:
+- return VCHIQ_ERROR;
+- }
+-
+- status = vchiq_bulk_transfer(handle,
+- memhandle, (void *)offset, size, userdata,
+- mode, VCHIQ_BULK_TRANSMIT);
+-
+- /* This call is for kernel thread use and should not be interrupted */
+- BUG_ON(status == VCHIQ_RETRY);
+- return status;
+-}
+-
+-VCHIQ_STATUS_T
+-vchiq_bulk_receive_handle(VCHIQ_SERVICE_HANDLE_T handle,
+- VCHI_MEM_HANDLE_T memhandle, void *offset, int size, void *userdata,
+- VCHIQ_BULK_MODE_T mode)
+-{
+- struct bulk_waiter bulk_waiter;
+- VCHIQ_STATUS_T status;
+-
+- switch (mode) {
+- case VCHIQ_BULK_MODE_NOCALLBACK:
+- case VCHIQ_BULK_MODE_CALLBACK:
+- break;
+- case VCHIQ_BULK_MODE_BLOCKING:
+- userdata = &bulk_waiter;
+- break;
+- default:
+- return VCHIQ_ERROR;
+- }
+-
+- status = vchiq_bulk_transfer(handle,
+- memhandle, offset, size, userdata,
+- mode, VCHIQ_BULK_RECEIVE);
+-
+- /* This call is for kernel thread use and should not be interrupted */
+- BUG_ON(status == VCHIQ_RETRY);
+- return status;
+-}
+-
+-VCHIQ_STATUS_T
+ vchiq_queue_message(VCHIQ_SERVICE_HANDLE_T handle,
+ const VCHIQ_ELEMENT_T *elements, int count)
+ {
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
+index 2855873..be1a063 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
+@@ -25,12 +25,25 @@
+
+ /* ---- Private Constants and Types -------------------------------------- */
+
++struct bulk_waiter_node {
++ struct bulk_waiter bulk_waiter;
++ int pid;
++ struct list_head list;
++};
++
+ struct vchiq_instance_struct {
+ VCHIQ_STATE_T *state;
+
+ int connected;
++
++ struct list_head bulk_waiter_list;
++ struct mutex bulk_waiter_list_mutex;
+ };
+
++static VCHIQ_STATUS_T
++vchiq_blocking_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, void *data,
++ int size, VCHIQ_BULK_DIR_T dir);
++
+ /****************************************************************************
+ *
+ * vchiq_initialise
+@@ -61,6 +74,8 @@ VCHIQ_STATUS_T vchiq_initialise(VCHIQ_INSTANCE_T *instanceOut)
+
+ instance->connected = 0;
+ instance->state = state;
++ mutex_init(&instance->bulk_waiter_list_mutex);
++ INIT_LIST_HEAD(&instance->bulk_waiter_list);
+
+ *instanceOut = instance;
+
+@@ -96,8 +111,23 @@ VCHIQ_STATUS_T vchiq_shutdown(VCHIQ_INSTANCE_T instance)
+
+ mutex_unlock(&state->mutex);
+
+- if (status == VCHIQ_SUCCESS)
++ if (status == VCHIQ_SUCCESS) {
++ struct list_head *pos, *next;
++ list_for_each_safe(pos, next,
++ &instance->bulk_waiter_list) {
++ struct bulk_waiter_node *waiter;
++ waiter = list_entry(pos,
++ struct bulk_waiter_node,
++ list);
++ list_del(pos);
++ vchiq_log_info(vchiq_arm_log_level,
++ "bulk_waiter - cleaned up %x "
++ "for pid %d",
++ (unsigned int)waiter, waiter->pid);
++ kfree(waiter);
++ }
+ kfree(instance);
++ }
+
+ vchiq_log_trace(vchiq_core_log_level,
+ "%s(%p): returning %d", __func__, instance, status);
+@@ -239,3 +269,156 @@ failed:
+ return status;
+ }
+ EXPORT_SYMBOL(vchiq_open_service);
++
++VCHIQ_STATUS_T
++vchiq_queue_bulk_transmit(VCHIQ_SERVICE_HANDLE_T handle,
++ const void *data, int size, void *userdata)
++{
++ return vchiq_bulk_transfer(handle,
++ VCHI_MEM_HANDLE_INVALID, (void *)data, size, userdata,
++ VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_TRANSMIT);
++}
++EXPORT_SYMBOL(vchiq_queue_bulk_transmit);
++
++VCHIQ_STATUS_T
++vchiq_queue_bulk_receive(VCHIQ_SERVICE_HANDLE_T handle, void *data, int size,
++ void *userdata)
++{
++ return vchiq_bulk_transfer(handle,
++ VCHI_MEM_HANDLE_INVALID, data, size, userdata,
++ VCHIQ_BULK_MODE_CALLBACK, VCHIQ_BULK_RECEIVE);
++}
++EXPORT_SYMBOL(vchiq_queue_bulk_receive);
++
++VCHIQ_STATUS_T
++vchiq_bulk_transmit(VCHIQ_SERVICE_HANDLE_T handle, const void *data, int size,
++ void *userdata, VCHIQ_BULK_MODE_T mode)
++{
++ VCHIQ_STATUS_T status;
++
++ switch (mode) {
++ case VCHIQ_BULK_MODE_NOCALLBACK:
++ case VCHIQ_BULK_MODE_CALLBACK:
++ status = vchiq_bulk_transfer(handle,
++ VCHI_MEM_HANDLE_INVALID, (void *)data, size, userdata,
++ mode, VCHIQ_BULK_TRANSMIT);
++ break;
++ case VCHIQ_BULK_MODE_BLOCKING:
++ status = vchiq_blocking_bulk_transfer(handle,
++ (void *)data, size, VCHIQ_BULK_TRANSMIT);
++ break;
++ default:
++ return VCHIQ_ERROR;
++ }
++
++ return status;
++}
++EXPORT_SYMBOL(vchiq_bulk_transmit);
++
++VCHIQ_STATUS_T
++vchiq_bulk_receive(VCHIQ_SERVICE_HANDLE_T handle, void *data, int size,
++ void *userdata, VCHIQ_BULK_MODE_T mode)
++{
++ VCHIQ_STATUS_T status;
++
++ switch (mode) {
++ case VCHIQ_BULK_MODE_NOCALLBACK:
++ case VCHIQ_BULK_MODE_CALLBACK:
++ status = vchiq_bulk_transfer(handle,
++ VCHI_MEM_HANDLE_INVALID, data, size, userdata,
++ mode, VCHIQ_BULK_RECEIVE);
++ break;
++ case VCHIQ_BULK_MODE_BLOCKING:
++ status = vchiq_blocking_bulk_transfer(handle,
++ (void *)data, size, VCHIQ_BULK_RECEIVE);
++ break;
++ default:
++ return VCHIQ_ERROR;
++ }
++
++ return status;
++}
++EXPORT_SYMBOL(vchiq_bulk_receive);
++
++static VCHIQ_STATUS_T
++vchiq_blocking_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, void *data,
++ int size, VCHIQ_BULK_DIR_T dir)
++{
++ VCHIQ_INSTANCE_T instance;
++ VCHIQ_SERVICE_T *service;
++ VCHIQ_STATUS_T status;
++ struct bulk_waiter_node *waiter = NULL;
++ struct list_head *pos;
++
++ service = find_service_by_handle(handle);
++ if (!service)
++ return VCHIQ_ERROR;
++
++ instance = service->instance;
++
++ unlock_service(service);
++
++ mutex_lock(&instance->bulk_waiter_list_mutex);
++ list_for_each(pos, &instance->bulk_waiter_list) {
++ if (list_entry(pos, struct bulk_waiter_node,
++ list)->pid == current->pid) {
++ waiter = list_entry(pos,
++ struct bulk_waiter_node,
++ list);
++ list_del(pos);
++ break;
++ }
++ }
++ mutex_unlock(&instance->bulk_waiter_list_mutex);
++
++ if (waiter) {
++ VCHIQ_BULK_T *bulk = waiter->bulk_waiter.bulk;
++ if (bulk) {
++ /* This thread has an outstanding bulk transfer. */
++ if ((bulk->data != data) ||
++ (bulk->size != size)) {
++ /* This is not a retry of the previous one.
++ ** Cancel the signal when the transfer
++ ** completes. */
++ spin_lock(&bulk_waiter_spinlock);
++ bulk->userdata = NULL;
++ spin_unlock(&bulk_waiter_spinlock);
++ }
++ }
++ }
++
++ if (!waiter) {
++ waiter = kzalloc(sizeof(struct bulk_waiter_node), GFP_KERNEL);
++ if (!waiter) {
++ vchiq_log_error(vchiq_core_log_level,
++ "%s - out of memory", __func__);
++ return VCHIQ_ERROR;
++ }
++ }
++
++ status = vchiq_bulk_transfer(handle, VCHI_MEM_HANDLE_INVALID,
++ data, size, &waiter->bulk_waiter, VCHIQ_BULK_MODE_BLOCKING,
++ dir);
++ if ((status != VCHIQ_RETRY) || fatal_signal_pending(current) ||
++ !waiter->bulk_waiter.bulk) {
++ VCHIQ_BULK_T *bulk = waiter->bulk_waiter.bulk;
++ if (bulk) {
++ /* Cancel the signal when the transfer
++ ** completes. */
++ spin_lock(&bulk_waiter_spinlock);
++ bulk->userdata = NULL;
++ spin_unlock(&bulk_waiter_spinlock);
++ }
++ kfree(waiter);
++ } else {
++ waiter->pid = current->pid;
++ mutex_lock(&instance->bulk_waiter_list_mutex);
++ list_add(&waiter->list, &instance->bulk_waiter_list);
++ mutex_unlock(&instance->bulk_waiter_list_mutex);
++ vchiq_log_info(vchiq_arm_log_level,
++ "saved bulk_waiter %x for pid %d",
++ (unsigned int)waiter, current->pid);
++ }
++
++ return status;
++}
+diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
+index 5f7bde5..812fea6 100644
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -320,14 +320,6 @@ config MMC_ATMELMCI
+ If unsure, say N.
+
+ endchoice
+-config MMC_BCM2708
+- tristate "BCM2708 Multimedia Card Interface support"
+- help
+- This selects the BCM2708 Multimedia Card Interface driver. If
+- you have a BCM2708 platform with a Multimedia Card
+- slot, say Y or M here.
+-
+- If unsure, say N.
+
+ config MMC_ATMELMCI_DMA
+ bool "Atmel MCI DMA support"
+diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
+index 79fe195..511710e 100644
+--- a/drivers/mmc/host/Makefile
++++ b/drivers/mmc/host/Makefile
+@@ -37,7 +37,6 @@ tmio_mmc_core-$(subst m,y,$(CONFIG_MMC_SDHI)) += tmio_mmc_dma.o
+ obj-$(CONFIG_MMC_SDHI) += sh_mobile_sdhi.o
+ obj-$(CONFIG_MMC_CB710) += cb710-mmc.o
+ obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o
+-obj-$(CONFIG_MMC_BCM2708) += bcm2708_mci.o
+ obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o
+ obj-$(CONFIG_MMC_DW) += dw_mmc.o
+ obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o
+diff --git a/drivers/mmc/host/bcm2708_mci.c b/drivers/mmc/host/bcm2708_mci.c
+deleted file mode 100644
+index 3c7de96..0000000
+--- a/drivers/mmc/host/bcm2708_mci.c
++++ /dev/null
+@@ -1,889 +0,0 @@
+-/*
+- * linux/drivers/mmc/host/bcm2708_mci.c - Broadcom BCM2708 MCI driver
+- *
+- * Copyright (C) 2010 Broadcom, All Rights Reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+- */
+-
+-#include <linux/slab.h>
+-#include <linux/module.h>
+-#include <linux/moduleparam.h>
+-#include <linux/init.h>
+-#include <linux/ioport.h>
+-#include <linux/device.h>
+-#include <linux/interrupt.h>
+-#include <linux/delay.h>
+-#include <linux/err.h>
+-#include <linux/highmem.h>
+-#include <linux/log2.h>
+-#include <linux/mmc/host.h>
+-#include <linux/mmc/mmc.h>
+-#include <linux/mmc/sd.h>
+-#include <linux/platform_device.h>
+-#include <linux/clk.h>
+-#include <linux/scatterlist.h>
+-#include <linux/dma-mapping.h>
+-
+-#include <asm/cacheflush.h>
+-#include <asm/div64.h>
+-#include <asm/io.h>
+-#include <asm/sizes.h>
+-//#include <asm/mach/mmc.h>
+-
+-#include <mach/gpio.h>
+-
+-#include "bcm2708_mci.h"
+-
+-#define DRIVER_NAME "bcm2708_mci"
+-
+-//#define PIO_DEBUG
+-#ifdef PIO_DEBUG
+-#define DBG(host,fmt,args...) \
+- printk(KERN_ERR"%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args)
+-#else
+-#define DBG(host,fmt,args...) \
+- pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args)
+-#endif
+-
+-#define USE_DMA
+-#define USE_DMA_IRQ
+-
+-#ifdef USE_DMA
+-#define SDHOST_DMA_CHANNEL 5
+-#endif
+-
+-#define BCM2708_DMA_ACTIVE (1 << 0)
+-#define BCM2708_DMA_INT (1 << 2)
+-
+-#define BCM2708_DMA_INT_EN (1 << 0)
+-#define BCM2708_DMA_D_INC (1 << 4)
+-#define BCM2708_DMA_D_WIDTH (1 << 5)
+-#define BCM2708_DMA_D_DREQ (1 << 6)
+-#define BCM2708_DMA_S_INC (1 << 8)
+-#define BCM2708_DMA_S_WIDTH (1 << 9)
+-#define BCM2708_DMA_S_DREQ (1 << 10)
+-
+-#define BCM2708_DMA_PER_MAP(x) ((x) << 16)
+-
+-#define BCM2708_DMA_DREQ_SDHOST 13
+-
+-#define BCM2708_DMA_CS 0x00
+-#define BCM2708_DMA_ADDR 0x04
+-
+-static void dump_sd_regs(void * mmc_base );
+-static int bcm2708_mci_reset(struct bcm2708_mci_host *host);
+-
+-static void do_command(void __iomem *base, u32 c, u32 a)
+-{
+- u32 cmdsts = 0;
+- writel(a, base + BCM2708_MCI_ARGUMENT);
+- writel(c | BCM2708_MCI_ENABLE, base + BCM2708_MCI_COMMAND);
+-
+- /* check for error and command done */
+- cmdsts = readl(base + BCM2708_MCI_COMMAND);
+- while ((cmdsts & BCM2708_MCI_ENABLE) && (!(cmdsts & BCM2708_MCI_FAIL_FLAG)))
+- cmdsts = readl(base + BCM2708_MCI_COMMAND);
+- if (cmdsts & BCM2708_MCI_FAIL_FLAG) {
+- printk(KERN_DEBUG"%s: Command %d failed with arg %d\n", __func__, c, a);
+- dump_sd_regs(base);
+- }
+-}
+-
+-//static void discard_words(void __iomem *base, int words)
+-//{
+-// int i;
+-// for (i = 0; i < words; i++) {
+-// while (!(readl(base + BCM2708_MCI_STATUS) & BCM2708_MCI_DATAFLAG));
+-// readl(base + BCM2708_MCI_DATA);
+-// }
+-//}
+-
+-#define CACHE_LINE_MASK 31
+-
+-static int suitable_for_dma(struct scatterlist *sg_ptr, int sg_len)
+-{
+- int i;
+-
+- for (i = 0; i < sg_len; i++) {
+- if (sg_ptr[i].offset & CACHE_LINE_MASK || sg_ptr[i].length & CACHE_LINE_MASK)
+- return 0;
+- }
+-
+- return 1;
+-}
+-
+-static void wait_for_complete(struct bcm2708_mci_host *host,
+- void __iomem *mmc_base)
+-{
+-#ifdef USE_SDHOST_IRQ
+-#error not implemented yet
+-#else
+- while ((readl(mmc_base + BCM2708_MCI_STATUS) &
+- (BCM2708_MCI_HSTS_BUSY | BCM2708_MCI_HSTS_BLOCK)) == 0)
+- continue;
+-
+- writel(BCM2708_MCI_HSTS_BUSY | BCM2708_MCI_HSTS_BLOCK,
+- mmc_base + BCM2708_MCI_STATUS);
+-#endif
+-}
+-
+-static void dump_sd_regs(void * mmc_base )
+-{
+- printk(KERN_DEBUG"Registers:\n");
+- printk(KERN_DEBUG"SDCMD:0x%x\n", readl(mmc_base + BCM2708_MCI_COMMAND));
+- printk(KERN_DEBUG"SDARG:0x%x\n", readl(mmc_base + BCM2708_MCI_ARGUMENT));
+- printk(KERN_DEBUG"SDTOUT:0x%x\n", readl(mmc_base + BCM2708_MCI_TIMEOUT));
+- printk(KERN_DEBUG"SDCDIV:0x%x\n", readl(mmc_base + BCM2708_MCI_CLKDIV));
+- printk(KERN_DEBUG"SDRSP0:0x%x\n", readl(mmc_base + BCM2708_MCI_RESPONSE0));
+- printk(KERN_DEBUG"SDRSP1:0x%x\n", readl(mmc_base + BCM2708_MCI_RESPONSE1));
+- printk(KERN_DEBUG"SDRSP2:0x%x\n", readl(mmc_base + BCM2708_MCI_RESPONSE2));
+- printk(KERN_DEBUG"SDRSP3:0x%x\n", readl(mmc_base + BCM2708_MCI_RESPONSE3));
+- printk(KERN_DEBUG"SDHSTS:0x%x\n", readl(mmc_base + BCM2708_MCI_STATUS));
+- printk(KERN_DEBUG"SDPO:0x%x\n", readl(mmc_base + BCM2708_MCI_VDD));
+- printk(KERN_DEBUG"SDEDM:0x%x\n", readl(mmc_base + BCM2708_MCI_EDM));
+- printk(KERN_DEBUG"SDHCFG:0x%x\n", readl(mmc_base + BCM2708_MCI_HOSTCONFIG));
+- printk(KERN_DEBUG"SDHBCT:0x%x\n", readl(mmc_base + BCM2708_MCI_HBCT));
+- //printk(KERN_ERR"SDDATA:0x%x\n", readl(mmc_base + BCM2708_MCI_DATA));
+- printk(KERN_DEBUG"SDHBLC:0x%x\n", readl(mmc_base + BCM2708_MCI_HBLC));
+-}
+-
+-
+-static void
+-bcm2708_mci_start_command(struct bcm2708_mci_host *host, struct mmc_command *cmd, struct mmc_data *data)
+-{
+- void __iomem *mmc_base = host->mmc_base;
+- void __iomem *dma_base = host->dma_base;
+- u32 status;
+- u32 c;
+- int redo = 0;
+-
+- DBG(host, "op %02x arg %08x flags %08x\n",
+- cmd->opcode, cmd->arg, cmd->flags);
+-
+-back:
+-
+- /*
+- * clear the controller status register
+- */
+-
+- writel(-1, mmc_base + BCM2708_MCI_STATUS);
+-
+- /*
+- * build the command register write, incorporating no
+- * response, long response, busy, read and write flags
+- */
+-
+- c = cmd->opcode;
+- if (cmd->flags & MMC_RSP_PRESENT) {
+- if (cmd->flags & MMC_RSP_136)
+- c |= BCM2708_MCI_LONGRESP;
+- } else
+- c |= BCM2708_MCI_NORESP;
+- if (cmd->flags & MMC_RSP_BUSY)
+- c |= BCM2708_MCI_BUSY;
+-
+- if (data) {
+- if (data->flags & MMC_DATA_READ)
+- c |= BCM2708_MCI_READ;
+- else
+- c |= BCM2708_MCI_WRITE;
+-
+- DBG(host, "BYTECOUT %d BLOCKCOUNT %d .. ",readl(mmc_base + BCM2708_MCI_HBCT), readl(mmc_base + BCM2708_MCI_HBLC));
+- DBG(host, "set blocksize to %d\n", data->blksz);
+- DBG(host, "set blockcnt to %d\n", data->blocks);
+- writel( data->blksz, mmc_base + BCM2708_MCI_HBCT);
+- writel(data->blocks, mmc_base + BCM2708_MCI_HBLC);
+- }
+-
+- /*
+- * run the command and wait for it to complete
+- */
+-
+- DBG(host, "executing command=%d\n", cmd->opcode);
+-
+- do_command(mmc_base, c, cmd->arg);
+-
+- DBG(host, "done cmd=%d\n", cmd->opcode);
+-
+- if (c & BCM2708_MCI_BUSY) {
+-
+- DBG(host, "waiting for command(%d) to complete\n", cmd->opcode);
+- wait_for_complete(host, mmc_base);
+- DBG(host, "done waiting for command(%d)\n", cmd->opcode);
+- }
+-
+- /*
+- * retrieve the response and error (if any)
+- */
+-
+- status = readl(mmc_base + BCM2708_MCI_STATUS);
+-
+- if (cmd->flags & MMC_RSP_136) {
+- cmd->resp[3] = readl(mmc_base + BCM2708_MCI_RESPONSE0);
+- cmd->resp[2] = readl(mmc_base + BCM2708_MCI_RESPONSE1);
+- cmd->resp[1] = readl(mmc_base + BCM2708_MCI_RESPONSE2);
+- cmd->resp[0] = readl(mmc_base + BCM2708_MCI_RESPONSE3);
+- } else {
+- cmd->resp[0] = readl(mmc_base + BCM2708_MCI_RESPONSE0);
+- }
+-
+- if (status & BCM2708_MCI_CMDTIMEOUT) {
+- printk(KERN_DEBUG "mmc driver saw timeout with opcode = %d, data = 0x%08x, timeout = %d", cmd->opcode, (unsigned int)data, readl(mmc_base + BCM2708_MCI_TIMEOUT));
+- if (data)
+- printk(KERN_DEBUG " data->sg_len = %d\n", data->sg_len);
+- else
+- printk(KERN_DEBUG "\n");
+- if (!redo) {
+- printk(KERN_DEBUG "redo\n");
+- redo = 1;
+- goto back;
+- } else
+- cmd->error = -ETIMEDOUT;
+- }
+-
+- /*
+- * pump data if necessary
+- */
+-
+- if (data) {
+- unsigned int sg_len = data->sg_len;
+- struct scatterlist *sg_ptr = data->sg;
+-
+- data->bytes_xfered = 0;
+-
+-#ifdef USE_DMA
+- if (suitable_for_dma(sg_ptr, sg_len)) {
+- int i, count = dma_map_sg(&host->dev->dev, sg_ptr, sg_len, data->flags & MMC_DATA_READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+-
+- for (i = 0; i < count; i++) {
+- BCM2708_DMA_CB_T *cb = &host->cb_base[i];
+-
+- if (data->flags & MMC_DATA_READ) {
+- cb->info = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_SDHOST)|BCM2708_DMA_S_DREQ|BCM2708_DMA_D_WIDTH|BCM2708_DMA_D_INC;
+- cb->src = 0x7e202040;
+- cb->dst = sg_dma_address(&sg_ptr[i]);
+- } else {
+- cb->info = BCM2708_DMA_PER_MAP(BCM2708_DMA_DREQ_SDHOST)|BCM2708_DMA_S_WIDTH|BCM2708_DMA_S_INC|BCM2708_DMA_D_DREQ;
+- cb->src = sg_dma_address(&sg_ptr[i]);
+- cb->dst = 0x7e202040;
+- }
+-
+- cb->length = sg_dma_len(&sg_ptr[i]);
+- cb->stride = 0;
+-
+- if (i == count - 1) {
+-#ifdef USE_DMA_IRQ
+- cb->info |= BCM2708_DMA_INT_EN;
+-#endif
+- cb->next = 0;
+- } else
+- cb->next = host->cb_handle + (i + 1) * sizeof(BCM2708_DMA_CB_T);
+-
+- cb->pad[0] = 0;
+- cb->pad[1] = 0;
+-
+- data->bytes_xfered += sg_ptr[i].length;
+- }
+-
+- dsb(); // data barrier operation
+-
+- writel(host->cb_handle, dma_base + BCM2708_DMA_ADDR);
+- writel(BCM2708_DMA_ACTIVE, dma_base + BCM2708_DMA_CS);
+-
+-#ifdef USE_DMA_IRQ
+- down(&host->sem);
+-#else
+- while ((readl(dma_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE));
+-#endif
+- dma_unmap_sg(&host->dev->dev, sg_ptr, sg_len, data->flags & MMC_DATA_READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+- } else
+-#endif
+- while (sg_len) {
+- unsigned long flags;
+- char *buffer;
+- u32 *ptr, *lim;
+-
+- DBG(host, "sg_len=%d sg_ptr=%p len=%d\n", sg_len, sg_ptr, sg_ptr->length);
+-
+- /*
+- * map the current scatter buffer
+- */
+-
+- buffer = bcm2708_mci_kmap_atomic(sg_ptr, &flags);
+-
+- /*
+- * pump the data
+- */
+-
+- ptr = (u32 *)(buffer);
+- lim = (u32 *)(buffer + sg_ptr->length);
+-
+- while (ptr < lim)
+- {
+-#ifdef PIO_DEBUG
+- unsigned int wait_count = 1;
+-#endif
+- while (!(readl(mmc_base + BCM2708_MCI_STATUS) & BCM2708_MCI_DATAFLAG))
+- {
+-#ifdef PIO_DEBUG
+- wait_count++;
+- if ( 0 == (wait_count % 20000) ) {
+-
+- printk(KERN_ERR"Timeout waiting for data flag\n");
+- dump_sd_regs(mmc_base);
+- }
+-#endif
+- }
+-
+- if (data->flags & MMC_DATA_READ)
+- *ptr++ = readl(mmc_base + BCM2708_MCI_DATA);
+- else
+- {
+-#ifdef PIO_DEBUG
+- uint32_t fifo_bytes, fifo_wait_count = 1;
+-
+- fifo_bytes = readl(mmc_base + BCM2708_MCI_EDM);
+- fifo_bytes = (fifo_bytes >> 4) & 0xf;
+-
+- while(fifo_bytes > 3)
+- {
+- fifo_wait_count++;
+- if ( 0 == (fifo_wait_count % 20000) ) {
+- printk(KERN_ERR"waiting for fifo_bytes < 3\n");
+- dump_sd_regs(mmc_base);
+- }
+-
+- fifo_bytes = readl(mmc_base + BCM2708_MCI_EDM);
+- fifo_bytes = (fifo_bytes >> 4) & 0xf;
+- }
+-
+- BUG_ON(fifo_bytes > 3);
+-#endif
+- writel(*ptr++, mmc_base + BCM2708_MCI_DATA);
+- }
+- }
+-
+- DBG(host, "done reading/writing %d bytes from mmc\n", sg_ptr->length);
+-
+-
+- /*
+- * unmap the buffer
+- */
+-
+- bcm2708_mci_kunmap_atomic(buffer, &flags);
+-
+- /*
+- * if we were reading, and we have completed this
+- * page, ensure that the data cache is coherent
+- */
+-
+- if (data->flags & MMC_DATA_READ)
+- flush_dcache_page(sg_page(sg_ptr));
+-
+- data->bytes_xfered += sg_ptr->length;
+-
+- sg_ptr++;
+- sg_len--;
+- }
+-
+-// if (host->is_acmd && cmd->opcode == SD_APP_SEND_SCR)
+-// discard_words(mmc_base, 126);
+-// if (host->is_acmd && cmd->opcode == SD_APP_SEND_NUM_WR_BLKS)
+-// discard_words(mmc_base, 127);
+-// if (!host->is_acmd && cmd->opcode == SD_SWITCH)
+-// discard_words(mmc_base, 112);
+-
+- if (data->stop) {
+-
+- DBG(host, "sending stop command %p\n", data->stop);
+- bcm2708_mci_start_command(host, data->stop, 0);
+-
+- while ((readl(mmc_base + BCM2708_MCI_STATUS) &
+- BCM2708_MCI_DATAFLAG))
+- {
+- DBG(host, "error data flag still set read=%d bytes\n", sg_ptr->length);
+- printk(KERN_ERR"SDDATA:0x%x\n", readl(mmc_base + BCM2708_MCI_DATA));
+- dump_sd_regs(mmc_base);
+- }
+- }
+- }
+- /*
+- * remember if we're an application command
+- */
+- host->is_acmd = cmd->opcode == MMC_APP_CMD;
+-}
+-
+-static void bcm2708_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
+-{
+- struct bcm2708_mci_host *host = mmc_priv(mmc);
+-
+- if (mrq->data && !is_power_of_2(mrq->data->blksz)) {
+- printk(KERN_ERR "%s: Unsupported block size (%d bytes)\n",
+- mmc_hostname(mmc), mrq->data->blksz);
+- mrq->cmd->error = -EINVAL;
+- mmc_request_done(mmc, mrq);
+- return;
+- }
+-
+- bcm2708_mci_start_command(host, mrq->cmd, mrq->data);
+-
+- mmc_request_done(host->mmc, mrq);
+-}
+-
+-static void bcm2708_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+-{
+-
+- struct bcm2708_mci_host *host = mmc_priv(mmc);
+- void *mmc_base = host->mmc_base;
+-
+-
+- printk(KERN_DEBUG"%s: Want to set clock: %d width: %d\n", mmc_hostname(mmc),
+- ios->clock, ios->bus_width);
+-
+- if (ios->clock == 25000000 || ios->clock == 26000000) {
+- printk(KERN_DEBUG"%s setting clock div to 10 (8+2)\n", mmc_hostname(mmc));
+- writel(0x8, mmc_base + BCM2708_MCI_CLKDIV);
+- } else if (ios->clock == 50000000 || ios->clock == 52000000) {
+- printk(KERN_DEBUG"%s setting clock div to 5 (3+2)\n", mmc_hostname(mmc));
+- writel(0x3, mmc_base + BCM2708_MCI_CLKDIV);
+- } else {
+- // On init or unknown clock, we set the clock really low
+- printk(KERN_DEBUG"%s Setting clock div to 0x4e0\n", mmc_hostname(mmc));
+- writel(0x4e0, mmc_base + BCM2708_MCI_CLKDIV);
+- }
+-
+- if (ios->bus_width) {
+- uint32_t hcfg;
+- hcfg = readl(mmc_base + BCM2708_MCI_HOSTCONFIG);
+- printk(KERN_DEBUG"%s setting bus width to %d\n", mmc_hostname(mmc), ios->bus_width);
+-
+- hcfg &= BCM2708_MCI_HOSTCONFIG_WIDEEXT_CLR;
+- hcfg |= (ios->bus_width == MMC_BUS_WIDTH_4) ? BCM2708_MCI_HOSTCONFIG_WIDEEXT_4BIT : 0;
+-
+- writel(hcfg, mmc_base + BCM2708_MCI_HOSTCONFIG);
+- }
+-}
+-
+-static int bcm2708_mci_get_cd(struct mmc_host *mmc)
+-{
+- int present = -ENOSYS;
+-
+- struct bcm2708_mci_host *host = mmc_priv(mmc);
+- void *gpio_base = host->gpio_base;
+-
+- present = readl( (gpio_base + GP_LEV0) );
+-
+- if ((present & (1<<29))==(1<<29))
+- present = 0;
+- else
+- present = 1;
+-
+- printk(KERN_DEBUG"***sdcard present***=%d\n", present);
+-
+- // FIXME - For now force SD card present for 2835DK
+- present = 1;
+- return present;
+-}
+-
+-/*
+- * Handle completion of command and data transfers.
+- */
+-
+-//static irqreturn_t bcm2708_mci_command_irq(int irq, void *dev_id)
+-//{
+-// struct bcm2708_mci_host *host = dev_id;
+-//
+-// writel(BCM2708_DMA_INT, host->dma_base + BCM2708_DMA_CS);
+-//
+-// printk(KERN_ERR "irq\n");
+-//
+-// return IRQ_RETVAL(0);
+-//}
+-
+-static irqreturn_t bcm2708_mci_sddet_irq(int irq, void *dev_id)
+-{
+- struct bcm2708_mci_host *host = dev_id;
+- irqreturn_t handled = IRQ_NONE;
+- int present;
+-
+- present = bcm2708_mci_get_cd(host->mmc);
+-
+- if (present!=host->present)
+- {
+- host->present = present;
+- printk(KERN_DEBUG "SDDET IRQ: sdcard present: %d\n",present);
+- bcm2708_mci_reset(host);
+- mmc_detect_change(host->mmc, msecs_to_jiffies(500));
+- }
+-
+- return IRQ_RETVAL(handled);
+-}
+-
+-#ifdef USE_DMA_IRQ
+-static irqreturn_t bcm2708_mci_data_irq(int irq, void *dev_id)
+-{
+- struct bcm2708_mci_host *host = dev_id;
+- irqreturn_t handled = IRQ_NONE;
+-
+- if (0 != (BCM2708_DMA_INT & readl(host->dma_base + BCM2708_DMA_CS))) {
+- writel(BCM2708_DMA_INT, host->dma_base + BCM2708_DMA_CS);
+- dsb();
+- handled = IRQ_HANDLED;
+- up(&host->sem);
+- } else {
+- printk(KERN_ERR"bcm2708_mci irq check failed !!\n");
+- }
+-
+- return IRQ_RETVAL(handled);
+-}
+-#endif
+-
+-static const struct mmc_host_ops bcm2708_mci_ops = {
+- .request = bcm2708_mci_request,
+- .set_ios = bcm2708_mci_set_ios,
+- .get_cd = bcm2708_mci_get_cd,
+-};
+-
+-static int bcm2708_mci_reset(struct bcm2708_mci_host *host)
+-{
+-
+- void *mmc_base = host->mmc_base;
+-
+- // pin muxing/gpios is done by vcloader
+-
+- printk(KERN_DEBUG"%s:Resetting BCM2708 MCI Controller.\n", __func__ );
+-
+- writel(0, mmc_base + BCM2708_MCI_COMMAND);
+- writel(0, mmc_base + BCM2708_MCI_ARGUMENT);
+- writel(0x00F00000, mmc_base + BCM2708_MCI_TIMEOUT);
+- writel(0, mmc_base + BCM2708_MCI_CLKDIV);
+- writel(0, mmc_base + BCM2708_MCI_STATUS);
+- writel(0, mmc_base + BCM2708_MCI_VDD);
+- writel(0, mmc_base + BCM2708_MCI_HOSTCONFIG);
+- writel(0, mmc_base + BCM2708_MCI_HBCT);
+- writel(0, mmc_base + BCM2708_MCI_HBLC);
+-
+- writel( BCM2708_MCI_HOSTCONFIG_SLOW_CARD | BCM2708_MCI_HOSTCONFIG_BUSY_IRPT_EN |
+- BCM2708_MCI_HOSTCONFIG_BLOCK_IRPT_EN | BCM2708_MCI_HOSTCONFIG_WIDE_INT_BUS,
+- mmc_base + BCM2708_MCI_HOSTCONFIG);
+-
+- // On A0 silicon it has been observed that the following must hold
+- // WRITE_THRESHOLD<=5 and READ_THRESHOLD<=WRITE_THRESHOLD+1
+- // with the chip running at 150MHz (with the interface running @ 150/22 = 6.8 MHz)
+- // the second requirement suggests that the verilog does not properly separate the read / write FIFOs
+- // On V3XDS Read=2 & Write=6
+-
+-#define READ_THRESHOLD 3
+-#define WRITE_THRESHOLD 3
+-#if 1 // !!! This is still required, without it we get CRC16 errors in data.
+- {
+- uint32_t temp;
+- temp = readl(mmc_base + BCM2708_MCI_EDM);
+- temp &= ~((0x1F<<14) | (0x1F<<9));
+- temp |= (WRITE_THRESHOLD << 9) | (READ_THRESHOLD << 14);
+- writel(temp, mmc_base + BCM2708_MCI_EDM);
+- }
+-#endif
+-
+- // Power on delay
+- mdelay(10);
+- writel(BCM2708_MCI_VDD_ENABLE, mmc_base + BCM2708_MCI_VDD);
+- mdelay(10);
+-
+- return 0;
+-}
+-
+-
+-static int __devinit bcm2708_mci_probe(struct platform_device *pdev)
+-{
+- struct mmc_host *mmc;
+- struct bcm2708_mci_host *host;
+- struct resource *mmc_res;
+- struct resource *dma_res;
+- struct resource *gpio_res;
+- struct resource *dat_res;
+- struct resource *sddet_res;
+- int ret;
+-
+- mmc = mmc_alloc_host(sizeof(struct bcm2708_mci_host), &pdev->dev);
+- if (!mmc) {
+- ret = -ENOMEM;
+- dev_dbg(&pdev->dev, "couldn't allocate mmc host\n");
+- goto fail0;
+- }
+-
+- host = mmc_priv(mmc);
+- host->mmc = mmc;
+-
+- host->dev = pdev;
+-
+- sema_init(&host->sem, 0);
+-
+-#ifdef USE_DMA
+- host->cb_base = dma_alloc_writecombine(&pdev->dev, SZ_4K, &host->cb_handle, GFP_KERNEL);
+- if (!host->cb_base) {
+- ret = -ENOMEM;
+- dev_dbg(&pdev->dev, "couldn't allocate dma base\n");
+- goto fail1;
+- }
+-#endif
+-
+- mmc_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- if (!mmc_res) {
+- ret = -ENXIO;
+- dev_dbg(&pdev->dev, "couldn't allocate mmc memory resource 0\n");
+- goto fail2;
+- }
+-
+- if (!request_mem_region(mmc_res->start, mmc_res->end - mmc_res->start + 1, DRIVER_NAME)) {
+- ret = -EBUSY;
+- goto fail2;
+- }
+-
+- dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+- if (!dma_res) {
+- ret = -ENXIO;
+- dev_dbg(&pdev->dev, "couldn't allocate dma memory resource 1\n");
+- goto fail3;
+- }
+-
+- /*
+- * Map I/O regions
+- */
+-
+- host->mmc_base = ioremap(mmc_res->start, resource_size(mmc_res));
+- if (!host->mmc_base) {
+- ret = -ENOMEM;
+- goto fail3;
+- }
+-
+- gpio_res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+- if (!gpio_res) {
+- ret = -ENXIO;
+- dev_dbg(&pdev->dev, "couldn't allocate gpio resource\n");
+- goto fail4;
+- }
+-
+- /*
+- * Map I/O regions
+- */
+-
+- host->gpio_base = ioremap(gpio_res->start, resource_size(gpio_res));
+- if (!host->gpio_base) {
+- ret = -ENOMEM;
+- goto fail4;
+- }
+-
+-#ifdef USE_DMA
+- host->dma_base = __io_address(dma_res->start);
+-
+- if (!host->dma_base) {
+- ret = -ENOMEM;
+- goto fail5;
+- }
+-
+- // USE DMA5 channel
+- host->dma_base = (void __iomem *)((char *) host->dma_base + (SDHOST_DMA_CHANNEL * 0x100));
+-
+- dev_dbg(&pdev->dev, "%s: using dma channel %d for sdhost\n", __func__, SDHOST_DMA_CHANNEL);
+-
+- /*
+- * Grab interrupts.
+- */
+-#ifdef USE_DMA_IRQ
+- dat_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+- if (!dat_res) {
+- ret = -ENXIO;
+- dev_dbg(&pdev->dev, "couldn't allocate irq for dma\n");
+- goto fail5;
+- }
+-
+- ret = request_irq(dat_res->start, bcm2708_mci_data_irq, 0, DRIVER_NAME " (dat)", host);
+- if (ret) {
+- goto fail5;
+- }
+- dev_dbg(&pdev->dev, "%s: using dma interrupt number %d for sdhost\n", __func__, dat_res->start);
+-
+-#endif
+-#endif
+-
+- host->present = bcm2708_mci_get_cd(host->mmc);
+-
+- sddet_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+- if (!sddet_res) {
+- ret = -ENXIO;
+- dev_dbg(&pdev->dev, "couldn't allocate irq for sd detect\n");
+- goto fail6;
+- }
+-
+- ret = request_irq(sddet_res->start, bcm2708_mci_sddet_irq, 0, DRIVER_NAME " (cmd)", host);
+- if (ret) {
+- goto fail6;
+- }
+-
+- host->is_acmd = 0;
+-
+- mmc->ops = &bcm2708_mci_ops;
+- mmc->f_min = 200000;
+- mmc->f_max = 52000000;
+- mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+-
+- /*
+- * We can do SGIO
+- */
+- mmc->max_segs = NR_SG;
+-
+- /*
+- * Since we only have a 16-bit data length register, we must
+- * ensure that we don't exceed 2^16-1 bytes in a single request.
+- */
+- mmc->max_req_size = 65535;
+-
+- /*
+- * Set the maximum segment size. Since we aren't doing DMA
+- * (yet) we are only limited by the data length register.
+- */
+- mmc->max_seg_size = mmc->max_req_size;
+-
+- /*
+- * Block size can be up to 2048 bytes, but must be a power of two.
+- */
+- mmc->max_blk_size = 2048;
+-
+- /*
+- * No limit on the number of blocks transferred.
+- */
+- mmc->max_blk_count = mmc->max_req_size;
+-
+- /*
+- * We support 4-bit data (at least on the DB)
+- */
+-
+- mmc->caps |= (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED) ;
+-
+- bcm2708_mci_reset(host);
+-
+- mmc_add_host(mmc);
+-
+- printk(KERN_INFO "%s: BCM2708 SD host at 0x%08llx 0x%08llx\n",
+- mmc_hostname(mmc),
+- (unsigned long long)mmc_res->start, (unsigned long long)dma_res->start);
+-
+- return 0;
+-
+-fail6:
+-#ifdef USE_DMA_IRQ
+- free_irq(dat_res->start, host);
+-#endif
+-fail5:
+- iounmap(host->gpio_base);
+-fail4:
+- iounmap(host->mmc_base);
+-fail3:
+- release_mem_region(mmc_res->start, mmc_res->end - mmc_res->start + 1);
+-fail2:
+- dma_free_writecombine(&pdev->dev, SZ_4K, host->cb_base, host->cb_handle);
+-fail1:
+- mmc_free_host(mmc);
+-fail0:
+- dev_err(&pdev->dev, "probe failed, err %d\n", ret);
+- return ret;
+-}
+-
+-static int __devexit bcm2708_mci_remove(struct platform_device *pdev)
+-{
+- struct mmc_host *mmc = platform_get_drvdata(pdev);
+-
+- if (mmc) {
+- struct bcm2708_mci_host *host = mmc_priv(mmc);
+- struct resource *res;
+- struct resource *res2;
+-
+- mmc_remove_host(mmc);
+-#ifdef USE_DMA
+-#ifdef USE_DMA_IRQ
+- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+- free_irq(res->start, host);
+-#endif
+-#endif
+-
+- res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+- free_irq(res2->start, host);
+-
+- iounmap(host->mmc_base);
+- iounmap(host->gpio_base);
+- iounmap(host->dma_base);
+-
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- release_mem_region(res->start, resource_size(res));
+-#ifdef USE_DMA
+- dma_free_writecombine(&pdev->dev, SZ_4K, host->cb_base, host->cb_handle);
+-#endif
+-
+- mmc_free_host(mmc);
+- platform_set_drvdata(pdev, NULL);
+-
+- return 0;
+- } else
+- return -1;
+-}
+-
+-#ifdef CONFIG_PM
+-static int bcm2708_mci_suspend(struct platform_device *dev, pm_message_t state)
+-{
+- struct mmc_host *mmc = platform_get_drvdata(dev);
+- int ret = 0;
+-
+- if (mmc) {
+- ret = mmc_suspend_host(mmc);
+- }
+-
+- return ret;
+-}
+-
+-static int bcm2708_mci_resume(struct platform_device *dev)
+-{
+- struct mmc_host *mmc = platform_get_drvdata(dev);
+- int ret = 0;
+-
+- if (mmc) {
+- ret = mmc_resume_host(mmc);
+- }
+-
+- return ret;
+-}
+-#else
+-#define bcm2708_mci_suspend NULL
+-#define bcm2708_mci_resume NULL
+-#endif
+-
+-static struct platform_driver bcm2708_mci_driver = {
+- .probe = bcm2708_mci_probe,
+- .remove = bcm2708_mci_remove,
+- .suspend = bcm2708_mci_suspend,
+- .resume = bcm2708_mci_resume,
+- .driver = {
+- .name = DRIVER_NAME,
+- .owner = THIS_MODULE,
+- },
+-};
+-
+-static int __init bcm2708_mci_init(void)
+-{
+- return platform_driver_register(&bcm2708_mci_driver);
+-}
+-
+-static void __exit bcm2708_mci_exit(void)
+-{
+- platform_driver_unregister(&bcm2708_mci_driver);
+-}
+-
+-module_init(bcm2708_mci_init);
+-module_exit(bcm2708_mci_exit);
+-
+-MODULE_DESCRIPTION("BCM2708 Multimedia Card Interface driver");
+-MODULE_LICENSE("GPL");
+-MODULE_ALIAS("platform:bcm2708_mci");
+diff --git a/drivers/mmc/host/bcm2708_mci.h b/drivers/mmc/host/bcm2708_mci.h
+deleted file mode 100644
+index b2851d9..0000000
+--- a/drivers/mmc/host/bcm2708_mci.h
++++ /dev/null
+@@ -1,101 +0,0 @@
+-/*
+- * linux/drivers/mmc/host/bcm2708_mci.c - Broadcom BCM2708 MCI driver
+- *
+- * Copyright (C) 2010 Broadcom, All Rights Reserved.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+- */
+-
+-struct clk;
+-
+-#define BCM2708_MCI_COMMAND 0x00
+-
+-#define BCM2708_MCI_READ (1 << 6)
+-#define BCM2708_MCI_WRITE (1 << 7)
+-#define BCM2708_MCI_LONGRESP (1 << 9)
+-#define BCM2708_MCI_NORESP (1 << 10)
+-#define BCM2708_MCI_BUSY (1 << 11)
+-#define BCM2708_MCI_FAIL_FLAG (1 << 14)
+-#define BCM2708_MCI_ENABLE (1 << 15)
+-
+-#define BCM2708_MCI_ARGUMENT 0x04
+-
+-#define BCM2708_MCI_TIMEOUT 0x08
+-#define BCM2708_MCI_CLKDIV 0x0c
+-
+-
+-#define BCM2708_MCI_RESPONSE0 0x10
+-#define BCM2708_MCI_RESPONSE1 0x14
+-#define BCM2708_MCI_RESPONSE2 0x18
+-#define BCM2708_MCI_RESPONSE3 0x1c
+-
+-#define BCM2708_MCI_STATUS 0x20
+-
+-#define BCM2708_MCI_VDD 0x30
+-#define BCM2708_MCI_VDD_ENABLE (1 << 0)
+-
+-#define BCM2708_MCI_EDM 0x34
+-
+-#define BCM2708_MCI_HOSTCONFIG 0x38
+-
+-#define BCM2708_MCI_HOSTCONFIG_WIDE_INT_BUS 0x2
+-#define BCM2708_MCI_HOSTCONFIG_WIDEEXT_4BIT 0x4
+-#define BCM2708_MCI_HOSTCONFIG_SLOW_CARD 0x8
+-#define BCM2708_MCI_HOSTCONFIG_BLOCK_IRPT_EN (1<<8)
+-#define BCM2708_MCI_HOSTCONFIG_BUSY_IRPT_EN (1<<10)
+-#define BCM2708_MCI_HOSTCONFIG_WIDEEXT_CLR 0xFFFFFFFB
+-
+-
+-#define BCM2708_MCI_DATAFLAG (1 << 0)
+-#define BCM2708_MCI_CMDTIMEOUT (1 << 6)
+-#define BCM2708_MCI_HSTS_BLOCK (1 << 9) /**< block flag in status reg */
+-#define BCM2708_MCI_HSTS_BUSY (1 << 10) /**< Busy flag in status reg */
+-
+-#define BCM2708_MCI_HBCT 0x3c
+-#define BCM2708_MCI_DATA 0x40
+-#define BCM2708_MCI_HBLC 0x50
+-
+-#define NR_SG 16
+-
+-typedef struct bulk_data_struct
+-{
+- unsigned long info;
+- unsigned long src;
+- unsigned long dst;
+- unsigned long length;
+- unsigned long stride;
+- unsigned long next;
+- unsigned long pad[2];
+-} BCM2708_DMA_CB_T;
+-
+-struct bcm2708_mci_host {
+- struct platform_device *dev;
+-
+- void __iomem *mmc_base;
+- void __iomem *dma_base;
+- void __iomem *gpio_base;
+-
+- BCM2708_DMA_CB_T *cb_base;
+- dma_addr_t cb_handle;
+-
+- struct mmc_host *mmc;
+-
+- struct semaphore sem;
+-
+- int is_acmd;
+- int present;
+-};
+-
+-static inline char *bcm2708_mci_kmap_atomic(struct scatterlist *sg, unsigned long *flags)
+-{
+-// local_irq_save(*flags);
+- return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
+-}
+-
+-static inline void bcm2708_mci_kunmap_atomic(void *buffer, unsigned long *flags)
+-{
+- kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
+-// local_irq_restore(*flags);
+-}
+diff --git a/drivers/mmc/host/sdhci-bcm2708.c b/drivers/mmc/host/sdhci-bcm2708.c
+index 80e4228..c6f943e 100644
+--- a/drivers/mmc/host/sdhci-bcm2708.c
++++ b/drivers/mmc/host/sdhci-bcm2708.c
+@@ -33,7 +33,6 @@
+ #include <linux/io.h>
+ #include <linux/dma-mapping.h>
+ #include <mach/dma.h>
+-#include <mach/power.h>
+
+ #include "sdhci.h"
+
+@@ -75,10 +74,6 @@
+ /* Mhz clock that the EMMC core is running at. Should match the platform clockman settings */
+ #define BCM2708_EMMC_CLOCK_FREQ 50000000
+
+-#define POWER_OFF 0
+-#define POWER_LAZY_OFF 1
+-#define POWER_ON 2
+-
+ #define REG_EXRDFIFO_EN 0x80
+ #define REG_EXRDFIFO_CFG 0x84
+
+@@ -386,10 +381,6 @@ struct sdhci_bcm2708_priv {
+ /* tracking scatter gather progress */
+ unsigned sg_ix; /* scatter gather list index */
+ unsigned sg_done; /* bytes in current sg_ix done */
+- /* power management */
+- BCM_POWER_HANDLE_T power_handle;
+- unsigned char power_state; /* enable/disable power state */
+- unsigned char power_mode; /* last set power mode */
+ #ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+ unsigned char dma_wanted; /* DMA transfer requested */
+ unsigned char dma_waits; /* wait states in DMAs */
+@@ -1043,7 +1034,6 @@ static ssize_t attr_status_show(struct device *_dev,
+
+ if (host) {
+ struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+- int power_state = host_priv->power_state;
+ return sprintf(buf,
+ "present: yes\n"
+ "power: %s\n"
+@@ -1053,10 +1043,7 @@ static ssize_t attr_status_show(struct device *_dev,
+ #else
+ "dma: unconfigured\n",
+ #endif
+- power_state == POWER_ON? "on":
+- power_state == POWER_OFF? "off":
+- power_state == POWER_LAZY_OFF? "lazy-off":
+- "<unknown>",
++ "always on",
+ host->clock
+ #ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+ , (host->flags & SDHCI_USE_PLATDMA)? "on": "off"
+@@ -1105,110 +1092,6 @@ static int sdhci_bcm2708_resume(struct platform_device *dev)
+ #endif
+
+
+-/* Click forwards one step towards fully on */
+-static int sdhci_bcm2708_enable(struct sdhci_host *host)
+-{
+- int rc;
+- struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+-
+- if (host_priv->power_state == POWER_OFF) {
+- /* warning: may schedule - don't call in irq mode */
+- rc = bcm_power_request(host_priv->power_handle,
+- BCM_POWER_SDCARD);
+-
+- if (rc == 0) {
+- mmc_power_restore_host(host->mmc);
+- host_priv->power_state = POWER_ON;
+- } else if (rc != -EINTR)
+- printk(KERN_ERR "%s: mmc power up request failed - "
+- "rc %d\n",
+- mmc_hostname(host->mmc), rc);
+- } else {
+- host_priv->power_state = POWER_ON;
+- rc = 0;
+- }
+-
+- return rc;
+-}
+-
+-/* Click backwards one step towards fully off */
+-static int sdhci_bcm2708_disable(struct sdhci_host *host, int lazy)
+-{
+- int rc;
+- struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+-
+- if ((host_priv->power_state == POWER_ON) && lazy) {
+- host_priv->power_state = POWER_LAZY_OFF;
+- return BCM2708_SDHCI_SLEEP_TIMEOUT;
+- }
+-
+- /* warning: may schedule - don't call in irq mode */
+- rc = bcm_power_request(host_priv->power_handle, BCM_POWER_NONE);
+-
+- if (rc == 0)
+- host_priv->power_state = POWER_OFF;
+- else if (rc != -EINTR)
+- printk(KERN_ERR "%s: mmc power down request failed - rc %d\n",
+- mmc_hostname(host->mmc), rc);
+-
+- return rc;
+-}
+-
+-static int sdhci_bcm2708_set_plat_power(struct sdhci_host *host,
+- int power_mode)
+-{
+- struct sdhci_bcm2708_priv *host_priv = SDHCI_HOST_PRIV(host);
+- int rc;
+-
+- do {
+- rc = mmc_host_enable(host->mmc);
+- } while (-EINTR == rc);
+-
+- if (rc == 0) do {
+- if (rc == 0 && power_mode != host_priv->power_mode)
+- {
+- switch (power_mode)
+- {
+- case MMC_POWER_OFF:
+- rc = bcm_power_request(host_priv->power_handle,
+- BCM_POWER_NONE);
+- break;
+-
+- case MMC_POWER_UP:
+- rc = bcm_power_request(host_priv->power_handle,
+- BCM_POWER_SDCARD);
+- /*
+- * We need an extra 10ms delay of 10ms before we
+- * can apply clock after applying power
+- */
+- if (rc == 0)
+- mdelay(10);
+- break;
+-
+- case MMC_POWER_ON:
+- mdelay(10);
+- /* do_send_init_stream = 1; */
+- break;
+- }
+-
+- if (rc == 0)
+- host_priv->power_mode = power_mode;
+- }
+- } while (-EINTR == rc);
+-
+- if (rc == 0) do {
+- if (rc == 0) {
+- if (power_mode == MMC_POWER_OFF)
+- rc = mmc_host_disable(host->mmc);
+- else
+- rc = mmc_host_lazy_disable(host->mmc);
+- }
+-
+- } while (-EINTR == rc);
+-
+- return rc;
+-}
+-
+ /*****************************************************************************\
+ * *
+ * Device quirk functions. Implemented as local ops because the flags *
+@@ -1259,10 +1142,6 @@ static struct sdhci_ops sdhci_bcm2708_ops = {
+ #endif
+ .get_max_clock = sdhci_bcm2708_get_max_clock,
+
+- .enable = sdhci_bcm2708_enable,
+- .disable = sdhci_bcm2708_disable,
+- .set_plat_power = sdhci_bcm2708_set_plat_power,
+-
+ #ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+ // Platform DMA operations
+ .pdma_able = sdhci_bcm2708_platdma_dmaable,
+@@ -1350,11 +1229,6 @@ static int __devinit sdhci_bcm2708_probe(struct platform_device *pdev)
+
+ host_priv = SDHCI_HOST_PRIV(host);
+
+- host_priv->power_state = POWER_ON;
+- ret = bcm_power_open(&host_priv->power_handle);
+- if (ret != 0)
+- goto err_power;
+-
+ #ifdef CONFIG_MMC_SDHCI_BCM2708_DMA
+ host_priv->dma_wanted = 0;
+ #ifdef CHECK_DMA_USE
+@@ -1436,8 +1310,6 @@ err_add_dma:
+ host_priv->cb_handle);
+ err_alloc_cb:
+ #endif
+- bcm_power_close(host_priv->power_handle);
+-err_power:
+ iounmap(host->ioaddr);
+ err_remap:
+ release_mem_region(iomem->start, resource_size(iomem));
+@@ -1470,7 +1342,6 @@ static int __devexit sdhci_bcm2708_remove(struct platform_device *pdev)
+ dma_free_writecombine(&pdev->dev, SZ_4K, host_priv->cb_base,
+ host_priv->cb_handle);
+ #endif
+- bcm_power_close(host_priv->power_handle);
+ sdhci_remove_host(host, dead);
+ iounmap(host->ioaddr);
+ release_mem_region(iomem->start, resource_size(iomem));
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index 9b7a727..0fd8107 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -1351,35 +1351,6 @@ static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
+ return power;
+ }
+
+-/* Power on or off the circuitary supporting the register set */
+-static int sdhci_set_plat_power(struct sdhci_host *host, int power_mode)
+-{
+- if (host->ops->set_plat_power)
+- return host->ops->set_plat_power(host, power_mode);
+- else
+- return 0;
+-}
+-
+-/* Click forwards one step towards fully on */
+-static int sdhci_enable(struct mmc_host *mmc)
+-{
+- struct sdhci_host *host;
+-
+- host = mmc_priv(mmc);
+-
+- return host->ops->enable? host->ops->enable(host): 0;
+-}
+-
+-/* Click backwards one step towards fully off */
+-static int sdhci_disable(struct mmc_host *mmc, int lazy)
+-{
+- struct sdhci_host *host;
+-
+- host = mmc_priv(mmc);
+-
+- return host->ops->disable? host->ops->disable(host, lazy): 0;
+-}
+-
+ /*****************************************************************************\
+ * *
+ * MMC callbacks *
+@@ -1469,7 +1440,6 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
+ unsigned long flags;
+ int vdd_bit = -1;
+ u8 ctrl;
+- int rc;
+
+ sdhci_spin_lock_irqsave(host, &flags);
+
+@@ -1630,12 +1600,6 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
+
+ mmiowb();
+ sdhci_spin_unlock_irqrestore(host, flags);
+-
+- if (ios->power_mode == MMC_POWER_OFF) {
+- do
+- rc = sdhci_set_plat_power(host, ios->power_mode);
+- while (rc == -EINTR);
+- }
+ }
+
+ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+@@ -2101,8 +2065,6 @@ static const struct mmc_host_ops sdhci_ops = {
+ .start_signal_voltage_switch = sdhci_start_signal_voltage_switch,
+ .execute_tuning = sdhci_execute_tuning,
+ .enable_preset_value = sdhci_enable_preset_value,
+- .enable = sdhci_enable,
+- .disable = sdhci_disable,
+ };
+
+ /*****************************************************************************\
+@@ -2638,12 +2600,6 @@ int sdhci_resume_host(struct sdhci_host *host)
+ {
+ int ret;
+
+- if (host->vmmc) {
+- int ret = regulator_enable(host->vmmc);
+- if (ret)
+- return ret;
+- }
+-
+ if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA |
+ SDHCI_USE_PLATDMA)) {
+ if (host->ops->enable_dma)
+diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
+index 5503909..9270ff4 100644
+--- a/drivers/mmc/host/sdhci.h
++++ b/drivers/mmc/host/sdhci.h
+@@ -276,11 +276,6 @@ struct sdhci_ops {
+ void (*platform_reset_exit)(struct sdhci_host *host, u8 mask);
+ int (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
+
+- int (*enable)(struct sdhci_host *mmc);
+- int (*disable)(struct sdhci_host *mmc, int lazy);
+- int (*set_plat_power)(struct sdhci_host *mmc,
+- int power_mode);
+-
+ int (*pdma_able)(struct sdhci_host *host,
+ struct mmc_data *data);
+ void (*pdma_avail)(struct sdhci_host *host,
+diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c
+index 72454d4..091510b 100644
+--- a/drivers/thermal/bcm2835-thermal.c
++++ b/drivers/thermal/bcm2835-thermal.c
+@@ -164,7 +164,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev)
+ return -ENODEV;
+ }
+
+- if(!(bcm2835_data.thermal_dev = thermal_zone_device_register("bcm2835_thermal", 1, NULL, &ops,1,1,1000,1000)))
++ if(!(bcm2835_data.thermal_dev = thermal_zone_device_register("bcm2835_thermal", 1, 0, NULL, &ops,1,1,1000,1000)))
+ {
+ print_debug("Unable to register the thermal device!");
+ return -EFAULT;
+diff --git a/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c
+index 9289fc0..903e670 100644
+--- a/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c
+@@ -1164,7 +1164,7 @@ static struct gadget_wrapper *alloc_wrapper(dwc_bus_dev_t *_dev)
+ d->gadget.dev.parent = &_dev->dev;
+ d->gadget.dev.release = dwc_otg_pcd_gadget_release;
+ d->gadget.ops = &dwc_otg_pcd_ops;
+- d->gadget.is_dualspeed = dwc_otg_pcd_is_dualspeed(otg_dev->pcd);
++ d->gadget.max_speed = dwc_otg_pcd_is_dualspeed(otg_dev->pcd) ? USB_SPEED_HIGH:USB_SPEED_FULL;
+ d->gadget.is_otg = dwc_otg_pcd_is_otg(otg_dev->pcd);
+
+ d->driver = 0;
+@@ -1296,7 +1296,7 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+ DWC_DEBUGPL(DBG_PCD, "registering gadget driver '%s'\n",
+ driver->driver.name);
+
+- if (!driver || driver->speed == USB_SPEED_UNKNOWN ||
++ if (!driver || driver->max_speed == USB_SPEED_UNKNOWN ||
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
+ !driver->bind ||
+ #else
+diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig
+index 3577572..f7ceafd 100644
+--- a/sound/arm/Kconfig
++++ b/sound/arm/Kconfig
+@@ -41,7 +41,7 @@ config SND_PXA2XX_AC97
+
+ config SND_BCM2835
+ tristate "BCM2835 ALSA driver"
+- depends on ARCH_BCM2708 && SND
++ depends on ARCH_BCM2708 && BCM2708_VCHIQ && SND
+ select SND_PCM
+ help
+ Say Y or M if you want to support BCM2835 Alsa pcm card driver
diff --git a/patches/linux-3.6.7/0161-Add-vc_cma-driver-to-enable-use-of-CMA.patch b/patches/linux-3.6.7/0161-Add-vc_cma-driver-to-enable-use-of-CMA.patch
new file mode 100644
index 0000000..afc7d79
--- /dev/null
+++ b/patches/linux-3.6.7/0161-Add-vc_cma-driver-to-enable-use-of-CMA.patch
@@ -0,0 +1,97 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Sun, 21 Oct 2012 19:35:39 +0100
+Subject: [PATCH] Add vc_cma driver to enable use of CMA
+
+---
+ arch/arm/mach-bcm2708/bcm2708.c | 18 ++++++++++++++++++
+ drivers/char/Kconfig | 2 ++
+ drivers/char/Makefile | 3 +++
+ drivers/misc/Makefile | 3 +--
+ 4 files changed, 24 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
+index 02cb556..a3fd1e7 100644
+--- a/arch/arm/mach-bcm2708/bcm2708.c
++++ b/arch/arm/mach-bcm2708/bcm2708.c
+@@ -60,6 +60,11 @@
+ #include "armctrl.h"
+ #include "clock.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
+@@ -673,6 +678,9 @@ 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;
+
+@@ -900,7 +908,16 @@ void __init bcm2708_init_early(void)
+ * context. Increase size of atomic coherent pool to make sure such
+ * the allocations won't fail.
+ */
++#if !defined(CONFIG_BCM_VC_CMA)
+ init_dma_coherent_pool_size(SZ_2M);
++#endif
++}
++
++static void __init board_reserve(void)
++{
++#if defined(CONFIG_BCM_VC_CMA)
++ vc_cma_reserve();
++#endif
+ }
+
+ MACHINE_START(BCM2708, "BCM2708")
+@@ -910,6 +927,7 @@ MACHINE_START(BCM2708, "BCM2708")
+ .timer =&bcm2708_timer,
+ .init_machine = bcm2708_init,
+ .init_early = bcm2708_init_early,
++ .reserve = board_reserve,
+ MACHINE_END
+
+ module_param(boardrev, uint, 0644);
+diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
+index ea6f632..fa42532 100644
+--- a/drivers/char/Kconfig
++++ b/drivers/char/Kconfig
+@@ -585,6 +585,8 @@ config DEVPORT
+
+ source "drivers/s390/char/Kconfig"
+
++source "drivers/char/broadcom/Kconfig"
++
+ config MSM_SMD_PKT
+ bool "Enable device interface for some SMD packet ports"
+ default n
+diff --git a/drivers/char/Makefile b/drivers/char/Makefile
+index d0b27a3..0b3f87a 100644
+--- a/drivers/char/Makefile
++++ b/drivers/char/Makefile
+@@ -63,3 +63,6 @@ obj-$(CONFIG_JS_RTC) += js-rtc.o
+ js-rtc-y = rtc.o
+
+ obj-$(CONFIG_TILE_SROM) += tile-srom.o
++
++obj-$(CONFIG_BRCM_CHAR_DRIVERS) += broadcom/
++
+diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
+index aeeb47e..dc9072b 100644
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -50,5 +50,4 @@ obj-y += carma/
+ obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
+ obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
+ obj-$(CONFIG_INTEL_MEI) += mei/
+-obj-y += vc04_services/
+-
++obj-$(CONFIG_BCM2708_VCHIQ) += vc04_services/
diff --git a/patches/linux-3.6.7/0162-Add-missing-CMA-files.patch b/patches/linux-3.6.7/0162-Add-missing-CMA-files.patch
new file mode 100644
index 0000000..72fc13c
--- /dev/null
+++ b/patches/linux-3.6.7/0162-Add-missing-CMA-files.patch
@@ -0,0 +1,998 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Tue, 23 Oct 2012 17:00:13 +0100
+Subject: [PATCH] Add missing CMA files
+
+---
+ drivers/char/broadcom/Kconfig | 18 +
+ drivers/char/broadcom/Makefile | 2 +
+ drivers/char/broadcom/vc_cma/Makefile | 15 +
+ drivers/char/broadcom/vc_cma/vc_cma.c | 886 ++++++++++++++++++++++++++++++++++
+ include/linux/broadcom/vc_cma.h | 30 ++
+ 5 files changed, 951 insertions(+)
+ create mode 100644 drivers/char/broadcom/Kconfig
+ create mode 100644 drivers/char/broadcom/Makefile
+ create mode 100644 drivers/char/broadcom/vc_cma/Makefile
+ create mode 100644 drivers/char/broadcom/vc_cma/vc_cma.c
+ create mode 100644 include/linux/broadcom/vc_cma.h
+
+diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig
+new file mode 100644
+index 0000000..9790e31
+--- /dev/null
++++ b/drivers/char/broadcom/Kconfig
+@@ -0,0 +1,18 @@
++#
++# Broadcom char driver config
++#
++
++menuconfig BRCM_CHAR_DRIVERS
++ tristate "Broadcom Char Drivers"
++ depends on PROC_FS
++ help
++ Broadcom's char drivers
++
++config BCM_VC_CMA
++ tristate "Videocore CMA"
++ #depends on BCM_VC_SERVICES
++ depends on CMA
++ default n
++ help
++ Helper for videocore CMA access.
++
+diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile
+new file mode 100644
+index 0000000..c8574c8
+--- /dev/null
++++ b/drivers/char/broadcom/Makefile
+@@ -0,0 +1,2 @@
++obj-$(CONFIG_BCM_VC_CMA) += vc_cma/
++
+diff --git a/drivers/char/broadcom/vc_cma/Makefile b/drivers/char/broadcom/vc_cma/Makefile
+new file mode 100644
+index 0000000..ae71918
+--- /dev/null
++++ b/drivers/char/broadcom/vc_cma/Makefile
+@@ -0,0 +1,15 @@
++EXTRA_CFLAGS += -Wall -Wstrict-prototypes -Wno-trigraphs
++EXTRA_CFLAGS += -Werror
++EXTRA_CFLAGS += -I"include/linux/broadcom"
++EXTRA_CFLAGS += -I"drivers/misc/vc04_services"
++EXTRA_CFLAGS += -I"drivers/misc/vc04_services/interface/vchi"
++EXTRA_CFLAGS += -I"drivers/misc/vc04_services/interface/vchiq_arm"
++
++EXTRA_CFLAGS += -D__KERNEL__
++EXTRA_CFLAGS += -D__linux__
++EXTRA_CFLAGS += -Werror
++
++obj-$(CONFIG_BCM_VC_CMA) += vc-cma.o
++
++vc-cma-objs := vc_cma.o
++
+diff --git a/drivers/char/broadcom/vc_cma/vc_cma.c b/drivers/char/broadcom/vc_cma/vc_cma.c
+new file mode 100644
+index 0000000..ec7aef1
+--- /dev/null
++++ b/drivers/char/broadcom/vc_cma/vc_cma.c
+@@ -0,0 +1,886 @@
++/*****************************************************************************
++* Copyright 2012 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/kthread.h>
++#include <linux/fs.h>
++#include <linux/device.h>
++#include <linux/cdev.h>
++#include <linux/mm.h>
++#include <linux/proc_fs.h>
++#include <linux/seq_file.h>
++#include <linux/dma-mapping.h>
++#include <linux/dma-contiguous.h>
++#include <linux/platform_device.h>
++#include <linux/uaccess.h>
++
++
++#include "vc_cma.h"
++
++#include "vchiq_util.h"
++#include "vchiq_connected.h"
++
++#define DRIVER_NAME "vc-cma"
++
++#define LOG_DBG(fmt, ...) \
++ if (vc_cma_debug) \
++ printk(KERN_INFO fmt "\n", ##__VA_ARGS__)
++#define LOG_ERR(fmt, ...) \
++ printk(KERN_ERR fmt "\n", ##__VA_ARGS__)
++
++#define VC_CMA_FOURCC VCHIQ_MAKE_FOURCC('C', 'M', 'A', ' ')
++#define VC_CMA_VERSION 2
++
++#define VC_CMA_CHUNK_ORDER 6 /* 256K */
++#define VC_CMA_CHUNK_SIZE (4096 << VC_CMA_CHUNK_ORDER)
++#define VC_CMA_MAX_PARAMS_PER_MSG \
++ ((VCHIQ_MAX_MSG_SIZE - sizeof(unsigned short))/sizeof(unsigned short))
++#define VC_CMA_RESERVE_COUNT_MAX 16
++
++#define PAGES_PER_CHUNK (VC_CMA_CHUNK_SIZE / PAGE_SIZE)
++
++enum {
++ VC_CMA_MSG_QUIT,
++ VC_CMA_MSG_OPEN,
++ VC_CMA_MSG_TICK,
++ VC_CMA_MSG_ALLOC, /* chunk count */
++ VC_CMA_MSG_FREE, /* chunk, chunk, ... */
++ VC_CMA_MSG_ALLOCATED, /* chunk, chunk, ... */
++ VC_CMA_MSG_REQUEST_ALLOC, /* chunk count */
++ VC_CMA_MSG_REQUEST_FREE, /* chunk count */
++ VC_CMA_MSG_RESERVE, /* bytes lo, bytes hi */
++ VC_CMA_MSG_UPDATE_RESERVE,
++ VC_CMA_MSG_MAX
++};
++
++struct cma_msg {
++ unsigned short type;
++ unsigned short params[VC_CMA_MAX_PARAMS_PER_MSG];
++};
++
++struct vc_cma_reserve_user {
++ unsigned int pid;
++ unsigned int reserve;
++};
++
++/* Device (/dev) related variables */
++static dev_t vc_cma_devnum;
++static struct class *vc_cma_class;
++static struct cdev vc_cma_cdev;
++static int vc_cma_inited;
++static int vc_cma_debug;
++
++/* Proc entry */
++static struct proc_dir_entry *vc_cma_proc_entry;
++
++phys_addr_t vc_cma_base;
++struct page *vc_cma_base_page;
++unsigned int vc_cma_size;
++EXPORT_SYMBOL(vc_cma_size);
++unsigned int vc_cma_initial;
++unsigned int vc_cma_chunks;
++unsigned int vc_cma_chunks_used;
++unsigned int vc_cma_chunks_reserved;
++
++unsigned int vc_cma_reserve_total;
++unsigned int vc_cma_reserve_count;
++struct vc_cma_reserve_user vc_cma_reserve_users[VC_CMA_RESERVE_COUNT_MAX];
++static DEFINE_SEMAPHORE(vc_cma_reserve_mutex);
++static DEFINE_SEMAPHORE(vc_cma_worker_queue_push_mutex);
++
++static u64 vc_cma_dma_mask = DMA_BIT_MASK(32);
++static struct platform_device vc_cma_device = {
++ .name = "vc-cma",
++ .id = 0,
++ .dev = {
++ .dma_mask = &vc_cma_dma_mask,
++ .coherent_dma_mask = DMA_BIT_MASK(32),
++ },
++};
++
++static VCHIQ_INSTANCE_T cma_instance;
++static VCHIQ_SERVICE_HANDLE_T cma_service;
++static VCHIU_QUEUE_T cma_msg_queue;
++static struct task_struct *cma_worker;
++
++static int vc_cma_set_reserve(unsigned int reserve, unsigned int pid);
++static int vc_cma_alloc_chunks(int num_chunks, struct cma_msg *reply);
++static VCHIQ_STATUS_T cma_service_callback(
++ VCHIQ_REASON_T reason,
++ VCHIQ_HEADER_T *header,
++ VCHIQ_SERVICE_HANDLE_T service,
++ void *bulk_userdata);
++static void send_vc_msg(
++ unsigned short type,
++ unsigned short param1,
++ unsigned short param2);
++static bool send_worker_msg(VCHIQ_HEADER_T *msg);
++
++static int __init early_vc_cma_mem(char *p)
++{
++ unsigned int new_size;
++ printk(KERN_ERR "early_vc_cma_mem(%s)", p);
++ vc_cma_size = memparse(p, &p);
++ vc_cma_initial = vc_cma_size;
++ if (*p == '/')
++ vc_cma_size = memparse(p + 1, &p);
++ if (*p == '@')
++ vc_cma_base = memparse(p + 1, &p);
++
++ new_size = (vc_cma_size - ((-vc_cma_base) & (VC_CMA_CHUNK_SIZE - 1)))
++ & ~(VC_CMA_CHUNK_SIZE - 1);
++ if (new_size > vc_cma_size)
++ vc_cma_size = 0;
++ vc_cma_initial = (vc_cma_initial + VC_CMA_CHUNK_SIZE - 1)
++ & ~(VC_CMA_CHUNK_SIZE - 1);
++ if (vc_cma_initial > vc_cma_size)
++ vc_cma_initial = vc_cma_size;
++ vc_cma_base = (vc_cma_base + VC_CMA_CHUNK_SIZE - 1)
++ & ~(VC_CMA_CHUNK_SIZE - 1);
++
++ printk(KERN_ERR " -> initial %x, size %x, base %x", vc_cma_initial,
++ vc_cma_size, (unsigned int)vc_cma_base);
++
++ return 0;
++}
++
++early_param("vc-cma-mem", early_vc_cma_mem);
++
++void __init vc_cma_early_init(void)
++{
++ LOG_DBG("vc_cma_early_init - vc_cma_chunks = %d", vc_cma_chunks);
++ if (vc_cma_size) {
++ int rc = platform_device_register(&vc_cma_device);
++ LOG_DBG("platform_device_register -> %d", rc);
++ }
++}
++
++void __init vc_cma_reserve(void)
++{
++ /* if vc_cma_size is set, then declare vc CMA area of the same
++ * size from the end of memory
++ */
++ if (vc_cma_size) {
++ if (dma_declare_contiguous(&vc_cma_device.dev, vc_cma_size,
++ vc_cma_base, 0) == 0) {
++ } else {
++ LOG_ERR("vc_cma: dma_declare_contiguous(%x,%x) failed",
++ vc_cma_size, (unsigned int)vc_cma_base);
++ vc_cma_size = 0;
++ }
++ }
++ vc_cma_chunks = vc_cma_size / VC_CMA_CHUNK_SIZE;
++}
++
++/****************************************************************************
++*
++* vc_cma_open
++*
++***************************************************************************/
++
++static int vc_cma_open(struct inode *inode, struct file *file)
++{
++ (void)inode;
++ (void)file;
++
++ return 0;
++}
++
++/****************************************************************************
++*
++* vc_cma_release
++*
++***************************************************************************/
++
++static int vc_cma_release(struct inode *inode, struct file *file)
++{
++ (void)inode;
++ (void)file;
++
++ vc_cma_set_reserve(0, current->tgid);
++
++ return 0;
++}
++
++/****************************************************************************
++*
++* vc_cma_ioctl
++*
++***************************************************************************/
++
++static long vc_cma_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
++{
++ int rc = 0;
++
++ (void)cmd;
++ (void)arg;
++
++ switch (cmd) {
++ case VC_CMA_IOC_RESERVE:
++ rc = vc_cma_set_reserve((unsigned int)arg, current->tgid);
++ if (rc >= 0)
++ rc = 0;
++ break;
++ default:
++ LOG_ERR("vc-cma: Unknown ioctl %x", cmd);
++ return -ENOTTY;
++ }
++
++ return rc;
++}
++
++
++/****************************************************************************
++*
++* File Operations for the driver.
++*
++***************************************************************************/
++
++static const struct file_operations vc_cma_fops = {
++ .owner = THIS_MODULE,
++ .open = vc_cma_open,
++ .release = vc_cma_release,
++ .unlocked_ioctl = vc_cma_ioctl,
++};
++
++/****************************************************************************
++*
++* vc_cma_proc_open
++*
++***************************************************************************/
++
++static int vc_cma_show_info(struct seq_file *m, void *v)
++{
++ int i;
++
++ seq_printf(m, "Videocore CMA:\n");
++ seq_printf(m, " Base : %08x\n", (unsigned int)vc_cma_base);
++ seq_printf(m, " Length : %08x\n", vc_cma_size);
++ seq_printf(m, " Initial : %08x\n", vc_cma_initial);
++ seq_printf(m, " Chunk size : %08x\n", VC_CMA_CHUNK_SIZE);
++ seq_printf(m, " Chunks : %4d (%d bytes)\n",
++ (int)vc_cma_chunks,
++ (int)(vc_cma_chunks * VC_CMA_CHUNK_SIZE));
++ seq_printf(m, " Used : %4d (%d bytes)\n",
++ (int)vc_cma_chunks_used,
++ (int)(vc_cma_chunks_used * VC_CMA_CHUNK_SIZE));
++ seq_printf(m, " Reserved : %4d (%d bytes)\n",
++ (unsigned int)vc_cma_chunks_reserved,
++ (int)(vc_cma_chunks_reserved * VC_CMA_CHUNK_SIZE));
++
++ for (i = 0; i < vc_cma_reserve_count; i++) {
++ struct vc_cma_reserve_user *user = &vc_cma_reserve_users[i];
++ seq_printf(m, " PID %5d: %d bytes\n", user->pid,
++ user->reserve);
++ }
++
++ seq_printf(m, "\n");
++
++ return 0;
++}
++
++static int vc_cma_proc_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, vc_cma_show_info, NULL);
++}
++
++/****************************************************************************
++*
++* vc_cma_proc_write
++*
++***************************************************************************/
++
++static int vc_cma_proc_write(
++ struct file *file,
++ const char __user *buffer,
++ size_t size,
++ loff_t *ppos)
++{
++ int rc = -EFAULT;
++ char input_str[20];
++
++ memset(input_str, 0, sizeof(input_str));
++
++ if (size > sizeof(input_str)) {
++ LOG_ERR("%s: input string length too long", __func__);
++ goto out;
++ }
++
++ if (copy_from_user(input_str, buffer, size - 1)) {
++ LOG_ERR("%s: failed to get input string", __func__);
++ goto out;
++ }
++
++#define ALLOC_STR "alloc"
++#define FREE_STR "free"
++#define DEBUG_STR "debug"
++#define RESERVE_STR "reserve"
++ if (strncmp(input_str, ALLOC_STR, strlen(ALLOC_STR)) == 0) {
++ int size;
++ char *p = input_str + strlen(ALLOC_STR);
++
++ while (*p == ' ')
++ p++;
++ size = memparse(p, NULL);
++ LOG_ERR("/proc/vc-cma: alloc %d", size);
++ if (size)
++ send_vc_msg(VC_CMA_MSG_REQUEST_FREE,
++ size / VC_CMA_CHUNK_SIZE, 0);
++ else
++ LOG_ERR("invalid size '%s'", p);
++ rc = size;
++ } else if (strncmp(input_str, FREE_STR,
++ strlen(FREE_STR)) == 0) {
++ int size;
++ char *p = input_str + strlen(FREE_STR);
++
++ while (*p == ' ')
++ p++;
++ size = memparse(p, NULL);
++ LOG_ERR("/proc/vc-cma: free %d", size);
++ if (size)
++ send_vc_msg(VC_CMA_MSG_REQUEST_ALLOC,
++ size / VC_CMA_CHUNK_SIZE, 0);
++ else
++ LOG_ERR("invalid size '%s'", p);
++ rc = size;
++ } else if (strncmp(input_str, DEBUG_STR, strlen(DEBUG_STR)) == 0) {
++ char *p = input_str + strlen(DEBUG_STR);
++ while (*p == ' ')
++ p++;
++ if ((strcmp(p, "on") == 0) || (strcmp(p, "1") == 0))
++ vc_cma_debug = 1;
++ else if ((strcmp(p, "off") == 0) || (strcmp(p, "0") == 0))
++ vc_cma_debug = 0;
++ LOG_ERR("/proc/vc-cma: debug %s", vc_cma_debug ? "on" : "off");
++ rc = size;
++ } else if (strncmp(input_str, RESERVE_STR, strlen(RESERVE_STR)) == 0) {
++ int size;
++ int reserved;
++ char *p = input_str + strlen(RESERVE_STR);
++ while (*p == ' ')
++ p++;
++ size = memparse(p, NULL);
++
++ reserved = vc_cma_set_reserve(size, current->tgid);
++ rc = (reserved >= 0) ? size : reserved;
++ }
++
++out:
++ return rc;
++}
++
++
++/****************************************************************************
++*
++* File Operations for /proc interface.
++*
++***************************************************************************/
++
++static const struct file_operations vc_cma_proc_fops = {
++ .open = vc_cma_proc_open,
++ .read = seq_read,
++ .write = vc_cma_proc_write,
++ .llseek = seq_lseek,
++ .release = single_release
++};
++
++
++static int vc_cma_set_reserve(unsigned int reserve, unsigned int pid)
++{
++ struct vc_cma_reserve_user *user = NULL;
++ int delta = 0;
++ int i;
++
++ if (down_interruptible(&vc_cma_reserve_mutex))
++ return -ERESTARTSYS;
++
++ for (i = 0; i < vc_cma_reserve_count; i++) {
++ if (pid == vc_cma_reserve_users[i].pid) {
++ user = &vc_cma_reserve_users[i];
++ delta = reserve - user->reserve;
++ if (reserve)
++ user->reserve = reserve;
++ else {
++ /* Remove this entry by copying downwards */
++ while ((i + 1) < vc_cma_reserve_count) {
++ user[0].pid = user[1].pid;
++ user[0].reserve = user[1].reserve;
++ user++;
++ i++;
++ }
++ vc_cma_reserve_count--;
++ user = NULL;
++ }
++ break;
++ }
++ }
++
++ if (reserve && !user) {
++ if (vc_cma_reserve_count == VC_CMA_RESERVE_COUNT_MAX) {
++ LOG_ERR("vc-cma: Too many reservations - "
++ "increase CMA_RESERVE_COUNT_MAX");
++ up(&vc_cma_reserve_mutex);
++ return -EBUSY;
++ }
++ user = &vc_cma_reserve_users[vc_cma_reserve_count];
++ user->pid = pid;
++ user->reserve = reserve;
++ delta = reserve;
++ vc_cma_reserve_count++;
++ }
++
++ vc_cma_reserve_total += delta;
++
++ send_vc_msg(VC_CMA_MSG_RESERVE,
++ vc_cma_reserve_total & 0xffff,
++ vc_cma_reserve_total >> 16);
++
++ send_worker_msg((VCHIQ_HEADER_T *)VC_CMA_MSG_UPDATE_RESERVE);
++
++ LOG_DBG("/proc/vc-cma: reserve %d (PID %d) - total %u",
++ reserve, pid, vc_cma_reserve_total);
++
++ up(&vc_cma_reserve_mutex);
++
++ return vc_cma_reserve_total;
++}
++
++static VCHIQ_STATUS_T cma_service_callback(
++ VCHIQ_REASON_T reason,
++ VCHIQ_HEADER_T *header,
++ VCHIQ_SERVICE_HANDLE_T service,
++ void *bulk_userdata)
++{
++ switch (reason) {
++ case VCHIQ_MESSAGE_AVAILABLE:
++ if (!send_worker_msg(header))
++ return VCHIQ_RETRY;
++ break;
++ case VCHIQ_SERVICE_CLOSED:
++ LOG_DBG("CMA service closed");
++ break;
++ default:
++ LOG_ERR("Unexpected CMA callback reason %d", reason);
++ break;
++ }
++ return VCHIQ_SUCCESS;
++}
++
++static void send_vc_msg(
++ unsigned short type,
++ unsigned short param1,
++ unsigned short param2)
++{
++ unsigned short msg[] = { type, param1, param2 };
++ VCHIQ_ELEMENT_T elem = { &msg, sizeof(msg) };
++ VCHIQ_STATUS_T ret;
++ vchiq_use_service(cma_service);
++ ret = vchiq_queue_message(cma_service, &elem, 1);
++ vchiq_release_service(cma_service);
++ if (ret != VCHIQ_SUCCESS)
++ LOG_ERR("vchiq_queue_message returned %x", ret);
++}
++
++static bool send_worker_msg(VCHIQ_HEADER_T *msg)
++{
++ if (down_interruptible(&vc_cma_worker_queue_push_mutex))
++ return false;
++ vchiu_queue_push(&cma_msg_queue, msg);
++ up(&vc_cma_worker_queue_push_mutex);
++ return true;
++}
++
++static int vc_cma_alloc_chunks(int num_chunks, struct cma_msg *reply)
++{
++ int i;
++ for (i = 0; i < num_chunks; i++) {
++ struct page *chunk;
++ unsigned int chunk_num;
++ chunk = dma_alloc_from_contiguous(
++ &vc_cma_device.dev,
++ PAGES_PER_CHUNK,
++ VC_CMA_CHUNK_ORDER);
++ if (!chunk)
++ break;
++ chunk_num =
++ (page_to_phys(chunk) - vc_cma_base) /
++ VC_CMA_CHUNK_SIZE;
++ BUG_ON(((page_to_phys(chunk) - vc_cma_base) %
++ VC_CMA_CHUNK_SIZE) != 0);
++ if (chunk_num >= vc_cma_chunks)
++ {
++ LOG_ERR("%s: ===============================",
++ __func__);
++ LOG_ERR("%s: chunk phys %x, vc_cma %x-%x - "
++ "bad SPARSEMEM configuration?",
++ __func__, (unsigned int)page_to_phys(chunk),
++ vc_cma_base, vc_cma_base + vc_cma_size - 1);
++ LOG_ERR("%s: dev->cma_area = %p\n", __func__, vc_cma_device.dev.cma_area);
++ LOG_ERR("%s: ===============================",
++ __func__);
++ break;
++ }
++ reply->params[i] = chunk_num;
++ vc_cma_chunks_used++;
++ }
++
++ if (i < num_chunks) {
++ LOG_ERR("%s: dma_alloc_from_contiguous failed "
++ "for %x bytes (alloc %d of %d, %d free)",
++ __func__, VC_CMA_CHUNK_SIZE, i,
++ num_chunks,
++ vc_cma_chunks - vc_cma_chunks_used);
++ num_chunks = i;
++ }
++
++ LOG_DBG("CMA allocated %d chunks -> %d used",
++ num_chunks, vc_cma_chunks_used);
++ reply->type = VC_CMA_MSG_ALLOCATED;
++
++ {
++ VCHIQ_ELEMENT_T elem = {
++ reply,
++ offsetof(struct cma_msg, params[0]) +
++ num_chunks * sizeof(reply->params[0])
++ };
++ VCHIQ_STATUS_T ret;
++ vchiq_use_service(cma_service);
++ ret = vchiq_queue_message(cma_service,
++ &elem, 1);
++ vchiq_release_service(cma_service);
++ if (ret != VCHIQ_SUCCESS)
++ LOG_ERR("vchiq_queue_message return "
++ "%x", ret);
++ }
++
++ return num_chunks;
++}
++
++static int cma_worker_proc(void *param)
++{
++ static struct cma_msg reply;
++ (void)param;
++
++ while (1) {
++ VCHIQ_HEADER_T *msg;
++ static struct cma_msg msg_copy;
++ struct cma_msg *cma_msg = &msg_copy;
++ int type, msg_size;
++
++ msg = vchiu_queue_pop(&cma_msg_queue);
++ if ((unsigned int)msg >= VC_CMA_MSG_MAX) {
++ msg_size = msg->size;
++ memcpy(&msg_copy, msg->data, msg_size);
++ type = cma_msg->type;
++ vchiq_release_message(cma_service, msg);
++ } else {
++ msg_size = 0;
++ type = (int)msg;
++ if (type == VC_CMA_MSG_QUIT)
++ break;
++ else if (type == VC_CMA_MSG_UPDATE_RESERVE) {
++ msg = NULL;
++ cma_msg = NULL;
++ } else {
++ BUG();
++ continue;
++ }
++ }
++
++ switch (type) {
++ case VC_CMA_MSG_ALLOC: {
++ int num_chunks, free_chunks;
++ num_chunks = cma_msg->params[0];
++ free_chunks = vc_cma_chunks - vc_cma_chunks_used;
++ LOG_DBG("CMA_MSG_ALLOC(%d chunks)", num_chunks);
++ if (num_chunks > VC_CMA_MAX_PARAMS_PER_MSG) {
++ LOG_ERR("CMA_MSG_ALLOC - chunk count (%d) "
++ "exceeds VC_CMA_MAX_PARAMS_PER_MSG (%d)",
++ num_chunks, VC_CMA_MAX_PARAMS_PER_MSG);
++ num_chunks = VC_CMA_MAX_PARAMS_PER_MSG;
++ }
++
++ if (num_chunks > free_chunks) {
++ LOG_ERR("CMA_MSG_ALLOC - chunk count (%d) "
++ "exceeds free chunks (%d)",
++ num_chunks, free_chunks);
++ num_chunks = free_chunks;
++ }
++
++ vc_cma_alloc_chunks(num_chunks, &reply);
++ }
++ break;
++
++ case VC_CMA_MSG_FREE: {
++ int chunk_count =
++ (msg_size - offsetof(struct cma_msg, params))/
++ sizeof(cma_msg->params[0]);
++ int i;
++ BUG_ON(chunk_count <= 0);
++
++ LOG_DBG("CMA_MSG_FREE(%d chunks - %x, ...)",
++ chunk_count, cma_msg->params[0]);
++ for (i = 0; i < chunk_count; i++) {
++ int chunk_num = cma_msg->params[i];
++ struct page *page = vc_cma_base_page +
++ chunk_num * PAGES_PER_CHUNK;
++ if (chunk_num >= vc_cma_chunks) {
++ LOG_ERR("CMA_MSG_FREE - chunk %d of %d"
++ " (value %x) exceeds maximum "
++ "(%x)",
++ i, chunk_count, chunk_num,
++ vc_cma_chunks - 1);
++ break;
++ }
++
++ if (!dma_release_from_contiguous(
++ &vc_cma_device.dev,
++ page, PAGES_PER_CHUNK)) {
++ LOG_ERR("CMA_MSG_FREE - failed to "
++ "release chunk %d (phys %x, "
++ "page %x)",
++ chunk_num, page_to_phys(page),
++ (unsigned int)page);
++ }
++ vc_cma_chunks_used--;
++ }
++ LOG_DBG("CMA released %d chunks -> %d used",
++ i, vc_cma_chunks_used);
++ }
++ break;
++
++ case VC_CMA_MSG_UPDATE_RESERVE: {
++ int chunks_needed =
++ ((vc_cma_reserve_total + VC_CMA_CHUNK_SIZE - 1)
++ / VC_CMA_CHUNK_SIZE) -
++ vc_cma_chunks_reserved;
++
++ LOG_DBG("CMA_MSG_UPDATE_RESERVE(%d chunks needed)",
++ chunks_needed);
++
++ /* Cap the reservations to what is available */
++ if (chunks_needed > 0) {
++ if (chunks_needed >
++ (vc_cma_chunks - vc_cma_chunks_used))
++ chunks_needed =
++ (vc_cma_chunks -
++ vc_cma_chunks_used);
++
++ chunks_needed = vc_cma_alloc_chunks(
++ chunks_needed, &reply);
++ }
++
++ LOG_DBG("CMA_MSG_UPDATE_RESERVE(%d chunks allocated)",
++ chunks_needed);
++ vc_cma_chunks_reserved += chunks_needed;
++ }
++ break;
++
++ default:
++ LOG_ERR("unexpected msg type %d", type);
++ break;
++ }
++ }
++
++ LOG_DBG("quitting...");
++ return 0;
++}
++
++static void vc_cma_connected_init(void)
++{
++ VCHIQ_SERVICE_PARAMS_T service_params;
++
++ LOG_DBG("vc_cma_connected_init");
++
++ if (!vchiu_queue_init(&cma_msg_queue, 16)) {
++ LOG_ERR("could not create CMA msg queue");
++ goto fail_queue;
++ }
++
++ if (vchiq_initialise(&cma_instance) != VCHIQ_SUCCESS)
++ goto fail_vchiq_init;
++
++ vchiq_connect(cma_instance);
++
++ service_params.fourcc = VC_CMA_FOURCC;
++ service_params.callback = cma_service_callback;
++ service_params.userdata = NULL;
++ service_params.version = VC_CMA_VERSION;
++ service_params.version_min = VC_CMA_VERSION;
++
++ if (vchiq_open_service(cma_instance, &service_params,
++ &cma_service) != VCHIQ_SUCCESS) {
++ LOG_ERR("failed to open service - already in use?");
++ goto fail_vchiq_open;
++ }
++
++ vchiq_release_service(cma_service);
++
++ cma_worker = kthread_create(cma_worker_proc, NULL, "cma_worker");
++ if (!cma_worker) {
++ LOG_ERR("could not create CMA worker thread");
++ goto fail_worker;
++ }
++ set_user_nice(cma_worker, -20);
++ wake_up_process(cma_worker);
++
++ return;
++
++fail_worker:
++ vchiq_close_service(cma_service);
++fail_vchiq_open:
++ vchiq_shutdown(cma_instance);
++fail_vchiq_init:
++ vchiu_queue_delete(&cma_msg_queue);
++fail_queue:
++ return;
++}
++
++
++/****************************************************************************
++*
++* vc_cma_connected_init
++*
++* This function is called once the videocore has been connected.
++*
++***************************************************************************/
++
++static int __init vc_cma_init(void)
++{
++ int rc = -EFAULT;
++ struct device *dev;
++
++ printk(KERN_INFO "vc-cma: Videocore CMA driver\n");
++ printk(KERN_INFO "vc-cma: vc_cma_base = 0x%08x\n",
++ vc_cma_base);
++ printk(KERN_INFO "vc-cma: vc_cma_size = 0x%08x (%u MiB)\n",
++ vc_cma_size, vc_cma_size / (1024 * 1024));
++ printk(KERN_INFO "vc-cma: vc_cma_initial = 0x%08x (%u MiB)\n",
++ vc_cma_initial, vc_cma_initial / (1024 * 1024));
++
++ vc_cma_base_page = phys_to_page(vc_cma_base);
++ if (vc_cma_chunks) {
++ int chunks_needed = vc_cma_initial / VC_CMA_CHUNK_SIZE;
++
++ for (vc_cma_chunks_used = 0;
++ vc_cma_chunks_used < chunks_needed;
++ vc_cma_chunks_used++) {
++ struct page *chunk;
++ chunk = dma_alloc_from_contiguous(&vc_cma_device.dev,
++ PAGES_PER_CHUNK, VC_CMA_CHUNK_ORDER);
++ if (!chunk)
++ break;
++ BUG_ON(((page_to_phys(chunk) - vc_cma_base) %
++ VC_CMA_CHUNK_SIZE) != 0);
++ }
++ if (vc_cma_chunks_used != chunks_needed) {
++ LOG_ERR("%s: dma_alloc_from_contiguous failed (%d "
++ "bytes, allocation %d of %d)",
++ __func__, VC_CMA_CHUNK_SIZE,
++ vc_cma_chunks_used,
++ chunks_needed);
++ goto out_release;
++ }
++ vchiq_add_connected_callback(vc_cma_connected_init);
++ }
++
++ rc = alloc_chrdev_region(&vc_cma_devnum, 0, 1, DRIVER_NAME);
++ if (rc < 0) {
++ LOG_ERR("%s: alloc_chrdev_region failed (rc=%d)", __func__,
++ rc);
++ goto out_release;
++ }
++
++ cdev_init(&vc_cma_cdev, &vc_cma_fops);
++ rc = cdev_add(&vc_cma_cdev, vc_cma_devnum, 1);
++ if (rc != 0) {
++ LOG_ERR("%s: cdev_add failed (rc=%d)", __func__, rc);
++ goto out_unregister;
++ }
++
++ vc_cma_class = class_create(THIS_MODULE, DRIVER_NAME);
++ if (IS_ERR(vc_cma_class)) {
++ rc = PTR_ERR(vc_cma_class);
++ LOG_ERR("%s: class_create failed (rc=%d)", __func__, rc);
++ goto out_cdev_del;
++ }
++
++ dev = device_create(vc_cma_class, NULL, vc_cma_devnum, NULL,
++ DRIVER_NAME);
++ if (IS_ERR(dev)) {
++ rc = PTR_ERR(dev);
++ LOG_ERR("%s: device_create failed (rc=%d)", __func__, rc);
++ goto out_class_destroy;
++ }
++
++ vc_cma_proc_entry = create_proc_entry(DRIVER_NAME, 0444, NULL);
++ if (vc_cma_proc_entry == NULL) {
++ rc = -EFAULT;
++ LOG_ERR("%s: create_proc_entry failed", __func__);
++ goto out_device_destroy;
++ }
++
++ vc_cma_proc_entry->proc_fops = &vc_cma_proc_fops;
++
++ vc_cma_inited = 1;
++ return 0;
++
++out_device_destroy:
++ device_destroy(vc_cma_class, vc_cma_devnum);
++
++out_class_destroy:
++ class_destroy(vc_cma_class);
++ vc_cma_class = NULL;
++
++out_cdev_del:
++ cdev_del(&vc_cma_cdev);
++
++out_unregister:
++ unregister_chrdev_region(vc_cma_devnum, 1);
++
++out_release:
++ /* It is tempting to try to clean up by calling
++ dma_release_from_contiguous for all allocated chunks, but it isn't
++ a very safe thing to do. If vc_cma_initial is non-zero it is because
++ VideoCore is already using that memory, so giving it back to Linux
++ is likely to be fatal.
++ */
++ return -1;
++}
++
++/****************************************************************************
++*
++* vc_cma_exit
++*
++***************************************************************************/
++
++static void __exit vc_cma_exit(void)
++{
++ LOG_DBG("%s: called", __func__);
++
++ if (vc_cma_inited) {
++ remove_proc_entry(vc_cma_proc_entry->name, NULL);
++ device_destroy(vc_cma_class, vc_cma_devnum);
++ class_destroy(vc_cma_class);
++ cdev_del(&vc_cma_cdev);
++ unregister_chrdev_region(vc_cma_devnum, 1);
++ }
++}
++
++module_init(vc_cma_init);
++module_exit(vc_cma_exit);
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Broadcom Corporation");
+diff --git a/include/linux/broadcom/vc_cma.h b/include/linux/broadcom/vc_cma.h
+new file mode 100644
+index 0000000..bdc9d79
+--- /dev/null
++++ b/include/linux/broadcom/vc_cma.h
+@@ -0,0 +1,30 @@
++/*****************************************************************************
++* Copyright 2012 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_CMA_H )
++#define VC_CMA_H
++
++#include <linux/ioctl.h>
++
++#define VC_CMA_IOC_MAGIC 0xc5
++
++#define VC_CMA_IOC_RESERVE _IO(VC_CMA_IOC_MAGIC, 0)
++
++#ifdef __KERNEL__
++extern void __init vc_cma_early_init(void);
++extern void __init vc_cma_reserve(void);
++#endif
++
++#endif /* VC_CMA_H */
++
diff --git a/patches/linux-3.6.7/0163-Fix-reboot-with-new-restart-method-of-machine-driver.patch b/patches/linux-3.6.7/0163-Fix-reboot-with-new-restart-method-of-machine-driver.patch
new file mode 100644
index 0000000..f864d60
--- /dev/null
+++ b/patches/linux-3.6.7/0163-Fix-reboot-with-new-restart-method-of-machine-driver.patch
@@ -0,0 +1,76 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Wed, 24 Oct 2012 22:00:43 +0100
+Subject: [PATCH] Fix reboot with new restart method of machine driver
+
+---
+ arch/arm/mach-bcm2708/bcm2708.c | 18 +++++++++++++++++-
+ arch/arm/mach-bcm2708/include/mach/system.h | 15 ---------------
+ 2 files changed, 17 insertions(+), 16 deletions(-)
+
+diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
+index a3fd1e7..838e0f2 100644
+--- a/arch/arm/mach-bcm2708/bcm2708.c
++++ b/arch/arm/mach-bcm2708/bcm2708.c
+@@ -663,6 +663,21 @@ int __init bcm_register_device(struct platform_device *pdev)
+ return ret;
+ }
+
++static void bcm2708_restart(char mode, const char *cmd)
++{
++ uint32_t pm_rstc, pm_wdog;
++ uint32_t timeout = 10;
++
++ /* 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)
+ {
+@@ -671,7 +686,7 @@ static void bcm2708_power_off(void)
+ pm_rsts = PM_PASSWORD | (pm_rsts & PM_RSTC_WRCFG_CLR) | PM_RSTS_HADWRH_SET;
+ writel(pm_rsts, IO_ADDRESS(PM_RSTS));
+ /* continue with normal reset mechanism */
+- arch_reset(0, "");
++ bcm2708_restart(0, "");
+ }
+
+ void __init bcm2708_init(void)
+@@ -928,6 +943,7 @@ MACHINE_START(BCM2708, "BCM2708")
+ .init_machine = bcm2708_init,
+ .init_early = bcm2708_init_early,
+ .reserve = board_reserve,
++ .restart = bcm2708_restart,
+ MACHINE_END
+
+ module_param(boardrev, uint, 0644);
+diff --git a/arch/arm/mach-bcm2708/include/mach/system.h b/arch/arm/mach-bcm2708/include/mach/system.h
+index bc9d458..2d0b821 100644
+--- a/arch/arm/mach-bcm2708/include/mach/system.h
++++ b/arch/arm/mach-bcm2708/include/mach/system.h
+@@ -35,19 +35,4 @@ static inline void arch_idle(void)
+ cpu_do_idle();
+ }
+
+-static inline void arch_reset(char mode, const char *cmd)
+-{
+- uint32_t pm_rstc, pm_wdog;
+- uint32_t timeout = 10;
+-
+- /* 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));
+-}
+-
+ #endif
diff --git a/patches/linux-3.6.7/0164-smsc95xx-sleep-before-read-for-lengthy-operations.patch b/patches/linux-3.6.7/0164-smsc95xx-sleep-before-read-for-lengthy-operations.patch
new file mode 100644
index 0000000..eb7b4d8
--- /dev/null
+++ b/patches/linux-3.6.7/0164-smsc95xx-sleep-before-read-for-lengthy-operations.patch
@@ -0,0 +1,45 @@
+From: Steve Glendinning <steve.glendinning@shawell.net>
+Date: Fri, 28 Sep 2012 00:07:07 +0000
+Subject: [PATCH] smsc95xx: sleep before read for lengthy operations
+
+During init, the device reset is unexpected to complete immediately,
+so sleep before testing the condition rather than after it.
+
+Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/smsc95xx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
+index e00ae5d..27f0205 100644
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -819,12 +819,12 @@ static int smsc95xx_reset(struct usbnet *dev)
+
+ timeout = 0;
+ do {
++ msleep(10);
+ ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
+ return ret;
+ }
+- msleep(10);
+ timeout++;
+ } while ((read_buf & HW_CFG_LRST_) && (timeout < 100));
+
+@@ -842,12 +842,12 @@ static int smsc95xx_reset(struct usbnet *dev)
+
+ timeout = 0;
+ do {
++ msleep(10);
+ ret = smsc95xx_read_reg(dev, PM_CTRL, &read_buf);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read PM_CTRL: %d\n", ret);
+ return ret;
+ }
+- msleep(10);
+ timeout++;
+ } while ((read_buf & PM_CTL_PHY_RST_) && (timeout < 100));
+
diff --git a/patches/linux-3.6.7/0165-smsc95xx-remove-unnecessary-variables.patch b/patches/linux-3.6.7/0165-smsc95xx-remove-unnecessary-variables.patch
new file mode 100644
index 0000000..d45ee58
--- /dev/null
+++ b/patches/linux-3.6.7/0165-smsc95xx-remove-unnecessary-variables.patch
@@ -0,0 +1,133 @@
+From: Steve Glendinning <steve.glendinning@shawell.net>
+Date: Fri, 28 Sep 2012 00:07:08 +0000
+Subject: [PATCH] smsc95xx: remove unnecessary variables
+
+Removes unnecessary variables as smsc95xx_write_reg takes its
+value by parameter. Early versions passed this parameter by
+reference.
+
+Also replace hardcoded interrupt status value with a #define
+
+Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/smsc95xx.c | 29 +++++++++--------------------
+ drivers/net/usb/smsc95xx.h | 1 +
+ 2 files changed, 10 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
+index 27f0205..e5e05ee 100644
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -465,12 +465,10 @@ static int smsc95xx_link_reset(struct usbnet *dev)
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
+ unsigned long flags;
+ u16 lcladv, rmtadv;
+- u32 intdata;
+
+ /* clear interrupt status */
+ smsc95xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);
+- intdata = 0xFFFFFFFF;
+- smsc95xx_write_reg(dev, INT_STS, intdata);
++ smsc95xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL_);
+
+ mii_check_media(mii, 1, 1);
+ mii_ethtool_gset(&dev->mii, &ecmd);
+@@ -733,7 +731,6 @@ static void smsc95xx_start_tx_path(struct usbnet *dev)
+ {
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ unsigned long flags;
+- u32 reg_val;
+
+ /* Enable Tx at MAC */
+ spin_lock_irqsave(&pdata->mac_cr_lock, flags);
+@@ -743,8 +740,7 @@ static void smsc95xx_start_tx_path(struct usbnet *dev)
+ smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr);
+
+ /* Enable Tx at SCSRs */
+- reg_val = TX_CFG_ON_;
+- smsc95xx_write_reg(dev, TX_CFG, reg_val);
++ smsc95xx_write_reg(dev, TX_CFG, TX_CFG_ON_);
+ }
+
+ /* Starts the Receive path */
+@@ -809,8 +805,7 @@ static int smsc95xx_reset(struct usbnet *dev)
+
+ netif_dbg(dev, ifup, dev->net, "entering smsc95xx_reset\n");
+
+- write_buf = HW_CFG_LRST_;
+- ret = smsc95xx_write_reg(dev, HW_CFG, write_buf);
++ ret = smsc95xx_write_reg(dev, HW_CFG, HW_CFG_LRST_);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write HW_CFG_LRST_ bit in HW_CFG register, ret = %d\n",
+ ret);
+@@ -833,8 +828,7 @@ static int smsc95xx_reset(struct usbnet *dev)
+ return ret;
+ }
+
+- write_buf = PM_CTL_PHY_RST_;
+- ret = smsc95xx_write_reg(dev, PM_CTRL, write_buf);
++ ret = smsc95xx_write_reg(dev, PM_CTRL, PM_CTL_PHY_RST_);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write PM_CTRL: %d\n", ret);
+ return ret;
+@@ -919,8 +913,7 @@ static int smsc95xx_reset(struct usbnet *dev)
+ "Read Value from BURST_CAP after writing: 0x%08x\n",
+ read_buf);
+
+- read_buf = DEFAULT_BULK_IN_DELAY;
+- ret = smsc95xx_write_reg(dev, BULK_IN_DLY, read_buf);
++ ret = smsc95xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY);
+ if (ret < 0) {
+ netdev_warn(dev->net, "ret = %d\n", ret);
+ return ret;
+@@ -966,8 +959,7 @@ static int smsc95xx_reset(struct usbnet *dev)
+ netif_dbg(dev, ifup, dev->net,
+ "Read Value from HW_CFG after writing: 0x%08x\n", read_buf);
+
+- write_buf = 0xFFFFFFFF;
+- ret = smsc95xx_write_reg(dev, INT_STS, write_buf);
++ ret = smsc95xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL_);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write INT_STS register, ret=%d\n",
+ ret);
+@@ -992,15 +984,13 @@ static int smsc95xx_reset(struct usbnet *dev)
+ }
+
+ /* Init Tx */
+- write_buf = 0;
+- ret = smsc95xx_write_reg(dev, FLOW, write_buf);
++ ret = smsc95xx_write_reg(dev, FLOW, 0);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write FLOW: %d\n", ret);
+ return ret;
+ }
+
+- read_buf = AFC_CFG_DEFAULT;
+- ret = smsc95xx_write_reg(dev, AFC_CFG, read_buf);
++ ret = smsc95xx_write_reg(dev, AFC_CFG, AFC_CFG_DEFAULT);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write AFC_CFG: %d\n", ret);
+ return ret;
+@@ -1015,8 +1005,7 @@ static int smsc95xx_reset(struct usbnet *dev)
+
+ /* Init Rx */
+ /* Set Vlan */
+- write_buf = (u32)ETH_P_8021Q;
+- ret = smsc95xx_write_reg(dev, VLAN1, write_buf);
++ ret = smsc95xx_write_reg(dev, VLAN1, (u32)ETH_P_8021Q);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write VAN1: %d\n", ret);
+ return ret;
+diff --git a/drivers/net/usb/smsc95xx.h b/drivers/net/usb/smsc95xx.h
+index 86bc449..a275b62 100644
+--- a/drivers/net/usb/smsc95xx.h
++++ b/drivers/net/usb/smsc95xx.h
+@@ -63,6 +63,7 @@
+ #define INT_STS_TDFO_ (0x00001000)
+ #define INT_STS_RXDF_ (0x00000800)
+ #define INT_STS_GPIOS_ (0x000007FF)
++#define INT_STS_CLEAR_ALL_ (0xFFFFFFFF)
+
+ #define RX_CFG (0x0C)
+ #define RX_FIFO_FLUSH_ (0x00000001)
diff --git a/patches/linux-3.6.7/0166-smsc95xx-check-return-code-from-control-messages.patch b/patches/linux-3.6.7/0166-smsc95xx-check-return-code-from-control-messages.patch
new file mode 100644
index 0000000..d194d98
--- /dev/null
+++ b/patches/linux-3.6.7/0166-smsc95xx-check-return-code-from-control-messages.patch
@@ -0,0 +1,702 @@
+From: Steve Glendinning <steve.glendinning@shawell.net>
+Date: Fri, 28 Sep 2012 00:07:09 +0000
+Subject: [PATCH] smsc95xx: check return code from control messages
+
+This patch adds additional checks of the values returned by
+smsc95xx_(read|write)_reg, and wraps their common patterns
+in macros.
+
+Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/smsc95xx.c | 331 ++++++++++++++++++++-------------------------
+ 1 file changed, 148 insertions(+), 183 deletions(-)
+
+diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
+index e5e05ee..9c13e25 100644
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -48,6 +48,15 @@
+ #define SMSC95XX_TX_OVERHEAD_CSUM (12)
+ #define MAC_ADDR_LEN (6)
+
++#define check_warn(ret, fmt, args...) \
++ ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })
++
++#define check_warn_return(ret, fmt, args...) \
++ ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); return ret; } })
++
++#define check_warn_goto_done(ret, fmt, args...) \
++ ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); goto done; } })
++
+ struct smsc95xx_priv {
+ u32 mac_cr;
+ u32 hash_hi;
+@@ -68,7 +77,8 @@ static char *macaddr = ":";
+ module_param(macaddr, charp, 0);
+ MODULE_PARM_DESC(macaddr, "MAC address");
+
+-static int smsc95xx_read_reg(struct usbnet *dev, u32 index, u32 *data)
++static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index,
++ u32 *data)
+ {
+ u32 *buf = kmalloc(4, GFP_KERNEL);
+ int ret;
+@@ -93,7 +103,8 @@ static int smsc95xx_read_reg(struct usbnet *dev, u32 index, u32 *data)
+ return ret;
+ }
+
+-static int smsc95xx_write_reg(struct usbnet *dev, u32 index, u32 data)
++static int __must_check smsc95xx_write_reg(struct usbnet *dev, u32 index,
++ u32 data)
+ {
+ u32 *buf = kmalloc(4, GFP_KERNEL);
+ int ret;
+@@ -121,13 +132,15 @@ static int smsc95xx_write_reg(struct usbnet *dev, u32 index, u32 data)
+
+ /* Loop until the read is completed with timeout
+ * called with phy_mutex held */
+-static int smsc95xx_phy_wait_not_busy(struct usbnet *dev)
++static int __must_check smsc95xx_phy_wait_not_busy(struct usbnet *dev)
+ {
+ unsigned long start_time = jiffies;
+ u32 val;
++ int ret;
+
+ do {
+- smsc95xx_read_reg(dev, MII_ADDR, &val);
++ ret = smsc95xx_read_reg(dev, MII_ADDR, &val);
++ check_warn_return(ret, "Error reading MII_ACCESS");
+ if (!(val & MII_BUSY_))
+ return 0;
+ } while (!time_after(jiffies, start_time + HZ));
+@@ -139,33 +152,32 @@ static int smsc95xx_mdio_read(struct net_device *netdev, int phy_id, int idx)
+ {
+ struct usbnet *dev = netdev_priv(netdev);
+ u32 val, addr;
++ int ret;
+
+ mutex_lock(&dev->phy_mutex);
+
+ /* confirm MII not busy */
+- if (smsc95xx_phy_wait_not_busy(dev)) {
+- netdev_warn(dev->net, "MII is busy in smsc95xx_mdio_read\n");
+- mutex_unlock(&dev->phy_mutex);
+- return -EIO;
+- }
++ ret = smsc95xx_phy_wait_not_busy(dev);
++ check_warn_goto_done(ret, "MII is busy in smsc95xx_mdio_read");
+
+ /* set the address, index & direction (read from PHY) */
+ phy_id &= dev->mii.phy_id_mask;
+ idx &= dev->mii.reg_num_mask;
+ addr = (phy_id << 11) | (idx << 6) | MII_READ_;
+- smsc95xx_write_reg(dev, MII_ADDR, addr);
++ ret = smsc95xx_write_reg(dev, MII_ADDR, addr);
++ check_warn_goto_done(ret, "Error writing MII_ADDR");
+
+- if (smsc95xx_phy_wait_not_busy(dev)) {
+- netdev_warn(dev->net, "Timed out reading MII reg %02X\n", idx);
+- mutex_unlock(&dev->phy_mutex);
+- return -EIO;
+- }
++ ret = smsc95xx_phy_wait_not_busy(dev);
++ check_warn_goto_done(ret, "Timed out reading MII reg %02X", idx);
+
+- smsc95xx_read_reg(dev, MII_DATA, &val);
++ ret = smsc95xx_read_reg(dev, MII_DATA, &val);
++ check_warn_goto_done(ret, "Error reading MII_DATA");
+
+- mutex_unlock(&dev->phy_mutex);
++ ret = (u16)(val & 0xFFFF);
+
+- return (u16)(val & 0xFFFF);
++done:
++ mutex_unlock(&dev->phy_mutex);
++ return ret;
+ }
+
+ static void smsc95xx_mdio_write(struct net_device *netdev, int phy_id, int idx,
+@@ -173,38 +185,41 @@ static void smsc95xx_mdio_write(struct net_device *netdev, int phy_id, int idx,
+ {
+ struct usbnet *dev = netdev_priv(netdev);
+ u32 val, addr;
++ int ret;
+
+ mutex_lock(&dev->phy_mutex);
+
+ /* confirm MII not busy */
+- if (smsc95xx_phy_wait_not_busy(dev)) {
+- netdev_warn(dev->net, "MII is busy in smsc95xx_mdio_write\n");
+- mutex_unlock(&dev->phy_mutex);
+- return;
+- }
++ ret = smsc95xx_phy_wait_not_busy(dev);
++ check_warn_goto_done(ret, "MII is busy in smsc95xx_mdio_write");
+
+ val = regval;
+- smsc95xx_write_reg(dev, MII_DATA, val);
++ ret = smsc95xx_write_reg(dev, MII_DATA, val);
++ check_warn_goto_done(ret, "Error writing MII_DATA");
+
+ /* set the address, index & direction (write to PHY) */
+ phy_id &= dev->mii.phy_id_mask;
+ idx &= dev->mii.reg_num_mask;
+ addr = (phy_id << 11) | (idx << 6) | MII_WRITE_;
+- smsc95xx_write_reg(dev, MII_ADDR, addr);
++ ret = smsc95xx_write_reg(dev, MII_ADDR, addr);
++ check_warn_goto_done(ret, "Error writing MII_ADDR");
+
+- if (smsc95xx_phy_wait_not_busy(dev))
+- netdev_warn(dev->net, "Timed out writing MII reg %02X\n", idx);
++ ret = smsc95xx_phy_wait_not_busy(dev);
++ check_warn_goto_done(ret, "Timed out writing MII reg %02X", idx);
+
++done:
+ mutex_unlock(&dev->phy_mutex);
+ }
+
+-static int smsc95xx_wait_eeprom(struct usbnet *dev)
++static int __must_check smsc95xx_wait_eeprom(struct usbnet *dev)
+ {
+ unsigned long start_time = jiffies;
+ u32 val;
++ int ret;
+
+ do {
+- smsc95xx_read_reg(dev, E2P_CMD, &val);
++ ret = smsc95xx_read_reg(dev, E2P_CMD, &val);
++ check_warn_return(ret, "Error reading E2P_CMD");
+ if (!(val & E2P_CMD_BUSY_) || (val & E2P_CMD_TIMEOUT_))
+ break;
+ udelay(40);
+@@ -218,13 +233,15 @@ static int smsc95xx_wait_eeprom(struct usbnet *dev)
+ return 0;
+ }
+
+-static int smsc95xx_eeprom_confirm_not_busy(struct usbnet *dev)
++static int __must_check smsc95xx_eeprom_confirm_not_busy(struct usbnet *dev)
+ {
+ unsigned long start_time = jiffies;
+ u32 val;
++ int ret;
+
+ do {
+- smsc95xx_read_reg(dev, E2P_CMD, &val);
++ ret = smsc95xx_read_reg(dev, E2P_CMD, &val);
++ check_warn_return(ret, "Error reading E2P_CMD");
+
+ if (!(val & E2P_CMD_BUSY_))
+ return 0;
+@@ -251,13 +268,15 @@ static int smsc95xx_read_eeprom(struct usbnet *dev, u32 offset, u32 length,
+
+ for (i = 0; i < length; i++) {
+ val = E2P_CMD_BUSY_ | E2P_CMD_READ_ | (offset & E2P_CMD_ADDR_);
+- smsc95xx_write_reg(dev, E2P_CMD, val);
++ ret = smsc95xx_write_reg(dev, E2P_CMD, val);
++ check_warn_return(ret, "Error writing E2P_CMD");
+
+ ret = smsc95xx_wait_eeprom(dev);
+ if (ret < 0)
+ return ret;
+
+- smsc95xx_read_reg(dev, E2P_DATA, &val);
++ ret = smsc95xx_read_reg(dev, E2P_DATA, &val);
++ check_warn_return(ret, "Error reading E2P_DATA");
+
+ data[i] = val & 0xFF;
+ offset++;
+@@ -281,7 +300,8 @@ static int smsc95xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length,
+
+ /* Issue write/erase enable command */
+ val = E2P_CMD_BUSY_ | E2P_CMD_EWEN_;
+- smsc95xx_write_reg(dev, E2P_CMD, val);
++ ret = smsc95xx_write_reg(dev, E2P_CMD, val);
++ check_warn_return(ret, "Error writing E2P_DATA");
+
+ ret = smsc95xx_wait_eeprom(dev);
+ if (ret < 0)
+@@ -291,11 +311,13 @@ static int smsc95xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length,
+
+ /* Fill data register */
+ val = data[i];
+- smsc95xx_write_reg(dev, E2P_DATA, val);
++ ret = smsc95xx_write_reg(dev, E2P_DATA, val);
++ check_warn_return(ret, "Error writing E2P_DATA");
+
+ /* Send "write" command */
+ val = E2P_CMD_BUSY_ | E2P_CMD_WRITE_ | (offset & E2P_CMD_ADDR_);
+- smsc95xx_write_reg(dev, E2P_CMD, val);
++ ret = smsc95xx_write_reg(dev, E2P_CMD, val);
++ check_warn_return(ret, "Error writing E2P_CMD");
+
+ ret = smsc95xx_wait_eeprom(dev);
+ if (ret < 0)
+@@ -313,14 +335,14 @@ static void smsc95xx_async_cmd_callback(struct urb *urb)
+ struct usbnet *dev = usb_context->dev;
+ int status = urb->status;
+
+- if (status < 0)
+- netdev_warn(dev->net, "async callback failed with %d\n", status);
++ check_warn(status, "async callback failed with %d\n", status);
+
+ kfree(usb_context);
+ usb_free_urb(urb);
+ }
+
+-static int smsc95xx_write_reg_async(struct usbnet *dev, u16 index, u32 *data)
++static int __must_check smsc95xx_write_reg_async(struct usbnet *dev, u16 index,
++ u32 *data)
+ {
+ struct usb_context *usb_context;
+ int status;
+@@ -376,6 +398,7 @@ static void smsc95xx_set_multicast(struct net_device *netdev)
+ struct usbnet *dev = netdev_priv(netdev);
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ unsigned long flags;
++ int ret;
+
+ pdata->hash_hi = 0;
+ pdata->hash_lo = 0;
+@@ -416,21 +439,23 @@ static void smsc95xx_set_multicast(struct net_device *netdev)
+ spin_unlock_irqrestore(&pdata->mac_cr_lock, flags);
+
+ /* Initiate async writes, as we can't wait for completion here */
+- smsc95xx_write_reg_async(dev, HASHH, &pdata->hash_hi);
+- smsc95xx_write_reg_async(dev, HASHL, &pdata->hash_lo);
+- smsc95xx_write_reg_async(dev, MAC_CR, &pdata->mac_cr);
++ ret = smsc95xx_write_reg_async(dev, HASHH, &pdata->hash_hi);
++ check_warn(ret, "failed to initiate async write to HASHH");
++
++ ret = smsc95xx_write_reg_async(dev, HASHL, &pdata->hash_lo);
++ check_warn(ret, "failed to initiate async write to HASHL");
++
++ ret = smsc95xx_write_reg_async(dev, MAC_CR, &pdata->mac_cr);
++ check_warn(ret, "failed to initiate async write to MAC_CR");
+ }
+
+-static void smsc95xx_phy_update_flowcontrol(struct usbnet *dev, u8 duplex,
+- u16 lcladv, u16 rmtadv)
++static int smsc95xx_phy_update_flowcontrol(struct usbnet *dev, u8 duplex,
++ u16 lcladv, u16 rmtadv)
+ {
+ u32 flow, afc_cfg = 0;
+
+ int ret = smsc95xx_read_reg(dev, AFC_CFG, &afc_cfg);
+- if (ret < 0) {
+- netdev_warn(dev->net, "error reading AFC_CFG\n");
+- return;
+- }
++ check_warn_return(ret, "Error reading AFC_CFG");
+
+ if (duplex == DUPLEX_FULL) {
+ u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv);
+@@ -454,8 +479,13 @@ static void smsc95xx_phy_update_flowcontrol(struct usbnet *dev, u8 duplex,
+ afc_cfg |= 0xF;
+ }
+
+- smsc95xx_write_reg(dev, FLOW, flow);
+- smsc95xx_write_reg(dev, AFC_CFG, afc_cfg);
++ ret = smsc95xx_write_reg(dev, FLOW, flow);
++ check_warn_return(ret, "Error writing FLOW");
++
++ ret = smsc95xx_write_reg(dev, AFC_CFG, afc_cfg);
++ check_warn_return(ret, "Error writing AFC_CFG");
++
++ return 0;
+ }
+
+ static int smsc95xx_link_reset(struct usbnet *dev)
+@@ -465,10 +495,14 @@ static int smsc95xx_link_reset(struct usbnet *dev)
+ struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
+ unsigned long flags;
+ u16 lcladv, rmtadv;
++ int ret;
+
+ /* clear interrupt status */
+- smsc95xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);
+- smsc95xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL_);
++ ret = smsc95xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);
++ check_warn_return(ret, "Error reading PHY_INT_SRC");
++
++ ret = smsc95xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL_);
++ check_warn_return(ret, "Error writing INT_STS");
+
+ mii_check_media(mii, 1, 1);
+ mii_ethtool_gset(&dev->mii, &ecmd);
+@@ -489,9 +523,11 @@ static int smsc95xx_link_reset(struct usbnet *dev)
+ }
+ spin_unlock_irqrestore(&pdata->mac_cr_lock, flags);
+
+- smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr);
++ ret = smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr);
++ check_warn_return(ret, "Error writing MAC_CR");
+
+- smsc95xx_phy_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv);
++ ret = smsc95xx_phy_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv);
++ check_warn_return(ret, "Error updating PHY flow control");
+
+ return 0;
+ }
+@@ -527,10 +563,7 @@ static int smsc95xx_set_features(struct net_device *netdev,
+ int ret;
+
+ ret = smsc95xx_read_reg(dev, COE_CR, &read_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to read COE_CR: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to read COE_CR: %d\n", ret);
+
+ if (features & NETIF_F_HW_CSUM)
+ read_buf |= Tx_COE_EN_;
+@@ -543,10 +576,7 @@ static int smsc95xx_set_features(struct net_device *netdev,
+ read_buf &= ~Rx_COE_EN_;
+
+ ret = smsc95xx_write_reg(dev, COE_CR, read_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to write COE_CR: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to write COE_CR: %d\n", ret);
+
+ netif_dbg(dev, hw, dev->net, "COE_CR = 0x%08x\n", read_buf);
+ return 0;
+@@ -712,53 +742,56 @@ static int smsc95xx_set_mac_address(struct usbnet *dev)
+ int ret;
+
+ ret = smsc95xx_write_reg(dev, ADDRL, addr_lo);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to write ADDRL: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to write ADDRL: %d\n", ret);
+
+ ret = smsc95xx_write_reg(dev, ADDRH, addr_hi);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to write ADDRH: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to write ADDRH: %d\n", ret);
+
+ return 0;
+ }
+
+ /* starts the TX path */
+-static void smsc95xx_start_tx_path(struct usbnet *dev)
++static int smsc95xx_start_tx_path(struct usbnet *dev)
+ {
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ unsigned long flags;
++ int ret;
+
+ /* Enable Tx at MAC */
+ spin_lock_irqsave(&pdata->mac_cr_lock, flags);
+ pdata->mac_cr |= MAC_CR_TXEN_;
+ spin_unlock_irqrestore(&pdata->mac_cr_lock, flags);
+
+- smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr);
++ ret = smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr);
++ check_warn_return(ret, "Failed to write MAC_CR: %d\n", ret);
+
+ /* Enable Tx at SCSRs */
+- smsc95xx_write_reg(dev, TX_CFG, TX_CFG_ON_);
++ ret = smsc95xx_write_reg(dev, TX_CFG, TX_CFG_ON_);
++ check_warn_return(ret, "Failed to write TX_CFG: %d\n", ret);
++
++ return 0;
+ }
+
+ /* Starts the Receive path */
+-static void smsc95xx_start_rx_path(struct usbnet *dev)
++static int smsc95xx_start_rx_path(struct usbnet *dev)
+ {
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ unsigned long flags;
++ int ret;
+
+ spin_lock_irqsave(&pdata->mac_cr_lock, flags);
+ pdata->mac_cr |= MAC_CR_RXEN_;
+ spin_unlock_irqrestore(&pdata->mac_cr_lock, flags);
+
+- smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr);
++ ret = smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr);
++ check_warn_return(ret, "Failed to write MAC_CR: %d\n", ret);
++
++ return 0;
+ }
+
+ static int smsc95xx_phy_initialize(struct usbnet *dev)
+ {
+- int bmcr, timeout = 0;
++ int bmcr, ret, timeout = 0;
+
+ /* Initialize MII structure */
+ dev->mii.dev = dev->net;
+@@ -787,7 +820,8 @@ static int smsc95xx_phy_initialize(struct usbnet *dev)
+ ADVERTISE_PAUSE_ASYM);
+
+ /* read to clear */
+- smsc95xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
++ ret = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
++ check_warn_return(ret, "Failed to read PHY_INT_SRC during init");
+
+ smsc95xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK,
+ PHY_INT_MASK_DEFAULT_);
+@@ -806,20 +840,13 @@ static int smsc95xx_reset(struct usbnet *dev)
+ netif_dbg(dev, ifup, dev->net, "entering smsc95xx_reset\n");
+
+ ret = smsc95xx_write_reg(dev, HW_CFG, HW_CFG_LRST_);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to write HW_CFG_LRST_ bit in HW_CFG register, ret = %d\n",
+- ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to write HW_CFG_LRST_ bit in HW_CFG\n");
+
+ timeout = 0;
+ do {
+ msleep(10);
+ ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to read HW_CFG: %d\n", ret);
+ timeout++;
+ } while ((read_buf & HW_CFG_LRST_) && (timeout < 100));
+
+@@ -829,19 +856,13 @@ static int smsc95xx_reset(struct usbnet *dev)
+ }
+
+ ret = smsc95xx_write_reg(dev, PM_CTRL, PM_CTL_PHY_RST_);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to write PM_CTRL: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to write PM_CTRL: %d\n", ret);
+
+ timeout = 0;
+ do {
+ msleep(10);
+ ret = smsc95xx_read_reg(dev, PM_CTRL, &read_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to read PM_CTRL: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to read PM_CTRL: %d\n", ret);
+ timeout++;
+ } while ((read_buf & PM_CTL_PHY_RST_) && (timeout < 100));
+
+@@ -858,10 +879,7 @@ static int smsc95xx_reset(struct usbnet *dev)
+ "MAC Address: %pM\n", dev->net->dev_addr);
+
+ ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to read HW_CFG: %d\n", ret);
+
+ netif_dbg(dev, ifup, dev->net,
+ "Read Value from HW_CFG : 0x%08x\n", read_buf);
+@@ -869,17 +887,10 @@ static int smsc95xx_reset(struct usbnet *dev)
+ read_buf |= HW_CFG_BIR_;
+
+ ret = smsc95xx_write_reg(dev, HW_CFG, read_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to write HW_CFG_BIR_ bit in HW_CFG register, ret = %d\n",
+- ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to write HW_CFG_BIR_ bit in HW_CFG\n");
+
+ ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to read HW_CFG: %d\n", ret);
+ netif_dbg(dev, ifup, dev->net,
+ "Read Value from HW_CFG after writing HW_CFG_BIR_: 0x%08x\n",
+ read_buf);
+@@ -899,40 +910,28 @@ static int smsc95xx_reset(struct usbnet *dev)
+ "rx_urb_size=%ld\n", (ulong)dev->rx_urb_size);
+
+ ret = smsc95xx_write_reg(dev, BURST_CAP, burst_cap);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to write BURST_CAP: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to write BURST_CAP: %d\n", ret);
+
+ ret = smsc95xx_read_reg(dev, BURST_CAP, &read_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to read BURST_CAP: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to read BURST_CAP: %d\n", ret);
++
+ netif_dbg(dev, ifup, dev->net,
+ "Read Value from BURST_CAP after writing: 0x%08x\n",
+ read_buf);
+
+ ret = smsc95xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY);
+- if (ret < 0) {
+- netdev_warn(dev->net, "ret = %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to write BULK_IN_DLY: %d\n", ret);
+
+ ret = smsc95xx_read_reg(dev, BULK_IN_DLY, &read_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to read BULK_IN_DLY: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to read BULK_IN_DLY: %d\n", ret);
++
+ netif_dbg(dev, ifup, dev->net,
+ "Read Value from BULK_IN_DLY after writing: 0x%08x\n",
+ read_buf);
+
+ ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to read HW_CFG: %d\n", ret);
++
+ netif_dbg(dev, ifup, dev->net,
+ "Read Value from HW_CFG: 0x%08x\n", read_buf);
+
+@@ -945,97 +944,66 @@ static int smsc95xx_reset(struct usbnet *dev)
+ read_buf |= NET_IP_ALIGN << 9;
+
+ ret = smsc95xx_write_reg(dev, HW_CFG, read_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to write HW_CFG register, ret=%d\n",
+- ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to write HW_CFG: %d\n", ret);
+
+ ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to read HW_CFG: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to read HW_CFG: %d\n", ret);
++
+ netif_dbg(dev, ifup, dev->net,
+ "Read Value from HW_CFG after writing: 0x%08x\n", read_buf);
+
+ ret = smsc95xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL_);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to write INT_STS register, ret=%d\n",
+- ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to write INT_STS: %d\n", ret);
+
+ ret = smsc95xx_read_reg(dev, ID_REV, &read_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to read ID_REV: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to read ID_REV: %d\n", ret);
+ netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x\n", read_buf);
+
+ /* Configure GPIO pins as LED outputs */
+ write_buf = LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED |
+ LED_GPIO_CFG_FDX_LED;
+ ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, write_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to write LED_GPIO_CFG register, ret=%d\n",
+- ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to write LED_GPIO_CFG: %d\n", ret);
+
+ /* Init Tx */
+ ret = smsc95xx_write_reg(dev, FLOW, 0);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to write FLOW: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to write FLOW: %d\n", ret);
+
+ ret = smsc95xx_write_reg(dev, AFC_CFG, AFC_CFG_DEFAULT);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to write AFC_CFG: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to write AFC_CFG: %d\n", ret);
+
+ /* Don't need mac_cr_lock during initialisation */
+ ret = smsc95xx_read_reg(dev, MAC_CR, &pdata->mac_cr);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to read MAC_CR: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to read MAC_CR: %d\n", ret);
+
+ /* Init Rx */
+ /* Set Vlan */
+ ret = smsc95xx_write_reg(dev, VLAN1, (u32)ETH_P_8021Q);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to write VAN1: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to write VLAN1: %d\n", ret);
+
+ /* Enable or disable checksum offload engines */
+- smsc95xx_set_features(dev->net, dev->net->features);
++ ret = smsc95xx_set_features(dev->net, dev->net->features);
++ check_warn_return(ret, "Failed to set checksum offload features");
+
+ smsc95xx_set_multicast(dev->net);
+
+- if (smsc95xx_phy_initialize(dev) < 0)
+- return -EIO;
++ ret = smsc95xx_phy_initialize(dev);
++ check_warn_return(ret, "Failed to init PHY");
+
+ ret = smsc95xx_read_reg(dev, INT_EP_CTL, &read_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to read INT_EP_CTL: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to read INT_EP_CTL: %d\n", ret);
+
+ /* enable PHY interrupts */
+ read_buf |= INT_EP_CTL_PHY_INT_;
+
+ ret = smsc95xx_write_reg(dev, INT_EP_CTL, read_buf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "Failed to write INT_EP_CTL: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "Failed to write INT_EP_CTL: %d\n", ret);
+
+- smsc95xx_start_tx_path(dev);
+- smsc95xx_start_rx_path(dev);
++ ret = smsc95xx_start_tx_path(dev);
++ check_warn_return(ret, "Failed to start TX path");
++
++ ret = smsc95xx_start_rx_path(dev);
++ check_warn_return(ret, "Failed to start RX path");
+
+ netif_dbg(dev, ifup, dev->net, "smsc95xx_reset, return 0\n");
+ return 0;
+@@ -1062,10 +1030,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
+ printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n");
+
+ ret = usbnet_get_endpoints(dev, intf);
+- if (ret < 0) {
+- netdev_warn(dev->net, "usbnet_get_endpoints failed: %d\n", ret);
+- return ret;
+- }
++ check_warn_return(ret, "usbnet_get_endpoints failed: %d\n", ret);
+
+ dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc95xx_priv),
+ GFP_KERNEL);
diff --git a/patches/linux-3.6.7/0167-smsc95xx-fix-resume-when-usb-device-is-reset.patch b/patches/linux-3.6.7/0167-smsc95xx-fix-resume-when-usb-device-is-reset.patch
new file mode 100644
index 0000000..9284a08
--- /dev/null
+++ b/patches/linux-3.6.7/0167-smsc95xx-fix-resume-when-usb-device-is-reset.patch
@@ -0,0 +1,25 @@
+From: Steve Glendinning <steve.glendinning@shawell.net>
+Date: Fri, 28 Sep 2012 00:07:10 +0000
+Subject: [PATCH] smsc95xx: fix resume when usb device is reset
+
+This patch fixes an issue on some systems, where after suspend the
+link is re-established but the ethernet interface does not resume.
+
+Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/smsc95xx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
+index 9c13e25..9405f6d 100644
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -1338,6 +1338,7 @@ static struct usb_driver smsc95xx_driver = {
+ .probe = usbnet_probe,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
++ .reset_resume = usbnet_resume,
+ .disconnect = usbnet_disconnect,
+ .disable_hub_initiated_lpm = 1,
+ };
diff --git a/patches/linux-3.6.7/0168-smsc95xx-enable-power-saving-mode-during-system-susp.patch b/patches/linux-3.6.7/0168-smsc95xx-enable-power-saving-mode-during-system-susp.patch
new file mode 100644
index 0000000..c4c17df
--- /dev/null
+++ b/patches/linux-3.6.7/0168-smsc95xx-enable-power-saving-mode-during-system-susp.patch
@@ -0,0 +1,86 @@
+From: Steve Glendinning <steve.glendinning@shawell.net>
+Date: Fri, 28 Sep 2012 00:07:11 +0000
+Subject: [PATCH] smsc95xx: enable power saving mode during system suspend
+
+This patch enables the device to enter its lowest power SUSPEND2
+state during system suspend, instead of staying up using full power.
+
+Patch updated to not add two pointers to .suspend & .resume.
+
+Patch updated to replace BUG_ON with WARN_ON_ONCE and return.
+
+Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/smsc95xx.c | 28 +++++++++++++++++++++++++++-
+ drivers/net/usb/smsc95xx.h | 6 +++++-
+ 2 files changed, 32 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
+index 9405f6d..ff48ed0 100644
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -1074,6 +1074,32 @@ static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf)
+ }
+ }
+
++static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
++{
++ struct usbnet *dev = usb_get_intfdata(intf);
++ int ret;
++ u32 val;
++
++ if (WARN_ON_ONCE(!dev))
++ return -EINVAL;
++
++ ret = usbnet_suspend(intf, message);
++ check_warn_return(ret, "usbnet_suspend error");
++
++ netdev_info(dev->net, "entering SUSPEND2 mode");
++
++ ret = smsc95xx_read_reg(dev, PM_CTRL, &val);
++ check_warn_return(ret, "Error reading PM_CTRL");
++
++ val &= ~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_);
++ val |= PM_CTL_SUS_MODE_2;
++
++ ret = smsc95xx_write_reg(dev, PM_CTRL, val);
++ check_warn_return(ret, "Error writing PM_CTRL");
++
++ return 0;
++}
++
+ static void smsc95xx_rx_csum_offload(struct sk_buff *skb)
+ {
+ skb->csum = *(u16 *)(skb_tail_pointer(skb) - 2);
+@@ -1336,7 +1362,7 @@ static struct usb_driver smsc95xx_driver = {
+ .name = "smsc95xx",
+ .id_table = products,
+ .probe = usbnet_probe,
+- .suspend = usbnet_suspend,
++ .suspend = smsc95xx_suspend,
+ .resume = usbnet_resume,
+ .reset_resume = usbnet_resume,
+ .disconnect = usbnet_disconnect,
+diff --git a/drivers/net/usb/smsc95xx.h b/drivers/net/usb/smsc95xx.h
+index a275b62..89ad925 100644
+--- a/drivers/net/usb/smsc95xx.h
++++ b/drivers/net/usb/smsc95xx.h
+@@ -84,12 +84,16 @@
+ #define HW_CFG_BCE_ (0x00000002)
+ #define HW_CFG_SRST_ (0x00000001)
+
++#define RX_FIFO_INF (0x18)
++
+ #define PM_CTRL (0x20)
++#define PM_CTL_RES_CLR_WKP_STS (0x00000200)
+ #define PM_CTL_DEV_RDY_ (0x00000080)
+ #define PM_CTL_SUS_MODE_ (0x00000060)
+ #define PM_CTL_SUS_MODE_0 (0x00000000)
+ #define PM_CTL_SUS_MODE_1 (0x00000020)
+-#define PM_CTL_SUS_MODE_2 (0x00000060)
++#define PM_CTL_SUS_MODE_2 (0x00000040)
++#define PM_CTL_SUS_MODE_3 (0x00000060)
+ #define PM_CTL_PHY_RST_ (0x00000010)
+ #define PM_CTL_WOL_EN_ (0x00000008)
+ #define PM_CTL_ED_EN_ (0x00000004)
diff --git a/patches/linux-3.6.7/0169-smsc95xx-add-wol-magic-packet-support.patch b/patches/linux-3.6.7/0169-smsc95xx-add-wol-magic-packet-support.patch
new file mode 100644
index 0000000..6fc371a
--- /dev/null
+++ b/patches/linux-3.6.7/0169-smsc95xx-add-wol-magic-packet-support.patch
@@ -0,0 +1,283 @@
+From: Steve Glendinning <steve.glendinning@shawell.net>
+Date: Fri, 28 Sep 2012 00:07:12 +0000
+Subject: [PATCH] smsc95xx: add wol magic packet support
+
+This patch enables wake from system suspend on magic packet.
+
+Patch updated to replace BUG_ON with WARN_ON_ONCE and return.
+
+Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/smsc95xx.c | 185 +++++++++++++++++++++++++++++++++++++++++++--
+ drivers/net/usb/smsc95xx.h | 5 ++
+ 2 files changed, 182 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
+index ff48ed0..d162b8b 100644
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -47,6 +47,7 @@
+ #define SMSC95XX_TX_OVERHEAD (8)
+ #define SMSC95XX_TX_OVERHEAD_CSUM (12)
+ #define MAC_ADDR_LEN (6)
++#define SUPPORTED_WAKE (WAKE_MAGIC)
+
+ #define check_warn(ret, fmt, args...) \
+ ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })
+@@ -61,6 +62,7 @@ struct smsc95xx_priv {
+ u32 mac_cr;
+ u32 hash_hi;
+ u32 hash_lo;
++ u32 wolopts;
+ spinlock_t mac_cr_lock;
+ };
+
+@@ -130,6 +132,30 @@ static int __must_check smsc95xx_write_reg(struct usbnet *dev, u32 index,
+ return ret;
+ }
+
++static int smsc95xx_set_feature(struct usbnet *dev, u32 feature)
++{
++ if (WARN_ON_ONCE(!dev))
++ return -EINVAL;
++
++ cpu_to_le32s(&feature);
++
++ return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
++ USB_REQ_SET_FEATURE, USB_RECIP_DEVICE, feature, 0, NULL, 0,
++ USB_CTRL_SET_TIMEOUT);
++}
++
++static int smsc95xx_clear_feature(struct usbnet *dev, u32 feature)
++{
++ if (WARN_ON_ONCE(!dev))
++ return -EINVAL;
++
++ cpu_to_le32s(&feature);
++
++ return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
++ USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, feature, 0, NULL, 0,
++ USB_CTRL_SET_TIMEOUT);
++}
++
+ /* Loop until the read is completed with timeout
+ * called with phy_mutex held */
+ static int __must_check smsc95xx_phy_wait_not_busy(struct usbnet *dev)
+@@ -641,6 +667,26 @@ smsc95xx_ethtool_getregs(struct net_device *netdev, struct ethtool_regs *regs,
+ }
+ }
+
++static void smsc95xx_ethtool_get_wol(struct net_device *net,
++ struct ethtool_wolinfo *wolinfo)
++{
++ struct usbnet *dev = netdev_priv(net);
++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
++
++ wolinfo->supported = SUPPORTED_WAKE;
++ wolinfo->wolopts = pdata->wolopts;
++}
++
++static int smsc95xx_ethtool_set_wol(struct net_device *net,
++ struct ethtool_wolinfo *wolinfo)
++{
++ struct usbnet *dev = netdev_priv(net);
++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
++
++ pdata->wolopts = wolinfo->wolopts & SUPPORTED_WAKE;
++ return 0;
++}
++
+ static const struct ethtool_ops smsc95xx_ethtool_ops = {
+ .get_link = usbnet_get_link,
+ .nway_reset = usbnet_nway_reset,
+@@ -654,6 +700,8 @@ static const struct ethtool_ops smsc95xx_ethtool_ops = {
+ .set_eeprom = smsc95xx_ethtool_set_eeprom,
+ .get_regs_len = smsc95xx_ethtool_getregslen,
+ .get_regs = smsc95xx_ethtool_getregs,
++ .get_wol = smsc95xx_ethtool_get_wol,
++ .set_wol = smsc95xx_ethtool_set_wol,
+ };
+
+ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+@@ -1077,26 +1125,147 @@ static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf)
+ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
+ {
+ struct usbnet *dev = usb_get_intfdata(intf);
++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ int ret;
+ u32 val;
+
+- if (WARN_ON_ONCE(!dev))
+- return -EINVAL;
+-
+ ret = usbnet_suspend(intf, message);
+ check_warn_return(ret, "usbnet_suspend error");
+
+- netdev_info(dev->net, "entering SUSPEND2 mode");
++ /* if no wol options set, enter lowest power SUSPEND2 mode */
++ if (!(pdata->wolopts & SUPPORTED_WAKE)) {
++ netdev_info(dev->net, "entering SUSPEND2 mode");
++
++ /* disable energy detect (link up) & wake up events */
++ ret = smsc95xx_read_reg(dev, WUCSR, &val);
++ check_warn_return(ret, "Error reading WUCSR");
++
++ val &= ~(WUCSR_MPEN_ | WUCSR_WAKE_EN_);
++
++ ret = smsc95xx_write_reg(dev, WUCSR, val);
++ check_warn_return(ret, "Error writing WUCSR");
++
++ ret = smsc95xx_read_reg(dev, PM_CTRL, &val);
++ check_warn_return(ret, "Error reading PM_CTRL");
++
++ val &= ~(PM_CTL_ED_EN_ | PM_CTL_WOL_EN_);
++
++ ret = smsc95xx_write_reg(dev, PM_CTRL, val);
++ check_warn_return(ret, "Error writing PM_CTRL");
++
++ /* enter suspend2 mode */
++ ret = smsc95xx_read_reg(dev, PM_CTRL, &val);
++ check_warn_return(ret, "Error reading PM_CTRL");
++
++ val &= ~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_);
++ val |= PM_CTL_SUS_MODE_2;
++
++ ret = smsc95xx_write_reg(dev, PM_CTRL, val);
++ check_warn_return(ret, "Error writing PM_CTRL");
++
++ return 0;
++ }
++
++ if (pdata->wolopts & WAKE_MAGIC) {
++ /* clear any pending magic packet status */
++ ret = smsc95xx_read_reg(dev, WUCSR, &val);
++ check_warn_return(ret, "Error reading WUCSR");
++
++ val |= WUCSR_MPR_;
++
++ ret = smsc95xx_write_reg(dev, WUCSR, val);
++ check_warn_return(ret, "Error writing WUCSR");
++ }
++
++ /* enable/disable magic packup wake */
++ ret = smsc95xx_read_reg(dev, WUCSR, &val);
++ check_warn_return(ret, "Error reading WUCSR");
++
++ if (pdata->wolopts & WAKE_MAGIC) {
++ netdev_info(dev->net, "enabling magic packet wakeup");
++ val |= WUCSR_MPEN_;
++ } else {
++ netdev_info(dev->net, "disabling magic packet wakeup");
++ val &= ~WUCSR_MPEN_;
++ }
++
++ ret = smsc95xx_write_reg(dev, WUCSR, val);
++ check_warn_return(ret, "Error writing WUCSR");
++
++ /* enable wol wakeup source */
++ ret = smsc95xx_read_reg(dev, PM_CTRL, &val);
++ check_warn_return(ret, "Error reading PM_CTRL");
++
++ val |= PM_CTL_WOL_EN_;
++
++ ret = smsc95xx_write_reg(dev, PM_CTRL, val);
++ check_warn_return(ret, "Error writing PM_CTRL");
++
++ /* enable receiver */
++ smsc95xx_start_rx_path(dev);
++
++ /* some wol options are enabled, so enter SUSPEND0 */
++ netdev_info(dev->net, "entering SUSPEND0 mode");
+
+ ret = smsc95xx_read_reg(dev, PM_CTRL, &val);
+ check_warn_return(ret, "Error reading PM_CTRL");
+
+- val &= ~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_);
+- val |= PM_CTL_SUS_MODE_2;
++ val &= (~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_));
++ val |= PM_CTL_SUS_MODE_0;
+
+ ret = smsc95xx_write_reg(dev, PM_CTRL, val);
+ check_warn_return(ret, "Error writing PM_CTRL");
+
++ /* clear wol status */
++ val &= ~PM_CTL_WUPS_;
++ val |= PM_CTL_WUPS_WOL_;
++ ret = smsc95xx_write_reg(dev, PM_CTRL, val);
++ check_warn_return(ret, "Error writing PM_CTRL");
++
++ /* read back PM_CTRL */
++ ret = smsc95xx_read_reg(dev, PM_CTRL, &val);
++ check_warn_return(ret, "Error reading PM_CTRL");
++
++ smsc95xx_set_feature(dev, USB_DEVICE_REMOTE_WAKEUP);
++
++ return 0;
++}
++
++static int smsc95xx_resume(struct usb_interface *intf)
++{
++ struct usbnet *dev = usb_get_intfdata(intf);
++ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
++ int ret;
++ u32 val;
++
++ BUG_ON(!dev);
++
++ if (pdata->wolopts & WAKE_MAGIC) {
++ smsc95xx_clear_feature(dev, USB_DEVICE_REMOTE_WAKEUP);
++
++ /* Disable magic packup wake */
++ ret = smsc95xx_read_reg(dev, WUCSR, &val);
++ check_warn_return(ret, "Error reading WUCSR");
++
++ val &= ~WUCSR_MPEN_;
++
++ ret = smsc95xx_write_reg(dev, WUCSR, val);
++ check_warn_return(ret, "Error writing WUCSR");
++
++ /* clear wake-up status */
++ ret = smsc95xx_read_reg(dev, PM_CTRL, &val);
++ check_warn_return(ret, "Error reading PM_CTRL");
++
++ val &= ~PM_CTL_WOL_EN_;
++ val |= PM_CTL_WUPS_;
++
++ ret = smsc95xx_write_reg(dev, PM_CTRL, val);
++ check_warn_return(ret, "Error writing PM_CTRL");
++ }
++
++ return usbnet_resume(intf);
++ check_warn_return(ret, "usbnet_resume error");
++
+ return 0;
+ }
+
+@@ -1363,8 +1532,8 @@ static struct usb_driver smsc95xx_driver = {
+ .id_table = products,
+ .probe = usbnet_probe,
+ .suspend = smsc95xx_suspend,
+- .resume = usbnet_resume,
+- .reset_resume = usbnet_resume,
++ .resume = smsc95xx_resume,
++ .reset_resume = smsc95xx_resume,
+ .disconnect = usbnet_disconnect,
+ .disable_hub_initiated_lpm = 1,
+ };
+diff --git a/drivers/net/usb/smsc95xx.h b/drivers/net/usb/smsc95xx.h
+index 89ad925..2ff9815 100644
+--- a/drivers/net/usb/smsc95xx.h
++++ b/drivers/net/usb/smsc95xx.h
+@@ -205,6 +205,11 @@
+ #define WUFF (0x128)
+
+ #define WUCSR (0x12C)
++#define WUCSR_GUE_ (0x00000200)
++#define WUCSR_WUFR_ (0x00000040)
++#define WUCSR_MPR_ (0x00000020)
++#define WUCSR_WAKE_EN_ (0x00000004)
++#define WUCSR_MPEN_ (0x00000002)
+
+ #define COE_CR (0x130)
+ #define Tx_COE_EN_ (0x00010000)
diff --git a/patches/linux-3.6.7/0170-smsc95xx-fix-tx-checksum-offload-for-big-endian.patch b/patches/linux-3.6.7/0170-smsc95xx-fix-tx-checksum-offload-for-big-endian.patch
new file mode 100644
index 0000000..bf2ffa9
--- /dev/null
+++ b/patches/linux-3.6.7/0170-smsc95xx-fix-tx-checksum-offload-for-big-endian.patch
@@ -0,0 +1,33 @@
+From: Steve Glendinning <steve.glendinning@shawell.net>
+Date: Fri, 2 Nov 2012 00:44:20 +0000
+Subject: [PATCH] smsc95xx: fix tx checksum offload for big endian
+
+f7b2927 introduced tx checksum offload support for smsc95xx,
+and enabled it by default. This feature doesn't take
+endianness into account, so causes most tx to fail on
+those platforms.
+
+This patch fixes the problem fully by adding the missing
+conversion.
+
+An alternate workaround is to disable TX checksum offload
+on those platforms. The cpu impact of this feature is very low.
+
+Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/usb/smsc95xx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
+index d162b8b..18955a9 100644
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -1400,6 +1400,7 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
+ } else {
+ u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
+ skb_push(skb, 4);
++ cpu_to_le32s(&csum_preamble);
+ memcpy(skb->data, &csum_preamble, 4);
+ }
+ }
diff --git a/patches/linux-3.6.7/0171-Update-to-latest-vchiq.patch b/patches/linux-3.6.7/0171-Update-to-latest-vchiq.patch
new file mode 100644
index 0000000..d1365b9
--- /dev/null
+++ b/patches/linux-3.6.7/0171-Update-to-latest-vchiq.patch
@@ -0,0 +1,961 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Wed, 14 Nov 2012 22:45:22 +0000
+Subject: [PATCH] Update to latest vchiq
+
+---
+ .../interface/vchiq_arm/vchiq_2835_arm.c | 5 +
+ .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 260 ++++++++++++---------
+ .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 12 +-
+ .../vc04_services/interface/vchiq_arm/vchiq_core.c | 123 +++++++---
+ .../vc04_services/interface/vchiq_arm/vchiq_core.h | 11 +-
+ .../vc04_services/interface/vchiq_arm/vchiq_if.h | 2 +
+ .../interface/vchiq_arm/vchiq_kern_lib.c | 6 +-
+ .../vc04_services/interface/vchiq_arm/vchiq_proc.c | 2 +
+ 8 files changed, 273 insertions(+), 148 deletions(-)
+ mode change 100755 => 100644 drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
+
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+index 93d4c3f..7f78246 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+@@ -308,6 +308,11 @@ vchiq_dump_platform_use_state(VCHIQ_STATE_T *state)
+ {
+ vchiq_log_info((vchiq_arm_log_level>=VCHIQ_LOG_INFO),"Suspend timer not in use");
+ }
++void
++vchiq_platform_handle_timeout(VCHIQ_STATE_T *state)
++{
++ (void)state;
++}
+ /*
+ * Local functions
+ */
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
+old mode 100755
+new mode 100644
+index 81daf3e..91edfd2
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
+@@ -54,7 +54,7 @@
+
+ /* Run time control of log level, based on KERN_XXX level. */
+ int vchiq_arm_log_level = VCHIQ_LOG_DEFAULT;
+-int vchiq_susp_log_level = VCHIQ_LOG_DEFAULT;
++int vchiq_susp_log_level = VCHIQ_LOG_ERROR;
+
+ #define SUSPEND_TIMER_TIMEOUT_MS 100
+ #define SUSPEND_RETRY_TIMER_TIMEOUT_MS 1000
+@@ -435,6 +435,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ if (args.is_open) {
+ if (!instance->connected) {
+ ret = -ENOTCONN;
++ kfree(user_service);
+ break;
+ }
+ srvstate = VCHIQ_SRVSTATE_OPENING;
+@@ -705,7 +706,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ */
+ rmb();
+
+- if ((ret == 0) && !instance->closing) {
++ if (ret == 0) {
+ int msgbufcount = args.msgbufcount;
+ for (ret = 0; ret < args.count; ret++) {
+ VCHIQ_COMPLETION_DATA_T *completion;
+@@ -1072,12 +1073,15 @@ vchiq_release(struct inode *inode, struct file *file)
+ "vchiq_release: instance=%lx",
+ (unsigned long)instance);
+
+- if (state) {
+- /* Ensure videocore is awake to allow termination. */
+- vchiq_use_internal(instance->state, NULL,
+- USE_TYPE_VCHIQ);
++ if (!state) {
++ ret = -EPERM;
++ goto out;
+ }
+
++ /* Ensure videocore is awake to allow termination. */
++ vchiq_use_internal(instance->state, NULL,
++ USE_TYPE_VCHIQ);
++
+ mutex_lock(&instance->completion_mutex);
+
+ /* Wake the completion thread and ask it to exit */
+@@ -1149,10 +1153,8 @@ vchiq_release(struct inode *inode, struct file *file)
+ instance->completion_remove++;
+ }
+
+- if (state) {
+- /* Release the PEER service count. */
+- vchiq_release_internal(instance->state, NULL);
+- }
++ /* Release the PEER service count. */
++ vchiq_release_internal(instance->state, NULL);
+
+ {
+ struct list_head *pos, *next;
+@@ -1183,6 +1185,7 @@ vchiq_release(struct inode *inode, struct file *file)
+ ret = -ENXIO;
+ }
+
++out:
+ return ret;
+ }
+
+@@ -1197,7 +1200,7 @@ vchiq_dump(void *dump_context, const char *str, int len)
+ {
+ DUMP_CONTEXT_T *context = (DUMP_CONTEXT_T *)dump_context;
+
+- if ((context->actual >= 0) && (context->actual < context->space)) {
++ if (context->actual < context->space) {
+ int copy_bytes;
+ if (context->offset > 0) {
+ int skip_bytes = min(len, (int)context->offset);
+@@ -1415,8 +1418,7 @@ vchiq_read(struct file *file, char __user *buf,
+
+ vchiq_dump_state(&context, &g_state);
+
+- if (context.actual >= 0)
+- *ppos += context.actual;
++ *ppos += context.actual;
+
+ return context.actual;
+ }
+@@ -1467,7 +1469,9 @@ vchiq_videocore_wanted(VCHIQ_STATE_T *state)
+ /* non-zero usage count - videocore still required */
+ return 1;
+ }
+-static VCHIQ_STATUS_T vchiq_keepalive_vchiq_callback(VCHIQ_REASON_T reason,
++
++static VCHIQ_STATUS_T
++vchiq_keepalive_vchiq_callback(VCHIQ_REASON_T reason,
+ VCHIQ_HEADER_T *header,
+ VCHIQ_SERVICE_HANDLE_T service_user,
+ void *bulk_user)
+@@ -1558,6 +1562,7 @@ exit:
+ }
+
+
++
+ VCHIQ_STATUS_T
+ vchiq_arm_init_state(VCHIQ_STATE_T *state, VCHIQ_ARM_STATE_T *arm_state)
+ {
+@@ -1565,7 +1570,6 @@ vchiq_arm_init_state(VCHIQ_STATE_T *state, VCHIQ_ARM_STATE_T *arm_state)
+ char threadname[10];
+
+ if (arm_state) {
+- mutex_init(&arm_state->vc_use_cnt_mutex);
+ rwlock_init(&arm_state->susp_res_lock);
+
+ init_completion(&arm_state->ka_evt);
+@@ -1772,14 +1776,22 @@ static int
+ block_resume(VCHIQ_ARM_STATE_T *arm_state)
+ {
+ int status = VCHIQ_SUCCESS;
+- while (arm_state->blocked_count) {
++ const unsigned long timeout_val =
++ msecs_to_jiffies(FORCE_SUSPEND_TIMEOUT_MS);
++ int resume_count = 0;
++
++ /* Allow any threads which were blocked by the last force suspend to
++ * complete if they haven't already. Only give this one shot; if
++ * blocked_count is incremented after blocked_blocker is completed
++ * (which only happens when blocked_count hits 0) then those threads
++ * will have to wait until next time around */
++ if (arm_state->blocked_count) {
+ INIT_COMPLETION(arm_state->blocked_blocker);
+ write_unlock_bh(&arm_state->susp_res_lock);
+ vchiq_log_info(vchiq_susp_log_level, "%s wait for previously "
+ "blocked clients", __func__);
+ if (wait_for_completion_interruptible_timeout(
+- &arm_state->blocked_blocker,
+- msecs_to_jiffies(FORCE_SUSPEND_TIMEOUT_MS))
++ &arm_state->blocked_blocker, timeout_val)
+ <= 0) {
+ vchiq_log_error(vchiq_susp_log_level, "%s wait for "
+ "previously blocked clients failed" , __func__);
+@@ -1791,30 +1803,33 @@ block_resume(VCHIQ_ARM_STATE_T *arm_state)
+ "clients resumed", __func__);
+ write_lock_bh(&arm_state->susp_res_lock);
+ }
++
++ /* We need to wait for resume to complete if it's in process */
+ while (arm_state->vc_resume_state != VC_RESUME_RESUMED &&
+ arm_state->vc_resume_state > VC_RESUME_IDLE) {
+- if (!try_wait_for_completion(&arm_state->vc_resume_complete)) {
+- write_unlock_bh(&arm_state->susp_res_lock);
+- vchiq_log_info(vchiq_susp_log_level, "%s wait for "
+- "resume", __func__);
+- if (wait_for_completion_interruptible_timeout(
+- &arm_state->vc_resume_complete,
+- msecs_to_jiffies(
+- FORCE_SUSPEND_TIMEOUT_MS))
+- <= 0) {
+- vchiq_log_error(vchiq_susp_log_level, "%s wait "
+- "for resume failed (%s)", __func__,
+- resume_state_names[
+- arm_state->vc_resume_state +
+- VC_RESUME_NUM_OFFSET]);
+- status = VCHIQ_ERROR;
+- write_lock_bh(&arm_state->susp_res_lock);
+- goto out;
+- }
+- vchiq_log_info(vchiq_susp_log_level, "%s resumed",
+- __func__);
++ if (resume_count > 1) {
++ status = VCHIQ_ERROR;
++ vchiq_log_error(vchiq_susp_log_level, "%s waited too "
++ "many times for resume" , __func__);
++ goto out;
++ }
++ write_unlock_bh(&arm_state->susp_res_lock);
++ vchiq_log_info(vchiq_susp_log_level, "%s wait for resume",
++ __func__);
++ if (wait_for_completion_interruptible_timeout(
++ &arm_state->vc_resume_complete, timeout_val)
++ <= 0) {
++ vchiq_log_error(vchiq_susp_log_level, "%s wait for "
++ "resume failed (%s)", __func__,
++ resume_state_names[arm_state->vc_resume_state +
++ VC_RESUME_NUM_OFFSET]);
++ status = VCHIQ_ERROR;
+ write_lock_bh(&arm_state->susp_res_lock);
++ goto out;
+ }
++ vchiq_log_info(vchiq_susp_log_level, "%s resumed", __func__);
++ write_lock_bh(&arm_state->susp_res_lock);
++ resume_count++;
+ }
+ INIT_COMPLETION(arm_state->resume_blocker);
+ arm_state->resume_blocked = 1;
+@@ -1823,7 +1838,7 @@ out:
+ return status;
+ }
+
+-inline static void
++static inline void
+ unblock_resume(VCHIQ_ARM_STATE_T *arm_state)
+ {
+ complete_all(&arm_state->resume_blocker);
+@@ -1865,7 +1880,8 @@ vchiq_arm_vcsuspend(VCHIQ_STATE_T *state)
+ /* fall through */
+ case VC_SUSPEND_REJECTED:
+ case VC_SUSPEND_FAILED:
+- INIT_COMPLETION(arm_state->vc_suspend_complete);
++ /* Ensure any idle state actions have been run */
++ set_suspend_state(arm_state, VC_SUSPEND_IDLE);
+ /* fall through */
+ case VC_SUSPEND_IDLE:
+ vchiq_log_info(vchiq_susp_log_level,
+@@ -1909,6 +1925,40 @@ out:
+ }
+
+
++static void
++output_timeout_error(VCHIQ_STATE_T *state)
++{
++ VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
++ char service_err[50] = "";
++ int vc_use_count = arm_state->videocore_use_count;
++ int active_services = state->unused_service;
++ int i;
++
++ if (!arm_state->videocore_use_count) {
++ snprintf(service_err, 50, " Videocore usecount is 0");
++ goto output_msg;
++ }
++ for (i = 0; i < active_services; i++) {
++ VCHIQ_SERVICE_T *service_ptr = state->services[i];
++ if (service_ptr && service_ptr->service_use_count &&
++ (service_ptr->srvstate != VCHIQ_SRVSTATE_FREE)) {
++ snprintf(service_err, 50, " %c%c%c%c(%d) service has "
++ "use count %d%s", VCHIQ_FOURCC_AS_4CHARS(
++ service_ptr->base.fourcc),
++ service_ptr->client_id,
++ service_ptr->service_use_count,
++ service_ptr->service_use_count ==
++ vc_use_count ? "" : " (+ more)");
++ break;
++ }
++ }
++
++output_msg:
++ vchiq_log_error(vchiq_susp_log_level,
++ "timed out waiting for vc suspend (%d).%s",
++ arm_state->autosuspend_override, service_err);
++
++}
+
+ /* Try to get videocore into suspended state, regardless of autosuspend state.
+ ** We don't actually force suspend, since videocore may get into a bad state
+@@ -1926,7 +1976,6 @@ vchiq_arm_force_suspend(VCHIQ_STATE_T *state)
+ VCHIQ_STATUS_T status = VCHIQ_ERROR;
+ long rc = 0;
+ int repeat = -1;
+- static int autosuspend_override;
+
+ if (!arm_state)
+ goto out;
+@@ -1939,11 +1988,11 @@ vchiq_arm_force_suspend(VCHIQ_STATE_T *state)
+ if (status != VCHIQ_SUCCESS)
+ goto unlock;
+ if (arm_state->vc_suspend_state == VC_SUSPEND_SUSPENDED) {
+- /* Already suspended - just block resume and exit */
+- vchiq_log_info(vchiq_susp_log_level, "%s already "
+- "suspended", __func__);
+- status = VCHIQ_SUCCESS;
+- goto unlock;
++ /* Already suspended - just block resume and exit */
++ vchiq_log_info(vchiq_susp_log_level, "%s already suspended",
++ __func__);
++ status = VCHIQ_SUCCESS;
++ goto unlock;
+ } else if (arm_state->vc_suspend_state <= VC_SUSPEND_IDLE) {
+ /* initiate suspend immediately in the case that we're waiting
+ * for the timeout */
+@@ -1952,14 +2001,14 @@ vchiq_arm_force_suspend(VCHIQ_STATE_T *state)
+ vchiq_log_info(vchiq_susp_log_level, "%s videocore "
+ "idle, initiating suspend", __func__);
+ status = vchiq_arm_vcsuspend(state);
+- } else if (autosuspend_override < FORCE_SUSPEND_FAIL_MAX) {
++ } else if (arm_state->autosuspend_override <
++ FORCE_SUSPEND_FAIL_MAX) {
+ vchiq_log_info(vchiq_susp_log_level, "%s letting "
+ "videocore go idle", __func__);
+ status = VCHIQ_SUCCESS;
+ } else {
+ vchiq_log_warning(vchiq_susp_log_level, "%s failed too "
+- "many times - no more Mr Nice Guy... "
+- "initiating suspend", __func__);
++ "many times - attempting suspend", __func__);
+ status = vchiq_arm_vcsuspend(state);
+ }
+ } else {
+@@ -1969,40 +2018,37 @@ vchiq_arm_force_suspend(VCHIQ_STATE_T *state)
+ }
+
+ /* Wait for suspend to happen due to system idle (not forced..) */
+- if (status == VCHIQ_SUCCESS) {
+- do {
+- write_unlock_bh(&arm_state->susp_res_lock);
++ if (status != VCHIQ_SUCCESS)
++ goto unblock_resume;
+
+- rc = wait_for_completion_interruptible_timeout(
++ do {
++ write_unlock_bh(&arm_state->susp_res_lock);
++
++ rc = wait_for_completion_interruptible_timeout(
+ &arm_state->vc_suspend_complete,
+ msecs_to_jiffies(FORCE_SUSPEND_TIMEOUT_MS));
+
+- write_lock_bh(&arm_state->susp_res_lock);
+- if (rc < 0) {
+- vchiq_log_warning(vchiq_susp_log_level, "%s "
+- "interrupted waiting for suspend",
+- __func__);
+- status = VCHIQ_ERROR;
+- goto unblock_resume;
+- } else if (rc == 0) {
+- if (arm_state->vc_suspend_state >
+- VC_SUSPEND_IDLE) {
+- /* Repeat timeout once if in progress */
+- if (repeat < 0) {
+- repeat = 1;
+- continue;
+- }
++ write_lock_bh(&arm_state->susp_res_lock);
++ if (rc < 0) {
++ vchiq_log_warning(vchiq_susp_log_level, "%s "
++ "interrupted waiting for suspend", __func__);
++ status = VCHIQ_ERROR;
++ goto unblock_resume;
++ } else if (rc == 0) {
++ if (arm_state->vc_suspend_state > VC_SUSPEND_IDLE) {
++ /* Repeat timeout once if in progress */
++ if (repeat < 0) {
++ repeat = 1;
++ continue;
+ }
+- autosuspend_override++;
+- vchiq_log_warning(vchiq_susp_log_level,
+- "%s timed out waiting for vc suspend "
+- "(%d)", __func__, autosuspend_override);
+- status = VCHIQ_RETRY;
+- goto unblock_resume;
+ }
+- } while (0 < (repeat--));
+- } else
+- goto unblock_resume;
++ arm_state->autosuspend_override++;
++ output_timeout_error(state);
++
++ status = VCHIQ_RETRY;
++ goto unblock_resume;
++ }
++ } while (0 < (repeat--));
+
+ /* Check and report state in case we need to abort ARM suspend */
+ if (arm_state->vc_suspend_state != VC_SUSPEND_SUSPENDED) {
+@@ -2019,8 +2065,7 @@ vchiq_arm_force_suspend(VCHIQ_STATE_T *state)
+ goto unblock_resume;
+ }
+
+- /* successfully suspended - reset override counter, unlock and exit */
+- autosuspend_override = 0;
++ /* successfully suspended - unlock and exit */
+ goto unlock;
+
+ unblock_resume:
+@@ -2077,8 +2122,14 @@ vchiq_arm_allow_resume(VCHIQ_STATE_T *state)
+ write_unlock_bh(&arm_state->susp_res_lock);
+
+ if (resume) {
+- wait_for_completion_interruptible(
+- &arm_state->vc_resume_complete);
++ if (wait_for_completion_interruptible(
++ &arm_state->vc_resume_complete) < 0) {
++ vchiq_log_error(vchiq_susp_log_level,
++ "%s interrupted", __func__);
++ /* failed, cannot accurately derive suspend
++ * state, so exit early. */
++ goto out;
++ }
+ }
+
+ read_lock_bh(&arm_state->susp_res_lock);
+@@ -2180,8 +2231,8 @@ vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
+
+ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
+
+- if (use_type != USE_TYPE_SERVICE) {
+- sprintf(entity, "PEER: ");
++ if (use_type == USE_TYPE_VCHIQ) {
++ sprintf(entity, "VCHIQ: ");
+ entity_uc = &arm_state->peer_use_count;
+ } else if (service) {
+ sprintf(entity, "%c%c%c%c:%03d",
+@@ -2238,18 +2289,9 @@ vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
+ }
+
+ stop_suspend_timer(arm_state);
+- write_unlock_bh(&arm_state->susp_res_lock);
+-
+- mutex_lock(&arm_state->vc_use_cnt_mutex);
+- if (!arm_state->videocore_use_count)
+- pm_qos_add_request(&arm_state->qos_request,
+- PM_QOS_CPU_DMA_LATENCY, 100);
+
+ local_uc = ++arm_state->videocore_use_count;
+ local_entity_uc = ++(*entity_uc);
+- mutex_unlock(&arm_state->vc_use_cnt_mutex);
+-
+- write_lock_bh(&arm_state->susp_res_lock);
+
+ /* If there's a pending request which hasn't yet been serviced then
+ * just clear it. If we're past VC_SUSPEND_REQUESTED state then
+@@ -2258,7 +2300,7 @@ vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
+ if (arm_state->vc_suspend_state <= VC_SUSPEND_REQUESTED)
+ set_suspend_state(arm_state, VC_SUSPEND_IDLE);
+
+- if (need_resume(state)) {
++ if ((use_type != USE_TYPE_SERVICE_NO_RESUME) && need_resume(state)) {
+ set_resume_state(arm_state, VC_RESUME_REQUESTED);
+ vchiq_log_info(vchiq_susp_log_level,
+ "%s %s count %d, state count %d",
+@@ -2339,17 +2381,9 @@ vchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service)
+ ret = VCHIQ_ERROR;
+ goto unlock;
+ }
+- write_unlock_bh(&arm_state->susp_res_lock);
+-
+- mutex_lock(&arm_state->vc_use_cnt_mutex);
+ local_uc = --arm_state->videocore_use_count;
+ local_entity_uc = --(*entity_uc);
+
+- if (!arm_state->videocore_use_count)
+- pm_qos_remove_request(&arm_state->qos_request);
+- mutex_unlock(&arm_state->vc_use_cnt_mutex);
+-
+- write_lock_bh(&arm_state->susp_res_lock);
+ if (!vchiq_videocore_wanted(state)) {
+ if (vchiq_platform_use_suspend_timer() &&
+ !arm_state->resume_blocked) {
+@@ -2421,6 +2455,19 @@ out:
+ }
+
+ VCHIQ_STATUS_T
++vchiq_use_service_no_resume(VCHIQ_SERVICE_HANDLE_T handle)
++{
++ VCHIQ_STATUS_T ret = VCHIQ_ERROR;
++ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
++ if (service) {
++ ret = vchiq_use_internal(service->state, service,
++ USE_TYPE_SERVICE_NO_RESUME);
++ unlock_service(service);
++ }
++ return ret;
++}
++
++VCHIQ_STATUS_T
+ vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle)
+ {
+ VCHIQ_STATUS_T ret = VCHIQ_ERROR;
+@@ -2512,7 +2559,7 @@ vchiq_dump_service_use_state(VCHIQ_STATE_T *state)
+ local_max_services);
+
+ for (i = 0; i < j; i++) {
+- vchiq_log_error(vchiq_arm_log_level,
++ vchiq_log_warning(vchiq_susp_log_level,
+ "----- %c%c%c%c:%d service count %d %s",
+ VCHIQ_FOURCC_AS_4CHARS(service_data[i].fourcc),
+ service_data[i].clientid,
+@@ -2520,7 +2567,7 @@ vchiq_dump_service_use_state(VCHIQ_STATE_T *state)
+ service_data[i].use_count ? nz : "");
+ }
+ vchiq_log_warning(vchiq_susp_log_level,
+- "----- PEER use count count %d", peer_count);
++ "----- VCHIQ use count count %d", peer_count);
+ vchiq_log_warning(vchiq_susp_log_level,
+ "--- Overall vchiq instance use count %d", vc_use_count);
+
+@@ -2530,15 +2577,16 @@ vchiq_dump_service_use_state(VCHIQ_STATE_T *state)
+ VCHIQ_STATUS_T
+ vchiq_check_service(VCHIQ_SERVICE_T *service)
+ {
+- VCHIQ_ARM_STATE_T *arm_state =
+- vchiq_platform_get_arm_state(service->state);
++ VCHIQ_ARM_STATE_T *arm_state;
+ VCHIQ_STATUS_T ret = VCHIQ_ERROR;
+
+- if (!arm_state || !service)
++ if (!service || !service->state)
+ goto out;
+
+ vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
+
++ arm_state = vchiq_platform_get_arm_state(service->state);
++
+ read_lock_bh(&arm_state->susp_res_lock);
+ if (service->service_use_count)
+ ret = VCHIQ_SUCCESS;
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h
+index 6db1074..bc0527d 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h
+@@ -21,10 +21,6 @@
+
+ #include <linux/mutex.h>
+ #include <linux/semaphore.h>
+-//#include <linux/pm_qos_params.h>
+-#define pm_qos_add_request(a,b,c) do {} while (0)
+-#define pm_qos_remove_request(a) do {} while (0)
+-struct pm_qos_request_list {int dummy;};
+ #include <linux/atomic.h>
+ #include "vchiq_core.h"
+
+@@ -50,11 +46,12 @@ enum vc_resume_status {
+
+ enum USE_TYPE_E {
+ USE_TYPE_SERVICE,
+- USE_TYPE_PEER,
++ USE_TYPE_SERVICE_NO_RESUME,
+ USE_TYPE_VCHIQ
+ };
+
+
++
+ typedef struct vchiq_arm_state_struct {
+ /* Keepalive-related data */
+ struct task_struct *ka_thread;
+@@ -70,7 +67,6 @@ typedef struct vchiq_arm_state_struct {
+ enum vc_suspend_status vc_suspend_state;
+ enum vc_resume_status vc_resume_state;
+
+- struct mutex vc_use_cnt_mutex;
+ unsigned int wake_address;
+
+ struct timer_list suspend_timer;
+@@ -97,14 +93,14 @@ typedef struct vchiq_arm_state_struct {
+ struct completion blocked_blocker;
+ int blocked_count;
+
++ int autosuspend_override;
++
+ /* Flag to indicate that the first vchiq connect has made it through.
+ ** This means that both sides should be fully ready, and we should
+ ** be able to suspend after this point.
+ */
+ int first_connect;
+
+- struct pm_qos_request_list qos_request;
+-
+ unsigned long long suspend_start_time;
+ unsigned long long sleep_start_time;
+ unsigned long long resume_start_time;
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
+index 0dc312b..af6fa88 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
+@@ -95,7 +95,9 @@ static const char *const conn_state_names[] = {
+ "PAUSING",
+ "PAUSE_SENT",
+ "PAUSED",
+- "RESUMING"
++ "RESUMING",
++ "PAUSE_TIMEOUT",
++ "RESUME_TIMEOUT"
+ };
+
+
+@@ -247,8 +249,7 @@ unlock_service(VCHIQ_SERVICE_T *service)
+ if (!service->ref_count) {
+ BUG_ON(service->srvstate != VCHIQ_SRVSTATE_FREE);
+ state->services[service->localport] = NULL;
+- }
+- else
++ } else
+ service = NULL;
+ }
+ spin_unlock(&service_spinlock);
+@@ -308,14 +309,22 @@ static inline VCHIQ_STATUS_T
+ make_service_callback(VCHIQ_SERVICE_T *service, VCHIQ_REASON_T reason,
+ VCHIQ_HEADER_T *header, void *bulk_userdata)
+ {
++ VCHIQ_STATUS_T status;
+ vchiq_log_trace(vchiq_core_log_level, "%d: callback:%d (%s, %x, %x)",
+ service->state->id, service->localport, reason_names[reason],
+ (unsigned int)header, (unsigned int)bulk_userdata);
+- return service->base.callback(reason, header, service->handle,
++ status = service->base.callback(reason, header, service->handle,
+ bulk_userdata);
++ if (status == VCHIQ_ERROR) {
++ vchiq_log_warning(vchiq_core_log_level,
++ "%d: ignoring ERROR from callback to service %x",
++ service->state->id, service->handle);
++ status = VCHIQ_SUCCESS;
++ }
++ return status;
+ }
+
+-static inline void
++inline void
+ vchiq_set_conn_state(VCHIQ_STATE_T *state, VCHIQ_CONNSTATE_T newstate)
+ {
+ VCHIQ_CONNSTATE_T oldstate = state->conn_state;
+@@ -1154,7 +1163,6 @@ notify_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue,
+ reason, NULL, bulk->userdata);
+ if (status == VCHIQ_RETRY)
+ break;
+- status = VCHIQ_SUCCESS;
+ }
+ }
+
+@@ -1225,6 +1233,7 @@ resolve_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue)
+ {
+ VCHIQ_STATE_T *state = service->state;
+ int resolved = 0;
++ int rc;
+
+ while ((queue->process != queue->local_insert) &&
+ (queue->process != queue->remote_insert)) {
+@@ -1240,7 +1249,10 @@ resolve_bulks(VCHIQ_SERVICE_T *service, VCHIQ_BULK_QUEUE_T *queue)
+ WARN_ON(!((int)(queue->local_insert - queue->process) > 0));
+ WARN_ON(!((int)(queue->remote_insert - queue->process) > 0));
+
+- mutex_lock(&state->bulk_transfer_mutex);
++ rc = mutex_lock_interruptible(&state->bulk_transfer_mutex);
++ if (rc != 0)
++ break;
++
+ vchiq_transfer_bulk(bulk);
+ mutex_unlock(&state->bulk_transfer_mutex);
+
+@@ -1398,6 +1410,7 @@ parse_open(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header)
+ service->version, service->version_min,
+ version, version_min);
+ vchiq_loud_error_footer();
++ unlock_service(service);
+ goto fail_open;
+ }
+ if (service->srvstate == VCHIQ_SRVSTATE_LISTENING) {
+@@ -1678,7 +1691,8 @@ parse_rx_slots(VCHIQ_STATE_T *state)
+ if (state->conn_state ==
+ VCHIQ_CONNSTATE_CONNECTED) {
+ DEBUG_TRACE(PARSE_LINE);
+- resolved = resolve_bulks(service, queue);
++ resolved = resolve_bulks(service,
++ queue);
+ }
+
+ mutex_unlock(&service->bulk_mutex);
+@@ -1904,6 +1918,11 @@ slot_handler_func(void *v)
+ BUG();
+ }
+ break;
++
++ case VCHIQ_CONNSTATE_PAUSE_TIMEOUT:
++ case VCHIQ_CONNSTATE_RESUME_TIMEOUT:
++ vchiq_platform_handle_timeout(state);
++ break;
+ default:
+ break;
+ }
+@@ -2581,16 +2600,25 @@ close_service_complete(VCHIQ_SERVICE_T *service, int failstate)
+ case VCHIQ_SRVSTATE_OPEN:
+ case VCHIQ_SRVSTATE_CLOSESENT:
+ case VCHIQ_SRVSTATE_CLOSERECVD:
+- if (is_server)
+- newstate = (service->auto_close ?
+- VCHIQ_SRVSTATE_LISTENING :
+- VCHIQ_SRVSTATE_CLOSEWAIT);
+- else
++ if (is_server) {
++ if (service->auto_close) {
++ service->client_id = 0;
++ service->remoteport = VCHIQ_PORT_FREE;
++ newstate = VCHIQ_SRVSTATE_LISTENING;
++ } else
++ newstate = VCHIQ_SRVSTATE_CLOSEWAIT;
++ } else
+ newstate = VCHIQ_SRVSTATE_CLOSED;
+ vchiq_set_service_state(service, newstate);
+ break;
+- default:
++ case VCHIQ_SRVSTATE_LISTENING:
+ break;
++ default:
++ vchiq_log_error(vchiq_core_log_level,
++ "close_service_complete(%x) called in state %s",
++ service->handle, srvstate_names[service->srvstate]);
++ WARN(1, "close_service_complete in unexpected state\n");
++ return VCHIQ_ERROR;
+ }
+
+ status = make_service_callback(service,
+@@ -2606,14 +2634,11 @@ close_service_complete(VCHIQ_SERVICE_T *service, int failstate)
+ vchiq_release_service_internal(service);
+
+ service->client_id = 0;
+- if (status == VCHIQ_ERROR)
+- /* Signal an error (fatal, since the other end
+- ** will probably have closed) */
+- vchiq_set_service_state(service, VCHIQ_SRVSTATE_OPEN);
++ service->remoteport = VCHIQ_PORT_FREE;
+
+ if (service->srvstate == VCHIQ_SRVSTATE_CLOSED)
+ vchiq_free_service_internal(service);
+- else {
++ else if (service->srvstate != VCHIQ_SRVSTATE_CLOSEWAIT) {
+ if (is_server)
+ service->closing = 0;
+
+@@ -2631,6 +2656,7 @@ vchiq_close_service_internal(VCHIQ_SERVICE_T *service, int close_recvd)
+ {
+ VCHIQ_STATE_T *state = service->state;
+ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
++ int is_server = (service->public_fourcc != VCHIQ_FOURCC_INVALID);
+
+ vchiq_log_info(vchiq_core_log_level, "%d: csi:%d,%d (%s)",
+ service->state->id, service->localport, close_recvd,
+@@ -2646,7 +2672,19 @@ vchiq_close_service_internal(VCHIQ_SERVICE_T *service, int close_recvd)
+ "vchiq_close_service_internal(1) called "
+ "in state %s",
+ srvstate_names[service->srvstate]);
+- else
++ else if (is_server) {
++ if (service->srvstate == VCHIQ_SRVSTATE_LISTENING) {
++ status = VCHIQ_ERROR;
++ } else {
++ service->client_id = 0;
++ service->remoteport = VCHIQ_PORT_FREE;
++ if (service->srvstate ==
++ VCHIQ_SRVSTATE_CLOSEWAIT)
++ vchiq_set_service_state(service,
++ VCHIQ_SRVSTATE_LISTENING);
++ }
++ up(&service->remove_event);
++ } else
+ vchiq_free_service_internal(service);
+ break;
+ case VCHIQ_SRVSTATE_OPENING:
+@@ -2717,8 +2755,7 @@ vchiq_close_service_internal(VCHIQ_SERVICE_T *service, int close_recvd)
+ break;
+
+ case VCHIQ_SRVSTATE_CLOSERECVD:
+- if (!close_recvd &&
+- (service->public_fourcc != VCHIQ_FOURCC_INVALID))
++ if (!close_recvd && is_server)
+ /* Force into LISTENING mode */
+ vchiq_set_service_state(service,
+ VCHIQ_SRVSTATE_LISTENING);
+@@ -2884,7 +2921,7 @@ vchiq_close_service(VCHIQ_SERVICE_HANDLE_T handle)
+ {
+ /* Unregister the service */
+ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+- VCHIQ_STATUS_T status = VCHIQ_ERROR;
++ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+
+ if (!service)
+ return VCHIQ_ERROR;
+@@ -2893,10 +2930,23 @@ vchiq_close_service(VCHIQ_SERVICE_HANDLE_T handle)
+ "%d: close_service:%d",
+ service->state->id, service->localport);
+
++ if ((service->srvstate == VCHIQ_SRVSTATE_FREE) ||
++ (service->srvstate == VCHIQ_SRVSTATE_LISTENING) ||
++ (service->srvstate == VCHIQ_SRVSTATE_HIDDEN)) {
++ unlock_service(service);
++ return VCHIQ_ERROR;
++ }
++
+ mark_service_closing(service);
+
++ if (current == service->state->slot_handler_thread) {
++ status = vchiq_close_service_internal(service,
++ 0/*!close_recvd*/);
++ BUG_ON(status == VCHIQ_RETRY);
++ } else {
+ /* Mark the service for termination by the slot handler */
+- request_poll(service->state, service, VCHIQ_POLL_TERMINATE);
++ request_poll(service->state, service, VCHIQ_POLL_TERMINATE);
++ }
+
+ while (1) {
+ if (down_interruptible(&service->remove_event) != 0) {
+@@ -2939,15 +2989,26 @@ vchiq_remove_service(VCHIQ_SERVICE_HANDLE_T handle)
+ "%d: remove_service:%d",
+ service->state->id, service->localport);
+
++ if (service->srvstate == VCHIQ_SRVSTATE_FREE) {
++ unlock_service(service);
++ return VCHIQ_ERROR;
++ }
++
+ /* Make it look like a client, because it must be removed and not
+ left in the LISTENING state. */
+ service->public_fourcc = VCHIQ_FOURCC_INVALID;
+
+ mark_service_closing(service);
+
+- /* Mark the service for termination by the slot handler */
+- request_poll(service->state, service, VCHIQ_POLL_TERMINATE);
+-
++ if ((service->srvstate == VCHIQ_SRVSTATE_HIDDEN) ||
++ (current == service->state->slot_handler_thread)) {
++ status = vchiq_close_service_internal(service,
++ 0/*!close_recvd*/);
++ BUG_ON(status == VCHIQ_RETRY);
++ } else {
++ /* Mark the service for termination by the slot handler */
++ request_poll(service->state, service, VCHIQ_POLL_TERMINATE);
++ }
+ while (1) {
+ if (down_interruptible(&service->remove_event) != 0) {
+ status = VCHIQ_RETRY;
+@@ -2973,6 +3034,7 @@ vchiq_remove_service(VCHIQ_SERVICE_HANDLE_T handle)
+ return status;
+ }
+
++
+ /* This function may be called by kernel threads or user threads.
+ * User threads may receive VCHIQ_RETRY to indicate that a signal has been
+ * received and the call should be retried after being returned to user
+@@ -3395,9 +3457,10 @@ vchiq_dump_state(void *dump_context, VCHIQ_STATE_T *state)
+ }
+
+ len = snprintf(buf, sizeof(buf),
+- " Slots: %d available (%d data), %d recyclable, %d stalls (%d data)",
+- state->slot_queue_available -
+- SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos),
++ " Slots: %d available (%d data), %d recyclable, %d stalls "
++ "(%d data)",
++ ((state->slot_queue_available * VCHIQ_SLOT_SIZE) -
++ state->local_tx_pos) / VCHIQ_SLOT_SIZE,
+ state->data_quota - state->data_use_count,
+ state->local->slot_queue_recycle - state->slot_queue_available,
+ state->stats.slot_stalls, state->stats.data_stalls);
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h
+index bcdff3a..9e38aa8 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.h
+@@ -191,7 +191,9 @@ typedef enum {
+ VCHIQ_CONNSTATE_PAUSING,
+ VCHIQ_CONNSTATE_PAUSE_SENT,
+ VCHIQ_CONNSTATE_PAUSED,
+- VCHIQ_CONNSTATE_RESUMING
++ VCHIQ_CONNSTATE_RESUMING,
++ VCHIQ_CONNSTATE_PAUSE_TIMEOUT,
++ VCHIQ_CONNSTATE_RESUME_TIMEOUT
+ } VCHIQ_CONNSTATE_T;
+
+ enum {
+@@ -667,6 +669,13 @@ vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state,
+ VCHIQ_CONNSTATE_T oldstate, VCHIQ_CONNSTATE_T newstate);
+
+ extern void
++vchiq_platform_handle_timeout(VCHIQ_STATE_T *state);
++
++extern void
++vchiq_set_conn_state(VCHIQ_STATE_T *state, VCHIQ_CONNSTATE_T newstate);
++
++
++extern void
+ vchiq_log_dump_mem(const char *label, uint32_t addr, const void *voidMem,
+ size_t numBytes);
+
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_if.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_if.h
+index d89f89e..2e775b4 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_if.h
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_if.h
+@@ -121,6 +121,8 @@ extern VCHIQ_STATUS_T vchiq_open_service(VCHIQ_INSTANCE_T instance,
+ extern VCHIQ_STATUS_T vchiq_close_service(VCHIQ_SERVICE_HANDLE_T service);
+ extern VCHIQ_STATUS_T vchiq_remove_service(VCHIQ_SERVICE_HANDLE_T service);
+ extern VCHIQ_STATUS_T vchiq_use_service(VCHIQ_SERVICE_HANDLE_T service);
++extern VCHIQ_STATUS_T vchiq_use_service_no_resume(
++ VCHIQ_SERVICE_HANDLE_T service);
+ extern VCHIQ_STATUS_T vchiq_release_service(VCHIQ_SERVICE_HANDLE_T service);
+
+ extern VCHIQ_STATUS_T vchiq_queue_message(VCHIQ_SERVICE_HANDLE_T service,
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
+index be1a063..088b486 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
+@@ -111,6 +111,9 @@ VCHIQ_STATUS_T vchiq_shutdown(VCHIQ_INSTANCE_T instance)
+
+ mutex_unlock(&state->mutex);
+
++ vchiq_log_trace(vchiq_core_log_level,
++ "%s(%p): returning %d", __func__, instance, status);
++
+ if (status == VCHIQ_SUCCESS) {
+ struct list_head *pos, *next;
+ list_for_each_safe(pos, next,
+@@ -129,9 +132,6 @@ VCHIQ_STATUS_T vchiq_shutdown(VCHIQ_INSTANCE_T instance)
+ kfree(instance);
+ }
+
+- vchiq_log_trace(vchiq_core_log_level,
+- "%s(%p): returning %d", __func__, instance, status);
+-
+ return status;
+ }
+ EXPORT_SYMBOL(vchiq_shutdown);
+diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_proc.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_proc.c
+index 6e06c3b..07e0ed5 100644
+--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_proc.c
++++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_proc.c
+@@ -132,6 +132,7 @@ static struct vchiq_proc_log_entry vchiq_proc_log_entries[] = {
+ { "core", &vchiq_core_log_level },
+ { "msg", &vchiq_core_msg_log_level },
+ { "sync", &vchiq_sync_log_level },
++ { "susp", &vchiq_susp_log_level },
+ { "arm", &vchiq_arm_log_level },
+ };
+ static int n_log_entries =
+@@ -221,3 +222,4 @@ struct proc_dir_entry *vchiq_clients_top(void)
+ {
+ return proc_info.clients;
+ }
++
diff --git a/patches/linux-3.6.7/0172-Make-sure-we-wait-for-the-reset-to-finish.patch b/patches/linux-3.6.7/0172-Make-sure-we-wait-for-the-reset-to-finish.patch
new file mode 100644
index 0000000..0fce113
--- /dev/null
+++ b/patches/linux-3.6.7/0172-Make-sure-we-wait-for-the-reset-to-finish.patch
@@ -0,0 +1,21 @@
+From: Gordon Hollingworth <gordon@holliweb.co.uk>
+Date: Sun, 4 Nov 2012 15:55:01 +0000
+Subject: [PATCH] Make sure we wait for the reset to finish
+
+---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
+index 3e762e2..e8c91e7 100644
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
+@@ -232,6 +232,8 @@ exit_handler_routine:
+ if (mphi_int_count >= 60)
+ {
+ DWC_WRITE_REG32(c_mphi_regs.ctrl, ((1<<31) + (1<<16)));
++ while(!(DWC_READ_REG32(c_mphi_regs.ctrl) & (1 << 17)))
++ ;
+ DWC_WRITE_REG32(c_mphi_regs.ctrl, (1<<31));
+ mphi_int_count = 0;
+ }
diff --git a/patches/linux-3.6.7/0173-Add-missing-pctv452e-DVB-module.patch b/patches/linux-3.6.7/0173-Add-missing-pctv452e-DVB-module.patch
new file mode 100644
index 0000000..01f2cbb
--- /dev/null
+++ b/patches/linux-3.6.7/0173-Add-missing-pctv452e-DVB-module.patch
@@ -0,0 +1,29 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Sun, 4 Nov 2012 17:02:59 +0000
+Subject: [PATCH] Add missing pctv452e DVB module
+
+---
+ arch/arm/configs/bcmrpi_defconfig | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
+index b4a3da1..539470e 100644
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -585,6 +585,7 @@ CONFIG_DVB_USB_DTT200U=m
+ CONFIG_DVB_USB_OPERA1=m
+ CONFIG_DVB_USB_AF9005=m
+ CONFIG_DVB_USB_AF9005_REMOTE=m
++CONFIG_DVB_USB_PCTV452E=m
+ CONFIG_DVB_USB_DW2102=m
+ CONFIG_DVB_USB_CINERGY_T2=m
+ CONFIG_DVB_USB_ANYSEE=m
+@@ -596,6 +597,8 @@ CONFIG_DVB_USB_EC168=m
+ CONFIG_DVB_USB_AZ6027=m
+ CONFIG_DVB_USB_LME2510=m
+ CONFIG_DVB_USB_TECHNISAT_USB2=m
++CONFIG_DVB_USB_IT913X=m
++CONFIG_DVB_USB_MXL111SF=m
+ CONFIG_SMS_SIANO_MDTV=m
+ CONFIG_SMS_USB_DRV=m
+ CONFIG_DVB_B2C2_FLEXCOP=m
diff --git a/patches/linux-3.6.7/0174-Add-Simon-Hall-s-dma-helper-module-useful-in-future-.patch b/patches/linux-3.6.7/0174-Add-Simon-Hall-s-dma-helper-module-useful-in-future-.patch
new file mode 100644
index 0000000..5bdb234
--- /dev/null
+++ b/patches/linux-3.6.7/0174-Add-Simon-Hall-s-dma-helper-module-useful-in-future-.patch
@@ -0,0 +1,799 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Mon, 19 Nov 2012 18:27:05 +0000
+Subject: [PATCH] Add Simon Hall's dma helper module, useful in future for X
+ acceleration
+
+---
+ arch/arm/mach-bcm2708/Kconfig | 7 +
+ arch/arm/mach-bcm2708/Makefile | 1 +
+ arch/arm/mach-bcm2708/dmaer.c | 755 +++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 763 insertions(+)
+ create mode 100755 arch/arm/mach-bcm2708/dmaer.c
+
+diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig
+index 63bb76c..2a24db6 100644
+--- a/arch/arm/mach-bcm2708/Kconfig
++++ b/arch/arm/mach-bcm2708/Kconfig
+@@ -31,4 +31,11 @@ config BCM2708_NOL2CACHE
+ help
+ Do not allow ARM to use GPU's L2 cache. Requires disable_l2cache in config.txt.
+
++config BCM2708_DMAER
++ tristate "BCM2708 DMA helper"
++ depends on MACH_BCM2708
++ default n
++ help
++ Enable DMA helper for accelerating X composition
++
+ endmenu
+diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile
+index 3ee8a4b..af4a6ee 100644
+--- a/arch/arm/mach-bcm2708/Makefile
++++ b/arch/arm/mach-bcm2708/Makefile
+@@ -5,4 +5,5 @@
+ obj-$(CONFIG_MACH_BCM2708) += clock.o bcm2708.o armctrl.o vcio.o power.o dma.o delay.o
+ obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o
+ obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o
++obj-$(CONFIG_BCM2708_DMAER) += dmaer.o
+
+diff --git a/arch/arm/mach-bcm2708/dmaer.c b/arch/arm/mach-bcm2708/dmaer.c
+new file mode 100755
+index 0000000..1b53ff2
+--- /dev/null
++++ b/arch/arm/mach-bcm2708/dmaer.c
+@@ -0,0 +1,755 @@
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kdev_t.h>
++#include <linux/fs.h>
++#include <linux/cdev.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/pagemap.h>
++#include <linux/device.h>
++#include <linux/jiffies.h>
++#include <linux/timex.h>
++
++#include <asm/uaccess.h>
++#include <asm/atomic.h>
++#include <asm/cacheflush.h>
++#include <asm/io.h>
++
++#include <mach/dma.h>
++
++MODULE_LICENSE("Dual BSD/GPL");
++
++//#define inline
++
++/***** TYPES ****/
++#define PAGES_PER_LIST 500
++struct PageList
++{
++ struct page *m_pPages[PAGES_PER_LIST];
++ unsigned int m_used;
++ struct PageList *m_pNext;
++};
++
++struct VmaPageList
++{
++ //each vma has a linked list of pages associated with it
++ struct PageList *m_pPageHead;
++ struct PageList *m_pPageTail;
++ unsigned int m_refCount;
++};
++struct DmaControlBlock
++{
++ unsigned int m_transferInfo;
++ void __user *m_pSourceAddr;
++ void __user *m_pDestAddr;
++ unsigned int m_xferLen;
++ unsigned int m_tdStride;
++ struct DmaControlBlock *m_pNext;
++ unsigned int m_blank1, m_blank2;
++};
++
++/***** DEFINES ******/
++//magic number defining the module
++#define DMA_MAGIC 0xdd
++
++//do user virtual to physical translation of the CB chain
++#define DMA_PREPARE _IOWR(DMA_MAGIC, 0, struct DmaControlBlock *)
++
++//kick the pre-prepared CB chain
++#define DMA_KICK _IOW(DMA_MAGIC, 1, struct DmaControlBlock *)
++
++//prepare it, kick it, wait for it
++#define DMA_PREPARE_KICK_WAIT _IOWR(DMA_MAGIC, 2, struct DmaControlBlock *)
++
++//prepare it, kick it, don't wait for it
++#define DMA_PREPARE_KICK _IOWR(DMA_MAGIC, 3, struct DmaControlBlock *)
++
++//not currently implemented
++#define DMA_WAIT_ONE _IO(DMA_MAGIC, 4, struct DmaControlBlock *)
++
++//wait on all kicked CB chains
++#define DMA_WAIT_ALL _IO(DMA_MAGIC, 5)
++
++//in order to discover the largest AXI burst that should be programmed into the transfer params
++#define DMA_MAX_BURST _IO(DMA_MAGIC, 6)
++
++//set the address range through which the user address is assumed to already by a physical address
++#define DMA_SET_MIN_PHYS _IOW(DMA_MAGIC, 7, unsigned long)
++#define DMA_SET_MAX_PHYS _IOW(DMA_MAGIC, 8, unsigned long)
++
++#define VIRT_TO_BUS_CACHE_SIZE 8
++
++/***** FILE OPS *****/
++static int Open(struct inode *pInode, struct file *pFile);
++static int Release(struct inode *pInode, struct file *pFile);
++static long Ioctl(struct file *pFile, unsigned int cmd, unsigned long arg);
++static ssize_t Read(struct file *pFile, char __user *pUser, size_t count, loff_t *offp);
++static int Mmap(struct file *pFile, struct vm_area_struct *pVma);
++
++/***** VMA OPS ****/
++static void VmaOpen(struct vm_area_struct *pVma);
++static void VmaClose(struct vm_area_struct *pVma);
++static int VmaFault(struct vm_area_struct *pVma, struct vm_fault *pVmf);
++
++/**** GENERIC ****/
++static int __init dmaer_init(void);
++static void __exit dmaer_exit(void);
++
++/*** OPS ***/
++static struct vm_operations_struct g_vmOps = {
++ .open = VmaOpen,
++ .close = VmaClose,
++ .fault = VmaFault,
++};
++
++static struct file_operations g_fOps = {
++ .owner = THIS_MODULE,
++ .llseek = 0,
++ .read = Read,
++ .write = 0,
++ .unlocked_ioctl = Ioctl,
++ .open = Open,
++ .release = Release,
++ .mmap = Mmap,
++};
++
++/***** GLOBALS ******/
++static dev_t g_majorMinor;
++static atomic_t g_oneLock = ATOMIC_INIT(1);
++static struct cdev g_cDev;
++static int g_trackedPages = 0;
++static unsigned int *g_pDmaChanBase;
++static int g_dmaIrq;
++static int g_dmaChan;
++
++static unsigned long g_virtAddr[VIRT_TO_BUS_CACHE_SIZE];
++static unsigned long g_busAddr[VIRT_TO_BUS_CACHE_SIZE];
++static unsigned long g_cbVirtAddr;
++static unsigned long g_cbBusAddr;
++static int g_cacheInsertAt;
++static int g_cacheHit, g_cacheMiss;
++
++//off by default
++static void __user *g_pMinPhys = (void __user *)-1;
++static void __user *g_pMaxPhys = (void __user *)0;
++
++/****** CACHE OPERATIONS ********/
++static inline void FlushAddrCache(void)
++{
++ int count = 0;
++ for (count = 0; count < VIRT_TO_BUS_CACHE_SIZE; count++)
++ g_virtAddr[count] = 0xffffffff; //never going to match as we always chop the bottom bits anyway
++
++ g_cbVirtAddr = 0xffffffff;
++
++ g_cacheInsertAt = 0;
++}
++
++//translate from a user virtual address to a bus address by mapping the page
++//NB this won't lock a page in memory, so to avoid potential paging issues using kernel logical addresses
++static inline void __iomem *UserVirtualToBus(void __user *pUser)
++{
++ int mapped;
++ struct page *pPage;
++ void *phys;
++
++ //map it (requiring that the pointer points to something that does not hang off the page boundary)
++ mapped = get_user_pages(current, current->mm,
++ (unsigned long)pUser, 1,
++ 1, 0,
++ &pPage,
++ 0);
++
++ if (mapped <= 0) //error
++ return 0;
++
++ //get the arm physical address
++ phys = page_address(pPage) + offset_in_page(pUser);
++ page_cache_release(pPage);
++
++ //and now the bus address
++ return (void __iomem *)__virt_to_bus(phys);
++}
++
++static inline void __iomem *UserVirtualToBusViaCbCache(void __user *pUser)
++{
++ unsigned long virtual_page = (unsigned long)pUser & ~4095;
++ unsigned long page_offset = (unsigned long)pUser & 4095;
++ unsigned long bus_addr;
++
++ if (g_cbVirtAddr == virtual_page)
++ {
++ bus_addr = g_cbBusAddr + page_offset;
++ g_cacheHit++;
++ return (void __iomem *)bus_addr;
++ }
++ else
++ {
++ bus_addr = (unsigned long)UserVirtualToBus(pUser);
++
++ if (!bus_addr)
++ return 0;
++
++ g_cbVirtAddr = virtual_page;
++ g_cbBusAddr = bus_addr & ~4095;
++ g_cacheMiss++;
++
++ return (void __iomem *)bus_addr;
++ }
++}
++
++//do the same as above, by query our virt->bus cache
++static inline void __iomem *UserVirtualToBusViaCache(void __user *pUser)
++{
++ int count;
++ //get the page and its offset
++ unsigned long virtual_page = (unsigned long)pUser & ~4095;
++ unsigned long page_offset = (unsigned long)pUser & 4095;
++ unsigned long bus_addr;
++
++ if (pUser >= g_pMinPhys && pUser < g_pMaxPhys)
++ {
++// printk(KERN_DEBUG "user->phys passthrough on %p\n", pUser);
++ return (void __iomem *)__virt_to_bus(pUser);
++ }
++
++ //check the cache for our entry
++ for (count = 0; count < VIRT_TO_BUS_CACHE_SIZE; count++)
++ if (g_virtAddr[count] == virtual_page)
++ {
++ bus_addr = g_busAddr[count] + page_offset;
++ g_cacheHit++;
++ return (void __iomem *)bus_addr;
++ }
++
++ //not found, look up manually and then insert its page address
++ bus_addr = (unsigned long)UserVirtualToBus(pUser);
++
++ if (!bus_addr)
++ return 0;
++
++ g_virtAddr[g_cacheInsertAt] = virtual_page;
++ g_busAddr[g_cacheInsertAt] = bus_addr & ~4095;
++
++ //round robin
++ g_cacheInsertAt++;
++ if (g_cacheInsertAt == VIRT_TO_BUS_CACHE_SIZE)
++ g_cacheInsertAt = 0;
++
++ g_cacheMiss++;
++
++ return (void __iomem *)bus_addr;
++}
++
++/***** FILE OPERATIONS ****/
++static int Open(struct inode *pInode, struct file *pFile)
++{
++ printk(KERN_DEBUG "file opening\n");
++
++ //only one at a time
++ if (!atomic_dec_and_test(&g_oneLock))
++ {
++ atomic_inc(&g_oneLock);
++ return -EBUSY;
++ }
++
++ return 0;
++}
++
++static int Release(struct inode *pInode, struct file *pFile)
++{
++ printk(KERN_DEBUG "file closing, %d pages tracked\n", g_trackedPages);
++ if (g_trackedPages)
++ printk(KERN_ERR "we\'re leaking memory!\n");
++
++ atomic_inc(&g_oneLock);
++ return 0;
++}
++
++static struct DmaControlBlock __user *DmaPrepare(struct DmaControlBlock __user *pUserCB, int *pError)
++{
++ struct DmaControlBlock kernCB;
++ struct DmaControlBlock __user *pUNext;
++ void __iomem *pSourceBus, __iomem *pDestBus;
++
++
++ //get the control block into kernel memory so we can work on it
++ if (copy_from_user(&kernCB, pUserCB, sizeof(struct DmaControlBlock)) != 0)
++ {
++ printk(KERN_ERR "copy_from_user failed for user cb %p\n", pUserCB);
++ *pError = 1;
++ return 0;
++ }
++
++ if (kernCB.m_pSourceAddr == 0 || kernCB.m_pDestAddr == 0)
++ {
++ printk(KERN_ERR "faulty source (%p) dest (%p) addresses for user cb %p\n",
++ kernCB.m_pSourceAddr, kernCB.m_pDestAddr, pUserCB);
++ *pError = 1;
++ return 0;
++ }
++
++ pSourceBus = UserVirtualToBusViaCache(kernCB.m_pSourceAddr);
++ pDestBus = UserVirtualToBusViaCache(kernCB.m_pDestAddr);
++
++ if (!pSourceBus || !pDestBus)
++ {
++ printk(KERN_ERR "virtual to bus translation failure for source/dest\n");
++ *pError = 1;
++ return 0;
++ }
++
++ //update the user structure with the new bus addresses
++ kernCB.m_pSourceAddr = pSourceBus;
++ kernCB.m_pDestAddr = pDestBus;
++
++ //sort out the bus address for the next block
++ pUNext = kernCB.m_pNext;
++
++ if (kernCB.m_pNext)
++ {
++ void __iomem *pNextBus;
++ pNextBus = UserVirtualToBusViaCbCache(kernCB.m_pNext);
++
++ if (!pNextBus)
++ {
++ printk(KERN_ERR "virtual to bus translation failure for m_pNext\n");
++ *pError = 1;
++ return 0;
++ }
++
++ //update the pointer with the bus address
++ kernCB.m_pNext = pNextBus;
++ }
++
++ //write it back to user space
++ if (copy_to_user(pUserCB, &kernCB, sizeof(struct DmaControlBlock)) != 0)
++ {
++ printk(KERN_ERR "copy_to_user failed for cb %p\n", pUserCB);
++ *pError = 1;
++ return 0;
++ }
++
++ __cpuc_flush_dcache_area(pUserCB, 32);
++
++ *pError = 0;
++ return pUNext;
++}
++
++static int DmaKick(struct DmaControlBlock __user *pUserCB)
++{
++ void __iomem *pBusCB;
++
++ pBusCB = UserVirtualToBusViaCbCache(pUserCB);
++ if (!pBusCB)
++ {
++ printk(KERN_ERR "virtual to bus translation failure for cb\n");
++ return 1;
++ }
++
++ //flush_cache_all();
++
++ bcm_dma_start(g_pDmaChanBase, (dma_addr_t)pBusCB);
++
++ return 0;
++}
++
++static void DmaWaitAll(void)
++{
++ int counter = 0;
++ volatile int inner_count;
++ volatile unsigned int cs;
++ //unsigned long time_before, time_after;
++
++ //time_before = jiffies;
++ //bcm_dma_wait_idle(g_pDmaChanBase);
++ dsb();
++
++ cs = readl(g_pDmaChanBase);
++
++ while ((cs & 1) == 1)
++ {
++ cs = readl(g_pDmaChanBase);
++ counter++;
++
++ for (inner_count = 0; inner_count < 32; inner_count++);
++
++ asm volatile ("MCR p15,0,r0,c7,c0,4 \n");
++ //cpu_do_idle();
++ if (counter >= 1000000)
++ {
++ printk(KERN_WARNING "DMA failed to finish in a timely fashion\n");
++ break;
++ }
++ }
++ //time_after = jiffies;
++ //printk(KERN_DEBUG "done, counter %d, cs %08x", counter, cs);
++ //printk(KERN_DEBUG "took %ld jiffies, %d HZ\n", time_after - time_before, HZ);
++}
++
++static long Ioctl(struct file *pFile, unsigned int cmd, unsigned long arg)
++{
++ int error = 0;
++ //printk(KERN_DEBUG "ioctl cmd %x arg %lx\n", cmd, arg);
++
++ switch (cmd)
++ {
++ case DMA_PREPARE:
++ case DMA_PREPARE_KICK:
++ case DMA_PREPARE_KICK_WAIT:
++ {
++ struct DmaControlBlock __user *pUCB = (struct DmaControlBlock *)arg;
++ int steps = 0;
++ //unsigned long start_time = jiffies;
++
++ //flush our address cache
++ FlushAddrCache();
++
++// printk(KERN_DEBUG "dma prepare\n");
++
++ //do virtual to bus translation for each entry
++ do
++ {
++ pUCB = DmaPrepare(pUCB, &error);
++ } while (error == 0 && ++steps && pUCB);
++ //printk(KERN_DEBUG "prepare done in %d steps, %ld\n", steps, jiffies - start_time);
++
++ //carry straight on if we want to kick too
++ if (cmd == DMA_PREPARE || error)
++ {
++// printk(KERN_DEBUG "falling out\n");
++ break;
++ }
++ };
++ case DMA_KICK:
++// printk(KERN_DEBUG "dma begin\n");
++
++ if (cmd == DMA_KICK)
++ FlushAddrCache();
++
++ DmaKick((struct DmaControlBlock __user *)arg);
++
++ if (cmd != DMA_PREPARE_KICK_WAIT)
++ break;
++/* case DMA_WAIT_ONE:
++ //printk(KERN_DEBUG "dma wait one\n");
++ break;*/
++ case DMA_WAIT_ALL:
++ //printk(KERN_DEBUG "dma wait all\n");
++ DmaWaitAll();
++ break;
++ case DMA_MAX_BURST:
++ if (g_dmaChan == 0)
++ return 10;
++ else
++ return 5;
++ case DMA_SET_MIN_PHYS:
++ g_pMinPhys = (void __user *)arg;
++ printk("min/max user/phys bypass set to %p %p\n", g_pMinPhys, g_pMaxPhys);
++ break;
++ case DMA_SET_MAX_PHYS:
++ g_pMaxPhys = (void __user *)arg;
++ printk("min/max user/phys bypass set to %p %p\n", g_pMinPhys, g_pMaxPhys);
++ break;
++ default:
++ printk(KERN_DEBUG "unknown ioctl: %d\n", cmd);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static ssize_t Read(struct file *pFile, char __user *pUser, size_t count, loff_t *offp)
++{
++ /*printk(KERN_DEBUG "file read pFile %p pUser %p count %ld offp %p\n",
++ pFile, pUser, count, offp);
++ printk(KERN_DEBUG "phys pFile %lx pUser %lx offp %lx\n",
++ __pa(pFile), __pa(pUser), __pa(offp));
++ printk(KERN_DEBUG "bus pFile %lx pUser %lx offp %lx\n",
++ virt_to_bus(pFile), virt_to_bus(pUser), virt_to_bus(offp));*/
++ return -EIO;
++}
++
++static int Mmap(struct file *pFile, struct vm_area_struct *pVma)
++{
++ struct PageList *pPages;
++ struct VmaPageList *pVmaList;
++
++// printk(KERN_DEBUG "MMAP vma %p, length %ld (%s %d)\n",
++// pVma, pVma->vm_end - pVma->vm_start,
++// current->comm, current->pid);
++// printk(KERN_DEBUG "MMAP %p %d (tracked %d)\n", pVma, current->pid, g_trackedPages);
++
++ //make a new page list
++ pPages = (struct PageList *)kmalloc(sizeof(struct PageList), GFP_KERNEL);
++ if (!pPages)
++ {
++ printk(KERN_ERR "couldn\'t allocate a new page list (%s %d)\n",
++ current->comm, current->pid);
++ return -ENOMEM;
++ }
++
++ //clear the page list
++ pPages->m_used = 0;
++ pPages->m_pNext = 0;
++
++ //insert our vma and new page list somewhere
++ if (!pVma->vm_private_data)
++ {
++ struct VmaPageList *pList;
++
++// printk(KERN_DEBUG "new vma list, making new one (%s %d)\n",
++// current->comm, current->pid);
++
++ //make a new vma list
++ pList = (struct VmaPageList *)kmalloc(sizeof(struct VmaPageList), GFP_KERNEL);
++ if (!pList)
++ {
++ printk(KERN_ERR "couldn\'t allocate vma page list (%s %d)\n",
++ current->comm, current->pid);
++ kfree(pPages);
++ return -ENOMEM;
++ }
++
++ //clear this list
++ pVma->vm_private_data = (void *)pList;
++ pList->m_refCount = 0;
++ }
++
++ pVmaList = (struct VmaPageList *)pVma->vm_private_data;
++
++ //add it to the vma list
++ pVmaList->m_pPageHead = pPages;
++ pVmaList->m_pPageTail = pPages;
++
++ pVma->vm_ops = &g_vmOps;
++ pVma->vm_flags |= VM_RESERVED;
++
++ VmaOpen(pVma);
++
++ return 0;
++}
++
++/****** VMA OPERATIONS ******/
++
++static void VmaOpen(struct vm_area_struct *pVma)
++{
++ struct VmaPageList *pVmaList;
++
++// printk(KERN_DEBUG "vma open %p private %p (%s %d), %d live pages\n", pVma, pVma->vm_private_data, current->comm, current->pid, g_trackedPages);
++// printk(KERN_DEBUG "OPEN %p %d %ld pages (tracked pages %d)\n",
++// pVma, current->pid, (pVma->vm_end - pVma->vm_start) >> 12,
++// g_trackedPages);
++
++ pVmaList = (struct VmaPageList *)pVma->vm_private_data;
++
++ if (pVmaList)
++ {
++ pVmaList->m_refCount++;
++// printk(KERN_DEBUG "ref count is now %d\n", pVmaList->m_refCount);
++ }
++// else
++// printk(KERN_DEBUG "err, open but no vma page list\n");
++}
++
++static void VmaClose(struct vm_area_struct *pVma)
++{
++ struct VmaPageList *pVmaList;
++ int freed = 0;
++
++// printk(KERN_DEBUG "vma close %p private %p (%s %d)\n", pVma, pVma->vm_private_data, current->comm, current->pid);
++
++ //find our vma in the list
++ pVmaList = (struct VmaPageList *)pVma->vm_private_data;
++
++ //may be a fork
++ if (pVmaList)
++ {
++ struct PageList *pPages;
++
++ pVmaList->m_refCount--;
++
++ if (pVmaList->m_refCount == 0)
++ {
++// printk(KERN_DEBUG "found vma, freeing pages (%s %d)\n",
++// current->comm, current->pid);
++
++ pPages = pVmaList->m_pPageHead;
++
++ if (!pPages)
++ {
++ printk(KERN_ERR "no page list (%s %d)!\n",
++ current->comm, current->pid);
++ return;
++ }
++
++ while (pPages)
++ {
++ struct PageList *next;
++ int count;
++
++// printk(KERN_DEBUG "page list (%s %d)\n",
++// current->comm, current->pid);
++
++ next = pPages->m_pNext;
++ for (count = 0; count < pPages->m_used; count++)
++ {
++// printk(KERN_DEBUG "freeing page %p (%s %d)\n",
++// pPages->m_pPages[count],
++// current->comm, current->pid);
++ __free_pages(pPages->m_pPages[count], 0);
++ g_trackedPages--;
++ freed++;
++ }
++
++// printk(KERN_DEBUG "freeing page list (%s %d)\n",
++// current->comm, current->pid);
++ kfree(pPages);
++ pPages = next;
++ }
++
++ //remove our vma from the list
++ kfree(pVmaList);
++ pVma->vm_private_data = 0;
++ }
++// else
++// printk(KERN_DEBUG "ref count is %d, not closing\n", pVmaList->m_refCount);
++ }
++ else
++ {
++// printk(KERN_ERR "uh-oh, vma %p not found (%s %d)!\n", pVma, current->comm, current->pid);
++// printk(KERN_ERR "CLOSE ERR\n");
++ }
++
++// printk(KERN_DEBUG "CLOSE %p %d %d pages (tracked pages %d)",
++// pVma, current->pid, freed, g_trackedPages);
++
++// printk(KERN_DEBUG "%d pages open\n", g_trackedPages);
++}
++
++static int VmaFault(struct vm_area_struct *pVma, struct vm_fault *pVmf)
++{
++// printk(KERN_DEBUG "vma fault for vma %p private %p at offset %ld (%s %d)\n", pVma, pVma->vm_private_data, pVmf->pgoff,
++// current->comm, current->pid);
++ //printk(KERN_DEBUG "FAULT\n");
++ pVmf->page = alloc_page(GFP_KERNEL);
++ /*if (pVmf->page)
++ printk(KERN_DEBUG "alloc page virtual %p\n", page_address(pVmf->page));*/
++
++ if (!pVmf->page)
++ {
++ printk(KERN_ERR "vma fault oom (%s %d)\n", current->comm, current->pid);
++ return VM_FAULT_OOM;
++ }
++ else
++ {
++ struct VmaPageList *pVmaList;
++
++ get_page(pVmf->page);
++ g_trackedPages++;
++
++ //find our vma in the list
++ pVmaList = (struct VmaPageList *)pVma->vm_private_data;
++
++ if (pVmaList)
++ {
++// printk(KERN_DEBUG "vma found (%s %d)\n", current->comm, current->pid);
++
++ if (pVmaList->m_pPageTail->m_used == PAGES_PER_LIST)
++ {
++// printk(KERN_DEBUG "making new page list (%s %d)\n", current->comm, current->pid);
++ //making a new page list
++ pVmaList->m_pPageTail->m_pNext = (struct PageList *)kmalloc(sizeof(struct PageList), GFP_KERNEL);
++ if (!pVmaList->m_pPageTail->m_pNext)
++ return -ENOMEM;
++
++ //update the tail pointer
++ pVmaList->m_pPageTail = pVmaList->m_pPageTail->m_pNext;
++ pVmaList->m_pPageTail->m_used = 0;
++ pVmaList->m_pPageTail->m_pNext = 0;
++ }
++
++// printk(KERN_DEBUG "adding page to list (%s %d)\n", current->comm, current->pid);
++
++ pVmaList->m_pPageTail->m_pPages[pVmaList->m_pPageTail->m_used] = pVmf->page;
++ pVmaList->m_pPageTail->m_used++;
++ }
++ else
++ printk(KERN_ERR "returned page for vma we don\'t know %p (%s %d)\n", pVma, current->comm, current->pid);
++
++ return 0;
++ }
++}
++
++/****** GENERIC FUNCTIONS ******/
++static int __init dmaer_init(void)
++{
++ int result = alloc_chrdev_region(&g_majorMinor, 0, 1, "dmaer");
++ if (result < 0)
++ {
++ printk(KERN_ERR "unable to get major device number\n");
++ return result;
++ }
++ else
++ printk(KERN_DEBUG "major device number %d\n", MAJOR(g_majorMinor));
++
++ printk(KERN_DEBUG "vma list size %d, page list size %d, page size %ld\n",
++ sizeof(struct VmaPageList), sizeof(struct PageList), PAGE_SIZE);
++
++
++ //get a dma channel to work with
++ result = bcm_dma_chan_alloc(BCM_DMA_FEATURE_FAST, (void **)&g_pDmaChanBase, &g_dmaIrq);
++ //result = 0;
++ //g_pDmaChanBase = 0xce808000;
++
++ if (result < 0)
++ {
++ printk(KERN_ERR "failed to allocate dma channel\n");
++ cdev_del(&g_cDev);
++ unregister_chrdev_region(g_majorMinor, 1);
++ }
++
++ //reset the channel
++ printk(KERN_DEBUG "allocated dma channel %d (%p), initial state %08x\n", result, g_pDmaChanBase, *g_pDmaChanBase);
++ *g_pDmaChanBase = 1 << 31;
++ printk(KERN_DEBUG "post-reset %08x\n", *g_pDmaChanBase);
++
++ g_dmaChan = result;
++
++ //clear the cache stats
++ g_cacheHit = 0;
++ g_cacheMiss = 0;
++
++ //register our device - after this we are go go go
++ cdev_init(&g_cDev, &g_fOps);
++ g_cDev.owner = THIS_MODULE;
++ g_cDev.ops = &g_fOps;
++
++ result = cdev_add(&g_cDev, g_majorMinor, 1);
++ if (result < 0)
++ {
++ printk(KERN_ERR "failed to add character device\n");
++ unregister_chrdev_region(g_majorMinor, 1);
++ bcm_dma_chan_free(g_dmaChan);
++ return result;
++ }
++
++ return 0;
++}
++
++static void __exit dmaer_exit(void)
++{
++ printk(KERN_INFO "closing dmaer device, cache stats: %d hits %d misses\n", g_cacheHit, g_cacheMiss);
++ //unregister the device
++ cdev_del(&g_cDev);
++ unregister_chrdev_region(g_majorMinor, 1);
++ //free the dma channel
++ bcm_dma_chan_free(g_dmaChan);
++}
++
++MODULE_AUTHOR("Simon Hall");
++module_init(dmaer_init);
++module_exit(dmaer_exit);
++
diff --git a/patches/linux-3.6.7/0175-Add-missing-options-from-more-recent-3.2.27-kernel-c.patch b/patches/linux-3.6.7/0175-Add-missing-options-from-more-recent-3.2.27-kernel-c.patch
new file mode 100644
index 0000000..05aa8f1
--- /dev/null
+++ b/patches/linux-3.6.7/0175-Add-missing-options-from-more-recent-3.2.27-kernel-c.patch
@@ -0,0 +1,298 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Mon, 19 Nov 2012 18:27:36 +0000
+Subject: [PATCH] Add missing options from more recent 3.2.27 kernel config
+
+---
+ arch/arm/configs/bcmrpi_defconfig | 145 ++++----------------------------------
+ 1 file changed, 12 insertions(+), 133 deletions(-)
+
+diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
+index 539470e..2069eb0 100644
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -11,6 +11,8 @@ CONFIG_TASK_DELAY_ACCT=y
+ CONFIG_TASK_XACCT=y
+ CONFIG_TASK_IO_ACCOUNTING=y
+ CONFIG_AUDIT=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
+ CONFIG_IKCONFIG=y
+ CONFIG_IKCONFIG_PROC=y
+ CONFIG_CGROUP_FREEZER=y
+@@ -33,10 +35,11 @@ CONFIG_MODVERSIONS=y
+ CONFIG_MODULE_SRCVERSION_ALL=y
+ # CONFIG_BLK_DEV_BSG is not set
+ CONFIG_BLK_DEV_THROTTLING=y
++CONFIG_PARTITION_ADVANCED=y
++CONFIG_MAC_PARTITION=y
++CONFIG_EFI_PARTITION=y
+ CONFIG_CFQ_GROUP_IOSCHED=y
+ CONFIG_ARCH_BCM2708=y
+-CONFIG_NO_HZ=y
+-CONFIG_HIGH_RES_TIMERS=y
+ CONFIG_PREEMPT=y
+ CONFIG_AEABI=y
+ CONFIG_UACCESS_WITH_MEMCPY=y
+@@ -179,7 +182,6 @@ CONFIG_IP_NF_MATCH_ECN=m
+ CONFIG_IP_NF_MATCH_TTL=m
+ CONFIG_IP_NF_FILTER=m
+ CONFIG_IP_NF_TARGET_REJECT=m
+-CONFIG_IP_NF_TARGET_LOG=m
+ CONFIG_IP_NF_TARGET_ULOG=m
+ CONFIG_NF_NAT=m
+ CONFIG_IP_NF_TARGET_MASQUERADE=m
+@@ -203,7 +205,6 @@ CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+ CONFIG_IP6_NF_MATCH_MH=m
+ CONFIG_IP6_NF_MATCH_RT=m
+ CONFIG_IP6_NF_TARGET_HL=m
+-CONFIG_IP6_NF_TARGET_LOG=m
+ CONFIG_IP6_NF_FILTER=m
+ CONFIG_IP6_NF_TARGET_REJECT=m
+ CONFIG_IP6_NF_MANGLE=m
+@@ -305,8 +306,6 @@ CONFIG_USB_IRDA=m
+ CONFIG_SIGMATEL_FIR=m
+ CONFIG_MCS_FIR=m
+ CONFIG_BT=m
+-CONFIG_BT_L2CAP=y
+-CONFIG_BT_SCO=y
+ CONFIG_BT_RFCOMM=m
+ CONFIG_BT_RFCOMM_TTY=y
+ CONFIG_BT_BNEP=m
+@@ -331,13 +330,14 @@ CONFIG_NFC=m
+ CONFIG_NFC_PN533=m
+ CONFIG_DEVTMPFS=y
+ CONFIG_DEVTMPFS_MOUNT=y
++CONFIG_CMA=y
++CONFIG_CMA_DEBUG=y
+ CONFIG_BLK_DEV_LOOP=y
+ CONFIG_BLK_DEV_CRYPTOLOOP=m
+ CONFIG_BLK_DEV_DRBD=m
+ CONFIG_BLK_DEV_NBD=m
+ CONFIG_BLK_DEV_RAM=y
+ CONFIG_CDROM_PKTCDVD=m
+-CONFIG_MISC_DEVICES=y
+ CONFIG_SCSI=y
+ # CONFIG_SCSI_PROC_FS is not set
+ CONFIG_BLK_DEV_SD=y
+@@ -360,7 +360,6 @@ CONFIG_BONDING=m
+ CONFIG_MACVLAN=m
+ CONFIG_NETCONSOLE=m
+ CONFIG_TUN=m
+-CONFIG_PHYLIB=m
+ CONFIG_MDIO_BITBANG=m
+ CONFIG_PPP=m
+ CONFIG_PPP_BSDCOMP=m
+@@ -415,7 +414,6 @@ CONFIG_B43=m
+ CONFIG_B43_PHY_N=y
+ CONFIG_B43LEGACY=m
+ CONFIG_HOSTAP=m
+-CONFIG_IWM=m
+ CONFIG_LIBERTAS=m
+ CONFIG_LIBERTAS_USB=m
+ CONFIG_LIBERTAS_SDIO=m
+@@ -427,8 +425,6 @@ CONFIG_RT73USB=m
+ CONFIG_RT2800USB=m
+ CONFIG_RT2800USB_RT53XX=y
+ CONFIG_RT2800USB_UNKNOWN=y
+-CONFIG_WL1251=m
+-CONFIG_WL12XX_MENU=m
+ CONFIG_ZD1211RW=m
+ CONFIG_MWIFIEX=m
+ CONFIG_MWIFIEX_SDIO=m
+@@ -464,6 +460,8 @@ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+ CONFIG_TTY_PRINTK=y
+ # CONFIG_HW_RANDOM is not set
+ CONFIG_RAW_DRIVER=y
++CONFIG_BRCM_CHAR_DRIVERS=y
++CONFIG_BCM_VC_CMA=y
+ CONFIG_I2C=y
+ CONFIG_I2C_CHARDEV=m
+ CONFIG_I2C_BCM2708=m
+@@ -491,118 +489,6 @@ CONFIG_THERMAL_BCM2835=y
+ CONFIG_WATCHDOG=y
+ CONFIG_BCM2708_WDT=m
+ CONFIG_MEDIA_SUPPORT=m
+-CONFIG_VIDEO_DEV=m
+-CONFIG_DVB_CORE=m
+-CONFIG_RC_ATI_REMOTE=m
+-CONFIG_IR_IMON=m
+-CONFIG_IR_MCEUSB=m
+-CONFIG_IR_REDRAT3=m
+-CONFIG_IR_STREAMZAP=m
+-CONFIG_RC_LOOPBACK=m
+-CONFIG_MEDIA_ATTACH=y
+-CONFIG_USB_VIDEO_CLASS=m
+-CONFIG_USB_M5602=m
+-CONFIG_USB_STV06XX=m
+-CONFIG_USB_GL860=m
+-CONFIG_USB_GSPCA_BENQ=m
+-CONFIG_USB_GSPCA_CONEX=m
+-CONFIG_USB_GSPCA_CPIA1=m
+-CONFIG_USB_GSPCA_ETOMS=m
+-CONFIG_USB_GSPCA_FINEPIX=m
+-CONFIG_USB_GSPCA_JEILINJ=m
+-CONFIG_USB_GSPCA_KINECT=m
+-CONFIG_USB_GSPCA_KONICA=m
+-CONFIG_USB_GSPCA_MARS=m
+-CONFIG_USB_GSPCA_MR97310A=m
+-CONFIG_USB_GSPCA_NW80X=m
+-CONFIG_USB_GSPCA_OV519=m
+-CONFIG_USB_GSPCA_OV534=m
+-CONFIG_USB_GSPCA_OV534_9=m
+-CONFIG_USB_GSPCA_PAC207=m
+-CONFIG_USB_GSPCA_PAC7302=m
+-CONFIG_USB_GSPCA_PAC7311=m
+-CONFIG_USB_GSPCA_SE401=m
+-CONFIG_USB_GSPCA_SN9C2028=m
+-CONFIG_USB_GSPCA_SN9C20X=m
+-CONFIG_USB_GSPCA_SONIXB=m
+-CONFIG_USB_GSPCA_SONIXJ=m
+-CONFIG_USB_GSPCA_SPCA500=m
+-CONFIG_USB_GSPCA_SPCA501=m
+-CONFIG_USB_GSPCA_SPCA505=m
+-CONFIG_USB_GSPCA_SPCA506=m
+-CONFIG_USB_GSPCA_SPCA508=m
+-CONFIG_USB_GSPCA_SPCA561=m
+-CONFIG_USB_GSPCA_SPCA1528=m
+-CONFIG_USB_GSPCA_SQ905=m
+-CONFIG_USB_GSPCA_SQ905C=m
+-CONFIG_USB_GSPCA_SQ930X=m
+-CONFIG_USB_GSPCA_STK014=m
+-CONFIG_USB_GSPCA_STV0680=m
+-CONFIG_USB_GSPCA_SUNPLUS=m
+-CONFIG_USB_GSPCA_T613=m
+-CONFIG_USB_GSPCA_TV8532=m
+-CONFIG_USB_GSPCA_VC032X=m
+-CONFIG_USB_GSPCA_VICAM=m
+-CONFIG_USB_GSPCA_XIRLINK_CIT=m
+-CONFIG_USB_GSPCA_ZC3XX=m
+-CONFIG_VIDEO_PVRUSB2=m
+-CONFIG_VIDEO_HDPVR=m
+-CONFIG_VIDEO_EM28XX=m
+-CONFIG_VIDEO_EM28XX_ALSA=m
+-CONFIG_VIDEO_EM28XX_DVB=m
+-CONFIG_VIDEO_TLG2300=m
+-CONFIG_VIDEO_CX231XX=m
+-CONFIG_VIDEO_CX231XX_ALSA=m
+-CONFIG_VIDEO_CX231XX_DVB=m
+-CONFIG_VIDEO_USBVISION=m
+-CONFIG_USB_ET61X251=m
+-CONFIG_USB_SN9C102=m
+-CONFIG_USB_PWC=m
+-CONFIG_USB_ZR364XX=m
+-CONFIG_USB_STKWEBCAM=m
+-CONFIG_USB_S2255=m
+-CONFIG_USB_DSBR=m
+-CONFIG_RADIO_SI470X=y
+-CONFIG_USB_SI470X=m
+-CONFIG_USB_MR800=m
+-CONFIG_DVB_USB=m
+-CONFIG_DVB_USB_A800=m
+-CONFIG_DVB_USB_DIBUSB_MB=m
+-CONFIG_DVB_USB_DIBUSB_MC=m
+-CONFIG_DVB_USB_DIB0700=m
+-CONFIG_DVB_USB_UMT_010=m
+-CONFIG_DVB_USB_CXUSB=m
+-CONFIG_DVB_USB_M920X=m
+-CONFIG_DVB_USB_GL861=m
+-CONFIG_DVB_USB_AU6610=m
+-CONFIG_DVB_USB_DIGITV=m
+-CONFIG_DVB_USB_VP7045=m
+-CONFIG_DVB_USB_VP702X=m
+-CONFIG_DVB_USB_GP8PSK=m
+-CONFIG_DVB_USB_NOVA_T_USB2=m
+-CONFIG_DVB_USB_TTUSB2=m
+-CONFIG_DVB_USB_DTT200U=m
+-CONFIG_DVB_USB_OPERA1=m
+-CONFIG_DVB_USB_AF9005=m
+-CONFIG_DVB_USB_AF9005_REMOTE=m
+-CONFIG_DVB_USB_PCTV452E=m
+-CONFIG_DVB_USB_DW2102=m
+-CONFIG_DVB_USB_CINERGY_T2=m
+-CONFIG_DVB_USB_ANYSEE=m
+-CONFIG_DVB_USB_DTV5100=m
+-CONFIG_DVB_USB_AF9015=m
+-CONFIG_DVB_USB_CE6230=m
+-CONFIG_DVB_USB_FRIIO=m
+-CONFIG_DVB_USB_EC168=m
+-CONFIG_DVB_USB_AZ6027=m
+-CONFIG_DVB_USB_LME2510=m
+-CONFIG_DVB_USB_TECHNISAT_USB2=m
+-CONFIG_DVB_USB_IT913X=m
+-CONFIG_DVB_USB_MXL111SF=m
+-CONFIG_SMS_SIANO_MDTV=m
+-CONFIG_SMS_USB_DRV=m
+-CONFIG_DVB_B2C2_FLEXCOP=m
+-CONFIG_DVB_B2C2_FLEXCOP_USB=m
+ CONFIG_FB=y
+ CONFIG_FB_BCM2708=y
+ CONFIG_FRAMEBUFFER_CONSOLE=y
+@@ -629,8 +515,6 @@ CONFIG_SND_USB_UA101=m
+ CONFIG_SND_USB_CAIAQ=m
+ CONFIG_SND_USB_6FIRE=m
+ CONFIG_SOUND_PRIME=m
+-CONFIG_HID_PID=y
+-CONFIG_USB_HIDDEV=y
+ CONFIG_HID_A4TECH=m
+ CONFIG_HID_ACRUX=m
+ CONFIG_HID_APPLE=m
+@@ -661,7 +545,6 @@ CONFIG_HID_ORTEK=m
+ CONFIG_HID_PANTHERLORD=m
+ CONFIG_HID_PETALYNX=m
+ CONFIG_HID_PICOLCD=m
+-CONFIG_HID_QUANTA=m
+ CONFIG_HID_ROCCAT=m
+ CONFIG_HID_SAMSUNG=m
+ CONFIG_HID_SONY=m
+@@ -675,6 +558,8 @@ CONFIG_HID_WACOM=m
+ CONFIG_HID_WIIMOTE=m
+ CONFIG_HID_ZEROPLUS=m
+ CONFIG_HID_ZYDACRON=m
++CONFIG_HID_PID=y
++CONFIG_USB_HIDDEV=y
+ CONFIG_USB=y
+ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+ CONFIG_USB_MON=m
+@@ -771,7 +656,7 @@ CONFIG_MMC_SDHCI=y
+ CONFIG_MMC_SDHCI_PLTFM=y
+ CONFIG_MMC_SDHCI_BCM2708=y
+ CONFIG_MMC_SDHCI_BCM2708_DMA=y
+-CONFIG_LEDS_GPIO=y
++CONFIG_LEDS_GPIO=m
+ CONFIG_LEDS_TRIGGER_TIMER=m
+ CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+ CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+@@ -811,7 +696,6 @@ CONFIG_STAGING=y
+ CONFIG_W35UND=m
+ CONFIG_PRISM2_USB=m
+ CONFIG_R8712U=m
+-CONFIG_ZRAM=m
+ # CONFIG_IOMMU_SUPPORT is not set
+ CONFIG_EXT4_FS=y
+ CONFIG_EXT4_FS_POSIX_ACL=y
+@@ -860,7 +744,6 @@ CONFIG_SQUASHFS_XATTR=y
+ CONFIG_SQUASHFS_LZO=y
+ CONFIG_SQUASHFS_XZ=y
+ CONFIG_NFS_FS=y
+-CONFIG_NFS_V3=y
+ CONFIG_NFS_V3_ACL=y
+ CONFIG_NFS_V4=y
+ CONFIG_ROOT_NFS=y
+@@ -874,9 +757,6 @@ CONFIG_CIFS_XATTR=y
+ CONFIG_CIFS_POSIX=y
+ CONFIG_9P_FS=m
+ CONFIG_9P_FS_POSIX_ACL=y
+-CONFIG_PARTITION_ADVANCED=y
+-CONFIG_MAC_PARTITION=y
+-CONFIG_EFI_PARTITION=y
+ CONFIG_NLS_DEFAULT="utf8"
+ CONFIG_NLS_CODEPAGE_437=y
+ CONFIG_NLS_CODEPAGE_737=m
+@@ -923,7 +803,6 @@ CONFIG_TIMER_STATS=y
+ CONFIG_DEBUG_MEMORY_INIT=y
+ CONFIG_BOOT_PRINTK_DELAY=y
+ CONFIG_LATENCYTOP=y
+-CONFIG_SYSCTL_SYSCALL_CHECK=y
+ # CONFIG_KPROBE_EVENT is not set
+ CONFIG_KGDB=y
+ CONFIG_KGDB_KDB=y
diff --git a/patches/linux-3.6.7/0176-lirc-added-support-for-RaspberryPi-GPIO.patch b/patches/linux-3.6.7/0176-lirc-added-support-for-RaspberryPi-GPIO.patch
new file mode 100644
index 0000000..decd167
--- /dev/null
+++ b/patches/linux-3.6.7/0176-lirc-added-support-for-RaspberryPi-GPIO.patch
@@ -0,0 +1,733 @@
+From: Aron Szabo <aron@aron.ws>
+Date: Sat, 16 Jun 2012 12:15:55 +0200
+Subject: [PATCH] lirc: added support for RaspberryPi GPIO
+
+---
+ drivers/staging/media/lirc/Kconfig | 6 +
+ drivers/staging/media/lirc/Makefile | 1 +
+ drivers/staging/media/lirc/lirc_rpi.c | 687 ++++++++++++++++++++++++++++++++++
+ 3 files changed, 694 insertions(+)
+ create mode 100644 drivers/staging/media/lirc/lirc_rpi.c
+
+diff --git a/drivers/staging/media/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig
+index 526ec0f..c7c6288 100644
+--- a/drivers/staging/media/lirc/Kconfig
++++ b/drivers/staging/media/lirc/Kconfig
+@@ -38,6 +38,12 @@ config LIRC_PARALLEL
+ help
+ Driver for Homebrew Parallel Port Receivers
+
++config LIRC_RPI
++ tristate "Homebrew GPIO Port Receiver/Transmitter for the RaspberryPi"
++ depends on LIRC
++ help
++ Driver for Homebrew GPIO Port Receiver/Transmitter for the RaspberryPi
++
+ config LIRC_SASEM
+ tristate "Sasem USB IR Remote"
+ depends on LIRC && USB
+diff --git a/drivers/staging/media/lirc/Makefile b/drivers/staging/media/lirc/Makefile
+index d76b0fa..af4be00 100644
+--- a/drivers/staging/media/lirc/Makefile
++++ b/drivers/staging/media/lirc/Makefile
+@@ -7,6 +7,7 @@ obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o
+ obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o
+ obj-$(CONFIG_LIRC_IMON) += lirc_imon.o
+ obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
++obj-$(CONFIG_LIRC_RPI) += lirc_rpi.o
+ obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
+ obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
+ obj-$(CONFIG_LIRC_SIR) += lirc_sir.o
+diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c
+new file mode 100644
+index 0000000..96acab0
+--- /dev/null
++++ b/drivers/staging/media/lirc/lirc_rpi.c
+@@ -0,0 +1,687 @@
++/*
++ * lirc_rpi.c
++ *
++ * lirc_rpi - Device driver that records pulse- and pause-lengths
++ * (space-lengths) (just like the lirc_serial driver does)
++ * between GPIO interrupt events on the Raspberry Pi.
++ * Lots of code has been taken from the lirc_serial module,
++ * so I would like say thanks to the authors.
++ *
++ * Copyright (C) 2012 Aron Robert Szabo <aron@reon.hu>,
++ * Michael Bishop <cleverca22@gmail.com>
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++#include <linux/kernel.h>
++#include <linux/time.h>
++#include <linux/string.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/irq.h>
++#include <linux/spinlock.h>
++#include <media/lirc.h>
++#include <media/lirc_dev.h>
++#include <linux/gpio.h>
++
++#define LIRC_DRIVER_NAME "lirc_rpi"
++#define RBUF_LEN 256
++#define LIRC_TRANSMITTER_LATENCY 256
++
++#ifndef MAX_UDELAY_MS
++#define MAX_UDELAY_US 5000
++#else
++#define MAX_UDELAY_US (MAX_UDELAY_MS*1000)
++#endif
++
++#define dprintk(fmt, args...) \
++ do { \
++ if (debug) \
++ printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \
++ fmt, ## args); \
++ } while (0)
++
++/* module parameters */
++
++/* set the default GPIO input pin */
++static int gpio_in_pin = 18;
++/* set the default GPIO output pin */
++static int gpio_out_pin = 17;
++/* enable debugging messages */
++static int debug;
++/* -1 = auto, 0 = active high, 1 = active low */
++static int sense = -1;
++/* use softcarrier by default */
++static int softcarrier = 1;
++
++struct gpio_chip *gpiochip;
++struct irq_chip *irqchip;
++struct irq_data *irqdata;
++
++/* forward declarations */
++static long send_pulse(unsigned long length);
++static void send_space(long length);
++static void lirc_rpi_exit(void);
++
++int valid_gpio_pins[] = { 0, 1, 4, 8, 7, 9, 10, 11, 14, 15, 17, 18, 21, 22, 23,
++ 24, 25 };
++
++static struct platform_device *lirc_rpi_dev;
++static struct timeval lasttv = { 0, 0 };
++static struct lirc_buffer rbuf;
++static spinlock_t lock;
++
++/* initialized/set in init_timing_params() */
++static unsigned int freq = 38000;
++static unsigned int duty_cycle = 50;
++static unsigned long period;
++static unsigned long pulse_width;
++static unsigned long space_width;
++
++static void safe_udelay(unsigned long usecs)
++{
++ while (usecs > MAX_UDELAY_US) {
++ udelay(MAX_UDELAY_US);
++ usecs -= MAX_UDELAY_US;
++ }
++ udelay(usecs);
++}
++
++static int init_timing_params(unsigned int new_duty_cycle,
++ unsigned int new_freq)
++{
++ /*
++ * period, pulse/space width are kept with 8 binary places -
++ * IE multiplied by 256.
++ */
++ if (256 * 1000000L / new_freq * new_duty_cycle / 100 <=
++ LIRC_TRANSMITTER_LATENCY)
++ return -EINVAL;
++ if (256 * 1000000L / new_freq * (100 - new_duty_cycle) / 100 <=
++ LIRC_TRANSMITTER_LATENCY)
++ return -EINVAL;
++ duty_cycle = new_duty_cycle;
++ freq = new_freq;
++ period = 256 * 1000000L / freq;
++ pulse_width = period * duty_cycle / 100;
++ space_width = period - pulse_width;
++ dprintk("in init_timing_params, freq=%d pulse=%ld, "
++ "space=%ld\n", freq, pulse_width, space_width);
++ return 0;
++}
++
++static long send_pulse_softcarrier(unsigned long length)
++{
++ int flag;
++ unsigned long actual, target, d;
++
++ length <<= 8;
++
++ actual = 0; target = 0; flag = 0;
++ while (actual < length) {
++ if (flag) {
++ gpiochip->set(gpiochip, gpio_out_pin, 0);
++ target += space_width;
++ } else {
++ gpiochip->set(gpiochip, gpio_out_pin, 1);
++ target += pulse_width;
++ }
++ d = (target - actual -
++ LIRC_TRANSMITTER_LATENCY + 128) >> 8;
++ /*
++ * Note - we've checked in ioctl that the pulse/space
++ * widths are big enough so that d is > 0
++ */
++ udelay(d);
++ actual += (d << 8) + LIRC_TRANSMITTER_LATENCY;
++ flag = !flag;
++ }
++ return (actual-length) >> 8;
++}
++
++static long send_pulse(unsigned long length)
++{
++ if (length <= 0)
++ return 0;
++
++ if (softcarrier) {
++ return send_pulse_softcarrier(length);
++ } else {
++ gpiochip->set(gpiochip, gpio_out_pin, 1);
++ safe_udelay(length);
++ return 0;
++ }
++}
++
++static void send_space(long length)
++{
++ gpiochip->set(gpiochip, gpio_out_pin, 0);
++ if (length <= 0)
++ return;
++ safe_udelay(length);
++}
++
++static void rbwrite(int l)
++{
++ if (lirc_buffer_full(&rbuf)) {
++ /* no new signals will be accepted */
++ dprintk("Buffer overrun\n");
++ return;
++ }
++ lirc_buffer_write(&rbuf, (void *)&l);
++}
++
++static void frbwrite(int l)
++{
++ /* simple noise filter */
++ static int pulse, space;
++ static unsigned int ptr;
++
++ if (ptr > 0 && (l & PULSE_BIT)) {
++ pulse += l & PULSE_MASK;
++ if (pulse > 250) {
++ rbwrite(space);
++ rbwrite(pulse | PULSE_BIT);
++ ptr = 0;
++ pulse = 0;
++ }
++ return;
++ }
++ if (!(l & PULSE_BIT)) {
++ if (ptr == 0) {
++ if (l > 20000) {
++ space = l;
++ ptr++;
++ return;
++ }
++ } else {
++ if (l > 20000) {
++ space += pulse;
++ if (space > PULSE_MASK)
++ space = PULSE_MASK;
++ space += l;
++ if (space > PULSE_MASK)
++ space = PULSE_MASK;
++ pulse = 0;
++ return;
++ }
++ rbwrite(space);
++ rbwrite(pulse | PULSE_BIT);
++ ptr = 0;
++ pulse = 0;
++ }
++ }
++ rbwrite(l);
++}
++
++static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs)
++{
++ struct timeval tv;
++ long deltv;
++ int data;
++ int signal;
++
++ /* use the GPIO signal level */
++ signal = gpiochip->get(gpiochip, gpio_in_pin);
++
++ /* unmask the irq */
++ irqchip->irq_unmask(irqdata);
++
++ if (sense != -1) {
++ /* get current time */
++ do_gettimeofday(&tv);
++
++ /* calc time since last interrupt in microseconds */
++ deltv = tv.tv_sec-lasttv.tv_sec;
++ if (tv.tv_sec < lasttv.tv_sec ||
++ (tv.tv_sec == lasttv.tv_sec &&
++ tv.tv_usec < lasttv.tv_usec)) {
++ printk(KERN_WARNING LIRC_DRIVER_NAME
++ ": AIEEEE: your clock just jumped backwards\n");
++ printk(KERN_WARNING LIRC_DRIVER_NAME
++ ": %d %d %lx %lx %lx %lx\n", signal, sense,
++ tv.tv_sec, lasttv.tv_sec,
++ tv.tv_usec, lasttv.tv_usec);
++ data = PULSE_MASK;
++ } else if (deltv > 15) {
++ data = PULSE_MASK; /* really long time */
++ if (!(signal^sense)) {
++ /* sanity check */
++ printk(KERN_WARNING LIRC_DRIVER_NAME
++ ": AIEEEE: %d %d %lx %lx %lx %lx\n",
++ signal, sense, tv.tv_sec, lasttv.tv_sec,
++ tv.tv_usec, lasttv.tv_usec);
++ /*
++ * detecting pulse while this
++ * MUST be a space!
++ */
++ sense = sense ? 0 : 1;
++ }
++ } else {
++ data = (int) (deltv*1000000 +
++ (tv.tv_usec - lasttv.tv_usec));
++ }
++ frbwrite(signal^sense ? data : (data|PULSE_BIT));
++ lasttv = tv;
++ wake_up_interruptible(&rbuf.wait_poll);
++ }
++
++ return IRQ_HANDLED;
++}
++
++static int is_right_chip(struct gpio_chip *chip, void *data)
++{
++ dprintk("is_right_chip %s %d\n", chip->label, strcmp(data, chip->label));
++
++ if (strcmp(data, chip->label) == 0)
++ return 1;
++ return 0;
++}
++
++static int init_port(void)
++{
++ int i, nlow, nhigh, ret, irq;
++
++ gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip);
++
++ if (!gpiochip)
++ return -ENODEV;
++
++ if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) {
++ printk(KERN_ALERT LIRC_DRIVER_NAME
++ ": cant claim gpio pin %d\n", gpio_out_pin);
++ ret = -ENODEV;
++ goto exit_init_port;
++ }
++
++ if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) {
++ printk(KERN_ALERT LIRC_DRIVER_NAME
++ ": cant claim gpio pin %d\n", gpio_in_pin);
++ ret = -ENODEV;
++ goto exit_gpio_free_out_pin;
++ }
++
++ gpiochip->direction_input(gpiochip, gpio_in_pin);
++ gpiochip->direction_output(gpiochip, gpio_out_pin, 1);
++ gpiochip->set(gpiochip, gpio_out_pin, 0);
++
++ irq = gpiochip->to_irq(gpiochip, gpio_in_pin);
++ dprintk("to_irq %d\n", irq);
++ irqdata = irq_get_irq_data(irq);
++
++ if (irqdata && irqdata->chip) {
++ irqchip = irqdata->chip;
++ } else {
++ ret = -ENODEV;
++ goto exit_gpio_free_in_pin;
++ }
++
++ /* if pin is high, then this must be an active low receiver. */
++ if (sense == -1) {
++ /* wait 1/2 sec for the power supply */
++ msleep(500);
++
++ /*
++ * probe 9 times every 0.04s, collect "votes" for
++ * active high/low
++ */
++ nlow = 0;
++ nhigh = 0;
++ for (i = 0; i < 9; i++) {
++ if (gpiochip->get(gpiochip, gpio_in_pin))
++ nlow++;
++ else
++ nhigh++;
++ msleep(40);
++ }
++ sense = (nlow >= nhigh ? 1 : 0);
++ printk(KERN_INFO LIRC_DRIVER_NAME
++ ": auto-detected active %s receiver on GPIO pin %d\n",
++ sense ? "low" : "high", gpio_in_pin);
++ } else {
++ printk(KERN_INFO LIRC_DRIVER_NAME
++ ": manually using active %s receiver on GPIO pin %d\n",
++ sense ? "low" : "high", gpio_in_pin);
++ }
++
++ return 0;
++
++ exit_gpio_free_in_pin:
++ gpio_free(gpio_in_pin);
++
++ exit_gpio_free_out_pin:
++ gpio_free(gpio_out_pin);
++
++ exit_init_port:
++ return ret;
++}
++
++// called when the character device is opened
++static int set_use_inc(void *data)
++{
++ int result;
++ unsigned long flags;
++
++ /* initialize timestamp */
++ do_gettimeofday(&lasttv);
++
++ result = request_irq(gpiochip->to_irq(gpiochip, gpio_in_pin),
++ (irq_handler_t) irq_handler, 0,
++ LIRC_DRIVER_NAME, (void*) 0);
++
++ switch (result) {
++ case -EBUSY:
++ printk(KERN_ERR LIRC_DRIVER_NAME
++ ": IRQ %d is busy\n",
++ gpiochip->to_irq(gpiochip, gpio_in_pin));
++ return -EBUSY;
++ case -EINVAL:
++ printk(KERN_ERR LIRC_DRIVER_NAME
++ ": Bad irq number or handler\n");
++ return -EINVAL;
++ default:
++ dprintk("Interrupt %d obtained\n",
++ gpiochip->to_irq(gpiochip, gpio_in_pin));
++ break;
++ };
++
++ /* initialize pulse/space widths */
++ init_timing_params(duty_cycle, freq);
++
++ spin_lock_irqsave(&lock, flags);
++
++ /* GPIO Pin Falling/Rising Edge Detect Enable */
++ irqchip->irq_set_type(irqdata,
++ IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING);
++
++ /* unmask the irq */
++ irqchip->irq_unmask(irqdata);
++
++ spin_unlock_irqrestore(&lock, flags);
++
++ return 0;
++}
++
++static void set_use_dec(void *data)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&lock, flags);
++
++ /* GPIO Pin Falling/Rising Edge Detect Disable */
++ irqchip->irq_set_type(irqdata, 0);
++ irqchip->irq_mask(irqdata);
++
++ spin_unlock_irqrestore(&lock, flags);
++
++ free_irq(gpiochip->to_irq(gpiochip, gpio_in_pin), (void *) 0);
++
++ dprintk(KERN_INFO LIRC_DRIVER_NAME
++ ": freed IRQ %d\n", gpiochip->to_irq(gpiochip, gpio_in_pin));
++}
++
++static ssize_t lirc_write(struct file *file, const char *buf,
++ size_t n, loff_t *ppos)
++{
++ int i, count;
++ unsigned long flags;
++ long delta = 0;
++ int *wbuf;
++
++ count = n / sizeof(int);
++ if (n % sizeof(int) || count % 2 == 0)
++ return -EINVAL;
++ wbuf = memdup_user(buf, n);
++ if (IS_ERR(wbuf))
++ return PTR_ERR(wbuf);
++ spin_lock_irqsave(&lock, flags);
++
++ for (i = 0; i < count; i++) {
++ if (i%2)
++ send_space(wbuf[i] - delta);
++ else
++ delta = send_pulse(wbuf[i]);
++ }
++ gpiochip->set(gpiochip, gpio_out_pin, 0);
++
++ spin_unlock_irqrestore(&lock, flags);
++ kfree(wbuf);
++ return n;
++}
++
++static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
++{
++ int result;
++ __u32 value;
++
++ switch (cmd) {
++ case LIRC_GET_SEND_MODE:
++ return -ENOIOCTLCMD;
++ break;
++
++ case LIRC_SET_SEND_MODE:
++ result = get_user(value, (__u32 *) arg);
++ if (result)
++ return result;
++ /* only LIRC_MODE_PULSE supported */
++ if (value != LIRC_MODE_PULSE)
++ return -ENOSYS;
++ break;
++
++ case LIRC_GET_LENGTH:
++ return -ENOSYS;
++ break;
++
++ case LIRC_SET_SEND_DUTY_CYCLE:
++ dprintk("SET_SEND_DUTY_CYCLE\n");
++ result = get_user(value, (__u32 *) arg);
++ if (result)
++ return result;
++ if (value <= 0 || value > 100)
++ return -EINVAL;
++ return init_timing_params(value, freq);
++ break;
++
++ case LIRC_SET_SEND_CARRIER:
++ dprintk("SET_SEND_CARRIER\n");
++ result = get_user(value, (__u32 *) arg);
++ if (result)
++ return result;
++ if (value > 500000 || value < 20000)
++ return -EINVAL;
++ return init_timing_params(duty_cycle, value);
++ break;
++
++ default:
++ return lirc_dev_fop_ioctl(filep, cmd, arg);
++ }
++ return 0;
++}
++
++static const struct file_operations lirc_fops = {
++ .owner = THIS_MODULE,
++ .write = lirc_write,
++ .unlocked_ioctl = lirc_ioctl,
++ .read = lirc_dev_fop_read,
++ .poll = lirc_dev_fop_poll,
++ .open = lirc_dev_fop_open,
++ .release = lirc_dev_fop_close,
++ .llseek = no_llseek,
++};
++
++static struct lirc_driver driver = {
++ .name = LIRC_DRIVER_NAME,
++ .minor = -1,
++ .code_length = 1,
++ .sample_rate = 0,
++ .data = NULL,
++ .add_to_buf = NULL,
++ .rbuf = &rbuf,
++ .set_use_inc = set_use_inc,
++ .set_use_dec = set_use_dec,
++ .fops = &lirc_fops,
++ .dev = NULL,
++ .owner = THIS_MODULE,
++};
++
++static struct platform_driver lirc_rpi_driver = {
++ .driver = {
++ .name = LIRC_DRIVER_NAME,
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init lirc_rpi_init(void)
++{
++ int result;
++
++ /* Init read buffer. */
++ result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN);
++ if (result < 0)
++ return -ENOMEM;
++
++ result = platform_driver_register(&lirc_rpi_driver);
++ if (result) {
++ printk(KERN_ERR LIRC_DRIVER_NAME
++ ": lirc register returned %d\n", result);
++ goto exit_buffer_free;
++ }
++
++ lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
++ if (!lirc_rpi_dev) {
++ result = -ENOMEM;
++ goto exit_driver_unregister;
++ }
++
++ result = platform_device_add(lirc_rpi_dev);
++ if (result)
++ goto exit_device_put;
++
++ return 0;
++
++ exit_device_put:
++ platform_device_put(lirc_rpi_dev);
++
++ exit_driver_unregister:
++ platform_driver_unregister(&lirc_rpi_driver);
++
++ exit_buffer_free:
++ lirc_buffer_free(&rbuf);
++
++ return result;
++}
++
++static void lirc_rpi_exit(void)
++{
++ gpio_free(gpio_out_pin);
++ gpio_free(gpio_in_pin);
++ platform_device_unregister(lirc_rpi_dev);
++ platform_driver_unregister(&lirc_rpi_driver);
++ lirc_buffer_free(&rbuf);
++}
++
++static int __init lirc_rpi_init_module(void)
++{
++ int result, i;
++
++ result = lirc_rpi_init();
++ if (result)
++ return result;
++
++ /* check if the module received valid gpio pin numbers */
++ result = 0;
++ if (gpio_in_pin != gpio_out_pin) {
++ for(i = 0; (i < ARRAY_SIZE(valid_gpio_pins)) && (result != 2); i++) {
++ if (gpio_in_pin == valid_gpio_pins[i] ||
++ gpio_out_pin == valid_gpio_pins[i]) {
++ result++;
++ }
++ }
++ }
++
++ if (result != 2) {
++ result = -EINVAL;
++ printk(KERN_ERR LIRC_DRIVER_NAME
++ ": invalid GPIO pin(s) specified!\n");
++ goto exit_rpi;
++ }
++
++ driver.features = LIRC_CAN_SET_SEND_DUTY_CYCLE |
++ LIRC_CAN_SET_SEND_CARRIER |
++ LIRC_CAN_SEND_PULSE |
++ LIRC_CAN_REC_MODE2;
++
++ driver.dev = &lirc_rpi_dev->dev;
++ driver.minor = lirc_register_driver(&driver);
++
++ if (driver.minor < 0) {
++ printk(KERN_ERR LIRC_DRIVER_NAME
++ ": device registration failed with %d\n", result);
++ result = -EIO;
++ goto exit_rpi;
++ }
++
++ printk(KERN_INFO LIRC_DRIVER_NAME ": driver registered!\n");
++
++ result = init_port();
++ if (result < 0)
++ goto exit_rpi;
++
++ return 0;
++
++ exit_rpi:
++ lirc_rpi_exit();
++
++ return result;
++}
++
++static void __exit lirc_rpi_exit_module(void)
++{
++ lirc_rpi_exit();
++
++ lirc_unregister_driver(driver.minor);
++ printk(KERN_INFO LIRC_DRIVER_NAME ": cleaned up module\n");
++}
++
++module_init(lirc_rpi_init_module);
++module_exit(lirc_rpi_exit_module);
++
++MODULE_DESCRIPTION("Infra-red receiver and blaster driver for Raspberry Pi GPIO.");
++MODULE_AUTHOR("Aron Robert Szabo <aron@reon.hu>");
++MODULE_AUTHOR("Michael Bishop <cleverca22@gmail.com>");
++MODULE_LICENSE("GPL");
++
++module_param(gpio_out_pin, int, S_IRUGO);
++MODULE_PARM_DESC(gpio_out_pin, "GPIO output/transmitter pin number of the BCM"
++ " processor. Valid pin numbers are: 0, 1, 4, 8, 7, 9, 10, 11,"
++ " 14, 15, 17, 18, 21, 22, 23, 24, 25, default 17");
++
++module_param(gpio_in_pin, int, S_IRUGO);
++MODULE_PARM_DESC(gpio_in_pin, "GPIO input pin number of the BCM processor."
++ " Valid pin numbers are: 0, 1, 4, 8, 7, 9, 10, 11, 14, 15,"
++ " 17, 18, 21, 22, 23, 24, 25, default 18");
++
++module_param(sense, bool, S_IRUGO);
++MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit"
++ " (0 = active high, 1 = active low )");
++
++module_param(softcarrier, bool, S_IRUGO);
++MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)");
++
++module_param(debug, bool, S_IRUGO | S_IWUSR);
++MODULE_PARM_DESC(debug, "Enable debugging messages");
diff --git a/patches/linux-3.6.7/0177-Enable-building-of-lirc-rpi.patch b/patches/linux-3.6.7/0177-Enable-building-of-lirc-rpi.patch
new file mode 100644
index 0000000..9c0f6f5
--- /dev/null
+++ b/patches/linux-3.6.7/0177-Enable-building-of-lirc-rpi.patch
@@ -0,0 +1,20 @@
+From: popcornmix <popcornmix@gmail.com>
+Date: Thu, 8 Nov 2012 00:00:18 +0000
+Subject: [PATCH] Enable building of lirc-rpi
+
+---
+ arch/arm/configs/bcmrpi_defconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig
+index 2069eb0..12e6d92 100644
+--- a/arch/arm/configs/bcmrpi_defconfig
++++ b/arch/arm/configs/bcmrpi_defconfig
+@@ -40,6 +40,7 @@ CONFIG_MAC_PARTITION=y
+ CONFIG_EFI_PARTITION=y
+ CONFIG_CFQ_GROUP_IOSCHED=y
+ CONFIG_ARCH_BCM2708=y
++CONFIG_BCM2708_DMAER=m
+ CONFIG_PREEMPT=y
+ CONFIG_AEABI=y
+ CONFIG_UACCESS_WITH_MEMCPY=y
diff --git a/patches/linux-3.6.7/0201-Release-raspberrypi-20121120.patch b/patches/linux-3.6.7/0201-Release-raspberrypi-20121120.patch
new file mode 100644
index 0000000..a948d62
--- /dev/null
+++ b/patches/linux-3.6.7/0201-Release-raspberrypi-20121120.patch
@@ -0,0 +1,22 @@
+From: Michael Olbrich <m.olbrich@pengutronix.de>
+Date: Tue, 20 Nov 2012 07:45:52 +0100
+Subject: [PATCH] Release raspberrypi/20121120
+
+Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
+---
+ Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index 07f2308..816cd53 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ VERSION = 3
+ PATCHLEVEL = 6
+ SUBLEVEL = 7
+-EXTRAVERSION =
++EXTRAVERSION =-20121120
+ NAME = Terrified Chipmunk
+
+ # *DOCUMENTATION*
diff --git a/patches/linux-3.6.7/series b/patches/linux-3.6.7/series
new file mode 100644
index 0000000..e2e8109
--- /dev/null
+++ b/patches/linux-3.6.7/series
@@ -0,0 +1,187 @@
+# umpf-base: v3.6.7
+# umpf-name: raspberrypi
+# umpf-version: raspberrypi/20121120
+# umpf-topic: rpi-3.6.y
+# umpf-hashinfo: 5fe0247c8d24df4a15589f01809368a2f938935b
+# umpf-topic-range: 9f3dc4baa6813f64f89ce408dc93bdcba38ba022..616b92d3e834ac45950fdb3f7015c0160364c940
+0001-Add-dwc_otg-driver.patch
+0002-Main-bcm2708-linux-port.patch
+0003-bcm2708-watchdog-driver.patch
+0004-bcm2708-framebuffer-driver.patch
+0005-bcm2708-vchiq-driver.patch
+0006-Allow-mac-address-to-be-set-in-smsc95xx.patch
+0007-Fix-headers-for-vchiq-vcos-to-be-GPLv2.patch
+0008-Fix-some-issues-reported.-Lower-case-module-paramete.patch
+0009-Build-anything-reasonable-as-a-module.-Thanks-to-asb.patch
+0010-Add-config-option-to-enable-L2-cache.patch
+0011-Fix-bug-where-vchiq-fails-when-L2-enabled.patch
+0012-Add-devtmpfs-for-archlinux-and-emergency-and-debug-c.patch
+0013-Fix-32bpp-framebuffer-by-adding-alpha-bits.patch
+0014-Enable-L2-cache-is-now-the-default.-Invert-sense-of-.patch
+0015-Allow-24bpp-for-framebuffer.patch
+0016-Disable-debug-code-in-dwc_otg-driver-unless-CONFIG_U.patch
+0017-Enable-high-resolution-timers.patch
+0018-Fix-for-mmc-timeouts-when-erasing-multiple-blocks.patch
+0019-Fix-problem-with-dma-that-could-corrupt-sdcard-espec.patch
+0020-Update-to-match-latest-vc-side-vchiq.-Allows-vchiq-c.patch
+0021-First-pass-at-alsa-sound-driver.-Some-functionality-.patch
+0022-Cast-to-avoid-warning.patch
+0023-Add-new-ioctl-to-match-latest-vc-side-code.patch
+0024-Enable-sound-kernel-modules.-Tidy-formatting.-Fix-ct.patch
+0025-Add-missing-header-file-update-for-vc_mem-iocts.patch
+0026-Remove-most-of-the-alsa-debug-messages.patch
+0027-add-temporary-workaround-for-fbset-crashes.patch
+0028-Fix-harmless-base-size-typo.patch
+0029-Replace-if-1-sections-by-local-configuration-defines.patch
+0030-Don-t-send-data-block-when-emitting-silence.patch
+0031-Fix-hopefully-for-DWC_MEMCPY-kernel-panics.-Thanks-t.patch
+0032-Build-modules-needed-for-USB-booting-into-kernel.patch
+0033-Whitespace-tidy.-Thanks-Roger.patch
+0034-Update-vchiq-to-match-GPU-version.-Should-still-be-c.patch
+0035-added-support-for-TT-in-the-USB-driver.-Thanks-Naren.patch
+0036-Swap-Red-and-Blue-over-in-32bpp-framebuffer-mode.patch
+0037-Update-emergency-config-to-match-latest-debug-one.patch
+0038-Use-dwc_alloc_atomic.-Thanks-bootc.patch
+0039-possible-fix-for-sdcard-missing-status.-Thank-naren.patch
+0040-Fix-BUG-in-bcm2708_fb_set_par-doesn-t-work-if-the-co.patch
+0041-Fix-for-DWC-OTG-HCD-URB-Dequeue-has-NULL-URB-panic.-.patch
+0042-Fix-for-bug-in-mbox_read.-Thanks-lp0.patch
+0043-Add-__VCCOREVER__-to-makefile.patch
+0044-Change-PHYS_OFFSET-to-PLAT_PHYS_OFFSET.patch
+0045-sdcard-patch-improvements-from-naren.patch
+0046-Invert-sense-of-sdcard-access-trigger-OK-LED-so-it-i.patch
+0047-Added-power-off-message-to-allow-kexec-to-work.-Than.patch
+0048-remove-unwanted-file.patch
+0049-Enable-PREEMPT-and-SCHED_AUTOGROUP.patch
+0050-Added-support-for-USB-webcams.patch
+0051-Enable-ipv6-due-to-popular-demand.patch
+0052-Fix-regression-in-debug-kernel-config-options.patch
+0053-bcm2835-ctl-fix-alsamixer-control.patch
+0054-bcm2835-ctl-limit-maximal-volume-to-4db.patch
+0055-Add-iptables-and-devtmpfs_mount-to-non-cutdown-confi.patch
+0056-sdhci-bcm2708-speed-up-DMA-sync.patch
+0057-sdhci-bcm2708-remove-custom-clock-handling.patch
+0058-sdhci-bcm2708-add-additional-quirks.patch
+0059-sdhci-bcm2708-add-allow_highspeed-parameter.patch
+0060-sdhci-bcm2708-assume-50-MHz-eMMC-clock.patch
+0061-Allow-emmc-clock-to-be-specified-as-command-line-par.patch
+0062-sdhci-bcm2708-raise-DMA-sync-timeout.patch
+0063-Fix-bool-int-error.patch
+0064-Fix-bool-int-error-part-2.patch
+0065-More-config-options-for-iptables-device-mapper-PPP_M.patch
+0066-Explicitly-set-usb-host-channels-to-8-as-in-the-spec.patch
+0067-Add-hfs-hfsplus-modules.patch
+0068-Remove-silence-method-and-use-atomic-flags-for-kmall.patch
+0069-Fix-unintended-line-swap-that-cause-cause-memory-lea.patch
+0070-Use-ndelay-rather-than-udelay.-Thanks-lb.patch
+0071-Add-NFSD.-Add-some-dvb-options.-Add-CONFIG_LOCALVERS.patch
+0072-Fixed-issue-with-some-keyboards-giving-too-much-data.patch
+0073-Add-802.1q-vlan-module.patch
+0074-Add-interrupt-support-to-gpio-driver.-Thanks-Mrkva.patch
+0075-Add-a-pm_power_off-function-that-resets-us-and-indic.patch
+0076-Store-palette-info-where-GPU-can-see-it-so-8bpp-mode.patch
+0077-Avoid-blanking-console-when-not-in-palettised-mode.patch
+0078-Add-mechanism-to-reduce-the-number-of-SOF-interrupts.patch
+0079-Updating-dwc_otg-driver-to-fix-issue-releasing-pcm-s.patch
+0080-Backport-of-Chris-Boot-s-i2c-and-spi-drivers.patch
+0081-forgotten-files.patch
+0082-Enable-I2C-and-SPI-modules-in-full-config.patch
+0083-Possible-fix-for-failure-to-boot-with-compressed-ker.patch
+0084-Another-try-at-fixing-compressed-kernel-booting.patch
+0085-Add-missing-UART0_CLOCK-from-last-commit.patch
+0086-Change-to-add-SCSI-tape-support-as-loadable-modules-.patch
+0087-Add-temporary-fix-for-hang-when-quitting-X.patch
+0088-Better-fix-for-quitting-X-hang.-Interrupted-mailbox-.patch
+0089-Add-sync_after_dma-module-parameter.patch
+0090-Add-SPI_SPI_DEV-module.patch
+0091-Fix-var.width-var.height.-They-actually-mean-display.patch
+0092-The-TIMER_PERIOD-should-be-calculated-using-the-time.patch
+0093-update-bcmrpi_defconfig-with-various-user-requests.patch
+0094-Possible-fix-for-USB-packets-going-missing.-Thank-gs.patch
+0095-Revert-Possible-fix-for-USB-packets-going-missing.-T.patch
+0096-dwc_common_port-remove-unused-cruft-with-onerous-dep.patch
+0097-arm-remove-divdi3-it-s-not-necessary-at-all.patch
+0098-Remove-some-patch-backup-files.patch
+0099-mach-bcm2708-fix-mach-debug-macro.S-so-that-early-pr.patch
+0100-sound-arm-bcm2835.c-add-linux-module.h-include.patch
+0101-vcos-add-linux-kernel.h-include.patch
+0102-bcm2708-update-for-3.2-kernel.patch
+0103-bcm2708-use-a-constant-SC_MULT-SC_SHIFT.patch
+0104-Sync-with-bootc-s-file.patch
+0105-sdhci-bcm2708-use-extension-FIFO-to-buffer-DMA-trans.patch
+0106-sdhci-bcm2708-use-multiblock-type-transfers-for-sing.patch
+0107-Add-module-parameter-for-missing_status-quirk.-sdhci.patch
+0108-Some-fixed-for-ALSA.-Mute-and-volume-changing-should.patch
+0109-Fix-spinlock-recursion-in-sdhci-bcm2708.c.patch
+0110-Revert-Add-mechanism-to-reduce-the-number-of-SOF-int.patch
+0111-Enable-CONFIG_CRYPTO_XTS.patch
+0112-Update-Synopsys-USB-OTG-driver-to-v2.94a-and-disable.patch
+0113-Merged-in-microframe-scheduler-currently-disabled.-E.patch
+0114-Make-microframe-schedule-patch-a-little-closer-to-de.patch
+0115-Remove-remove-documentation-from-the-source-tree.patch
+0116-Fix-for-broken-GPIO-with-3.2-kernel.patch
+0117-Revert-Disable-IRQs-in-dwc_otg_hcd_qh_free-because-D.patch
+0118-Regenerate-defconfigs-for-udpated-kernel-verision.patch
+0119-Another-fix-for-10-second-hang-on-closing-sound-driv.patch
+0120-amba-pl011-Don-t-send-a-character-during-startup.patch
+0121-Revert-Regenerate-defconfigs-for-udpated-kernel-veri.patch
+0122-Regenerate-defconfigs-for-updated-kernel-verision-tr.patch
+0123-Read-memory-size-for-vc_mem-through-mailbox-property.patch
+0124-Revert-amba-pl011-Don-t-send-a-character-during-star.patch
+0125-Update-to-dwc_otg-3.00.-Seems-to-be-a-very-minor-upd.patch
+0126-enabling-the-realtime-clock-1-wire-chip-DS1307-and-1.patch
+0127-Switch-of-tracing-options-in-kernel.-Costs-20-in-ipe.patch
+0128-Turn-on-microframe_schedule-by-default.-Can-still-be.patch
+0129-Add-low-latency-mode-to-sdcard-driver.-Enable-with-s.patch
+0130-Fix-build-for-non-preempt-case.-Fix-warning.patch
+0131-Add-config-options-to-allow-iotop-to-run.patch
+0132-Fix-for-vmalloc-failure-with-modprobe-and-cutdown-ke.patch
+0133-Enable-low-latency-mode-by-default-in-sdcard-driver..patch
+0134-Add-FIQ-patch-to-dwc_otg-driver.-Enable-with-dwc_otg.patch
+0135-Fix-typo.patch
+0136-Add-non-mainline-source-for-rtl8188cu-wireless-drive.patch
+0137-Add-verious-user-config-requests.patch
+0138-Don-t-believe-KDIR-is-required-when-building-as-part.patch
+0139-Avoid-dynamic-memory-allocation-for-channel-lock-in-.patch
+0140-Add-cpufreq-driver.patch
+0141-Tidy-up-debug-messages.patch
+0142-Enable-fiq-fix-by-default.-Add-NAK-holdoff-scheme.-E.patch
+0143-Added-hwmon-thermal-driver-for-reporting-core-temper.patch
+0144-Add-config-options-for-thermal-sensor-L2TP-RT2800USB.patch
+0145-Remove-some-unnecessary-dmesg-output.patch
+0146-Switch-to-powersave-governor.-We-ll-enable-ondemand-.patch
+0147-Enable-multiple-ALSA-channels.patch
+0148-Remove-vcos-abstraction-layer-from-ALSA-driver.-Than.patch
+0149-Fix-Kernel-OOPS-in-SDHCI-on-boot-with-the-llm-patch..patch
+0150-Use-system-timer-for-udelay-so-unaffected-by-cpufreq.patch
+0151-Move-__delay-function-into-assembly-to-get-accurate-.patch
+0152-set-i2c-speed-via-module-parameter-or-menuconfig.-Th.patch
+0153-Allow-the-number-of-cycles-delay-between-sdcard-peri.patch
+0154-Fix-vc-mem-by-using-module-parameters.patch
+0155-Move-to-version-5-of-VCHIQ.-Note-this-requires-a-cor.patch
+0156-Add-in-missed-vchiq-files.patch
+0157-Make-vchiq-enabled-by-default.-Tidy-Kconfig-file.patch
+0158-Support-dummy-vc-mem-ioctl-used-by-vcdbg.patch
+0159-Remove-BUG-call-from-vchiq-that-is-trigger-when-alsa.patch
+0160-Fix-up-issues-with-rebase.patch
+0161-Add-vc_cma-driver-to-enable-use-of-CMA.patch
+0162-Add-missing-CMA-files.patch
+0163-Fix-reboot-with-new-restart-method-of-machine-driver.patch
+0164-smsc95xx-sleep-before-read-for-lengthy-operations.patch
+0165-smsc95xx-remove-unnecessary-variables.patch
+0166-smsc95xx-check-return-code-from-control-messages.patch
+0167-smsc95xx-fix-resume-when-usb-device-is-reset.patch
+0168-smsc95xx-enable-power-saving-mode-during-system-susp.patch
+0169-smsc95xx-add-wol-magic-packet-support.patch
+0170-smsc95xx-fix-tx-checksum-offload-for-big-endian.patch
+0171-Update-to-latest-vchiq.patch
+0172-Make-sure-we-wait-for-the-reset-to-finish.patch
+0173-Add-missing-pctv452e-DVB-module.patch
+0174-Add-Simon-Hall-s-dma-helper-module-useful-in-future-.patch
+0175-Add-missing-options-from-more-recent-3.2.27-kernel-c.patch
+0176-lirc-added-support-for-RaspberryPi-GPIO.patch
+0177-Enable-building-of-lirc-rpi.patch
+# umpf-release: raspberrypi/20121120
+# umpf-topic-range: 616b92d3e834ac45950fdb3f7015c0160364c940..2fa2312469b45410e563a17a3882b6abc5e3eb06
+0201-Release-raspberrypi-20121120.patch
+# umpf-end
diff --git a/platformconfig b/platformconfig
index 334497f..0a00f81 100644
--- a/platformconfig
+++ b/platformconfig
@@ -83,8 +83,8 @@ PTXCONF_KERNEL=y
PTXCONF_KERNEL_MODULES=y
PTXCONF_KERNEL_MODULES_INSTALL=y
PTXCONF_KERNEL_MODULES_BUILD="modules"
-PTXCONF_KERNEL_VERSION="3.2.27"
-PTXCONF_KERNEL_MD5="22c48976f366de2da591fb2b9d0f744b"
+PTXCONF_KERNEL_VERSION="3.6.7"
+PTXCONF_KERNEL_MD5="089209f655c8811db20d8b6ff37a8093"
PTXCONF_KERNEL_ARCH_STRING="arm"
# PTXCONF_KERNEL_IMAGE_BZ is not set
# PTXCONF_KERNEL_IMAGE_Z is not set