summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Luebbe <jlu@pengutronix.de>2013-07-20 19:51:52 +0200
committerJan Luebbe <jlu@pengutronix.de>2013-07-20 19:51:52 +0200
commita8106e82041f2d471d5ceeee76c463d38147e8db (patch)
treebed3635f65b1ae482f19358fc14a9aad94b397e6
parent918a7a71f5d31f0315efaad88ec6475d407db2a4 (diff)
downloadplatform-pengutronix-beaglebone-a8106e82041f2d471d5ceeee76c463d38147e8db.tar.gz
platform-pengutronix-beaglebone-a8106e82041f2d471d5ceeee76c463d38147e8db.tar.xz
kernel: update to 3.8.14
Thanks to Koen Kooi for maintaining the patch stack. Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
-rw-r--r--kernelconfig156
-rw-r--r--kernelconfig-3.2.163563
-rw-r--r--patches/linux-3.8.13/0001-Without-MACH_-option-Early-printk-DEBUG_LL.patch (renamed from patches/linux-3.8.4/0001-Without-MACH_-option-Early-printk-DEBUG_LL.patch)0
-rw-r--r--patches/linux-3.8.13/0002-ARM-OMAP-Hack-AM33xx-clock-data-to-allow-JTAG-use.patch (renamed from patches/linux-3.8.4/0002-ARM-OMAP-Hack-AM33xx-clock-data-to-allow-JTAG-use.patch)0
-rw-r--r--patches/linux-3.8.13/0003-video-st7735fb-add-st7735-framebuffer-driver.patch (renamed from patches/linux-3.8.4/0003-video-st7735fb-add-st7735-framebuffer-driver.patch)0
-rw-r--r--patches/linux-3.8.13/0004-dmaengine-add-helper-function-to-request-a-slave-DMA.patch (renamed from patches/linux-3.8.4/0004-dmaengine-add-helper-function-to-request-a-slave-DMA.patch)0
-rw-r--r--patches/linux-3.8.13/0005-of-Add-generic-device-tree-DMA-helpers.patch (renamed from patches/linux-3.8.4/0005-of-Add-generic-device-tree-DMA-helpers.patch)0
-rw-r--r--patches/linux-3.8.13/0006-of-dma-fix-build-break-for-CONFIG_OF.patch (renamed from patches/linux-3.8.4/0006-of-dma-fix-build-break-for-CONFIG_OF.patch)0
-rw-r--r--patches/linux-3.8.13/0007-of-dma-fix-typos-in-generic-dma-binding-definition.patch (renamed from patches/linux-3.8.4/0007-of-dma-fix-typos-in-generic-dma-binding-definition.patch)0
-rw-r--r--patches/linux-3.8.13/0008-dmaengine-fix-build-failure-due-to-missing-semi-colo.patch (renamed from patches/linux-3.8.4/0008-dmaengine-fix-build-failure-due-to-missing-semi-colo.patch)0
-rw-r--r--patches/linux-3.8.13/0009-dmaengine-edma-fix-slave-config-dependency-on-direct.patch (renamed from patches/linux-3.8.4/0009-dmaengine-edma-fix-slave-config-dependency-on-direct.patch)0
-rw-r--r--patches/linux-3.8.13/0010-dmaengine-add-dma_get_channel_caps.patch (renamed from patches/linux-3.8.4/0010-dmaengine-add-dma_get_channel_caps.patch)0
-rw-r--r--patches/linux-3.8.13/0011-dma-edma-add-device_channel_caps-support.patch (renamed from patches/linux-3.8.4/0011-dma-edma-add-device_channel_caps-support.patch)0
-rw-r--r--patches/linux-3.8.13/0012-mmc-davinci-get-SG-segment-limits-with-dma_get_chann.patch (renamed from patches/linux-3.8.4/0012-mmc-davinci-get-SG-segment-limits-with-dma_get_chann.patch)0
-rw-r--r--patches/linux-3.8.13/0013-ARM-davinci-move-private-EDMA-API-to-arm-common.patch (renamed from patches/linux-3.8.4/0013-ARM-davinci-move-private-EDMA-API-to-arm-common.patch)0
-rw-r--r--patches/linux-3.8.13/0014-ARM-edma-remove-unused-transfer-controller-handlers.patch (renamed from patches/linux-3.8.4/0014-ARM-edma-remove-unused-transfer-controller-handlers.patch)0
-rw-r--r--patches/linux-3.8.13/0015-ARM-edma-add-AM33XX-support-to-the-private-EDMA-API.patch (renamed from patches/linux-3.8.4/0015-ARM-edma-add-AM33XX-support-to-the-private-EDMA-API.patch)0
-rw-r--r--patches/linux-3.8.13/0016-dmaengine-edma-enable-build-for-AM33XX.patch (renamed from patches/linux-3.8.4/0016-dmaengine-edma-enable-build-for-AM33XX.patch)0
-rw-r--r--patches/linux-3.8.13/0017-dmaengine-edma-Add-TI-EDMA-device-tree-binding.patch (renamed from patches/linux-3.8.4/0017-dmaengine-edma-Add-TI-EDMA-device-tree-binding.patch)0
-rw-r--r--patches/linux-3.8.13/0018-ARM-dts-add-AM33XX-EDMA-support.patch (renamed from patches/linux-3.8.4/0018-ARM-dts-add-AM33XX-EDMA-support.patch)0
-rw-r--r--patches/linux-3.8.13/0019-dmaengine-add-dma_request_slave_channel_compat.patch (renamed from patches/linux-3.8.4/0019-dmaengine-add-dma_request_slave_channel_compat.patch)0
-rw-r--r--patches/linux-3.8.13/0020-mmc-omap_hsmmc-convert-to-dma_request_slave_channel_.patch (renamed from patches/linux-3.8.4/0020-mmc-omap_hsmmc-convert-to-dma_request_slave_channel_.patch)0
-rw-r--r--patches/linux-3.8.13/0021-mmc-omap_hsmmc-set-max_segs-based-on-dma-engine-limi.patch (renamed from patches/linux-3.8.4/0021-mmc-omap_hsmmc-set-max_segs-based-on-dma-engine-limi.patch)0
-rw-r--r--patches/linux-3.8.13/0022-mmc-omap_hsmmc-add-generic-DMA-request-support-to-th.patch (renamed from patches/linux-3.8.4/0022-mmc-omap_hsmmc-add-generic-DMA-request-support-to-th.patch)0
-rw-r--r--patches/linux-3.8.13/0023-ARM-dts-add-AM33XX-MMC-support.patch (renamed from patches/linux-3.8.4/0023-ARM-dts-add-AM33XX-MMC-support.patch)0
-rw-r--r--patches/linux-3.8.13/0024-spi-omap2-mcspi-convert-to-dma_request_slave_channel.patch (renamed from patches/linux-3.8.4/0024-spi-omap2-mcspi-convert-to-dma_request_slave_channel.patch)0
-rw-r--r--patches/linux-3.8.13/0025-spi-omap2-mcspi-add-generic-DMA-request-support-to-t.patch (renamed from patches/linux-3.8.4/0025-spi-omap2-mcspi-add-generic-DMA-request-support-to-t.patch)0
-rw-r--r--patches/linux-3.8.13/0026-ARM-dts-add-AM33XX-SPI-DMA-support.patch (renamed from patches/linux-3.8.4/0026-ARM-dts-add-AM33XX-SPI-DMA-support.patch)0
-rw-r--r--patches/linux-3.8.13/0027-ARM-dts-Add-SPI-Flash-support-to-am335x-evm.patch (renamed from patches/linux-3.8.4/0027-ARM-dts-Add-SPI-Flash-support-to-am335x-evm.patch)0
-rw-r--r--patches/linux-3.8.13/0028-Documentation-bindings-add-spansion.patch (renamed from patches/linux-3.8.4/0028-Documentation-bindings-add-spansion.patch)0
-rw-r--r--patches/linux-3.8.13/0029-ARM-dts-enable-spi1-node-and-pinmux-on-BeagleBone.patch (renamed from patches/linux-3.8.4/0029-ARM-dts-enable-spi1-node-and-pinmux-on-BeagleBone.patch)0
-rw-r--r--patches/linux-3.8.13/0030-ARM-dts-add-BeagleBone-Adafruit-1.8-LCD-support.patch (renamed from patches/linux-3.8.4/0030-ARM-dts-add-BeagleBone-Adafruit-1.8-LCD-support.patch)0
-rw-r--r--patches/linux-3.8.13/0031-misc-add-gpevt-driver.patch (renamed from patches/linux-3.8.4/0031-misc-add-gpevt-driver.patch)0
-rw-r--r--patches/linux-3.8.13/0032-ARM-dts-add-BeagleBone-gpevt-support.patch (renamed from patches/linux-3.8.4/0032-ARM-dts-add-BeagleBone-gpevt-support.patch)0
-rw-r--r--patches/linux-3.8.13/0033-ARM-configs-working-dmaengine-configs-for-da8xx-and-.patch (renamed from patches/linux-3.8.4/0033-ARM-configs-working-dmaengine-configs-for-da8xx-and-.patch)0
-rw-r--r--patches/linux-3.8.13/0034-ARM-dts-Add-UART4-support-to-BeagleBone.patch (renamed from patches/linux-3.8.4/0034-ARM-dts-Add-UART4-support-to-BeagleBone.patch)0
-rw-r--r--patches/linux-3.8.13/0035-gpevnt-Remove-__devinit.patch42
-rw-r--r--patches/linux-3.8.13/0036-ARM-OMAP2-am33xx-hwmod-Fix-register-offset-NULL-chec.patch (renamed from patches/linux-3.8.4/0035-ARM-OMAP2-am33xx-hwmod-Fix-register-offset-NULL-chec.patch)0
-rw-r--r--patches/linux-3.8.13/0037-rtc-OMAP-Add-system-pm_power_off-to-rtc-driver.patch (renamed from patches/linux-3.8.4/0036-rtc-OMAP-Add-system-pm_power_off-to-rtc-driver.patch)0
-rw-r--r--patches/linux-3.8.13/0038-ARM-dts-AM33XX-Set-pmic-shutdown-controller-for-Beag.patch (renamed from patches/linux-3.8.4/0037-ARM-dts-AM33XX-Set-pmic-shutdown-controller-for-Beag.patch)0
-rw-r--r--patches/linux-3.8.13/0039-ARM-dts-AM33XX-Enable-system-power-off-control-in-am.patch (renamed from patches/linux-3.8.4/0038-ARM-dts-AM33XX-Enable-system-power-off-control-in-am.patch)0
-rw-r--r--patches/linux-3.8.13/0040-i2c-pinctrl-ify-i2c-omap.c.patch (renamed from patches/linux-3.8.4/0039-i2c-pinctrl-ify-i2c-omap.c.patch)0
-rw-r--r--patches/linux-3.8.13/0041-arm-dts-AM33XX-Configure-pinmuxs-for-user-leds-contr.patch (renamed from patches/linux-3.8.4/0040-arm-dts-AM33XX-Configure-pinmuxs-for-user-leds-contr.patch)0
-rw-r--r--patches/linux-3.8.13/0042-beaglebone-DT-set-default-triggers-for-LEDS.patch (renamed from patches/linux-3.8.4/0041-beaglebone-DT-set-default-triggers-for-LEDS.patch)0
-rw-r--r--patches/linux-3.8.13/0043-beaglebone-add-a-cpu-led-trigger.patch (renamed from patches/linux-3.8.4/0042-beaglebone-add-a-cpu-led-trigger.patch)0
-rw-r--r--patches/linux-3.8.13/0044-am33xx-DT-add-commented-out-OPP-values-for-ES2.0.patch (renamed from patches/linux-3.8.4/0043-am33xx-DT-add-commented-out-OPP-values-for-ES2.0.patch)0
-rw-r--r--patches/linux-3.8.13/0045-mfd-input-iio-ti_am335x_adc-use-one-structure-for-ti.patch136
-rw-r--r--patches/linux-3.8.13/0046-input-ti_am33x_tsc-Step-enable-bits-made-configurabl.patch215
-rw-r--r--patches/linux-3.8.13/0047-input-ti_am33x_tsc-Order-of-TSC-wires-made-configura.patch (renamed from patches/linux-3.8.4/0045-input-ti_am335x_tsc-Order-of-TSC-wires-made-configur.patch)198
-rw-r--r--patches/linux-3.8.13/0048-input-ti_am33x_tsc-remove-unwanted-fifo-flush.patch (renamed from patches/linux-3.8.4/0046-input-touchscreen-ti_tsc-remove-unwanted-fifo-flush.patch)12
-rw-r--r--patches/linux-3.8.13/0049-input-ti_am33x_tsc-Add-DT-support.patch312
-rw-r--r--patches/linux-3.8.13/0050-iio-ti_am335x_adc-Add-DT-support.patch96
-rw-r--r--patches/linux-3.8.13/0051-arm-dts-AM335x-evm-Add-TSC-ADC-MFD-device-support.patch (renamed from patches/linux-3.8.4/0051-arm-dts-AM335x-evm-Add-TSC-ADC-MFD-device-support.patch)0
-rw-r--r--patches/linux-3.8.13/0052-mfd-ti_am335x_tscadc-Add-DT-support.patch (renamed from patches/linux-3.8.4/0048-MFD-ti_am335x_tscadc-Add-DT-support.patch)28
-rw-r--r--patches/linux-3.8.13/0053-iio-ti_tscadc-provide-datasheet_name-and-scan_type.patch85
-rw-r--r--patches/linux-3.8.13/0054-mfd-ti_tscadc-deal-with-partial-activation.patch110
-rw-r--r--patches/linux-3.8.13/0055-input-ti_am335x_adc-use-only-FIFO0-and-clean-up-a-li.patch261
-rw-r--r--patches/linux-3.8.13/0056-input-ti_am335x_tsc-ACK-the-HW_PEN-irq-in-ISR.patch32
-rw-r--r--patches/linux-3.8.13/0057-input-ti_am335x_tsc-return-IRQ_NONE-if-there-was-no-.patch37
-rw-r--r--patches/linux-3.8.13/0058-iio-ti_am335x_adc-Allow-to-specify-input-line.patch213
-rw-r--r--patches/linux-3.8.13/0059-iio-ti_am335x_adc-check-if-we-found-the-value.patch43
-rw-r--r--patches/linux-3.8.13/0060-MFD-ti_tscadc-disable-TSC-control.patch59
-rw-r--r--patches/linux-3.8.13/0061-IIO-ADC-ti_adc-Fix-1st-sample-read.patch119
-rw-r--r--patches/linux-3.8.13/0062-input-ti_tsc-Enable-shared-IRQ-TSC.patch61
-rw-r--r--patches/linux-3.8.13/0063-Revert.-Backport-IIO.patch49
-rw-r--r--patches/linux-3.8.13/0064-iio-ti_am335x_adc-Added-iio_voltageX_scale.patch60
-rw-r--r--patches/linux-3.8.13/0065-iio-ti_am335x_adc-Add-the-in-kernel-IIO-map-interfac.patch122
-rw-r--r--patches/linux-3.8.13/0066-pinctrl-pinctrl-single-must-be-initialized-early.patch (renamed from patches/linux-3.8.4/0058-pinctrl-pinctrl-single-must-be-initialized-early.patch)0
-rw-r--r--patches/linux-3.8.13/0067-Bone-DTS-working-i2c2-i2c3-in-the-tree.patch (renamed from patches/linux-3.8.4/0059-Bone-DTS-working-i2c2-i2c3-in-the-tree.patch)0
-rw-r--r--patches/linux-3.8.13/0068-am33xx-Convert-I2C-from-omap-to-am33xx-names.patch (renamed from patches/linux-3.8.4/0060-am33xx-Convert-I2C-from-omap-to-am33xx-names.patch)2
-rw-r--r--patches/linux-3.8.13/0069-am335x-evm-hack-around-i2c-node-names.patch (renamed from patches/linux-3.8.4/0061-am335x-evm-hack-around-i2c-node-names.patch)2
-rw-r--r--patches/linux-3.8.13/0070-tsl2550-fix-lux1_input-error-in-low-light.patch31
-rw-r--r--patches/linux-3.8.13/0071-viafb-rename-display_timing-to-via_display_timing.patch (renamed from patches/linux-3.8.4/0062-viafb-rename-display_timing-to-via_display_timing.patch)0
-rw-r--r--patches/linux-3.8.13/0072-video-add-display_timing-and-videomode.patch (renamed from patches/linux-3.8.4/0063-video-add-display_timing-and-videomode.patch)0
-rw-r--r--patches/linux-3.8.13/0073-video-add-of-helper-for-display-timings-videomode.patch (renamed from patches/linux-3.8.4/0064-video-add-of-helper-for-display-timings-videomode.patch)0
-rw-r--r--patches/linux-3.8.13/0074-fbmon-add-videomode-helpers.patch (renamed from patches/linux-3.8.4/0065-fbmon-add-videomode-helpers.patch)0
-rw-r--r--patches/linux-3.8.13/0075-fbmon-add-of_videomode-helpers.patch (renamed from patches/linux-3.8.4/0066-fbmon-add-of_videomode-helpers.patch)0
-rw-r--r--patches/linux-3.8.13/0076-drm_modes-add-videomode-helpers.patch (renamed from patches/linux-3.8.4/0067-drm_modes-add-videomode-helpers.patch)2
-rw-r--r--patches/linux-3.8.13/0077-drm_modes-add-of_videomode-helpers.patch (renamed from patches/linux-3.8.4/0068-drm_modes-add-of_videomode-helpers.patch)2
-rw-r--r--patches/linux-3.8.13/0078-fbmon-fix-build-error.patch (renamed from patches/linux-3.8.4/0069-fbmon-fix-build-error.patch)0
-rw-r--r--patches/linux-3.8.13/0079-of-display-timings-use-of_get_child_by_name.patch (renamed from patches/linux-3.8.4/0070-of-display-timings-use-of_get_child_by_name.patch)0
-rw-r--r--patches/linux-3.8.13/0080-da8xx-Allow-use-by-am33xx-based-devices.patch (renamed from patches/linux-3.8.4/0071-da8xx-Allow-use-by-am33xx-based-devices.patch)0
-rw-r--r--patches/linux-3.8.13/0081-video-da8xx-fb-fb_check_var-enhancement.patch (renamed from patches/linux-3.8.4/0072-video-da8xx-fb-fb_check_var-enhancement.patch)0
-rw-r--r--patches/linux-3.8.13/0082-video-da8xx-fb-simplify-lcd_reset.patch (renamed from patches/linux-3.8.4/0073-video-da8xx-fb-simplify-lcd_reset.patch)0
-rw-r--r--patches/linux-3.8.13/0083-video-da8xx-fb-use-modedb-helper-to-update-var.patch (renamed from patches/linux-3.8.4/0074-video-da8xx-fb-use-modedb-helper-to-update-var.patch)0
-rw-r--r--patches/linux-3.8.13/0084-video-da8xx-fb-remove-unneeded-var-initialization.patch (renamed from patches/linux-3.8.4/0075-video-da8xx-fb-remove-unneeded-var-initialization.patch)0
-rw-r--r--patches/linux-3.8.13/0085-video-da8xx-fb-store-current-display-information.patch (renamed from patches/linux-3.8.4/0076-video-da8xx-fb-store-current-display-information.patch)0
-rw-r--r--patches/linux-3.8.13/0086-video-da8xx-fb-store-clk-rate-even-if-CPUFREQ.patch (renamed from patches/linux-3.8.4/0077-video-da8xx-fb-store-clk-rate-even-if-CPUFREQ.patch)0
-rw-r--r--patches/linux-3.8.13/0087-video-da8xx-fb-pix-clk-and-clk-div-handling-cleanup.patch (renamed from patches/linux-3.8.4/0078-video-da8xx-fb-pix-clk-and-clk-div-handling-cleanup.patch)0
-rw-r--r--patches/linux-3.8.13/0088-video-da8xx-fb-store-struct-device.patch (renamed from patches/linux-3.8.4/0079-video-da8xx-fb-store-struct-device.patch)0
-rw-r--r--patches/linux-3.8.13/0089-video-da8xx-fb-report-correct-pixclock.patch (renamed from patches/linux-3.8.4/0080-video-da8xx-fb-report-correct-pixclock.patch)0
-rw-r--r--patches/linux-3.8.13/0090-video-da8xx-fb-fb_set_par-support.patch (renamed from patches/linux-3.8.4/0081-video-da8xx-fb-fb_set_par-support.patch)0
-rw-r--r--patches/linux-3.8.13/0091-ARM-dts-AM33XX-Add-lcdc-node.patch (renamed from patches/linux-3.8.4/0082-ARM-dts-AM33XX-Add-lcdc-node.patch)0
-rw-r--r--patches/linux-3.8.13/0092-ARM-dts-AM33XX-Add-am335x-evm-lcdc-panel-timings.patch (renamed from patches/linux-3.8.4/0083-ARM-dts-AM33XX-Add-am335x-evm-lcdc-panel-timings.patch)4
-rw-r--r--patches/linux-3.8.13/0093-ARM-dts-AM33XX-Add-am335x-evm-lcdc-pincontrol-info.patch (renamed from patches/linux-3.8.4/0084-ARM-dts-AM33XX-Add-am335x-evm-lcdc-pincontrol-info.patch)2
-rw-r--r--patches/linux-3.8.13/0094-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-panel-timings.patch (renamed from patches/linux-3.8.4/0085-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-panel-timings.patch)0
-rw-r--r--patches/linux-3.8.13/0095-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-pincontrol-info.patch (renamed from patches/linux-3.8.4/0086-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-pincontrol-info.patch)0
-rw-r--r--patches/linux-3.8.13/0096-ARM-OMAP-AM33xx-hwmod-Corrects-PWM-subsystem-HWMOD-e.patch (renamed from patches/linux-3.8.4/0087-ARM-OMAP-AM33xx-hwmod-Corrects-PWM-subsystem-HWMOD-e.patch)0
-rw-r--r--patches/linux-3.8.13/0097-ARM-OMAP-AM33xx-hwmod-Add-parent-child-relationship-.patch (renamed from patches/linux-3.8.4/0088-ARM-OMAP-AM33xx-hwmod-Add-parent-child-relationship-.patch)0
-rw-r--r--patches/linux-3.8.13/0098-ARM-dts-AM33XX-Add-PWMSS-device-tree-nodes.patch (renamed from patches/linux-3.8.4/0089-ARM-dts-AM33XX-Add-PWMSS-device-tree-nodes.patch)0
-rw-r--r--patches/linux-3.8.13/0099-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch (renamed from patches/linux-3.8.4/0090-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch)2
-rw-r--r--patches/linux-3.8.13/0100-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch (renamed from patches/linux-3.8.4/0091-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch)0
-rw-r--r--patches/linux-3.8.13/0101-clk-divider-prepare-for-minimum-divider.patch (renamed from patches/linux-3.8.4/0092-clk-divider-prepare-for-minimum-divider.patch)0
-rw-r--r--patches/linux-3.8.13/0102-clk-divider-handle-minimum-divider.patch (renamed from patches/linux-3.8.4/0093-clk-divider-handle-minimum-divider.patch)0
-rw-r--r--patches/linux-3.8.13/0103-ARM-OMAP2-dpll-round-rate-to-closest-value.patch (renamed from patches/linux-3.8.4/0094-ARM-OMAP2-dpll-round-rate-to-closest-value.patch)0
-rw-r--r--patches/linux-3.8.13/0104-ARM-OMAP2-dpll-am335x-avoid-freqsel.patch (renamed from patches/linux-3.8.4/0095-ARM-OMAP2-dpll-am335x-avoid-freqsel.patch)0
-rw-r--r--patches/linux-3.8.13/0105-ARM-OMAP2-clock-DEFINE_STRUCT_CLK_FLAGS-helper.patch (renamed from patches/linux-3.8.4/0096-ARM-OMAP2-clock-DEFINE_STRUCT_CLK_FLAGS-helper.patch)0
-rw-r--r--patches/linux-3.8.13/0106-ARM-AM33XX-clock-SET_RATE_PARENT-in-lcd-path.patch (renamed from patches/linux-3.8.4/0097-ARM-AM33XX-clock-SET_RATE_PARENT-in-lcd-path.patch)0
-rw-r--r--patches/linux-3.8.13/0107-video-da8xx-fb-make-io-operations-safe.patch (renamed from patches/linux-3.8.4/0098-video-da8xx-fb-make-io-operations-safe.patch)0
-rw-r--r--patches/linux-3.8.13/0108-video-da8xx-fb-fix-24bpp-raster-configuration.patch (renamed from patches/linux-3.8.4/0099-video-da8xx-fb-fix-24bpp-raster-configuration.patch)0
-rw-r--r--patches/linux-3.8.13/0109-video-da8xx-fb-enable-sync-lost-intr-for-v2-ip.patch (renamed from patches/linux-3.8.4/0100-video-da8xx-fb-enable-sync-lost-intr-for-v2-ip.patch)0
-rw-r--r--patches/linux-3.8.13/0110-video-da8xx-fb-use-devres.patch (renamed from patches/linux-3.8.4/0101-video-da8xx-fb-use-devres.patch)0
-rw-r--r--patches/linux-3.8.13/0111-video-da8xx-fb-ensure-non-null-cfg-in-pdata.patch (renamed from patches/linux-3.8.4/0102-video-da8xx-fb-ensure-non-null-cfg-in-pdata.patch)0
-rw-r--r--patches/linux-3.8.13/0112-video-da8xx-fb-reorganize-panel-detection.patch (renamed from patches/linux-3.8.4/0103-video-da8xx-fb-reorganize-panel-detection.patch)0
-rw-r--r--patches/linux-3.8.13/0113-video-da8xx-fb-minimal-dt-support.patch (renamed from patches/linux-3.8.4/0104-video-da8xx-fb-minimal-dt-support.patch)0
-rw-r--r--patches/linux-3.8.13/0114-video-da8xx-fb-invoke-platform-callback-safely.patch (renamed from patches/linux-3.8.4/0105-video-da8xx-fb-invoke-platform-callback-safely.patch)0
-rw-r--r--patches/linux-3.8.13/0115-video-da8xx-fb-obtain-fb_videomode-info-from-dt.patch (renamed from patches/linux-3.8.4/0106-video-da8xx-fb-obtain-fb_videomode-info-from-dt.patch)0
-rw-r--r--patches/linux-3.8.13/0116-video-da8xx-fb-ensure-pdata-only-for-non-dt.patch (renamed from patches/linux-3.8.4/0107-video-da8xx-fb-ensure-pdata-only-for-non-dt.patch)0
-rw-r--r--patches/linux-3.8.13/0117-video-da8xx-fb-setup-struct-lcd_ctrl_config-for-dt.patch (renamed from patches/linux-3.8.4/0108-video-da8xx-fb-setup-struct-lcd_ctrl_config-for-dt.patch)0
-rw-r--r--patches/linux-3.8.13/0118-video-da8xx-fb-CCF-clock-divider-handling.patch (renamed from patches/linux-3.8.4/0109-video-da8xx-fb-CCF-clock-divider-handling.patch)0
-rw-r--r--patches/linux-3.8.13/0119-pwm_backlight-Add-device-tree-support-for-Low-Thresh.patch (renamed from patches/linux-3.8.4/0110-pwm_backlight-Add-device-tree-support-for-Low-Thresh.patch)0
-rw-r--r--patches/linux-3.8.13/0120-Control-module-EHRPWM-clk-enabling.patch (renamed from patches/linux-3.8.4/0111-Control-module-EHRPWM-clk-enabling.patch)0
-rw-r--r--patches/linux-3.8.13/0121-pwm-pwm_test-Driver-support-for-PWM-module-testing.patch (renamed from patches/linux-3.8.4/0112-pwm-pwm_test-Driver-support-for-PWM-module-testing.patch)0
-rw-r--r--patches/linux-3.8.13/0122-ARM-OMAP2-PWM-limit-am33xx_register_ehrpwm-to-soc_is.patch (renamed from patches/linux-3.8.4/0113-ARM-OMAP2-PWM-limit-am33xx_register_ehrpwm-to-soc_is.patch)0
-rw-r--r--patches/linux-3.8.13/0123-pwm-export-of_pwm_request.patch (renamed from patches/linux-3.8.4/0114-pwm-export-of_pwm_request.patch)0
-rw-r--r--patches/linux-3.8.13/0124-pwm-pwm-tiehrpwm-Update-the-clock-handling-of-pwm-ti.patch (renamed from patches/linux-3.8.4/0115-pwm-pwm-tiehrpwm-Update-the-clock-handling-of-pwm-ti.patch)0
-rw-r--r--patches/linux-3.8.13/0125-ARM-AM33XX-clk-Add-clock-node-for-EHRPWM-TBCLK.patch (renamed from patches/linux-3.8.4/0116-ARM-AM33XX-clk-Add-clock-node-for-EHRPWM-TBCLK.patch)0
-rw-r--r--patches/linux-3.8.13/0126-HACK-am33xx.dtsi-turn-on-all-PWMs.patch (renamed from patches/linux-3.8.4/0117-HACK-am33xx.dtsi-turn-on-all-PWMs.patch)0
-rw-r--r--patches/linux-3.8.13/0127-pwm-add-sysfs-interface.patch790
-rw-r--r--patches/linux-3.8.13/0128-am33xx.dtsi-enable-MMC-HSPE-bit-for-all-3-controller.patch (renamed from patches/linux-3.8.4/0118-am33xx.dtsi-enable-MMC-HSPE-bit-for-all-3-controller.patch)0
-rw-r--r--patches/linux-3.8.13/0129-omap-hsmmc-Correct-usage-of-of_find_node_by_name.patch (renamed from patches/linux-3.8.4/0119-omap-hsmmc-Correct-usage-of-of_find_node_by_name.patch)0
-rw-r--r--patches/linux-3.8.13/0130-ARM-OMAP2xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch (renamed from patches/linux-3.8.4/0120-ARM-OMAP2xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch)0
-rw-r--r--patches/linux-3.8.13/0131-ARM-OMAP2xxx-hwmod-Add-DMA-support-for-SHAM-module.patch (renamed from patches/linux-3.8.4/0121-ARM-OMAP2xxx-hwmod-Add-DMA-support-for-SHAM-module.patch)0
-rw-r--r--patches/linux-3.8.13/0132-ARM-OMAP3xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch (renamed from patches/linux-3.8.4/0122-ARM-OMAP3xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch)2
-rw-r--r--patches/linux-3.8.13/0133-ARM-OMAP2-Remove-unnecessary-message-when-no-SHA-IP-.patch (renamed from patches/linux-3.8.4/0123-ARM-OMAP2-Remove-unnecessary-message-when-no-SHA-IP-.patch)0
-rw-r--r--patches/linux-3.8.13/0134-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch (renamed from patches/linux-3.8.4/0124-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch)0
-rw-r--r--patches/linux-3.8.13/0135-ARM-AM33XX-Add-sha0-crypto-clock-data.patch (renamed from patches/linux-3.8.4/0125-ARM-AM33XX-Add-sha0-crypto-clock-data.patch)0
-rw-r--r--patches/linux-3.8.13/0136-ARM-AM33XX-hwmod-Update-and-uncomment-SHA0-module-da.patch (renamed from patches/linux-3.8.4/0126-ARM-AM33XX-hwmod-Update-and-uncomment-SHA0-module-da.patch)0
-rw-r--r--patches/linux-3.8.13/0137-ARM-dts-Add-SHAM-data-and-documentation-for-AM33XX.patch (renamed from patches/linux-3.8.4/0127-ARM-dts-Add-SHAM-data-and-documentation-for-AM33XX.patch)2
-rw-r--r--patches/linux-3.8.13/0138-ARM-OMAP2xxx-hwmod-Convert-AES-crypto-devcie-data-to.patch (renamed from patches/linux-3.8.4/0128-ARM-OMAP2xxx-hwmod-Convert-AES-crypto-devcie-data-to.patch)2
-rw-r--r--patches/linux-3.8.13/0139-ARM-OMAP3xxx-hwmod-Convert-AES-crypto-device-data-to.patch (renamed from patches/linux-3.8.4/0129-ARM-OMAP3xxx-hwmod-Convert-AES-crypto-device-data-to.patch)2
-rw-r--r--patches/linux-3.8.13/0140-ARM-OMAP2-Remove-unnecessary-message-when-no-AES-IP-.patch (renamed from patches/linux-3.8.4/0130-ARM-OMAP2-Remove-unnecessary-message-when-no-AES-IP-.patch)0
-rw-r--r--patches/linux-3.8.13/0141-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch (renamed from patches/linux-3.8.4/0131-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch)0
-rw-r--r--patches/linux-3.8.13/0142-ARM-AM33XX-Add-aes0-crypto-clock-data.patch (renamed from patches/linux-3.8.4/0132-ARM-AM33XX-Add-aes0-crypto-clock-data.patch)0
-rw-r--r--patches/linux-3.8.13/0143-ARM-AM33XX-hwmod-Update-and-uncomment-AES0-module-da.patch (renamed from patches/linux-3.8.4/0133-ARM-AM33XX-hwmod-Update-and-uncomment-AES0-module-da.patch)0
-rw-r--r--patches/linux-3.8.13/0144-ARM-dts-Add-AES-data-and-documentation-for-AM33XX.patch (renamed from patches/linux-3.8.4/0134-ARM-dts-Add-AES-data-and-documentation-for-AM33XX.patch)2
-rw-r--r--patches/linux-3.8.13/0145-crypto-omap-sham-Remove-unnecessary-pr_info-noise.patch (renamed from patches/linux-3.8.4/0135-crypto-omap-sham-Remove-unnecessary-pr_info-noise.patch)0
-rw-r--r--patches/linux-3.8.13/0146-crypto-omap-sham-Convert-to-use-pm_runtime-API.patch (renamed from patches/linux-3.8.4/0136-crypto-omap-sham-Convert-to-use-pm_runtime-API.patch)0
-rw-r--r--patches/linux-3.8.13/0147-crypto-omap-sham-Add-suspend-resume-support.patch (renamed from patches/linux-3.8.4/0137-crypto-omap-sham-Add-suspend-resume-support.patch)0
-rw-r--r--patches/linux-3.8.13/0148-crypto-omap-sham-Add-code-to-use-dmaengine-API.patch (renamed from patches/linux-3.8.4/0138-crypto-omap-sham-Add-code-to-use-dmaengine-API.patch)0
-rw-r--r--patches/linux-3.8.13/0149-crypto-omap-sham-Remove-usage-of-private-DMA-API.patch (renamed from patches/linux-3.8.4/0139-crypto-omap-sham-Remove-usage-of-private-DMA-API.patch)0
-rw-r--r--patches/linux-3.8.13/0150-crypto-omap-sham-Add-Device-Tree-Support.patch (renamed from patches/linux-3.8.4/0140-crypto-omap-sham-Add-Device-Tree-Support.patch)0
-rw-r--r--patches/linux-3.8.13/0151-crypto-omap-sham-Convert-to-dma_request_slave_channe.patch (renamed from patches/linux-3.8.4/0141-crypto-omap-sham-Convert-to-dma_request_slave_channe.patch)0
-rw-r--r--patches/linux-3.8.13/0152-crypto-omap-sham-Add-OMAP4-AM33XX-SHAM-Support.patch (renamed from patches/linux-3.8.4/0142-crypto-omap-sham-Add-OMAP4-AM33XX-SHAM-Support.patch)0
-rw-r--r--patches/linux-3.8.13/0153-crypto-omap-sham-Add-SHA224-and-SHA256-Support.patch (renamed from patches/linux-3.8.4/0143-crypto-omap-sham-Add-SHA224-and-SHA256-Support.patch)0
-rw-r--r--patches/linux-3.8.13/0154-crypto-omap-aes-Remmove-unnecessary-pr_info-noise.patch (renamed from patches/linux-3.8.4/0144-crypto-omap-aes-Remmove-unnecessary-pr_info-noise.patch)0
-rw-r--r--patches/linux-3.8.13/0155-crypto-omap-aes-Don-t-reset-controller-for-every-ope.patch (renamed from patches/linux-3.8.4/0145-crypto-omap-aes-Don-t-reset-controller-for-every-ope.patch)0
-rw-r--r--patches/linux-3.8.13/0156-crypto-omap-aes-Convert-to-use-pm_runtime-API.patch (renamed from patches/linux-3.8.4/0146-crypto-omap-aes-Convert-to-use-pm_runtime-API.patch)0
-rw-r--r--patches/linux-3.8.13/0157-crypto-omap-aes-Add-suspend-resume-support.patch (renamed from patches/linux-3.8.4/0147-crypto-omap-aes-Add-suspend-resume-support.patch)0
-rw-r--r--patches/linux-3.8.13/0158-crypto-omap-aes-Add-code-to-use-dmaengine-API.patch (renamed from patches/linux-3.8.4/0148-crypto-omap-aes-Add-code-to-use-dmaengine-API.patch)0
-rw-r--r--patches/linux-3.8.13/0159-crypto-omap-aes-Remove-usage-of-private-DMA-API.patch (renamed from patches/linux-3.8.4/0149-crypto-omap-aes-Remove-usage-of-private-DMA-API.patch)0
-rw-r--r--patches/linux-3.8.13/0160-crypto-omap-aes-Add-Device-Tree-Support.patch (renamed from patches/linux-3.8.4/0150-crypto-omap-aes-Add-Device-Tree-Support.patch)0
-rw-r--r--patches/linux-3.8.13/0161-crypto-omap-aes-Convert-to-dma_request_slave_channel.patch (renamed from patches/linux-3.8.4/0151-crypto-omap-aes-Convert-to-dma_request_slave_channel.patch)0
-rw-r--r--patches/linux-3.8.13/0162-crypto-omap-aes-Add-OMAP4-AM33XX-AES-Support.patch (renamed from patches/linux-3.8.4/0152-crypto-omap-aes-Add-OMAP4-AM33XX-AES-Support.patch)0
-rw-r--r--patches/linux-3.8.13/0163-crypto-omap-aes-Add-CTR-algorithm-Support.patch (renamed from patches/linux-3.8.4/0153-crypto-omap-aes-Add-CTR-algorithm-Support.patch)0
-rw-r--r--patches/linux-3.8.13/0164-6lowpan-Refactor-packet-delivery-into-a-function.patch72
-rw-r--r--patches/linux-3.8.13/0165-6lowpan-Handle-uncompressed-IPv6-packets-over-6LoWPA.patch68
-rw-r--r--patches/linux-3.8.13/0166-wpan-whitespace-fix.patch23
-rw-r--r--patches/linux-3.8.13/0167-6lowpan-use-stack-buffer-instead-of-heap.patch50
-rw-r--r--patches/linux-3.8.13/0168-wpan-use-stack-buffer-instead-of-heap.patch43
-rw-r--r--patches/linux-3.8.13/0169-mrf24j40-pinctrl-support.patch43
-rw-r--r--patches/linux-3.8.13/0170-mrf24j40-Warn-if-transmit-interrupts-timeout.patch23
-rw-r--r--patches/linux-3.8.13/0171-mrf24j40-Increase-max-SPI-speed-to-10MHz.patch28
-rw-r--r--patches/linux-3.8.13/0172-mrf24j40-Fix-byte-order-of-IEEE-address.patch25
-rw-r--r--patches/linux-3.8.13/0173-6lowpan-lowpan_is_iid_16_bit_compressable-does-not-d.patch (renamed from patches/linux-3.8.4/0154-6lowpan-lowpan_is_iid_16_bit_compressable-does-not-d.patch)25
-rw-r--r--patches/linux-3.8.13/0174-6lowpan-next-header-is-not-properly-set-upon-decompr.patch (renamed from patches/linux-3.8.4/0155-6lowpan-next-header-is-not-properly-set-upon-decompr.patch)11
-rw-r--r--patches/linux-3.8.13/0175-6lowpan-always-enable-link-layer-acknowledgments.patch (renamed from patches/linux-3.8.4/0156-6lowpan-always-enable-link-layer-acknowledgments.patch)12
-rw-r--r--patches/linux-3.8.13/0176-mac802154-turn-on-ACK-when-enabled-by-the-upper-laye.patch (renamed from patches/linux-3.8.4/0157-mac802154-turn-on-ACK-when-enabled-by-the-upper-laye.patch)6
-rw-r--r--patches/linux-3.8.13/0177-6lowpan-use-short-IEEE-802.15.4-addresses-for-broadc.patch (renamed from patches/linux-3.8.4/0158-6lowpan-use-short-IEEE-802.15.4-addresses-for-broadc.patch)20
-rw-r--r--patches/linux-3.8.13/0178-6lowpan-fix-first-fragment-FRAG1-handling.patch (renamed from patches/linux-3.8.4/0159-6lowpan-fix-first-fragment-FRAG1-handling.patch)83
-rw-r--r--patches/linux-3.8.13/0179-6lowpan-add-debug-messages-for-6LoWPAN-fragmentation.patch80
-rw-r--r--patches/linux-3.8.13/0180-6lowpan-store-fragment-tag-values-per-device-instead.patch (renamed from patches/linux-3.8.4/0160-6lowpan-store-fragment-tag-values-per-device-instead.patch)10
-rw-r--r--patches/linux-3.8.13/0181-mac802154-add-mac802154_dev_get_dsn.patch57
-rw-r--r--patches/linux-3.8.13/0182-6lowpan-obtain-IEEE802.15.4-sequence-number-from-the.patch (renamed from patches/linux-3.8.4/0161-6lowpan-obtain-IEEE802.15.4-sequence-number-from-the.patch)15
-rw-r--r--patches/linux-3.8.13/0183-6lowpan-use-the-PANID-provided-by-the-device-instead.patch (renamed from patches/linux-3.8.4/0163-6lowpan-use-the-PANID-provided-by-the-device-instead.patch)12
-rw-r--r--patches/linux-3.8.13/0184-6lowpan-modify-udp-compression-uncompression-to-matc.patch (renamed from patches/linux-3.8.4/0164-6lowpan-modify-udp-compression-uncompression-to-matc.patch)39
-rw-r--r--patches/linux-3.8.13/0185-6lowpan-fix-a-small-formatting-issue.patch25
-rw-r--r--patches/linux-3.8.13/0186-6lowpan-use-IEEE802154_ADDR_LEN-instead-of-a-magic-n.patch22
-rw-r--r--patches/linux-3.8.13/0187-gpio-keys-Pinctrl-fy.patch (renamed from patches/linux-3.8.4/0170-gpio-keys-Pinctrl-fy.patch)0
-rw-r--r--patches/linux-3.8.13/0188-tps65217-Allow-placement-elsewhere-than-parent-mfd-d.patch (renamed from patches/linux-3.8.4/0171-tps65217-Allow-placement-elsewhere-than-parent-mfd-d.patch)0
-rw-r--r--patches/linux-3.8.13/0189-pwm-backlight-Pinctrl-fy.patch (renamed from patches/linux-3.8.4/0172-pwm-backlight-Pinctrl-fy.patch)0
-rw-r--r--patches/linux-3.8.13/0190-ARM-CUSTOM-Build-a-uImage-with-dtb-already-appended.patch (renamed from patches/linux-3.8.4/0173-ARM-CUSTOM-Build-a-uImage-with-dtb-already-appended.patch)0
-rw-r--r--patches/linux-3.8.13/0191-beaglebone-create-a-shared-dtsi-for-beaglebone-based.patch (renamed from patches/linux-3.8.4/0174-beaglebone-create-a-shared-dtsi-for-beaglebone-based.patch)0
-rw-r--r--patches/linux-3.8.13/0192-beaglebone-enable-emmc-for-bonelt.patch (renamed from patches/linux-3.8.4/0175-beaglebone-enable-emmc-for-bonelt.patch)0
-rw-r--r--patches/linux-3.8.13/0193-Fix-appended-dtb-rule.patch (renamed from patches/linux-3.8.4/0176-Fix-appended-dtb-rule.patch)0
-rw-r--r--patches/linux-3.8.13/0194-deb-pkg-Simplify-architecture-matching-for-cross-bui.patch (renamed from patches/linux-3.8.4/0177-deb-pkg-Simplify-architecture-matching-for-cross-bui.patch)0
-rw-r--r--patches/linux-3.8.13/0195-Without-MACH_-option-Early-printk-DEBUG_LL.patch (renamed from patches/linux-3.8.4/0178-Without-MACH_-option-Early-printk-DEBUG_LL.patch)0
-rw-r--r--patches/linux-3.8.13/0196-ARM-7668-1-fix-memset-related-crashes-caused-by-rece.patch252
-rw-r--r--patches/linux-3.8.13/0197-ARM-7670-1-fix-the-memset-fix.patch79
-rw-r--r--patches/linux-3.8.13/0198-regulator-core-if-voltage-scaling-fails-restore-orig.patch (renamed from patches/linux-3.8.4/0179-regulator-core-if-voltage-scaling-fails-restore-orig.patch)2
-rw-r--r--patches/linux-3.8.13/0199-omap2-twl-common-Add-default-power-configuration.patch (renamed from patches/linux-3.8.4/0180-omap2-twl-common-Add-default-power-configuration.patch)0
-rw-r--r--patches/linux-3.8.13/0200-omap2-irq-fix-interrupt-latency.patch22
-rw-r--r--patches/linux-3.8.13/0201-OMAP-DSS2-add-bootarg-for-selecting-svideo.patch (renamed from patches/linux-3.8.4/0181-OMAP-DSS2-add-bootarg-for-selecting-svideo.patch)0
-rw-r--r--patches/linux-3.8.13/0202-video-add-timings-for-hd720.patch (renamed from patches/linux-3.8.4/0182-video-add-timings-for-hd720.patch)0
-rw-r--r--patches/linux-3.8.13/0203-Beagle-expansion-add-buddy-param-for-expansionboard-.patch (renamed from patches/linux-3.8.4/0183-Beagle-expansion-add-buddy-param-for-expansionboard-.patch)0
-rw-r--r--patches/linux-3.8.13/0204-Beagle-expansion-add-zippy.patch (renamed from patches/linux-3.8.4/0184-Beagle-expansion-add-zippy.patch)0
-rw-r--r--patches/linux-3.8.13/0205-Beagle-expansion-add-zippy2.patch (renamed from patches/linux-3.8.4/0185-Beagle-expansion-add-zippy2.patch)0
-rw-r--r--patches/linux-3.8.13/0206-Beagle-expansion-add-trainer.patch (renamed from patches/linux-3.8.4/0186-Beagle-expansion-add-trainer.patch)0
-rw-r--r--patches/linux-3.8.13/0207-Beagle-expansion-add-CircuitCo-ulcd-Support.patch (renamed from patches/linux-3.8.4/0187-Beagle-expansion-add-CircuitCo-ulcd-Support.patch)0
-rw-r--r--patches/linux-3.8.13/0208-Beagle-expansion-add-wifi.patch (renamed from patches/linux-3.8.4/0188-Beagle-expansion-add-wifi.patch)0
-rw-r--r--patches/linux-3.8.13/0209-Beagle-expansion-add-beaglefpga.patch (renamed from patches/linux-3.8.4/0189-Beagle-expansion-add-beaglefpga.patch)0
-rw-r--r--patches/linux-3.8.13/0210-Beagle-expansion-add-spidev.patch (renamed from patches/linux-3.8.4/0190-Beagle-expansion-add-spidev.patch)0
-rw-r--r--patches/linux-3.8.13/0211-Beagle-expansion-add-Aptina-li5m03-camera.patch (renamed from patches/linux-3.8.4/0191-Beagle-expansion-add-Aptina-li5m03-camera.patch)0
-rw-r--r--patches/linux-3.8.13/0212-Beagle-expansion-add-LSR-COM6L-Adapter-Board.patch (renamed from patches/linux-3.8.4/0192-Beagle-expansion-add-LSR-COM6L-Adapter-Board.patch)0
-rw-r--r--patches/linux-3.8.13/0213-meego-modedb-add-Toshiba-LTA070B220F-800x480-support.patch (renamed from patches/linux-3.8.4/0193-meego-modedb-add-Toshiba-LTA070B220F-800x480-support.patch)0
-rw-r--r--patches/linux-3.8.13/0214-backlight-Add-TLC59108-backlight-control-driver.patch (renamed from patches/linux-3.8.4/0194-backlight-Add-TLC59108-backlight-control-driver.patch)0
-rw-r--r--patches/linux-3.8.13/0215-tlc59108-adjust-for-beagleboard-uLCD7.patch (renamed from patches/linux-3.8.4/0195-tlc59108-adjust-for-beagleboard-uLCD7.patch)0
-rw-r--r--patches/linux-3.8.13/0216-zeroMAP-Open-your-eyes.patch (renamed from patches/linux-3.8.4/0196-zeroMAP-Open-your-eyes.patch)0
-rw-r--r--patches/linux-3.8.13/0217-ARM-OMAP-Beagle-use-TWL4030-generic-reset-script.patch (renamed from patches/linux-3.8.4/0197-ARM-OMAP-Beagle-use-TWL4030-generic-reset-script.patch)0
-rw-r--r--patches/linux-3.8.13/0218-panda-fix-wl12xx-regulator.patch23
-rw-r--r--patches/linux-3.8.13/0219-ti-st-st-kim-fixing-firmware-path.patch32
-rw-r--r--patches/linux-3.8.13/0220-am33xx-cpsw-default-to-ethernet-hwaddr-from-efuse-if.patch (renamed from patches/linux-3.8.4/0198-am33xx-cpsw-default-to-ethernet-hwaddr-from-efuse-if.patch)0
-rw-r--r--patches/linux-3.8.13/0221-Attempted-SMC911x-BQL-patch.patch (renamed from patches/linux-3.8.4/0199-Attempted-SMC911x-BQL-patch.patch)0
-rw-r--r--patches/linux-3.8.13/0222-cpsw-Fix-interrupt-storm-among-other-things.patch (renamed from patches/linux-3.8.4/0200-cpsw-Fix-interrupt-storm-among-other-things.patch)2
-rw-r--r--patches/linux-3.8.13/0223-beaglebone-TT3201-MCP2515-fixes.patch162
-rw-r--r--patches/linux-3.8.13/0224-add-proper-db.txt-for-CRDA.patch830
-rw-r--r--patches/linux-3.8.13/0225-mcp251x-add-device-tree-support.patch349
-rw-r--r--patches/linux-3.8.13/0226-am33xx-Add-clock-for-the-lcdc-DRM-driver.patch (renamed from patches/linux-3.8.4/0201-am33xx-Add-clock-for-the-lcdc-DRM-driver.patch)0
-rw-r--r--patches/linux-3.8.13/0227-drm-small-fix-in-drm_send_vblank_event.patch (renamed from patches/linux-3.8.4/0202-drm-small-fix-in-drm_send_vblank_event.patch)0
-rw-r--r--patches/linux-3.8.13/0228-drm-cma-add-debugfs-helpers.patch (renamed from patches/linux-3.8.4/0203-drm-cma-add-debugfs-helpers.patch)0
-rw-r--r--patches/linux-3.8.13/0229-drm-i2c-encoder-helper-wrappers.patch (renamed from patches/linux-3.8.4/0204-drm-i2c-encoder-helper-wrappers.patch)0
-rw-r--r--patches/linux-3.8.13/0230-drm-nouveau-use-i2c-encoder-helper-wrappers.patch (renamed from patches/linux-3.8.4/0205-drm-nouveau-use-i2c-encoder-helper-wrappers.patch)0
-rw-r--r--patches/linux-3.8.13/0231-drm-i2c-give-i2c-it-s-own-Kconfig.patch (renamed from patches/linux-3.8.4/0206-drm-i2c-give-i2c-it-s-own-Kconfig.patch)0
-rw-r--r--patches/linux-3.8.13/0232-drm-tilcdc-add-TI-LCD-Controller-DRM-driver-v4.patch (renamed from patches/linux-3.8.4/0207-drm-tilcdc-add-TI-LCD-Controller-DRM-driver-v4.patch)0
-rw-r--r--patches/linux-3.8.13/0233-drm-i2c-nxp-tda998x-v3.patch (renamed from patches/linux-3.8.4/0208-drm-i2c-nxp-tda998x-v3.patch)0
-rw-r--r--patches/linux-3.8.13/0234-drm-tilcdc-add-encoder-slave.patch (renamed from patches/linux-3.8.4/0209-drm-tilcdc-add-encoder-slave.patch)0
-rw-r--r--patches/linux-3.8.13/0235-drm-tilcdc-add-support-for-LCD-panels-v5.patch (renamed from patches/linux-3.8.4/0210-drm-tilcdc-add-support-for-LCD-panels-v5.patch)0
-rw-r--r--patches/linux-3.8.13/0236-drm-lcdc-Power-control-GPIO-support.patch (renamed from patches/linux-3.8.4/0211-drm-lcdc-Power-control-GPIO-support.patch)0
-rw-r--r--patches/linux-3.8.13/0237-drm-tilcdc-Fix-scheduling-while-atomic-from-irq-hand.patch53
-rw-r--r--patches/linux-3.8.13/0238-add-dvi-pinmuxes-to-am33xx.dtsi.patch (renamed from patches/linux-3.8.4/0212-add-dvi-pinmuxes-to-am33xx.dtsi.patch)0
-rw-r--r--patches/linux-3.8.13/0239-add-defconfig-file-to-use-as-.config.patch (renamed from patches/linux-3.8.4/0213-add-defconfig-file-to-use-as-.config.patch)0
-rw-r--r--patches/linux-3.8.13/0240-am33xx-musb-Add-OF-definitions.patch (renamed from patches/linux-3.8.4/0214-am33xx-musb-Add-OF-definitions.patch)0
-rw-r--r--patches/linux-3.8.13/0241-Mark-the-device-as-PRIVATE.patch (renamed from patches/linux-3.8.4/0215-Mark-the-device-as-PRIVATE.patch)0
-rw-r--r--patches/linux-3.8.13/0242-omap_hsmmc-Bug-fixes-pinctl-gpio-reset.patch (renamed from patches/linux-3.8.4/0216-omap_hsmmc-Bug-fixes-pinctl-gpio-reset.patch)0
-rw-r--r--patches/linux-3.8.13/0243-tps65217-bl-Locate-backlight-node-correctly.patch (renamed from patches/linux-3.8.4/0217-tps65217-bl-Locate-backlight-node-correctly.patch)0
-rw-r--r--patches/linux-3.8.13/0244-arm-Export-cache-flush-management-symbols-when-MULTI.patch (renamed from patches/linux-3.8.4/0218-arm-Export-cache-flush-management-symbols-when-MULTI.patch)0
-rw-r--r--patches/linux-3.8.13/0245-am335x-bone-dtsi-Clean-up.patch (renamed from patches/linux-3.8.4/0219-am335x-bone-dtsi-Clean-up.patch)0
-rw-r--r--patches/linux-3.8.13/0246-am335x-bone-dtsi-Introduce-new-I2C-entries.patch (renamed from patches/linux-3.8.4/0220-am335x-bone-dtsi-Introduce-new-I2C-entries.patch)0
-rw-r--r--patches/linux-3.8.13/0247-am335x-dt-Add-I2C0-pinctrl-entries.patch (renamed from patches/linux-3.8.4/0221-am335x-dt-Add-I2C0-pinctrl-entries.patch)0
-rw-r--r--patches/linux-3.8.13/0248-Cleanup-am33xx.dtsi.patch (renamed from patches/linux-3.8.4/0222-Cleanup-am33xx.dtsi.patch)0
-rw-r--r--patches/linux-3.8.13/0249-Fix-platform-device-resource-linking.patch (renamed from patches/linux-3.8.4/0223-Fix-platform-device-resource-linking.patch)0
-rw-r--r--patches/linux-3.8.13/0250-Link-platform-device-resources-properly.patch (renamed from patches/linux-3.8.4/0224-Link-platform-device-resources-properly.patch)0
-rw-r--r--patches/linux-3.8.13/0251-Properly-handle-resources-for-omap_devices.patch (renamed from patches/linux-3.8.4/0225-Properly-handle-resources-for-omap_devices.patch)0
-rw-r--r--patches/linux-3.8.13/0252-omap-Avoid-crashes-in-the-case-of-hwmod-misconfigura.patch (renamed from patches/linux-3.8.4/0226-omap-Avoid-crashes-in-the-case-of-hwmod-misconfigura.patch)0
-rw-r--r--patches/linux-3.8.13/0253-i2c-EEPROM-In-kernel-memory-accessor-interface.patch (renamed from patches/linux-3.8.4/0227-i2c-EEPROM-In-kernel-memory-accessor-interface.patch)0
-rw-r--r--patches/linux-3.8.13/0254-Fix-util_is_printable_string.patch (renamed from patches/linux-3.8.4/0228-Fix-util_is_printable_string.patch)0
-rw-r--r--patches/linux-3.8.13/0255-fdtdump-properly-handle-multi-string-properties.patch (renamed from patches/linux-3.8.4/0229-fdtdump-properly-handle-multi-string-properties.patch)0
-rw-r--r--patches/linux-3.8.13/0256-dtc-Dynamic-symbols-fixup-support.patch (renamed from patches/linux-3.8.4/0230-dtc-Dynamic-symbols-fixup-support.patch)0
-rw-r--r--patches/linux-3.8.13/0257-dtc-Add-DTCO-rule-for-DTB-objects.patch (renamed from patches/linux-3.8.4/0231-dtc-Add-DTCO-rule-for-DTB-objects.patch)0
-rw-r--r--patches/linux-3.8.13/0258-OF-Compile-Device-Tree-sources-with-resolve-option.patch (renamed from patches/linux-3.8.4/0232-OF-Compile-Device-Tree-sources-with-resolve-option.patch)0
-rw-r--r--patches/linux-3.8.13/0259-firmware-update-.gitignore-with-dtbo-objects.patch (renamed from patches/linux-3.8.4/0233-firmware-update-.gitignore-with-dtbo-objects.patch)0
-rw-r--r--patches/linux-3.8.13/0260-OF-Introduce-device-tree-node-flag-helpers.patch (renamed from patches/linux-3.8.4/0234-OF-Introduce-device-tree-node-flag-helpers.patch)0
-rw-r--r--patches/linux-3.8.13/0261-OF-export-of_property_notify.patch (renamed from patches/linux-3.8.4/0235-OF-export-of_property_notify.patch)0
-rw-r--r--patches/linux-3.8.13/0262-OF-Export-all-DT-proc-update-functions.patch (renamed from patches/linux-3.8.4/0236-OF-Export-all-DT-proc-update-functions.patch)0
-rw-r--r--patches/linux-3.8.13/0263-OF-Introduce-utility-helper-functions.patch (renamed from patches/linux-3.8.4/0237-OF-Introduce-utility-helper-functions.patch)0
-rw-r--r--patches/linux-3.8.13/0264-OF-Introduce-Device-Tree-resolve-support.patch (renamed from patches/linux-3.8.4/0238-OF-Introduce-Device-Tree-resolve-support.patch)0
-rw-r--r--patches/linux-3.8.13/0265-OF-Introduce-DT-overlay-support.patch (renamed from patches/linux-3.8.4/0239-OF-Introduce-DT-overlay-support.patch)0
-rw-r--r--patches/linux-3.8.13/0266-capemgr-Capemgr-makefiles-and-Kconfig-fragments.patch (renamed from patches/linux-3.8.4/0240-capemgr-Capemgr-makefiles-and-Kconfig-fragments.patch)0
-rw-r--r--patches/linux-3.8.13/0267-capemgr-Beaglebone-capemanager.patch (renamed from patches/linux-3.8.4/0241-capemgr-Beaglebone-capemanager.patch)0
-rw-r--r--patches/linux-3.8.13/0268-capemgr-Add-beaglebone-s-cape-driver-bindings.patch (renamed from patches/linux-3.8.4/0242-capemgr-Add-beaglebone-s-cape-driver-bindings.patch)0
-rw-r--r--patches/linux-3.8.13/0269-capemgr-am33xx-family-DT-bindings.patch (renamed from patches/linux-3.8.4/0243-capemgr-am33xx-family-DT-bindings.patch)0
-rw-r--r--patches/linux-3.8.13/0270-bone-geiger-Geiger-bone-driver.patch (renamed from patches/linux-3.8.4/0244-bone-geiger-Geiger-bone-driver.patch)0
-rw-r--r--patches/linux-3.8.13/0271-capemgr-firmware-makefiles-for-DT-objects.patch (renamed from patches/linux-3.8.4/0245-capemgr-firmware-makefiles-for-DT-objects.patch)0
-rw-r--r--patches/linux-3.8.13/0272-capemgr-emmc2-cape-definition.patch (renamed from patches/linux-3.8.4/0246-capemgr-emmc2-cape-definition.patch)0
-rw-r--r--patches/linux-3.8.13/0273-capemgr-DVI-capes-definitions.patch (renamed from patches/linux-3.8.4/0247-capemgr-DVI-capes-definitions.patch)0
-rw-r--r--patches/linux-3.8.13/0274-capemgr-Geiger-cape-definition.patch (renamed from patches/linux-3.8.4/0248-capemgr-Geiger-cape-definition.patch)4
-rw-r--r--patches/linux-3.8.13/0275-capemgr-LCD3-cape-definition.patch (renamed from patches/linux-3.8.4/0249-capemgr-LCD3-cape-definition.patch)0
-rw-r--r--patches/linux-3.8.13/0276-capemgr-Add-weather-cape-definition.patch (renamed from patches/linux-3.8.4/0250-capemgr-Add-weather-cape-definition.patch)0
-rw-r--r--patches/linux-3.8.13/0277-ehrpwm-add-missing-dts-nodes.patch (renamed from patches/linux-3.8.4/0251-ehrpwm-add-missing-dts-nodes.patch)0
-rw-r--r--patches/linux-3.8.13/0278-am33xx-DT-Update-am33xx.dsi-with-the-new-PWM-DT-bind.patch (renamed from patches/linux-3.8.4/0252-am33xx-DT-Update-am33xx.dsi-with-the-new-PWM-DT-bind.patch)0
-rw-r--r--patches/linux-3.8.13/0279-geiger-cape-Update-to-using-the-new-PWM-interface.patch (renamed from patches/linux-3.8.4/0253-geiger-cape-Update-to-using-the-new-PWM-interface.patch)2
-rw-r--r--patches/linux-3.8.13/0280-lcd3-cape-Change-into-using-the-lcdc-DRM-driver-inst.patch (renamed from patches/linux-3.8.4/0254-lcd3-cape-Change-into-using-the-lcdc-DRM-driver-inst.patch)0
-rw-r--r--patches/linux-3.8.13/0281-am33xx-Add-default-config.patch (renamed from patches/linux-3.8.4/0255-am33xx-Add-default-config.patch)0
-rw-r--r--patches/linux-3.8.13/0282-lcd3-cape-Convert-to-using-the-proper-touchscreen-dr.patch (renamed from patches/linux-3.8.4/0256-lcd3-cape-Convert-to-using-the-proper-touchscreen-dr.patch)4
-rw-r--r--patches/linux-3.8.13/0283-geiger-cape-Convert-to-using-the-new-ADC-driver.patch (renamed from patches/linux-3.8.4/0257-geiger-cape-Convert-to-using-the-new-ADC-driver.patch)6
-rw-r--r--patches/linux-3.8.13/0284-cape-dvi-Convert-DVI-capes-to-the-new-LCDC-DRM-drive.patch (renamed from patches/linux-3.8.4/0258-cape-dvi-Convert-DVI-capes-to-the-new-LCDC-DRM-drive.patch)0
-rw-r--r--patches/linux-3.8.13/0285-boneblack-Add-default-HDMI-cape.patch (renamed from patches/linux-3.8.4/0259-boneblack-Add-default-HDMI-cape.patch)0
-rw-r--r--patches/linux-3.8.13/0286-cape-bone-dvi-Use-720p-mode-as-default.patch (renamed from patches/linux-3.8.4/0260-cape-bone-dvi-Use-720p-mode-as-default.patch)0
-rw-r--r--patches/linux-3.8.13/0287-am33xx.dtsi-Make-the-MUSB-not-crash-on-load.patch (renamed from patches/linux-3.8.4/0261-am33xx.dtsi-Make-the-MUSB-not-crash-on-load.patch)0
-rw-r--r--patches/linux-3.8.13/0288-regulator-DUMMY_REGULATOR-should-work-for-OF-too.patch (renamed from patches/linux-3.8.4/0262-regulator-DUMMY_REGULATOR-should-work-for-OF-too.patch)2
-rw-r--r--patches/linux-3.8.13/0289-OF-Overlay-Remove-excessive-debugging-crud.patch (renamed from patches/linux-3.8.4/0263-OF-Overlay-Remove-excessive-debugging-crud.patch)0
-rw-r--r--patches/linux-3.8.13/0290-of-i2c-Export-single-device-registration-method.patch (renamed from patches/linux-3.8.4/0264-of-i2c-Export-single-device-registration-method.patch)0
-rw-r--r--patches/linux-3.8.13/0291-OF-Overlay-I2C-client-devices-special-handling.patch (renamed from patches/linux-3.8.4/0265-OF-Overlay-I2C-client-devices-special-handling.patch)0
-rw-r--r--patches/linux-3.8.13/0292-omap-Fix-bug-on-partial-resource-addition.patch (renamed from patches/linux-3.8.4/0266-omap-Fix-bug-on-partial-resource-addition.patch)0
-rw-r--r--patches/linux-3.8.13/0293-ASoC-davinci-mcasp-Add-pinctrl-support.patch (renamed from patches/linux-3.8.4/0267-ASoC-davinci-mcasp-Add-pinctrl-support.patch)0
-rw-r--r--patches/linux-3.8.13/0294-ASoC-Davinci-machine-Add-device-tree-binding.patch (renamed from patches/linux-3.8.4/0268-ASoC-Davinci-machine-Add-device-tree-binding.patch)0
-rw-r--r--patches/linux-3.8.13/0295-am33xx-Add-mcasp0-and-mcasp1-device-tree-entries.patch (renamed from patches/linux-3.8.4/0269-am33xx-Add-mcasp0-and-mcasp1-device-tree-entries.patch)0
-rw-r--r--patches/linux-3.8.13/0296-ASoC-dts-OMAP2-AM33xx-HACK-Add-missing-dma-info.patch (renamed from patches/linux-3.8.4/0270-ASoC-dts-OMAP2-AM33xx-HACK-Add-missing-dma-info.patch)0
-rw-r--r--patches/linux-3.8.13/0297-ASoC-Davinci-McASP-remove-unused-header-include.patch (renamed from patches/linux-3.8.4/0271-ASoC-Davinci-McASP-remove-unused-header-include.patch)0
-rw-r--r--patches/linux-3.8.13/0298-ASoC-AM33XX-Add-support-for-AM33xx-SoC-Audio.patch (renamed from patches/linux-3.8.4/0272-ASoC-AM33XX-Add-support-for-AM33xx-SoC-Audio.patch)0
-rw-r--r--patches/linux-3.8.13/0299-am33xx-mcasp-Add-dma-channel-definitions.patch (renamed from patches/linux-3.8.4/0273-am33xx-mcasp-Add-dma-channel-definitions.patch)0
-rw-r--r--patches/linux-3.8.13/0300-ARM-OMAP2-AM33xx-removed-invalid-McASP-HWMOD-data.patch (renamed from patches/linux-3.8.4/0274-ARM-OMAP2-AM33xx-removed-invalid-McASP-HWMOD-data.patch)0
-rw-r--r--patches/linux-3.8.13/0301-davinci-evm-Header-include-move-fix.patch (renamed from patches/linux-3.8.4/0275-davinci-evm-Header-include-move-fix.patch)0
-rw-r--r--patches/linux-3.8.13/0302-bone-dvi-cape-Add-DT-definition-for-00A2-revision.patch (renamed from patches/linux-3.8.4/0276-bone-dvi-cape-Add-DT-definition-for-00A2-revision.patch)0
-rw-r--r--patches/linux-3.8.13/0303-bone-dvi-cape-Update-A1-cape-definition-with-sound.patch (renamed from patches/linux-3.8.4/0277-bone-dvi-cape-Update-A1-cape-definition-with-sound.patch)0
-rw-r--r--patches/linux-3.8.13/0304-sndsoc-mcasp-Get-DMA-channels-via-byname.patch (renamed from patches/linux-3.8.4/0278-sndsoc-mcasp-Get-DMA-channels-via-byname.patch)0
-rw-r--r--patches/linux-3.8.13/0305-sound-soc-Davinci-Remove-__devinit-__devexit.patch (renamed from patches/linux-3.8.4/0279-sound-soc-Davinci-Remove-__devinit-__devexit.patch)0
-rw-r--r--patches/linux-3.8.13/0306-st7735fb-Remove-__devinit-__devexit.patch (renamed from patches/linux-3.8.4/0280-st7735fb-Remove-__devinit-__devexit.patch)0
-rw-r--r--patches/linux-3.8.13/0307-capemgr-Remove-__devinit-__devexit.patch (renamed from patches/linux-3.8.4/0281-capemgr-Remove-__devinit-__devexit.patch)0
-rw-r--r--patches/linux-3.8.13/0308-capes-fw-target-firmware-directory-change.patch (renamed from patches/linux-3.8.4/0282-capes-fw-target-firmware-directory-change.patch)0
-rw-r--r--patches/linux-3.8.13/0309-am33xx-edma-Always-update-unused-channel-list.patch (renamed from patches/linux-3.8.4/0283-am33xx-edma-Always-update-unused-channel-list.patch)0
-rw-r--r--patches/linux-3.8.13/0310-defconfig-Update-bone-default-config.patch (renamed from patches/linux-3.8.4/0284-defconfig-Update-bone-default-config.patch)0
-rw-r--r--patches/linux-3.8.13/0311-capes-add-dvi-a2-and-lcd3-a2-dts-files.patch (renamed from patches/linux-3.8.4/0285-capes-add-dvi-a2-and-lcd3-a2-dts-files.patch)4
-rw-r--r--patches/linux-3.8.13/0312-capemgr-catch-up-with-lcdc-tilcdc-rename.patch (renamed from patches/linux-3.8.4/0286-capemgr-catch-up-with-lcdc-tilcdc-rename.patch)4
-rw-r--r--patches/linux-3.8.13/0313-firmware-fix-dvi-a1-target.patch (renamed from patches/linux-3.8.4/0287-firmware-fix-dvi-a1-target.patch)0
-rw-r--r--patches/linux-3.8.13/0314-capes-remove-tda-from-hdmi-cape-lcdc-handles-it-by-t.patch (renamed from patches/linux-3.8.4/0288-capes-remove-tda-from-hdmi-cape-lcdc-handles-it-by-t.patch)0
-rw-r--r--patches/linux-3.8.13/0315-tilcdc-magic-debug-statement-makes-power-gpio-work-o.patch (renamed from patches/linux-3.8.4/0289-tilcdc-magic-debug-statement-makes-power-gpio-work-o.patch)0
-rw-r--r--patches/linux-3.8.13/0316-capemgr-add-dts-overlay-for-LCD7-00A2-cape.patch (renamed from patches/linux-3.8.4/0290-capemgr-add-dts-overlay-for-LCD7-00A2-cape.patch)4
-rw-r--r--patches/linux-3.8.13/0317-HACK-am33xx.dtsi-enable-all-PWMs.patch (renamed from patches/linux-3.8.4/0291-HACK-am33xx.dtsi-enable-all-PWMs.patch)0
-rw-r--r--patches/linux-3.8.13/0318-beaglebone-Add-nixie-cape-prototype-driver.patch (renamed from patches/linux-3.8.4/0292-beaglebone-Add-nixie-cape-prototype-driver.patch)0
-rw-r--r--patches/linux-3.8.13/0319-beaglebone-Add-nixie-cape-device-tree-entry.patch (renamed from patches/linux-3.8.4/0293-beaglebone-Add-nixie-cape-device-tree-entry.patch)0
-rw-r--r--patches/linux-3.8.13/0320-am335x-bone-common.dtsi-Cleanup-test-remnants.patch (renamed from patches/linux-3.8.4/0294-am335x-bone-common.dtsi-Cleanup-test-remnants.patch)0
-rw-r--r--patches/linux-3.8.13/0321-omap_hsmmc-Add-ti-vcc-aux-disable-is-sleep-DT-proper.patch (renamed from patches/linux-3.8.4/0295-omap_hsmmc-Add-ti-vcc-aux-disable-is-sleep-DT-proper.patch)0
-rw-r--r--patches/linux-3.8.13/0322-bone-common-ti-vcc-aux-disable-is-sleep-enable.patch (renamed from patches/linux-3.8.4/0296-bone-common-ti-vcc-aux-disable-is-sleep-enable.patch)0
-rw-r--r--patches/linux-3.8.13/0323-am33xx-disable-NAPI.patch (renamed from patches/linux-3.8.4/0297-am33xx-disable-NAPI.patch)0
-rw-r--r--patches/linux-3.8.13/0324-capemgr-Fixed-AIN-name-display-in-error-message.patch (renamed from patches/linux-3.8.4/0298-capemgr-Fixed-AIN-name-display-in-error-message.patch)0
-rw-r--r--patches/linux-3.8.13/0325-am33xx.dtsi-remove-duplicate-nodes.patch (renamed from patches/linux-3.8.4/0299-am33xx.dtsi-remove-duplicate-nodes.patch)0
-rw-r--r--patches/linux-3.8.13/0326-cape-dtbos-update-to-latest-OF-videomode-bindings.patch (renamed from patches/linux-3.8.4/0300-cape-dtbos-update-to-latest-OF-videomode-bindings.patch)6
-rw-r--r--patches/linux-3.8.13/0327-beaglebone-uncomment-eMMC-override.patch (renamed from patches/linux-3.8.4/0301-beaglebone-uncomment-eMMC-override.patch)0
-rw-r--r--patches/linux-3.8.13/0328-bone-capes-Update-with-new-tscadc-bindings.patch (renamed from patches/linux-3.8.4/0302-bone-capes-Update-with-new-tscadc-bindings.patch)30
-rw-r--r--patches/linux-3.8.13/0329-am33xx.dtsi-Update-and-disable-status-of-nodes.patch (renamed from patches/linux-3.8.4/0303-am33xx.dtsi-Update-and-disable-status-of-nodes.patch)0
-rw-r--r--patches/linux-3.8.13/0330-bone-capes-Adapt-to-new-pwms-setup.patch (renamed from patches/linux-3.8.4/0304-bone-capes-Adapt-to-new-pwms-setup.patch)6
-rw-r--r--patches/linux-3.8.13/0331-tilcdc-introduce-panel-tfp410-power-down-gpio-contro.patch (renamed from patches/linux-3.8.4/0305-tilcdc-introduce-panel-tfp410-power-down-gpio-contro.patch)0
-rw-r--r--patches/linux-3.8.13/0332-bone-dvi-Update-to-new-style-tilcdc-bindings.patch (renamed from patches/linux-3.8.4/0306-bone-dvi-Update-to-new-style-tilcdc-bindings.patch)0
-rw-r--r--patches/linux-3.8.13/0333-tilcdc-tfp410-Rework-power-down-GPIO-logic.patch (renamed from patches/linux-3.8.4/0307-tilcdc-tfp410-Rework-power-down-GPIO-logic.patch)0
-rw-r--r--patches/linux-3.8.13/0334-tilcdc-Add-reduced-blanking-mode-checks.patch (renamed from patches/linux-3.8.4/0308-tilcdc-Add-reduced-blanking-mode-checks.patch)6
-rw-r--r--patches/linux-3.8.13/0335-cape-dvi-Switch-all-DVI-capes-to-using-the-TFTP410-p.patch (renamed from patches/linux-3.8.4/0309-cape-dvi-Switch-all-DVI-capes-to-using-the-TFTP410-p.patch)0
-rw-r--r--patches/linux-3.8.13/0336-beaglebone-switch-eMMC-to-8bit-mode.patch (renamed from patches/linux-3.8.4/0310-beaglebone-switch-eMMC-to-8bit-mode.patch)0
-rw-r--r--patches/linux-3.8.13/0337-Pinmux-helper-driver.patch (renamed from patches/linux-3.8.4/0311-Pinmux-helper-driver.patch)0
-rw-r--r--patches/linux-3.8.13/0338-OF-Clear-detach-flag-on-attach.patch (renamed from patches/linux-3.8.4/0312-OF-Clear-detach-flag-on-attach.patch)0
-rw-r--r--patches/linux-3.8.13/0339-OF-overlay-Fix-overlay-revert-failure.patch (renamed from patches/linux-3.8.4/0313-OF-overlay-Fix-overlay-revert-failure.patch)0
-rw-r--r--patches/linux-3.8.13/0340-bone-capemgr-Make-sure-cape-removal-works.patch (renamed from patches/linux-3.8.4/0314-bone-capemgr-Make-sure-cape-removal-works.patch)0
-rw-r--r--patches/linux-3.8.13/0341-bone-capemgr-Fix-crash-when-trying-to-remove-non-exi.patch (renamed from patches/linux-3.8.4/0315-bone-capemgr-Fix-crash-when-trying-to-remove-non-exi.patch)0
-rw-r--r--patches/linux-3.8.13/0342-beaglebone-LCD7-cape-enable-PWM-and-allow-the-specif.patch (renamed from patches/linux-3.8.4/0316-beaglebone-LCD7-cape-enable-PWM-and-allow-the-specif.patch)2
-rw-r--r--patches/linux-3.8.13/0343-bone-capemgr-Introduce-pinmux-helper.patch (renamed from patches/linux-3.8.4/0317-bone-capemgr-Introduce-pinmux-helper.patch)0
-rw-r--r--patches/linux-3.8.13/0344-bone-geiger-Fix-comment-to-match-the-contents.patch (renamed from patches/linux-3.8.4/0318-bone-geiger-Fix-comment-to-match-the-contents.patch)2
-rw-r--r--patches/linux-3.8.13/0345-of-overlay-Handle-I2C-devices-already-registered-by-.patch (renamed from patches/linux-3.8.4/0319-of-overlay-Handle-I2C-devices-already-registered-by-.patch)0
-rw-r--r--patches/linux-3.8.13/0346-pinmux-helper-Add-runtime-configuration-capability.patch (renamed from patches/linux-3.8.4/0320-pinmux-helper-Add-runtime-configuration-capability.patch)0
-rw-r--r--patches/linux-3.8.13/0347-pinmux-helper-Switch-to-using-kmalloc.patch (renamed from patches/linux-3.8.4/0321-pinmux-helper-Switch-to-using-kmalloc.patch)0
-rw-r--r--patches/linux-3.8.13/0348-i2c-DTify-pca954x-driver.patch (renamed from patches/linux-3.8.4/0322-i2c-DTify-pca954x-driver.patch)0
-rw-r--r--patches/linux-3.8.13/0349-tty-Add-JHD629-I2C-LCD-Keypad-TTY-driver.patch (renamed from patches/linux-3.8.4/0323-tty-Add-JHD629-I2C-LCD-Keypad-TTY-driver.patch)0
-rw-r--r--patches/linux-3.8.13/0350-grove-i2c-Add-rudimentary-grove-i2c-motor-control-dr.patch (renamed from patches/linux-3.8.4/0324-grove-i2c-Add-rudimentary-grove-i2c-motor-control-dr.patch)0
-rw-r--r--patches/linux-3.8.13/0351-tty-jhd629-i2c-Clean-keypad-buffer-when-starting.patch (renamed from patches/linux-3.8.4/0325-tty-jhd629-i2c-Clean-keypad-buffer-when-starting.patch)0
-rw-r--r--patches/linux-3.8.13/0352-am335x-bone-common-Remove-SPI-unused-pinmux-config.patch (renamed from patches/linux-3.8.4/0326-am335x-bone-common-Remove-SPI-unused-pinmux-config.patch)0
-rw-r--r--patches/linux-3.8.13/0353-bone-capemgr-Force-a-slot-to-load-unconditionally.patch (renamed from patches/linux-3.8.4/0327-bone-capemgr-Force-a-slot-to-load-unconditionally.patch)0
-rw-r--r--patches/linux-3.8.13/0354-beaglebone-Added-Adafruit-prototype-cape.patch (renamed from patches/linux-3.8.4/0328-beaglebone-Added-Adafruit-prototype-cape.patch)0
-rw-r--r--patches/linux-3.8.13/0355-tilcdc-Enable-reduced-blanking-check-only-on-DVI-sla.patch (renamed from patches/linux-3.8.4/0329-tilcdc-Enable-reduced-blanking-check-only-on-DVI-sla.patch)6
-rw-r--r--patches/linux-3.8.13/0356-cape-adafruit-Use-the-correct-spi-bus-spi1-no-spi0.patch (renamed from patches/linux-3.8.4/0330-cape-adafruit-Use-the-correct-spi-bus-spi1-no-spi0.patch)0
-rw-r--r--patches/linux-3.8.13/0357-BBB-tester-Introduce-board-DTS.patch (renamed from patches/linux-3.8.4/0331-BBB-tester-Introduce-board-DTS.patch)0
-rw-r--r--patches/linux-3.8.13/0358-BBB-tester-Introduce-cape-describing-the-contents-of.patch (renamed from patches/linux-3.8.4/0332-BBB-tester-Introduce-cape-describing-the-contents-of.patch)0
-rw-r--r--patches/linux-3.8.13/0359-bone-tester-Add-overrides-for-BB-BONE-TESTER.patch (renamed from patches/linux-3.8.4/0333-bone-tester-Add-overrides-for-BB-BONE-TESTER.patch)0
-rw-r--r--patches/linux-3.8.13/0360-cape-tester-Add-uart-specific-default-pinmux-state.patch (renamed from patches/linux-3.8.4/0334-cape-tester-Add-uart-specific-default-pinmux-state.patch)0
-rw-r--r--patches/linux-3.8.13/0361-cape-tester-Add-pinmux-helper-for-drvvbus-gpio.patch (renamed from patches/linux-3.8.4/0335-cape-tester-Add-pinmux-helper-for-drvvbus-gpio.patch)0
-rw-r--r--patches/linux-3.8.13/0362-cape-Added-support-for-IIO-helper-cape.patch (renamed from patches/linux-3.8.4/0336-cape-Added-support-for-IIO-helper-cape.patch)0
-rw-r--r--patches/linux-3.8.13/0363-cape-Added-example-IIO-tester-dynamics-overlay.patch (renamed from patches/linux-3.8.4/0337-cape-Added-example-IIO-tester-dynamics-overlay.patch)0
-rw-r--r--patches/linux-3.8.13/0364-docs-Added-capemanager-extra_override-usage.patch (renamed from patches/linux-3.8.4/0338-docs-Added-capemanager-extra_override-usage.patch)0
-rw-r--r--patches/linux-3.8.13/0365-capemgr-Added-module-param-descriptions.patch (renamed from patches/linux-3.8.4/0339-capemgr-Added-module-param-descriptions.patch)0
-rw-r--r--patches/linux-3.8.13/0366-beaglebone-Add-Adafruit-RTC-prototype-cape.patch (renamed from patches/linux-3.8.4/0340-beaglebone-Add-Adafruit-RTC-prototype-cape.patch)0
-rw-r--r--patches/linux-3.8.13/0367-cape-vsense-scale-division-by-zero-check.patch (renamed from patches/linux-3.8.4/0341-cape-vsense-scale-division-by-zero-check.patch)0
-rw-r--r--patches/linux-3.8.13/0368-capes-add-cape-for-beaglebone-based-Hexy-robot.patch (renamed from patches/linux-3.8.4/0342-capes-add-cape-for-beaglebone-based-Hexy-robot.patch)0
-rw-r--r--patches/linux-3.8.13/0369-Extend-bone-iio-helper.patch (renamed from patches/linux-3.8.4/0343-Extend-bone-iio-helper.patch)0
-rw-r--r--patches/linux-3.8.13/0370-Update-iio-helper-with-more-channels.patch (renamed from patches/linux-3.8.4/0344-Update-iio-helper-with-more-channels.patch)4
-rw-r--r--patches/linux-3.8.13/0371-Add-ADC-IIO-helper.patch (renamed from patches/linux-3.8.4/0345-Add-ADC-IIO-helper.patch)4
-rw-r--r--patches/linux-3.8.13/0372-Changing-DT-data-to-make-selection-of-standard-i.e.-.patch (renamed from patches/linux-3.8.4/0346-Changing-DT-data-to-make-selection-of-standard-i.e.-.patch)0
-rw-r--r--patches/linux-3.8.13/0373-Enhancing-to-support-extra-device-tree-options-for-t.patch (renamed from patches/linux-3.8.4/0347-Enhancing-to-support-extra-device-tree-options-for-t.patch)8
-rw-r--r--patches/linux-3.8.13/0374-add-WIP-support-LCD4-rev-00A4.patch (renamed from patches/linux-3.8.4/0348-add-WIP-support-LCD4-rev-00A4.patch)0
-rw-r--r--patches/linux-3.8.13/0375-add-eMMC-cape-support.patch (renamed from patches/linux-3.8.4/0349-add-eMMC-cape-support.patch)0
-rw-r--r--patches/linux-3.8.13/0376-Remove-UART-pins-from-the-expansion-set.patch (renamed from patches/linux-3.8.4/0350-Remove-UART-pins-from-the-expansion-set.patch)2
-rw-r--r--patches/linux-3.8.13/0377-Remove-LCD-pins-from-the-expansion-test-part.patch (renamed from patches/linux-3.8.4/0351-Remove-LCD-pins-from-the-expansion-test-part.patch)2
-rw-r--r--patches/linux-3.8.13/0378-Remove-I2C2-pins-from-expansion-test.patch (renamed from patches/linux-3.8.4/0352-Remove-I2C2-pins-from-expansion-test.patch)2
-rw-r--r--patches/linux-3.8.13/0379-Add-expansion-test-cape-fragment.patch (renamed from patches/linux-3.8.4/0353-Add-expansion-test-cape-fragment.patch)0
-rw-r--r--patches/linux-3.8.13/0380-tilcdc-added-some-extra-debug-and-softened-the-wordi.patch (renamed from patches/linux-3.8.4/0354-tilcdc-added-some-extra-debug-and-softened-the-wordi.patch)8
-rw-r--r--patches/linux-3.8.13/0381-Make-sure-various-timings-fit-within-the-bits-availa.patch (renamed from patches/linux-3.8.4/0355-Make-sure-various-timings-fit-within-the-bits-availa.patch)8
-rw-r--r--patches/linux-3.8.13/0382-fix-cape-bone-hexy.patch91
-rw-r--r--patches/linux-3.8.13/0383-firmware-DT-Fragment-for-MRF24J40-BeagleBone-Cape.patch109
-rw-r--r--patches/linux-3.8.13/0384-firmware-capes-Update-MRF24J40-cape-to-work-with-lat.patch70
-rw-r--r--patches/linux-3.8.13/0385-am335x-bone-common-DT-Override-for-MRF24J40-Cape.patch52
-rw-r--r--patches/linux-3.8.13/0386-beaglebone-black-limit-LDO3-to-1.8V.patch26
-rw-r--r--patches/linux-3.8.13/0387-beaglebone-black-add-new-fixed-regulator-for-uSD-eMM.patch47
-rw-r--r--patches/linux-3.8.13/0388-capemgr-Implement-disable-overrides-on-the-cmd-line.patch218
-rw-r--r--patches/linux-3.8.13/0389-tilcdc-Enable-pinmux-states.patch492
-rw-r--r--patches/linux-3.8.13/0390-cape-Add-a-simple-cape-for-handling-the-uSD-button.patch84
-rw-r--r--patches/linux-3.8.13/0391-beaglebone-add-support-for-DVI-00A3.patch42
-rw-r--r--patches/linux-3.8.13/0392-beaglebone-remove-audio-section-from-DVID-rev-2-and-.patch90
-rw-r--r--patches/linux-3.8.13/0393-beaglebone-add-dts-for-audio-cape.patch154
-rw-r--r--patches/linux-3.8.13/0394-cape-bone-hexy-add-iio-helper.patch48
-rw-r--r--patches/linux-3.8.13/0395-cape-Add-CAPE-BONE-EXPTEST-to-capemaps.patch27
-rw-r--r--patches/linux-3.8.13/0396-tester-button-cape.patch31
-rw-r--r--patches/linux-3.8.13/0397-pwm_test-fix-some-issues.patch89
-rw-r--r--patches/linux-3.8.13/0398-pwm_test-Clean-up-and-make-it-work-on-DT-correctly.patch467
-rw-r--r--patches/linux-3.8.13/0399-capes-Add-PWM-test-example-cape.patch89
-rw-r--r--patches/linux-3.8.13/0400-Sync-tester-DTS-with-am335x-common.patch134
-rw-r--r--patches/linux-3.8.13/0401-Add-in-missing-cape-bone-tester-back-in.patch28
-rw-r--r--patches/linux-3.8.13/0402-cape-bone-hexy-move-OLED-to-different-reset-gpio.patch22
-rw-r--r--patches/linux-3.8.13/0403-firmware-capes-added-dts-file-for-every-PWM-pin.patch830
-rw-r--r--patches/linux-3.8.13/0404-capes-add-LCD7-A3.patch271
-rw-r--r--patches/linux-3.8.13/0405-capes-add-basic-support-for-LCD4-capes.patch440
-rw-r--r--patches/linux-3.8.13/0406-OF-overlay-Add-depth-option-for-device-creation.patch83
-rw-r--r--patches/linux-3.8.13/0407-capes-Add-BB-BONE-GPEVT-cape.patch72
-rw-r--r--patches/linux-3.8.13/0408-clock-Export-__clock_set_parent.patch47
-rw-r--r--patches/linux-3.8.13/0409-omap-clk-Add-adjustable-clkout2.patch276
-rw-r--r--patches/linux-3.8.13/0410-am33xx-Update-DTS-EDMA.patch48
-rw-r--r--patches/linux-3.8.13/0411-bone-Added-RS232-prototype-cape-DT-object.patch110
-rw-r--r--patches/linux-3.8.13/0412-Add-support-for-BB-BONE_SERL-01-00A1-CanBus-cape.patch66
-rw-r--r--patches/linux-3.8.13/0413-capes-Add-virtual-capes-serving-as-examples.patch676
-rw-r--r--patches/linux-3.8.13/0414-capes-Add-TowerTech-TT3201-CAN-Bus-Cape-TT3201-001-3.patch175
-rw-r--r--patches/linux-3.8.13/0415-capes-Add-commented-out-example-of-use-of-spi1_cs1.patch28
-rw-r--r--patches/linux-3.8.13/0416-cape-LCD4-Correct-key-active-polarity.patch57
-rw-r--r--patches/linux-3.8.13/0417-capes-lcd3-Correct-button-polarity.patch107
-rw-r--r--patches/linux-3.8.13/0418-cape-Fix-LCD7-keys-polarity.patch157
-rw-r--r--patches/linux-3.8.13/0419-gpio-Introduce-GPIO-OF-helper.patch470
-rw-r--r--patches/linux-3.8.13/0420-capes-ADC-GPIO-helper-capes.patch168
-rw-r--r--patches/linux-3.8.13/0421-capes-RS232-Cape-support-added.patch81
-rw-r--r--patches/linux-3.8.13/0422-uio-uio_pruss-port-to-AM33xx.patch (renamed from patches/linux-3.8.4/0356-uio-uio_pruss-port-to-AM33xx.patch)0
-rw-r--r--patches/linux-3.8.13/0423-ARM-omap-add-DT-support-for-deasserting-hardware-res.patch (renamed from patches/linux-3.8.4/0357-ARM-omap-add-DT-support-for-deasserting-hardware-res.patch)0
-rw-r--r--patches/linux-3.8.13/0424-ARM-dts-AM33xx-PRUSS-support.patch (renamed from patches/linux-3.8.4/0358-ARM-dts-AM33xx-PRUSS-support.patch)2
-rw-r--r--patches/linux-3.8.13/0425-uio_pruss-add-dt-support-replicape-00A1.patch75
-rw-r--r--patches/linux-3.8.13/0426-pruss-Make-sure-it-works-when-no-child-nodes-are-pre.patch79
-rw-r--r--patches/linux-3.8.13/0427-am33xx-pru-Very-simple-led-cape-via-GPO-of-the-PRU.patch76
-rw-r--r--patches/linux-3.8.13/0428-PRU-remote-proc-wip.patch355
-rw-r--r--patches/linux-3.8.13/0429-Add-sysfs-entry-for-DDR-sync.patch64
-rw-r--r--patches/linux-3.8.13/0430-virtio-ring-Introduce-dma-mapping-for-real-devices.patch227
-rw-r--r--patches/linux-3.8.13/0431-virtio_console-Simplify-virtio_console-for-h-w-devic.patch81
-rw-r--r--patches/linux-3.8.13/0432-rpmsg-Make-the-buffers-number-and-size-configurable.patch59
-rw-r--r--patches/linux-3.8.13/0433-remoteproc-Use-driver-ops-for-allocation-of-virtqueu.patch167
-rw-r--r--patches/linux-3.8.13/0434-rproc-core-Allow-bootup-without-resources.patch40
-rw-r--r--patches/linux-3.8.13/0435-tools-virtio-fix-build-for-3.8.patch87
-rw-r--r--patches/linux-3.8.13/0436-rproc-pru-PRU-remoteproc-updated-to-work-with-virtio.patch2487
-rw-r--r--patches/linux-3.8.13/0437-capes-pru-Update-with-PRU-03-PRU-04.patch547
-rw-r--r--patches/linux-3.8.13/0438-rproc-PRU-Add-downcall-RPC-capability.patch587
-rw-r--r--patches/linux-3.8.13/0439-rproc-pru-Implement-a-software-defined-PWM-channel-s.patch326
-rw-r--r--patches/linux-3.8.13/0440-capes-PRU-PWM-channels-information.patch59
-rw-r--r--patches/linux-3.8.13/0441-drivers-usb-phy-add-a-new-driver-for-usb-part-of-con.patch (renamed from patches/linux-3.8.4/0359-drivers-usb-phy-add-a-new-driver-for-usb-part-of-con.patch)0
-rw-r--r--patches/linux-3.8.13/0442-drivers-usb-start-using-the-control-module-driver.patch (renamed from patches/linux-3.8.4/0360-drivers-usb-start-using-the-control-module-driver.patch)0
-rw-r--r--patches/linux-3.8.13/0443-usb-otg-Add-an-API-to-bind-the-USB-controller-and-PH.patch (renamed from patches/linux-3.8.4/0361-usb-otg-Add-an-API-to-bind-the-USB-controller-and-PH.patch)0
-rw-r--r--patches/linux-3.8.13/0444-usb-otg-utils-add-facilities-in-phy-lib-to-support-m.patch (renamed from patches/linux-3.8.4/0362-usb-otg-utils-add-facilities-in-phy-lib-to-support-m.patch)0
-rw-r--r--patches/linux-3.8.13/0445-ARM-OMAP-USB-Add-phy-binding-information.patch (renamed from patches/linux-3.8.4/0363-ARM-OMAP-USB-Add-phy-binding-information.patch)0
-rw-r--r--patches/linux-3.8.13/0446-drivers-usb-musb-omap-make-use-of-the-new-PHY-lib-AP.patch (renamed from patches/linux-3.8.4/0364-drivers-usb-musb-omap-make-use-of-the-new-PHY-lib-AP.patch)0
-rw-r--r--patches/linux-3.8.13/0447-usb-otg-add-device-tree-support-to-otg-library.patch (renamed from patches/linux-3.8.4/0365-usb-otg-add-device-tree-support-to-otg-library.patch)0
-rw-r--r--patches/linux-3.8.13/0448-USB-MUSB-OMAP-get-PHY-by-phandle-for-dt-boot.patch (renamed from patches/linux-3.8.4/0366-USB-MUSB-OMAP-get-PHY-by-phandle-for-dt-boot.patch)0
-rw-r--r--patches/linux-3.8.13/0449-MUSB-Hack-around-to-make-host-port-to-work.patch (renamed from patches/linux-3.8.4/0367-MUSB-Hack-around-to-make-host-port-to-work.patch)6
-rw-r--r--patches/linux-3.8.13/0450-make-sure-we-register-unregister-the-NOP-xceiver-onl.patch (renamed from patches/linux-3.8.4/0368-make-sure-we-register-unregister-the-NOP-xceiver-onl.patch)0
-rw-r--r--patches/linux-3.8.13/0451-ARM-OMAP-am335x-musb-use-250-for-power.patch42
-rw-r--r--patches/linux-3.8.13/0452-ARM-OMAP2-MUSB-Specify-omap4-has-mailbox.patch42
-rw-r--r--patches/linux-3.8.13/0453-usb-musb-avoid-stopping-the-session-in-host-mode.patch30
-rw-r--r--patches/linux-3.8.13/0454-beaglebone-black-1ghz-hack.patch (renamed from patches/linux-3.8.4/0369-beaglebone-black-1ghz-hack.patch)6
-rw-r--r--patches/linux-3.8.13/0455-ARM-AM33xx-Add-SoC-specific-restart-hook.patch (renamed from patches/linux-3.8.4/0370-ARM-AM33xx-Add-SoC-specific-restart-hook.patch)2
-rw-r--r--patches/linux-3.8.13/0456-iio-common-Add-STMicroelectronics-common-library.patch (renamed from patches/linux-3.8.4/0371-iio-common-Add-STMicroelectronics-common-library.patch)0
-rw-r--r--patches/linux-3.8.13/0457-iio-accel-Add-STMicroelectronics-accelerometers-driv.patch (renamed from patches/linux-3.8.4/0372-iio-accel-Add-STMicroelectronics-accelerometers-driv.patch)0
-rw-r--r--patches/linux-3.8.13/0458-iio-gyro-Add-STMicroelectronics-gyroscopes-driver.patch (renamed from patches/linux-3.8.4/0373-iio-gyro-Add-STMicroelectronics-gyroscopes-driver.patch)0
-rw-r--r--patches/linux-3.8.13/0459-iio-magnetometer-Add-STMicroelectronics-magnetometer.patch (renamed from patches/linux-3.8.4/0374-iio-magnetometer-Add-STMicroelectronics-magnetometer.patch)0
-rw-r--r--patches/linux-3.8.13/0460-iio-magn-Add-sensors_supported-in-st_magn_sensors.patch (renamed from patches/linux-3.8.4/0375-iio-magn-Add-sensors_supported-in-st_magn_sensors.patch)0
-rw-r--r--patches/linux-3.8.13/0461-pwm-pca9685-skeleton-i2c-client-driver-for-PCA9685-1.patch (renamed from patches/linux-3.8.4/0376-pwm-pca9685-skeleton-i2c-client-driver-for-PCA9685-1.patch)4
-rw-r--r--patches/linux-3.8.13/0462-Invensense-MPU6050-Device-Driver.patch1553
-rw-r--r--patches/linux-3.8.13/0463-iio-imu-inv_mpu6050-depends-on-IIO_BUFFER.patch31
-rw-r--r--patches/linux-3.8.13/0464-using-kfifo_in_spinlocked-instead-of-separate-code.patch26
-rw-r--r--patches/linux-3.8.13/0465-W1-w1-gpio-switch-to-using-dev_pm_ops.patch (renamed from patches/linux-3.8.4/0377-W1-w1-gpio-switch-to-using-dev_pm_ops.patch)0
-rw-r--r--patches/linux-3.8.13/0466-W1-w1-gpio-guard-DT-IDs-with-CONFIG_OF.patch (renamed from patches/linux-3.8.4/0378-W1-w1-gpio-guard-DT-IDs-with-CONFIG_OF.patch)0
-rw-r--r--patches/linux-3.8.13/0467-W1-w1-gpio-rework-handling-of-platform-data.patch (renamed from patches/linux-3.8.4/0379-W1-w1-gpio-rework-handling-of-platform-data.patch)0
-rw-r--r--patches/linux-3.8.13/0468-W1-w1-gpio-switch-to-using-managed-resources-devm.patch (renamed from patches/linux-3.8.4/0380-W1-w1-gpio-switch-to-using-managed-resources-devm.patch)0
-rw-r--r--patches/linux-3.8.13/0469-ARM-OMAP-Clear-GPMC-bits-when-applying-new-setting.patch54
-rw-r--r--patches/linux-3.8.13/0470-ARM-omap2-gpmc-Mark-local-scoped-functions-static.patch107
-rw-r--r--patches/linux-3.8.13/0471-ARM-omap2-gpmc-Remove-unused-gpmc_round_ns_to_ticks-.patch33
-rw-r--r--patches/linux-3.8.13/0472-ARM-omap2-gpmc-Fix-gpmc_cs_reserved-return-value.patch37
-rw-r--r--patches/linux-3.8.13/0473-ARM-omap2-gpmc-nand-Print-something-useful-on-CS-req.patch29
-rw-r--r--patches/linux-3.8.13/0474-ARM-omap2-gpmc-onenand-Print-something-useful-on-CS-.patch29
-rw-r--r--patches/linux-3.8.13/0475-ARM-omap2-gpmc-onenand-Replace-pr_err-with-dev_err.patch46
-rw-r--r--patches/linux-3.8.13/0476-ARM-omap2-gpmc-onenand-Replace-printk-KERN_ERR-with-.patch28
-rw-r--r--patches/linux-3.8.13/0477-ARM-omap2-gpmc-Remove-redundant-chip-select-out-of-r.patch44
-rw-r--r--patches/linux-3.8.13/0478-ARM-OMAP2-Simplify-code-configuring-ONENAND-devices.patch103
-rw-r--r--patches/linux-3.8.13/0479-ARM-OMAP2-Add-variable-to-store-number-of-GPMC-waitp.patch285
-rw-r--r--patches/linux-3.8.13/0480-ARM-OMAP2-Add-structure-for-storing-GPMC-settings.patch323
-rw-r--r--patches/linux-3.8.13/0481-ARM-OMAP2-Add-function-for-configuring-GPMC-settings.patch176
-rw-r--r--patches/linux-3.8.13/0482-ARM-OMAP2-Convert-ONENAND-to-use-gpmc_cs_program_set.patch133
-rw-r--r--patches/linux-3.8.13/0483-ARM-OMAP2-Convert-NAND-to-use-gpmc_cs_program_settin.patch84
-rw-r--r--patches/linux-3.8.13/0484-ARM-OMAP2-Convert-SMC91x-to-use-gpmc_cs_program_sett.patch81
-rw-r--r--patches/linux-3.8.13/0485-ARM-OMAP2-Convert-TUSB-to-use-gpmc_cs_program_settin.patch98
-rw-r--r--patches/linux-3.8.13/0486-ARM-OMAP2-Don-t-configure-of-chip-select-options-in-.patch129
-rw-r--r--patches/linux-3.8.13/0487-ARM-OMAP2-Add-function-to-read-GPMC-settings-from-de.patch196
-rw-r--r--patches/linux-3.8.13/0488-ARM-OMAP2-Add-additional-GPMC-timing-parameters.patch238
-rw-r--r--patches/linux-3.8.13/0489-ARM-OMAP2-Add-device-tree-support-for-NOR-flash.patch273
-rw-r--r--patches/linux-3.8.13/0490-ARM-OMAP2-Convert-NAND-to-retrieve-GPMC-settings-fro.patch42
-rw-r--r--patches/linux-3.8.13/0491-ARM-OMAP2-Convert-ONENAND-to-retrieve-GPMC-settings-.patch122
-rw-r--r--patches/linux-3.8.13/0492-ARM-OMAP2-Detect-incorrectly-aligned-GPMC-base-addre.patch76
-rw-r--r--patches/linux-3.8.13/0493-ARM-OMAP2-Remove-unnecesssary-GPMC-definitions-and-v.patch52
-rw-r--r--patches/linux-3.8.13/0494-ARM-OMAP2-Allow-GPMC-probe-to-complete-even-if-CS-ma.patch79
-rw-r--r--patches/linux-3.8.13/0495-ARM-OMAP2-return-ENODEV-if-GPMC-child-device-creatio.patch34
-rw-r--r--patches/linux-3.8.13/0496-ARM-OMAP2-rename-gpmc_probe_nor_child-to-gpmc_probe_.patch52
-rw-r--r--patches/linux-3.8.13/0497-ARM-OMAP2-Add-GPMC-DT-support-for-Ethernet-child-nod.patch142
-rw-r--r--patches/linux-3.8.13/0498-mtd-omap-nand-pass-device_node-in-platform-data.patch (renamed from patches/linux-3.8.4/0382-mtd-omap-nand-pass-device_node-in-platform-data.patch)3
-rw-r--r--patches/linux-3.8.13/0499-ARM-OMAP-gpmc-nand-drop-__init-annotation.patch (renamed from patches/linux-3.8.4/0383-ARM-OMAP-gpmc-nand-drop-__init-annotation.patch)12
-rw-r--r--patches/linux-3.8.13/0500-ARM-OMAP-gpmc-enable-hwecc-for-AM33xx-SoCs.patch (renamed from patches/linux-3.8.4/0384-ARM-OMAP-gpmc-enable-hwecc-for-AM33xx-SoCs.patch)8
-rw-r--r--patches/linux-3.8.13/0501-ARM-OMAP-gpmc-don-t-create-devices-from-initcall-on-.patch (renamed from patches/linux-3.8.4/0381-ARM-OMAP-gpmc-don-t-create-devices-from-initcall-on-.patch)8
-rw-r--r--patches/linux-3.8.13/0502-ARM-OMAP2-gpmc-onenand-drop-__init-annotation.patch26
-rw-r--r--patches/linux-3.8.13/0503-gpmc-Add-missing-gpmc-includes.patch22
-rw-r--r--patches/linux-3.8.13/0504-mtd-omap-onenand-pass-device_node-in-platform-data.patch54
-rw-r--r--patches/linux-3.8.13/0505-ARM-OMAP2-Convert-ONENAND-to-use-gpmc_cs_program_set.patch44
-rw-r--r--patches/linux-3.8.13/0506-omap-gpmc-Various-driver-fixes.patch203
-rw-r--r--patches/linux-3.8.13/0507-gpmc-Add-DT-node-for-gpmc-on-am33xx.patch35
-rw-r--r--patches/linux-3.8.13/0508-CHROMIUM-Input-atmel_mxt_ts-refactor-i2c-error-handl.patch163
-rw-r--r--patches/linux-3.8.13/0509-CHROMIUM-Input-atmel_mxt_ts-register-input-device-be.patch109
-rw-r--r--patches/linux-3.8.13/0510-CHROMIUM-Input-atmel_mxt_ts-refactor-input-device-cr.patch157
-rw-r--r--patches/linux-3.8.13/0511-CHROMIUM-Input-atmel_mxt_ts-handle-bootloader-mode-a.patch180
-rw-r--r--patches/linux-3.8.13/0512-CHROMIUM-Input-atmel_mxt_ts-handle-errors-during-fw-.patch74
-rw-r--r--patches/linux-3.8.13/0513-CHROMIUM-Input-atmel_mxt_ts-destroy-state-before-fw-.patch51
-rw-r--r--patches/linux-3.8.13/0514-CHROMIUM-Input-atmel_mxt_ts-refactor-bootloader-entr.patch239
-rw-r--r--patches/linux-3.8.13/0515-CHROMIUM-Input-atmel_mxt_ts-wait-for-CHG-assert-in-m.patch170
-rw-r--r--patches/linux-3.8.13/0516-CHROMIUM-Input-atmel_mxt_ts-wait-for-CHG-after-bootl.patch84
-rw-r--r--patches/linux-3.8.13/0517-CHROMIUM-Input-atmel_mxt_ts-change-MXT_BOOT_LOW-to-0.patch37
-rw-r--r--patches/linux-3.8.13/0518-CHROMIUM-Input-atmel_mxt_ts-Increase-FWRESET_TIME.patch31
-rw-r--r--patches/linux-3.8.13/0519-CHROMIUM-Input-atmel_mxt_ts-add-calibrate-sysfs-entr.patch80
-rw-r--r--patches/linux-3.8.13/0520-CHROMIUM-Input-atmel_mxt_ts-add-sysfs-entry-to-read-.patch82
-rw-r--r--patches/linux-3.8.13/0521-CHROMIUM-Input-atmel_mxt_ts-add-sysfs-entry-to-read-.patch103
-rw-r--r--patches/linux-3.8.13/0522-CHROMIUM-Input-atmel_mxt_ts-verify-info-block-checks.patch111
-rw-r--r--patches/linux-3.8.13/0523-CHROMIUM-Input-atmel_mxt_tx-add-matrix_size-sysfs-en.patch63
-rw-r--r--patches/linux-3.8.13/0524-CHROMIUM-Input-atmel_mxt_ts-define-helper-functions-.patch117
-rw-r--r--patches/linux-3.8.13/0525-CHROMIUM-Input-atmel_mxt_ts-add-debugfs-infrastructu.patch127
-rw-r--r--patches/linux-3.8.13/0526-CHROMIUM-Input-atmel_mxt_ts-add-deltas-and-refs-debu.patch338
-rw-r--r--patches/linux-3.8.13/0527-CHROMIUM-Input-atmel_mxt_ts-add-device-id-for-touchp.patch180
-rw-r--r--patches/linux-3.8.13/0528-CHROMIUM-Input-atmel_mxt_ts-Read-resolution-from-dev.patch130
-rw-r--r--patches/linux-3.8.13/0529-CHROMIUM-Input-atmel_mxt_ts-Report-TOUCH-MAJOR-in-te.patch147
-rw-r--r--patches/linux-3.8.13/0530-CHROMIUM-Input-atmel_mxt_ts-add-new-object-types.patch78
-rw-r--r--patches/linux-3.8.13/0531-CHROMIUM-INPUT-atmel_mxt_ts-Increase-the-wait-times-.patch48
-rw-r--r--patches/linux-3.8.13/0532-CHROMIUM-Input-atmel_mxt_ts-dump-mxt_read-write_reg.patch91
-rw-r--r--patches/linux-3.8.13/0533-CHROMIUM-Input-atmel_mxt_ts-take-an-instance-for-mxt.patch59
-rw-r--r--patches/linux-3.8.13/0534-CHROMIUM-Input-atmel_mxt_ts-allow-writing-to-object-.patch108
-rw-r--r--patches/linux-3.8.13/0535-CHROMIUM-Input-atmel_mxt_ts-add-backupnv-sysfs-entry.patch72
-rw-r--r--patches/linux-3.8.13/0536-CHROMIUM-Input-atmel_mxt_ts-read-num-messages-then-a.patch237
-rw-r--r--patches/linux-3.8.13/0537-CHROMIUM-Input-atmel_mxt_ts-remove-mxt_make_highchg.patch104
-rw-r--r--patches/linux-3.8.13/0538-CHROMIUM-Input-atmel_mxt_ts-Remove-matrix-size-updat.patch64
-rw-r--r--patches/linux-3.8.13/0539-CHROMIUM-Input-atmel_mxt_ts-parse-vector-field-of-da.patch69
-rw-r--r--patches/linux-3.8.13/0540-CHROMIUM-Input-atmel_mxt_ts-Add-IDLE-DEEP-SLEEP-mode.patch226
-rw-r--r--patches/linux-3.8.13/0541-CHROMIUM-Input-atmel_mxt_ts-Move-object-from-sysfs-t.patch372
-rw-r--r--patches/linux-3.8.13/0542-CHROMIUM-Input-atmel_mxt_ts-Set-default-irqflags-whe.patch55
-rw-r--r--patches/linux-3.8.13/0543-CHROMIUM-Input-atmel_mxt_ts-Support-the-case-with-no.patch110
-rw-r--r--patches/linux-3.8.13/0544-CHROMIUM-Input-atmel_mxt_ts-Wait-on-auto-calibration.patch117
-rw-r--r--patches/linux-3.8.13/0545-CHROMIUM-Input-atmel_mxt_ts-Add-sysfs-entry-for-r-w-.patch182
-rw-r--r--patches/linux-3.8.13/0546-CHROMIUM-Input-atmel_mxt_ts-Add-sysfs-entry-for-r-w-.patch137
-rw-r--r--patches/linux-3.8.13/0547-CHROMIUM-Input-atmel_mxt_ts-add-sysfs-entry-for-writ.patch408
-rw-r--r--patches/linux-3.8.13/0548-CHROMIUM-Input-atmel_mxt_ts-make-mxt_initialize-asyn.patch223
-rw-r--r--patches/linux-3.8.13/0549-CHROMIUM-Input-atmel_mxt_ts-move-backup_nv-to-handle.patch62
-rw-r--r--patches/linux-3.8.13/0550-CHROMIUM-Input-atmel_mxt_ts-Add-defines-for-T9-Touch.patch81
-rw-r--r--patches/linux-3.8.13/0551-CHROMIUM-Input-atmel_mxt_ts-disable-reporting-on-sto.patch48
-rw-r--r--patches/linux-3.8.13/0552-CHROMIUM-Input-atmel_mxt_ts-Suppress-handle-messages.patch112
-rw-r--r--patches/linux-3.8.13/0553-CHROMIUM-Input-atmel_mxt_ts-save-and-restore-t9_ctrl.patch70
-rw-r--r--patches/linux-3.8.13/0554-CHROMIUM-Input-atmel_mxt_ts-enable-RPTEN-if-can-wake.patch95
-rw-r--r--patches/linux-3.8.13/0555-CHROMIUM-Input-atmel_mxt_ts-release-all-fingers-on-r.patch126
-rw-r--r--patches/linux-3.8.13/0556-CHROMIUM-Input-atmel_mxt_ts-make-suspend-power-acqui.patch167
-rw-r--r--patches/linux-3.8.13/0557-CHROMIUM-Input-atmel_mxt_ts-recalibrate-on-system-re.patch80
-rw-r--r--patches/linux-3.8.13/0558-CHROMIUM-Input-atmel_mxt_ts-Use-correct-max-touch_ma.patch59
-rw-r--r--patches/linux-3.8.13/0559-CHROMIUM-Input-atmel_mxt_ts-Add-support-for-T65-Lens.patch70
-rw-r--r--patches/linux-3.8.13/0560-CHROMIUM-Input-atmel_mxt_ts-On-Tpads-enable-T42-disa.patch118
-rw-r--r--patches/linux-3.8.13/0561-CHROMIUM-Input-atmel_mxt_ts-Set-power-wakeup-to-disa.patch39
-rw-r--r--patches/linux-3.8.13/0562-CHROMIUM-Input-atmel_mxt_ts-mxt_stop-on-lid-close.patch121
-rw-r--r--patches/linux-3.8.13/0563-CHROMIUM-Input-atmel_mxt_ts-Disable-T9-on-mxt_stop.patch49
-rw-r--r--patches/linux-3.8.13/0564-CHROMIUM-Input-atmel_mxt_ts-Set-T9-in-mxt_resume-bas.patch73
-rw-r--r--patches/linux-3.8.13/0565-video-ssd1307fb-Add-support-for-SSD1306-OLED-control.patch431
-rw-r--r--patches/linux-3.8.13/0566-ssd1307fb-Rework-the-communication-functions.patch111
-rw-r--r--patches/linux-3.8.13/0567-ssd1307fb-Speed-up-the-communication-with-the-contro.patch53
-rw-r--r--patches/linux-3.8.13/0568-ssd1307fb-Make-use-of-horizontal-addressing-mode.patch105
-rw-r--r--patches/linux-3.8.13/0569-SSD1307fb-1Hz-8Hz-defio-updates.patch22
-rw-r--r--patches/linux-3.8.13/0570-ARM-force-march-armv7a-for-thumb2-builds-http-lists..patch23
-rw-r--r--patches/linux-3.8.13/0571-headers_install-Fix-build-failures-on-deep-directory.patch56
-rw-r--r--patches/linux-3.8.13/0572-libtraceevent-Remove-hard-coded-include-to-usr-local.patch33
-rw-r--r--patches/linux-3.8.13/0573-Make-single-.dtb-targets-also-with-DTC_FLAGS.patch21
-rw-r--r--patches/linux-3.8.13/0574-video-Add-generic-HDMI-infoframe-helpers.patch593
-rw-r--r--patches/linux-3.8.13/0575-BeagleBone-Black-TDA998x-Initial-HDMI-Audio-support.patch784
-rw-r--r--patches/linux-3.8.13/0576-Clean-up-some-formating-and-debug-in-Davinci-MCASP-d.patch55
-rw-r--r--patches/linux-3.8.13/0577-tilcdc-Prune-modes-that-can-t-support-audio.patch240
-rw-r--r--patches/linux-3.8.13/0578-Enable-output-of-correct-AVI-Infoframe-type-hdmi.patch24
-rw-r--r--patches/linux-3.8.13/0579-drm-am335x-add-support-for-2048-lines-vertical.patch86
-rw-r--r--patches/linux-3.8.13/0580-drm-tda998x-Adding-extra-CEA-mode-for-1920x1080-24.patch31
-rw-r--r--patches/linux-3.8.13/0581-tilcdc-Remove-superfluous-newlines-from-DBG-messages.patch63
-rw-r--r--patches/linux-3.8.13/0582-tilcdc-1280x1024x60-bw-1920x1080x24-bw.patch43
-rw-r--r--patches/linux-3.8.13/0583-tilcdc-Only-support-Audio-on-50-60-Hz-modes.patch62
-rw-r--r--patches/linux-3.8.13/0584-drm-i2c-nxp-tda998x-fix-EDID-reading-on-TDA19988-dev.patch68
-rw-r--r--patches/linux-3.8.13/0585-tilcdc-Allow-non-audio-modes-when-we-don-t-support-t.patch26
-rw-r--r--patches/linux-3.8.13/0586-drm-i2c-nxp-tda998x-ensure-VIP-output-mux-is-properl.patch39
-rw-r--r--patches/linux-3.8.13/0587-drm-i2c-nxp-tda998x-fix-npix-nline-programming.patch28
-rw-r--r--patches/linux-3.8.13/0588-drm-tilcdc-Clear-bits-of-register-we-re-going-to-set.patch63
-rw-r--r--patches/linux-3.8.13/0589-DRM-tda998x-add-missing-include.patch42
-rw-r--r--patches/linux-3.8.13/0590-drm-i2c-nxp-tda998x-prepare-for-video-input-configur.patch50
-rw-r--r--patches/linux-3.8.13/0591-WIP-of-new-tda998x-patches.patch808
-rw-r--r--patches/linux-3.8.13/0592-tilcdc-Slave-panel-settings-read-from-DT-now.patch221
-rw-r--r--patches/linux-3.8.13/0593-drm-tda998x-Revert-WIP-to-previous-state.patch838
-rw-r--r--patches/linux-3.8.13/0594-tilcdc-More-refined-audio-mode-compatibility-check.patch69
-rw-r--r--patches/linux-3.8.13/0595-drm-tilcdc-Implement-whitelist-blacklist-mode-suppor.patch435
-rw-r--r--patches/linux-3.8.13/0596-boneblack-Remove-default-pinmuxing-for-MMC1.patch43
-rw-r--r--patches/linux-3.8.13/0597-capemgr-Implement-cape-priorities.patch276
-rw-r--r--patches/linux-3.8.13/0598-rstctl-Reset-control-subsystem.patch1049
-rw-r--r--patches/linux-3.8.13/0599-omap_hsmmc-Enable-rstctl-bindings.patch82
-rw-r--r--patches/linux-3.8.13/0600-bone-Add-rstctl-DT-binding-for-beaglebone.patch77
-rw-r--r--patches/linux-3.8.13/0601-bone-eMMC-Add-rstctl-rstctl-DT-bindings.patch64
-rw-r--r--patches/linux-3.8.13/0602-capes-Add-testing-capes-for-rstctl.patch115
-rw-r--r--patches/linux-3.8.13/0603-omap_hsmmc-Bail-out-when-rstctl-error-is-unrecoverab.patch35
-rw-r--r--patches/linux-3.8.13/0604-bone-Put-priorities-in-built-in-capes.patch114
-rw-r--r--patches/linux-3.8.13/0605-bone-common-dtsi-remove-reset-cape.patch30
-rw-r--r--patches/linux-3.8.13/0606-mmc-add-missing-select-RSTCTL-in-MMC_OMAP.patch24
-rw-r--r--patches/linux-3.8.13/0607-soc_camera-QL-mt9l112-camera-driver-for-the-beaglebo.patch1606
-rw-r--r--patches/linux-3.8.13/0608-capes-Add-BB-BONE-CAM3-cape.patch202
-rw-r--r--patches/linux-3.8.13/0609-cssp_camera-Correct-license-identifier.patch24
-rw-r--r--patches/linux-3.8.13/0610-cssp_camera-increase-delays-make-sensor-detection-wo.patch32
-rw-r--r--patches/linux-3.8.13/0611-mt9t112-forward-port-optimizations-from-Angstrom-3.2.patch585
-rw-r--r--patches/linux-3.8.13/0612-cssp_camera-Use-flip-if-available.patch53
-rw-r--r--patches/linux-3.8.13/0613-cssp_camera-Fix-it-for-small-resolutions.patch932
-rw-r--r--patches/linux-3.8.13/0614-cssp_camera-Increase-delay-after-enabling-clocks-to-.patch30
-rw-r--r--patches/linux-3.8.13/0615-Debugging-camera-stuff.patch93
-rw-r--r--patches/linux-3.8.13/0616-cssp_camera-Make-it-work-with-Beaglebone-black.patch112
-rw-r--r--patches/linux-3.8.13/0617-bone-capemgr-Introduce-simple-resource-tracking.patch163
-rw-r--r--patches/linux-3.8.13/0618-capes-Add-resources-to-capes.patch705
-rw-r--r--patches/linux-3.8.13/0619-capes-Update-most-of-the-capes-with-resource-definit.patch1100
-rw-r--r--patches/linux-3.8.13/0620-capes-Update-RS232-CAN-capes-with-resources.patch47
-rw-r--r--patches/linux-3.8.13/0621-capemgr-Add-enable_partno-parameter.patch114
-rw-r--r--patches/linux-3.8.13/0622-cape-GPIOHELP-use-correct-part-number.patch21
-rw-r--r--patches/linux-3.8.13/0623-bbb-Add-a-fall-back-non-audio-HDMI-cape.patch186
-rw-r--r--patches/linux-3.8.13/0624-capes-HDMI-slaves-need-panel-settings.patch57
-rw-r--r--patches/linux-3.8.13/0625-capes-boneblack-HDMI-capes-have-blacklisted-modes.patch65
-rw-r--r--patches/linux-3.8.13/0626-capes-LCD7-Fix-definitions.patch106
-rw-r--r--patches/linux-3.8.13/0627-capes-LCD7-Fix-enter-key-pinmux.patch37
-rw-r--r--patches/linux-3.8.13/0628-Fix-timings-for-LCD3-cape.patch41
-rw-r--r--patches/linux-3.8.13/0629-capes-LCD-capes-updated-with-timing-fixes.patch183
-rw-r--r--patches/linux-3.8.13/0630-Fix-mmc2-being-enabled-when-eMMC-is-disabled.patch22
-rw-r--r--patches/linux-3.8.13/0631-capes-LCD7-fix-vsync-len-off-by-one.patch49
-rw-r--r--patches/linux-3.8.13/0632-LCD-capes-set-default-brightness-to-100.patch106
-rw-r--r--patches/linux-3.8.13/0633-lcd-capes-update-adc-channels.patch50
-rw-r--r--patches/linux-3.8.13/0634-bone-renamed-adafruit-RTC-cape.patch177
-rw-r--r--patches/linux-3.8.13/0635-bone-add-PPS-to-BB-BONE-RTC-cape.patch79
-rw-r--r--patches/linux-3.8.13/0636-firmware-remove-rule-for-cape-bone-adafruit-lcd-00A0.patch21
-rw-r--r--patches/linux-3.8.13/0637-tps65217-Enable-KEY_POWER-press-on-AC-loss-PWR_BUT.patch201
-rw-r--r--patches/linux-3.8.13/0638-dt-bone-common-Add-interrupt-for-PMIC.patch33
-rw-r--r--patches/linux-3.8.13/0639-drivers-pps-clients-pps-gpio.c-convert-to-module_pla.patch44
-rw-r--r--patches/linux-3.8.13/0640-drivers-pps-clients-pps-gpio.c-convert-to-devm_-help.patch88
-rw-r--r--patches/linux-3.8.13/0641-pps-gpio-add-device-tree-binding-and-support.patch126
-rw-r--r--patches/linux-3.8.13/0642-leds-leds-pwm-Convert-to-use-devm_get_pwm.patch84
-rw-r--r--patches/linux-3.8.13/0643-leds-leds-pwm-Preparing-the-driver-for-device-tree-s.patch104
-rw-r--r--patches/linux-3.8.13/0644-leds-leds-pwm-Simplify-cleanup-code.patch35
-rw-r--r--patches/linux-3.8.13/0645-leds-leds-pwm-Add-device-tree-bindings.patch240
-rw-r--r--patches/linux-3.8.13/0646-leds-leds-pwm-Defer-led_pwm_set-if-PWM-can-sleep.patch118
-rw-r--r--patches/linux-3.8.13/0647-leds-pwm-Enable-compilation-on-this-version-of-the-k.patch54
-rw-r--r--patches/linux-3.8.13/0648-capes-Add-bacon-cape.patch247
-rw-r--r--patches/linux-3.8.13/0649-cape-bacon-Cosmetic-change-of-the-adc-helper-name.patch21
-rw-r--r--patches/linux-3.8.13/0650-cape-bacon-educational-edition.patch199
-rw-r--r--patches/linux-3.8.13/0651-capes-bacon-Update-with-new-ADC-driver-method.patch35
-rw-r--r--patches/linux-3.8.13/0652-capes-BACON-Educational-cape-with-free-form-muxing.patch234
-rw-r--r--patches/linux-3.8.13/0653-firmware-add-BeBoPr-cape.patch446
-rw-r--r--patches/linux-3.8.13/0701-Release-distrokit-beaglebone-20130720.patch22
-rw-r--r--patches/linux-3.8.13/series663
-rw-r--r--patches/linux-3.8.4/0044-input-ti_am335x_tsc-Step-enable-bits-made-configurab.patch73
-rw-r--r--patches/linux-3.8.4/0047-MFD-ti_am335x_tscadc-add-device-tree-binding-informa.patch68
-rw-r--r--patches/linux-3.8.4/0049-input-ti_am335x_tsc-Add-DT-support.patch139
-rw-r--r--patches/linux-3.8.4/0050-IIO-ti_am335x_adc-Add-DT-support.patch64
-rw-r--r--patches/linux-3.8.4/0052-ti_tscadc-Update-with-IIO-map-interface-deal-with-pa.patch187
-rw-r--r--patches/linux-3.8.4/0053-ti_tscadc-Match-mfd-sub-devices-to-regmap-interface.patch166
-rw-r--r--patches/linux-3.8.4/0054-input-ti_am335x_tsc-Add-variance-filters.patch77
-rw-r--r--patches/linux-3.8.4/0055-am335x-adc-Do-not-use-find_node_by_name-use-get_chil.patch27
-rw-r--r--patches/linux-3.8.4/0056-am335x-tsc-Do-not-use-find_node_by_name-use-get_chil.patch27
-rw-r--r--patches/linux-3.8.4/0057-am335x-tscadc-Do-not-use-find_node_by_name-use-get_c.patch39
-rw-r--r--patches/linux-3.8.4/0162-6lowpan-add-a-new-parameter-in-sysfs-to-turn-on-off-.patch44
-rw-r--r--patches/linux-3.8.4/0165-6lowpan-make-memory-allocation-atomic-during-6lowpan.patch26
-rw-r--r--patches/linux-3.8.4/0166-mac802154-make-mem-alloc-ATOMIC-to-prevent-schedulin.patch25
-rw-r--r--patches/linux-3.8.4/0167-mac802154-remove-unnecessary-spinlocks.patch50
-rw-r--r--patches/linux-3.8.4/0168-mac802154-re-introduce-MAC-primitives-required-to-se.patch100
-rw-r--r--patches/linux-3.8.4/0169-serial-initial-import-of-the-IEEE-802.15.4-serial-dr.patch1323
-rw-r--r--patches/linux-3.8.4/0385-ARM-OMAP-gpmc-add-DT-bindings-for-GPMC-timings-and-N.patch408
-rw-r--r--patches/linux-3.8.4/0401-Release-distrokit-beaglebone-20130329.patch22
-rw-r--r--patches/linux-3.8.4/series395
-rw-r--r--platformconfig4
677 files changed, 47063 insertions, 7280 deletions
diff --git a/kernelconfig b/kernelconfig
index d9be2e9..598a36d 100644
--- a/kernelconfig
+++ b/kernelconfig
@@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
-# Linux/arm 3.8.4-20130329 Kernel Configuration
+# Linux/arm 3.8.13-20130720 Kernel Configuration
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -165,12 +165,10 @@ CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
CONFIG_OPROFILE=m
CONFIG_HAVE_OPROFILE=y
-CONFIG_KPROBES=y
+# CONFIG_KPROBES is not set
# CONFIG_JUMP_LABEL is not set
-CONFIG_KRETPROBES=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
@@ -464,9 +462,10 @@ CONFIG_ARCH_NR_GPIO=0
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
CONFIG_HZ=512
-# CONFIG_THUMB2_KERNEL is not set
+CONFIG_THUMB2_KERNEL=y
+CONFIG_THUMB2_AVOID_R_ARM_THM_JUMP11=y
+CONFIG_ARM_ASM_UNIFIED=y
CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
@@ -872,14 +871,16 @@ CONFIG_LLC=m
# CONFIG_LAPB is not set
# CONFIG_WAN_ROUTER is not set
CONFIG_PHONET=m
-# CONFIG_IEEE802154 is not set
+CONFIG_IEEE802154=m
+CONFIG_IEEE802154_6LOWPAN=m
+CONFIG_MAC802154=m
CONFIG_NET_SCHED=y
#
# Queueing/Scheduling
#
# CONFIG_NET_SCH_CBQ is not set
-# CONFIG_NET_SCH_HTB is not set
+CONFIG_NET_SCH_HTB=y
# CONFIG_NET_SCH_HFSC is not set
# CONFIG_NET_SCH_PRIO is not set
# CONFIG_NET_SCH_MULTIQ is not set
@@ -933,8 +934,6 @@ CONFIG_BPF_JIT=y
# Network testing
#
# CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_TCPPROBE is not set
-# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
CONFIG_CAN=m
CONFIG_CAN_RAW=m
@@ -1117,11 +1116,10 @@ CONFIG_UEVENT_HELPER_PATH=""
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_FW_LOADER=y
CONFIG_FIRMWARE_IN_KERNEL=y
-CONFIG_EXTRA_FIRMWARE="am335x-pm-firmware.bin"
-CONFIG_EXTRA_FIRMWARE_DIR="${PTXDIST_PLATFORMCONFIGDIR}/firmware"
+CONFIG_EXTRA_FIRMWARE=""
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
@@ -1307,7 +1305,7 @@ CONFIG_BMP085=y
CONFIG_BMP085_I2C=m
# CONFIG_BMP085_SPI is not set
# CONFIG_USB_SWITCH_FSA9480 is not set
-# CONFIG_GPEVT is not set
+CONFIG_GPEVT=y
CONFIG_GROVE_I2C=y
# CONFIG_C2PORT is not set
@@ -1333,7 +1331,7 @@ CONFIG_TI_ST=m
#
# CONFIG_ALTERA_STAPL is not set
CONFIG_BEAGLEBONE_PINMUX_HELPER=y
-CONFIG_BEAGLEBONE_IIO_HELPER=m
+CONFIG_BEAGLEBONE_IIO_HELPER=y
CONFIG_CAPE_BEAGLEBONE=y
CONFIG_CAPE_BEAGLEBONE_GEIGER=y
CONFIG_CAPE_BEAGLEBONE_NIXIE=y
@@ -1636,6 +1634,11 @@ CONFIG_MWIFIEX_USB=m
#
# CONFIG_WIMAX_I2400M_USB is not set
# CONFIG_WAN is not set
+CONFIG_IEEE802154_DRIVERS=m
+# CONFIG_IEEE802154_FAKEHARD is not set
+# CONFIG_IEEE802154_FAKELB is not set
+# CONFIG_IEEE802154_AT86RF230 is not set
+CONFIG_IEEE802154_MRF24J40=m
# CONFIG_ISDN is not set
#
@@ -1836,7 +1839,7 @@ CONFIG_SERIAL_OMAP_CONSOLE=y
# CONFIG_TTY_PRINTK is not set
CONFIG_HVC_DRIVER=y
# CONFIG_HVC_DCC is not set
-CONFIG_VIRTIO_CONSOLE=m
+CONFIG_VIRTIO_CONSOLE=y
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
# CONFIG_HW_RANDOM_TIMERIOMEM is not set
@@ -1923,13 +1926,13 @@ CONFIG_SPI_SPIDEV=y
# PPS support
#
CONFIG_PPS=y
-CONFIG_PPS_DEBUG=y
+# CONFIG_PPS_DEBUG is not set
#
# PPS clients support
#
# CONFIG_PPS_CLIENT_KTIMER is not set
-# CONFIG_PPS_CLIENT_LDISC is not set
+CONFIG_PPS_CLIENT_LDISC=y
CONFIG_PPS_CLIENT_GPIO=y
#
@@ -1962,6 +1965,7 @@ CONFIG_GPIOLIB=y
CONFIG_OF_GPIO=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_OF_HELPER=y
#
# Memory mapped GPIO drivers:
@@ -2297,7 +2301,7 @@ CONFIG_REGULATOR_TPS6507X=y
CONFIG_REGULATOR_TPS65217=y
# CONFIG_REGULATOR_TPS6524X is not set
CONFIG_REGULATOR_TWL4030=y
-CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_SUPPORT=y
#
# Multimedia core support
@@ -2308,21 +2312,21 @@ CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
CONFIG_MEDIA_RADIO_SUPPORT=y
CONFIG_MEDIA_RC_SUPPORT=y
CONFIG_MEDIA_CONTROLLER=y
-CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
-CONFIG_VIDEO_V4L2=m
-# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_ADV_DEBUG=y
# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
CONFIG_VIDEO_TUNER=m
CONFIG_V4L2_MEM2MEM_DEV=m
-CONFIG_VIDEOBUF_GEN=m
+CONFIG_VIDEOBUF_GEN=y
CONFIG_VIDEOBUF_VMALLOC=m
-CONFIG_VIDEOBUF_DMA_CONTIG=m
CONFIG_VIDEOBUF_DVB=m
-CONFIG_VIDEOBUF2_CORE=m
-CONFIG_VIDEOBUF2_MEMOPS=m
+CONFIG_VIDEOBUF2_CORE=y
+CONFIG_VIDEOBUF2_MEMOPS=y
+CONFIG_VIDEOBUF2_DMA_CONTIG=y
CONFIG_VIDEOBUF2_VMALLOC=m
-CONFIG_DVB_CORE=m
+CONFIG_DVB_CORE=y
CONFIG_DVB_NET=y
CONFIG_DVB_MAX_ADAPTERS=8
CONFIG_DVB_DYNAMIC_MINORS=y
@@ -2330,7 +2334,7 @@ CONFIG_DVB_DYNAMIC_MINORS=y
#
# Media drivers
#
-CONFIG_RC_CORE=m
+CONFIG_RC_CORE=y
CONFIG_RC_MAP=m
CONFIG_RC_DECODERS=y
CONFIG_LIRC=m
@@ -2499,16 +2503,14 @@ CONFIG_VIDEO_EM28XX_DVB=m
CONFIG_VIDEO_EM28XX_RC=m
CONFIG_TTPCI_EEPROM=m
CONFIG_V4L_PLATFORM_DRIVERS=y
-CONFIG_VIDEO_VPSS_SYSTEM=m
-CONFIG_VIDEO_VPFE_CAPTURE=m
-CONFIG_VIDEO_DM6446_CCDC=m
-CONFIG_VIDEO_OMAP2_VOUT_VRFB=y
-CONFIG_VIDEO_OMAP2_VOUT=m
+# CONFIG_VIDEO_VPFE_CAPTURE is not set
+# CONFIG_VIDEO_OMAP2_VOUT is not set
# CONFIG_VIDEO_TIMBERDALE is not set
-CONFIG_SOC_CAMERA=m
-CONFIG_SOC_CAMERA_PLATFORM=m
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_PLATFORM=y
# CONFIG_VIDEO_SH_MOBILE_CSI2 is not set
# CONFIG_VIDEO_SH_MOBILE_CEU is not set
+CONFIG_VIDEO_QL_CAMIF=y
CONFIG_V4L_MEM2MEM_DRIVERS=y
# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
CONFIG_V4L_TEST_DRIVERS=y
@@ -2546,7 +2548,7 @@ CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
# Media ancillary drivers (tuners, sensors, i2c, frontends)
#
CONFIG_VIDEO_TVEEPROM=m
-CONFIG_VIDEO_IR_I2C=m
+CONFIG_VIDEO_IR_I2C=y
#
# Audio decoders, processors and mixers
@@ -2604,11 +2606,11 @@ CONFIG_VIDEO_MT9V011=m
# soc_camera sensor drivers
#
# CONFIG_SOC_CAMERA_IMX074 is not set
-CONFIG_SOC_CAMERA_MT9M001=m
-CONFIG_SOC_CAMERA_MT9M111=m
-CONFIG_SOC_CAMERA_MT9T031=m
-CONFIG_SOC_CAMERA_MT9T112=m
-CONFIG_SOC_CAMERA_MT9V022=m
+CONFIG_SOC_CAMERA_MT9M001=y
+CONFIG_SOC_CAMERA_MT9M111=y
+CONFIG_SOC_CAMERA_MT9T031=y
+CONFIG_SOC_CAMERA_MT9T112=y
+CONFIG_SOC_CAMERA_MT9V022=y
# CONFIG_SOC_CAMERA_OV2640 is not set
# CONFIG_SOC_CAMERA_OV5642 is not set
# CONFIG_SOC_CAMERA_OV6650 is not set
@@ -2618,25 +2620,25 @@ CONFIG_SOC_CAMERA_MT9V022=m
# CONFIG_SOC_CAMERA_RJ54N1 is not set
# CONFIG_SOC_CAMERA_TW9910 is not set
CONFIG_MEDIA_ATTACH=y
-CONFIG_MEDIA_TUNER=m
-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=y
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA827X=y
+CONFIG_MEDIA_TUNER_TDA18271=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
CONFIG_MEDIA_TUNER_MT2060=m
CONFIG_MEDIA_TUNER_MT2063=m
CONFIG_MEDIA_TUNER_MT2266=m
CONFIG_MEDIA_TUNER_QT1010=m
-CONFIG_MEDIA_TUNER_XC2028=m
-CONFIG_MEDIA_TUNER_XC5000=m
-CONFIG_MEDIA_TUNER_XC4000=m
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_XC4000=y
CONFIG_MEDIA_TUNER_MXL5005S=m
CONFIG_MEDIA_TUNER_MXL5007T=m
-CONFIG_MEDIA_TUNER_MC44S803=m
+CONFIG_MEDIA_TUNER_MC44S803=y
CONFIG_MEDIA_TUNER_MAX2165=m
CONFIG_MEDIA_TUNER_TDA18218=m
CONFIG_MEDIA_TUNER_FC0011=m
@@ -2779,6 +2781,7 @@ CONFIG_DISPLAY_TIMING=y
CONFIG_VIDEOMODE=y
CONFIG_OF_DISPLAY_TIMING=y
CONFIG_OF_VIDEOMODE=y
+CONFIG_HDMI=y
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
# CONFIG_FB_DDC is not set
@@ -2799,7 +2802,6 @@ CONFIG_FB_SYS_FOPS=y
CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
-# CONFIG_FB_BACKLIGHT is not set
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
@@ -3074,7 +3076,7 @@ CONFIG_MUSB_PIO_ONLY=y
#
# USB Device Class drivers
#
-CONFIG_USB_ACM=m
+CONFIG_USB_ACM=y
CONFIG_USB_PRINTER=m
CONFIG_USB_WDM=m
CONFIG_USB_TMC=m
@@ -3195,7 +3197,6 @@ CONFIG_USB_CYPRESS_CY7C63=m
CONFIG_USB_CYTHERM=m
CONFIG_USB_IDMOUSE=m
CONFIG_USB_FTDI_ELAN=m
-# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
CONFIG_USB_LD=m
CONFIG_USB_TRANCEVIBRATOR=m
@@ -3306,6 +3307,7 @@ CONFIG_LEDS_GPIO=y
# CONFIG_LEDS_PCA955X is not set
# CONFIG_LEDS_PCA9633 is not set
# CONFIG_LEDS_DAC124S085 is not set
+CONFIG_LEDS_PWM=y
# CONFIG_LEDS_REGULATOR is not set
# CONFIG_LEDS_BD2802 is not set
# CONFIG_LEDS_LT3593 is not set
@@ -3434,7 +3436,7 @@ CONFIG_UIO_PDRV=y
CONFIG_UIO_PDRV_GENIRQ=y
# CONFIG_UIO_DMEM_GENIRQ is not set
CONFIG_UIO_PRUSS=m
-CONFIG_VIRTIO=m
+CONFIG_VIRTIO=y
#
# Virtio drivers
@@ -3617,7 +3619,7 @@ CONFIG_COMMON_CLK=y
#
# Common Clock Framework
#
-# CONFIG_COMMON_CLK_DEBUG is not set
+CONFIG_COMMON_CLK_DEBUG=y
CONFIG_HWSPINLOCK=m
#
@@ -3632,13 +3634,17 @@ CONFIG_OF_IOMMU=y
#
# Remoteproc drivers (EXPERIMENTAL)
#
-CONFIG_REMOTEPROC=m
+CONFIG_REMOTEPROC=y
CONFIG_STE_MODEM_RPROC=m
+CONFIG_PRU_RPROC=y
#
# Rpmsg drivers (EXPERIMENTAL)
#
-# CONFIG_VIRT_DRIVERS is not set
+CONFIG_RPMSG=y
+CONFIG_RPMSG_NUM_BUFS=32
+CONFIG_RPMSG_BUF_SIZE=16
+CONFIG_VIRT_DRIVERS=y
# CONFIG_PM_DEVFREQ is not set
# CONFIG_EXTCON is not set
# CONFIG_MEMORY is not set
@@ -3734,6 +3740,7 @@ CONFIG_IIO_ST_GYRO_SPI_3AXIS=m
# CONFIG_ADIS16480 is not set
CONFIG_IIO_ADIS_LIB=m
CONFIG_IIO_ADIS_LIB_BUFFER=y
+CONFIG_INV_MPU6050_IIO=m
#
# Light sensors
@@ -3750,6 +3757,7 @@ CONFIG_IIO_ST_MAGN_3AXIS=m
CONFIG_IIO_ST_MAGN_I2C_3AXIS=m
CONFIG_IIO_ST_MAGN_SPI_3AXIS=m
CONFIG_PWM=y
+CONFIG_PWM_SYSFS=y
CONFIG_PWM_PCA9685=m
CONFIG_PWM_TIECAP=y
CONFIG_PWM_TIEHRPWM=y
@@ -3758,6 +3766,10 @@ CONFIG_PWM_TIPWMSS=y
# CONFIG_PWM_TWL_LED is not set
CONFIG_EHRPWM_TEST=m
# CONFIG_IPACK_BUS is not set
+CONFIG_RSTCTL=y
+CONFIG_RSTCTL_GPIO=y
+CONFIG_RSTCTL_TEST=y
+CONFIG_RSTCTL_TEST_CONSUMER=y
#
# File systems
@@ -3803,7 +3815,8 @@ CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
CONFIG_DNOTIFY=y
CONFIG_INOTIFY_USER=y
-# CONFIG_FANOTIFY is not set
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
CONFIG_QUOTA=y
# CONFIG_QUOTA_NETLINK_INTERFACE is not set
CONFIG_PRINT_QUOTA_WARNING=y
@@ -3815,6 +3828,7 @@ CONFIG_QUOTACTL=y
CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=m
CONFIG_CUSE=m
+CONFIG_GENERIC_ACL=y
#
# Caches
@@ -3845,8 +3859,8 @@ CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_TMPFS_XATTR is not set
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
CONFIG_MISC_FILESYSTEMS=y
@@ -4017,7 +4031,6 @@ CONFIG_DEBUG_MUTEXES=y
# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_ATOMIC_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-CONFIG_STACKTRACE=y
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_HIGHMEM is not set
@@ -4037,7 +4050,6 @@ CONFIG_DEBUG_INFO_REDUCED=y
CONFIG_RCU_CPU_STALL_TIMEOUT=60
# CONFIG_RCU_CPU_STALL_INFO 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
@@ -4049,20 +4061,14 @@ CONFIG_PM_NOTIFIER_ERROR_INJECT=m
# CONFIG_OF_RECONFIG_NOTIFIER_ERROR_INJECT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_DEBUG_PAGEALLOC is not set
-CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_TRACE_CLOCK=y
CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_EVENT_POWER_TRACING_DEPRECATED=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
# CONFIG_FUNCTION_TRACER is not set
@@ -4075,8 +4081,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ALL_BRANCHES is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
-CONFIG_KPROBE_EVENT=y
-CONFIG_PROBE_EVENTS=y
+# CONFIG_PROBE_EVENTS is not set
# CONFIG_RING_BUFFER_BENCHMARK is not set
# CONFIG_RBTREE_TEST is not set
# CONFIG_INTERVAL_TREE_TEST is not set
@@ -4096,7 +4101,6 @@ CONFIG_DEBUG_LL_UART_NONE=y
# CONFIG_DEBUG_SEMIHOSTING is not set
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
CONFIG_EARLY_PRINTK=y
-# CONFIG_ARM_KPROBES_TEST is not set
# CONFIG_PID_IN_CONTEXTIDR is not set
#
@@ -4229,7 +4233,7 @@ CONFIG_ASYMMETRIC_KEY_TYPE=m
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
CONFIG_PUBLIC_KEY_ALGO_RSA=m
CONFIG_X509_CERTIFICATE_PARSER=m
-CONFIG_BINARY_PRINTF=y
+# CONFIG_BINARY_PRINTF is not set
#
# Library routines
diff --git a/kernelconfig-3.2.16 b/kernelconfig-3.2.16
deleted file mode 100644
index 649ee4c..0000000
--- a/kernelconfig-3.2.16
+++ /dev/null
@@ -1,3563 +0,0 @@
-#
-# Automatically generated file; DO NOT EDIT.
-# Linux/arm 3.2.16 Kernel Configuration
-#
-CONFIG_ARM=y
-CONFIG_HAVE_PWM=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_VECTORS_BASE=0xffff0000
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-CONFIG_GENERIC_BUG=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-CONFIG_HAVE_IRQ_WORK=y
-CONFIG_IRQ_WORK=y
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_CROSS_COMPILE=""
-CONFIG_LOCALVERSION=""
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_HAVE_KERNEL_GZIP=y
-CONFIG_HAVE_KERNEL_LZMA=y
-CONFIG_HAVE_KERNEL_LZO=y
-# CONFIG_KERNEL_GZIP is not set
-# CONFIG_KERNEL_LZMA is not set
-CONFIG_KERNEL_LZO=y
-CONFIG_DEFAULT_HOSTNAME="beaglebone"
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_POSIX_MQUEUE_SYSCTL=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_FHANDLE=y
-CONFIG_TASKSTATS=y
-CONFIG_TASK_DELAY_ACCT=y
-CONFIG_TASK_XACCT=y
-CONFIG_TASK_IO_ACCOUNTING=y
-CONFIG_AUDIT=y
-CONFIG_HAVE_GENERIC_HARDIRQS=y
-
-#
-# IRQ subsystem
-#
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_HAVE_SPARSE_IRQ=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_SPARSE_IRQ=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
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=17
-CONFIG_CGROUPS=y
-# CONFIG_CGROUP_DEBUG is not set
-CONFIG_CGROUP_FREEZER=y
-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_CGROUP_PERF=y
-CONFIG_CGROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_CFS_BANDWIDTH=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_BLK_CGROUP=y
-# CONFIG_DEBUG_BLK_CGROUP 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
-# CONFIG_SYSFS_DEPRECATED is not set
-# CONFIG_RELAY is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_RD_GZIP=y
-CONFIG_RD_BZIP2=y
-CONFIG_RD_LZMA=y
-CONFIG_RD_XZ=y
-CONFIG_RD_LZO=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
-CONFIG_EXPERT=y
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-CONFIG_EMBEDDED=y
-CONFIG_HAVE_PERF_EVENTS=y
-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=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_HAVE_OPROFILE=y
-# CONFIG_KPROBES is not set
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
-CONFIG_HAVE_CLK=y
-CONFIG_HAVE_DMA_API_DEBUG=y
-CONFIG_HAVE_HW_BREAKPOINT=y
-
-#
-# GCOV-based kernel profiling
-#
-# CONFIG_GCOV_KERNEL is not set
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-CONFIG_MODULE_FORCE_LOAD=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_BLOCK=y
-CONFIG_LBDAF=y
-CONFIG_BLK_DEV_BSG=y
-# CONFIG_BLK_DEV_BSGLIB is not set
-CONFIG_BLK_DEV_INTEGRITY=y
-CONFIG_BLK_DEV_THROTTLING=y
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_CFQ_GROUP_IOSCHED=y
-# CONFIG_DEFAULT_DEADLINE is not set
-CONFIG_DEFAULT_CFQ=y
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="cfq"
-# CONFIG_INLINE_SPIN_TRYLOCK is not set
-# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
-# CONFIG_INLINE_SPIN_LOCK is not set
-# 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_INLINE_SPIN_UNLOCK_BH is not set
-# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
-# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_READ_TRYLOCK is not set
-# CONFIG_INLINE_READ_LOCK is not set
-# CONFIG_INLINE_READ_LOCK_BH is not set
-# CONFIG_INLINE_READ_LOCK_IRQ is not set
-# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
-# CONFIG_INLINE_READ_UNLOCK is not set
-# CONFIG_INLINE_READ_UNLOCK_BH is not set
-# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
-# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_WRITE_TRYLOCK is not set
-# CONFIG_INLINE_WRITE_LOCK is not set
-# CONFIG_INLINE_WRITE_LOCK_BH is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
-# CONFIG_INLINE_WRITE_UNLOCK is not set
-# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
-# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
-# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
-# CONFIG_MUTEX_SPIN_ON_OWNER is not set
-CONFIG_FREEZER=y
-
-#
-# System Type
-#
-CONFIG_MMU=y
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_VEXPRESS is not set
-# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_BCMRING is not set
-# CONFIG_ARCH_HIGHBANK is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CNS3XXX is not set
-# CONFIG_ARCH_GEMINI is not set
-# CONFIG_ARCH_PRIMA2 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_MXS is not set
-# CONFIG_ARCH_NETX is not set
-# CONFIG_ARCH_H720X is not set
-# 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_DOVE is not set
-# CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_LPC32XX is not set
-# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_MMP is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_W90X900 is not set
-# CONFIG_ARCH_TEGRA is not set
-# CONFIG_ARCH_PICOXCELL is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_MSM is not set
-# 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_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
-# CONFIG_ARCH_DAVINCI is not set
-CONFIG_ARCH_OMAP=y
-# CONFIG_PLAT_SPEAR is not set
-# CONFIG_ARCH_VT8500 is not set
-# CONFIG_ARCH_ZYNQ is not set
-# CONFIG_GPIO_PCA953X is not set
-# CONFIG_KEYBOARD_GPIO_POLLED is not set
-
-#
-# TI OMAP Common Features
-#
-# CONFIG_ARCH_OMAP1 is not set
-CONFIG_ARCH_OMAP2PLUS=y
-
-#
-# OMAP Feature Selections
-#
-# CONFIG_OMAP_SMARTREFLEX is not set
-# CONFIG_OMAP_RESET_CLOCKS is not set
-CONFIG_OMAP_MUX=y
-CONFIG_OMAP_MUX_DEBUG=y
-CONFIG_OMAP_MUX_WARNINGS=y
-CONFIG_OMAP_MCBSP=y
-CONFIG_OMAP_MBOX_FWK=y
-CONFIG_OMAP_MBOX_KFIFO_SIZE=256
-# CONFIG_OMAP_32K_TIMER is not set
-# CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE is not set
-CONFIG_OMAP_DM_TIMER=y
-CONFIG_OMAP_PM_NOOP=y
-CONFIG_MACH_OMAP_GENERIC=y
-
-#
-# TI OMAP2/3/4 Specific Features
-#
-CONFIG_ARCH_OMAP2PLUS_TYPICAL=y
-# CONFIG_ARCH_OMAP2 is not set
-CONFIG_ARCH_OMAP3=y
-# CONFIG_ARCH_OMAP4 is not set
-# CONFIG_SOC_OMAP3430 is not set
-CONFIG_SOC_OMAPTI81XX=y
-CONFIG_SOC_OMAPAM33XX=y
-CONFIG_OMAP_PACKAGE_CBB=y
-
-#
-# OMAP Board Type
-#
-CONFIG_MACH_OMAP3_BEAGLE=y
-# CONFIG_MACH_DEVKIT8000 is not set
-# CONFIG_MACH_OMAP_LDP is not set
-# CONFIG_MACH_OMAP3530_LV_SOM is not set
-# CONFIG_MACH_OMAP3_TORPEDO is not set
-# CONFIG_MACH_ENCORE is not set
-# CONFIG_MACH_OVERO is not set
-# CONFIG_MACH_OMAP3EVM is not set
-# CONFIG_MACH_OMAP3517EVM is not set
-# CONFIG_MACH_CRANEBOARD is not set
-# CONFIG_MACH_OMAP3_PANDORA is not set
-# CONFIG_MACH_OMAP3_TOUCHBOOK is not set
-# CONFIG_MACH_OMAP_3430SDP is not set
-# CONFIG_MACH_NOKIA_RM680 is not set
-# CONFIG_MACH_NOKIA_RX51 is not set
-# CONFIG_MACH_OMAP_ZOOM2 is not set
-# CONFIG_MACH_OMAP_ZOOM3 is not set
-# CONFIG_MACH_CM_T35 is not set
-# CONFIG_MACH_CM_T3517 is not set
-# CONFIG_MACH_IGEP0020 is not set
-# CONFIG_MACH_IGEP0030 is not set
-# CONFIG_MACH_SBC3530 is not set
-# CONFIG_MACH_OMAP_3630SDP is not set
-CONFIG_MACH_TI8168EVM=y
-CONFIG_MACH_TI8148EVM=y
-CONFIG_MACH_AM335XEVM=y
-CONFIG_MACH_AM335XIAEVM=y
-# CONFIG_OMAP3_EMU is not set
-# CONFIG_OMAP3_SDRC_AC_TIMING is not set
-CONFIG_OMAP3_EDMA=y
-
-#
-# System MMU
-#
-
-#
-# Processor Type
-#
-CONFIG_CPU_V7=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_THUMBEE=y
-# CONFIG_SWP_EMULATE is not set
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_BPREDICT_DISABLE is not set
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_DMA_MEM_BUFFERABLE=y
-CONFIG_MULTI_IRQ_HANDLER=y
-CONFIG_ARM_ERRATA_430973=y
-# CONFIG_ARM_ERRATA_458693 is not set
-# CONFIG_ARM_ERRATA_460075 is not set
-# CONFIG_ARM_ERRATA_720789 is not set
-# CONFIG_ARM_ERRATA_743622 is not set
-# CONFIG_ARM_ERRATA_751472 is not set
-# CONFIG_ARM_ERRATA_754322 is not set
-
-#
-# Bus support
-#
-# CONFIG_PCI_SYSCALL is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCCARD is not set
-
-#
-# 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_PREEMPT_NONE is not set
-# CONFIG_PREEMPT_VOLUNTARY is not set
-CONFIG_PREEMPT=y
-CONFIG_PREEMPT_COUNT=y
-CONFIG_HZ=100
-# CONFIG_THUMB2_KERNEL is not set
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
-CONFIG_HAVE_ARCH_PFN_VALID=y
-# CONFIG_HIGHMEM is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_HAVE_MEMBLOCK=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_COMPACTION is not set
-# 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_NEED_PER_CPU_KM=y
-# CONFIG_CLEANCACHE is not set
-CONFIG_FORCE_MAX_ZONEORDER=11
-# CONFIG_LEDS is not set
-CONFIG_ALIGNMENT_TRAP=y
-# CONFIG_UACCESS_WITH_MEMCPY is not set
-# CONFIG_SECCOMP is not set
-# CONFIG_CC_STACKPROTECTOR is not set
-# CONFIG_DEPRECATED_PARAM_STRUCT is not set
-
-#
-# Boot options
-#
-CONFIG_USE_OF=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-# CONFIG_ARM_APPENDED_DTB is not set
-CONFIG_CMDLINE=" debug "
-CONFIG_CMDLINE_FROM_BOOTLOADER=y
-# CONFIG_CMDLINE_EXTEND is not set
-# CONFIG_CMDLINE_FORCE is not set
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_KEXEC is not set
-# CONFIG_CRASH_DUMP is not set
-CONFIG_AUTO_ZRELADDR=y
-
-#
-# CPU Power Management
-#
-
-#
-# CPU Frequency scaling
-#
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_TABLE=y
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_FREQ_STAT_DETAILS=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=y
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
-
-#
-# ARM CPU frequency scaling drivers
-#
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_NEON=y
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
-CONFIG_HAVE_AOUT=y
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_MISC=y
-
-#
-# Power management options
-#
-# CONFIG_SUSPEND is not set
-CONFIG_PM_RUNTIME=y
-CONFIG_PM=y
-CONFIG_PM_DEBUG=y
-# CONFIG_PM_ADVANCED_DEBUG is not set
-# CONFIG_APM_EMULATION is not set
-CONFIG_ARCH_HAS_OPP=y
-CONFIG_PM_OPP=y
-CONFIG_PM_CLK=y
-CONFIG_CPU_PM=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARM_CPU_SUSPEND=y
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=y
-CONFIG_XFRM_SUB_POLICY=y
-CONFIG_XFRM_MIGRATE=y
-CONFIG_XFRM_STATISTICS=y
-CONFIG_XFRM_IPCOMP=m
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE_DEMUX=m
-CONFIG_NET_IPGRE=m
-# CONFIG_NET_IPGRE_BROADCAST is not set
-CONFIG_IP_MROUTE=y
-# CONFIG_IP_PIMSM_V1 is not set
-# CONFIG_IP_PIMSM_V2 is not set
-CONFIG_ARPD=y
-CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_XFRM_TUNNEL=m
-CONFIG_INET_TUNNEL=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-CONFIG_INET_LRO=m
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-CONFIG_TCP_CONG_ADVANCED=y
-CONFIG_TCP_CONG_BIC=m
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_TCP_CONG_WESTWOOD=m
-CONFIG_TCP_CONG_HTCP=m
-CONFIG_TCP_CONG_HSTCP=m
-CONFIG_TCP_CONG_HYBLA=m
-CONFIG_TCP_CONG_VEGAS=m
-CONFIG_TCP_CONG_SCALABLE=m
-CONFIG_TCP_CONG_LP=m
-CONFIG_TCP_CONG_VENO=m
-CONFIG_TCP_CONG_YEAH=m
-CONFIG_TCP_CONG_ILLINOIS=m
-CONFIG_DEFAULT_CUBIC=y
-# CONFIG_DEFAULT_RENO is not set
-CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
-CONFIG_IPV6=m
-CONFIG_IPV6_PRIVACY=y
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_ROUTE_INFO=y
-CONFIG_IPV6_OPTIMISTIC_DAD=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_MIP6=m
-CONFIG_INET6_XFRM_TUNNEL=m
-CONFIG_INET6_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_TRANSPORT=m
-CONFIG_INET6_XFRM_MODE_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_BEET=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_SIT=m
-CONFIG_IPV6_SIT_6RD=y
-CONFIG_IPV6_NDISC_NODETYPE=y
-CONFIG_IPV6_TUNNEL=m
-CONFIG_IPV6_MULTIPLE_TABLES=y
-CONFIG_IPV6_SUBTREES=y
-CONFIG_IPV6_MROUTE=y
-CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y
-CONFIG_IPV6_PIMSM_V2=y
-# CONFIG_NETWORK_SECMARK is not set
-CONFIG_NETWORK_PHY_TIMESTAMPING=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_NETFILTER_ADVANCED=y
-CONFIG_BRIDGE_NETFILTER=y
-
-#
-# Core Netfilter Configuration
-#
-# CONFIG_NETFILTER_NETLINK_QUEUE is not set
-# CONFIG_NETFILTER_NETLINK_LOG is not set
-# CONFIG_NF_CONNTRACK is not set
-CONFIG_NETFILTER_XTABLES=m
-
-#
-# Xtables combined modules
-#
-# CONFIG_NETFILTER_XT_MARK is not set
-
-#
-# Xtables targets
-#
-CONFIG_NETFILTER_XT_TARGET_AUDIT=m
-# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
-# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
-# CONFIG_NETFILTER_XT_TARGET_LED is not set
-# CONFIG_NETFILTER_XT_TARGET_MARK is not set
-# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
-# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
-# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
-# CONFIG_NETFILTER_XT_TARGET_TEE is not set
-# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
-
-#
-# Xtables matches
-#
-# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
-# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
-# CONFIG_NETFILTER_XT_MATCH_CPU is not set
-# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
-# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
-# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
-# CONFIG_NETFILTER_XT_MATCH_ESP is not set
-# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
-# CONFIG_NETFILTER_XT_MATCH_HL is not set
-# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
-# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
-# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
-# CONFIG_NETFILTER_XT_MATCH_MAC is not set
-# CONFIG_NETFILTER_XT_MATCH_MARK is not set
-# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
-# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
-# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
-# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
-# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
-# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
-# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
-# CONFIG_NETFILTER_XT_MATCH_REALM is not set
-# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
-# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
-# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
-# CONFIG_NETFILTER_XT_MATCH_STRING is not set
-# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
-# CONFIG_NETFILTER_XT_MATCH_TIME is not set
-# CONFIG_NETFILTER_XT_MATCH_U32 is not set
-# CONFIG_IP_VS is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_NF_DEFRAG_IPV4 is not set
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=m
-# CONFIG_IP_NF_MATCH_AH is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_TTL is not set
-# CONFIG_IP_NF_FILTER is not set
-# CONFIG_IP_NF_TARGET_LOG is not set
-# CONFIG_IP_NF_TARGET_ULOG is not set
-# CONFIG_IP_NF_MANGLE is not set
-# CONFIG_IP_NF_RAW is not set
-CONFIG_IP_NF_ARPTABLES=m
-# CONFIG_IP_NF_ARPFILTER is not set
-# CONFIG_IP_NF_ARP_MANGLE is not set
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_NF_DEFRAG_IPV6 is not set
-# CONFIG_IP6_NF_QUEUE is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-# CONFIG_BRIDGE_NF_EBTABLES is not set
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_SCTP is not set
-# CONFIG_RDS is not set
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_L2TP is not set
-CONFIG_STP=m
-CONFIG_GARP=m
-CONFIG_BRIDGE=m
-CONFIG_BRIDGE_IGMP_SNOOPING=y
-# CONFIG_NET_DSA is not set
-CONFIG_VLAN_8021Q=m
-CONFIG_VLAN_8021Q_GVRP=y
-# CONFIG_DECNET is not set
-CONFIG_LLC=m
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# 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
-CONFIG_NET_SCHED=y
-
-#
-# Queueing/Scheduling
-#
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_MULTIQ=m
-CONFIG_NET_SCH_RED=m
-# CONFIG_NET_SCH_SFB is not set
-# CONFIG_NET_SCH_SFQ is not set
-# CONFIG_NET_SCH_TEQL is not set
-# CONFIG_NET_SCH_TBF is not set
-# CONFIG_NET_SCH_GRED is not set
-# CONFIG_NET_SCH_DSMARK is not set
-# CONFIG_NET_SCH_NETEM is not set
-# CONFIG_NET_SCH_DRR is not set
-# CONFIG_NET_SCH_MQPRIO is not set
-# CONFIG_NET_SCH_CHOKE is not set
-# CONFIG_NET_SCH_QFQ is not set
-
-#
-# Classification
-#
-# CONFIG_NET_CLS_BASIC is not set
-# CONFIG_NET_CLS_TCINDEX is not set
-# CONFIG_NET_CLS_ROUTE4 is not set
-# CONFIG_NET_CLS_FW is not set
-# CONFIG_NET_CLS_U32 is not set
-# CONFIG_NET_CLS_RSVP is not set
-# CONFIG_NET_CLS_RSVP6 is not set
-# CONFIG_NET_CLS_FLOW is not set
-# CONFIG_NET_CLS_CGROUP is not set
-# CONFIG_NET_EMATCH is not set
-# CONFIG_NET_CLS_ACT is not set
-CONFIG_NET_SCH_FIFO=y
-# CONFIG_DCB is not set
-CONFIG_DNS_RESOLVER=y
-# CONFIG_BATMAN_ADV is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-CONFIG_CAN=y
-CONFIG_CAN_RAW=y
-CONFIG_CAN_BCM=m
-CONFIG_CAN_GW=m
-
-#
-# CAN Device Drivers
-#
-CONFIG_CAN_VCAN=m
-CONFIG_CAN_SLCAN=m
-CONFIG_CAN_DEV=y
-CONFIG_CAN_CALC_BITTIMING=y
-CONFIG_CAN_TI_HECC=m
-CONFIG_CAN_MCP251X=y
-# CONFIG_CAN_SJA1000 is not set
-# CONFIG_CAN_C_CAN is not set
-CONFIG_CAN_D_CAN=y
-CONFIG_CAN_D_CAN_PLATFORM=y
-
-#
-# CAN USB interfaces
-#
-CONFIG_CAN_EMS_USB=m
-CONFIG_CAN_ESD_USB2=m
-# CONFIG_CAN_SOFTING is not set
-CONFIG_CAN_DEBUG_DEVICES=y
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-# CONFIG_IRDA_ULTRA is not set
-
-#
-# IrDA options
-#
-# CONFIG_IRDA_CACHE_LAST_LSAP is not set
-# CONFIG_IRDA_FAST_RR is not set
-# CONFIG_IRDA_DEBUG is not set
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=m
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-CONFIG_KINGSUN_DONGLE=m
-CONFIG_KSDAZZLE_DONGLE=m
-CONFIG_KS959_DONGLE=m
-
-#
-# FIR device drivers
-#
-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
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_HIDP=m
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BT_HCIBTUSB=m
-CONFIG_BT_HCIBTSDIO=m
-CONFIG_BT_HCIUART=m
-CONFIG_BT_HCIUART_H4=y
-CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_ATH3K=y
-CONFIG_BT_HCIUART_LL=y
-CONFIG_BT_HCIBCM203X=m
-CONFIG_BT_HCIBPA10X=m
-CONFIG_BT_HCIBFUSB=m
-# CONFIG_BT_HCIVHCI is not set
-# CONFIG_BT_MRVL is not set
-# CONFIG_BT_ATH3K is not set
-# CONFIG_AF_RXRPC is not set
-CONFIG_FIB_RULES=y
-CONFIG_WIRELESS=y
-CONFIG_WIRELESS_EXT=y
-CONFIG_WEXT_CORE=y
-CONFIG_WEXT_PROC=y
-CONFIG_WEXT_SPY=y
-CONFIG_WEXT_PRIV=y
-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_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_DEBUG is not set
-CONFIG_MAC80211=m
-CONFIG_MAC80211_HAS_RC=y
-CONFIG_MAC80211_RC_PID=y
-CONFIG_MAC80211_RC_MINSTREL=y
-CONFIG_MAC80211_RC_MINSTREL_HT=y
-CONFIG_MAC80211_RC_DEFAULT_PID=y
-# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
-CONFIG_MAC80211_RC_DEFAULT="pid"
-# CONFIG_MAC80211_MESH is not set
-# CONFIG_MAC80211_LEDS is not set
-# CONFIG_MAC80211_DEBUGFS is not set
-# CONFIG_MAC80211_DEBUG_MENU is not set
-CONFIG_WIMAX=m
-CONFIG_WIMAX_DEBUG_LEVEL=8
-CONFIG_RFKILL=m
-CONFIG_RFKILL_LEDS=y
-CONFIG_RFKILL_INPUT=y
-CONFIG_RFKILL_REGULATOR=m
-CONFIG_RFKILL_GPIO=m
-# CONFIG_NET_9P is not set
-# CONFIG_CAIF is not set
-CONFIG_CEPH_LIB=m
-# CONFIG_CEPH_LIB_PRETTYDEBUG is not set
-CONFIG_CEPH_LIB_USE_DNS_RESOLVER=y
-CONFIG_NFC=m
-CONFIG_NFC_NCI=m
-
-#
-# Near Field Communication (NFC) devices
-#
-CONFIG_PN544_NFC=m
-CONFIG_NFC_PN533=m
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_UEVENT_HELPER_PATH=""
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-CONFIG_FIRMWARE_IN_KERNEL=y
-CONFIG_EXTRA_FIRMWARE=""
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_DEVRES is not set
-# CONFIG_SYS_HYPERVISOR is not set
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_SPI=y
-
-#
-# CBUS support
-#
-# CONFIG_CBUS is not set
-CONFIG_CONNECTOR=y
-CONFIG_PROC_EVENTS=y
-# CONFIG_MTD is not set
-CONFIG_DTC=y
-CONFIG_OF=y
-
-#
-# Device Tree and Open Firmware support
-#
-CONFIG_PROC_DEVICETREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_DEVICE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_I2C=y
-CONFIG_OF_NET=y
-CONFIG_OF_SPI=y
-CONFIG_OF_MDIO=y
-CONFIG_PARPORT=m
-# CONFIG_PARPORT_PC is not set
-# CONFIG_PARPORT_GSC is not set
-# CONFIG_PARPORT_AX88796 is not set
-CONFIG_PARPORT_1284=y
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-# CONFIG_BLK_DEV_DRBD is not set
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=2
-CONFIG_BLK_DEV_RAM_SIZE=65536
-# CONFIG_BLK_DEV_XIP is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-CONFIG_CDROM_PKTCDVD_WCACHE=y
-CONFIG_ATA_OVER_ETH=m
-# CONFIG_MG_DISK is not set
-# CONFIG_VIRTIO_BLK is not set
-# CONFIG_BLK_DEV_RBD is not set
-# 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
-# CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_APDS9802ALS is not set
-# CONFIG_ISL29003 is not set
-# CONFIG_ISL29020 is not set
-# CONFIG_SENSORS_TSL2550 is not set
-# CONFIG_SENSORS_BH1780 is not set
-# CONFIG_SENSORS_BH1770 is not set
-# CONFIG_SENSORS_APDS990X is not set
-# CONFIG_HMC6352 is not set
-# CONFIG_DS1682 is not set
-# CONFIG_TI_DAC7512 is not set
-CONFIG_BMP085=m
-# CONFIG_USB_SWITCH_FSA9480 is not set
-# CONFIG_C2PORT is not set
-
-#
-# EEPROM support
-#
-CONFIG_EEPROM_AT24=y
-# CONFIG_EEPROM_AT25 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_EEPROM_MAX6875 is not set
-CONFIG_EEPROM_93CX6=m
-# CONFIG_EEPROM_93XX46 is not set
-# CONFIG_IWMC3200TOP is not set
-
-#
-# Texas Instruments shared transport line discipline
-#
-# CONFIG_TI_ST is not set
-# CONFIG_SENSORS_LIS3_SPI is not set
-# CONFIG_SENSORS_LIS3_I2C is not set
-
-#
-# Altera FPGA firmware download module
-#
-# CONFIG_ALTERA_STAPL is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI_MOD=y
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_TGT is not set
-# CONFIG_SCSI_NETLINK is not set
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=y
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_CHR_DEV_SCH=y
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-CONFIG_SCSI_SCAN_ASYNC=y
-CONFIG_SCSI_WAIT_SCAN=m
-
-#
-# SCSI Transports
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_ISCSI_BOOT_SYSFS is not set
-# CONFIG_LIBFC is not set
-# CONFIG_LIBFCOE is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_DH is not set
-# CONFIG_SCSI_OSD_INITIATOR is not set
-# CONFIG_ATA is not set
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID10=m
-CONFIG_MD_RAID456=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_MD_FAULTY=m
-CONFIG_BLK_DEV_DM=m
-# CONFIG_DM_DEBUG is not set
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-# CONFIG_DM_THIN_PROVISIONING is not set
-CONFIG_DM_MIRROR=m
-CONFIG_DM_RAID=m
-CONFIG_DM_LOG_USERSPACE=m
-CONFIG_DM_ZERO=m
-CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_QL=m
-CONFIG_DM_MULTIPATH_ST=m
-# CONFIG_DM_DELAY is not set
-CONFIG_DM_UEVENT=y
-CONFIG_DM_FLAKEY=m
-# CONFIG_TARGET_CORE is not set
-CONFIG_NETDEVICES=y
-CONFIG_NET_CORE=y
-CONFIG_BONDING=m
-CONFIG_DUMMY=m
-CONFIG_EQUALIZER=m
-CONFIG_MII=y
-CONFIG_MACVLAN=m
-CONFIG_MACVTAP=m
-CONFIG_NETCONSOLE=m
-CONFIG_NETPOLL=y
-# CONFIG_NETPOLL_TRAP is not set
-CONFIG_NET_POLL_CONTROLLER=y
-CONFIG_TUN=m
-# CONFIG_VETH is not set
-# CONFIG_VIRTIO_NET is not set
-
-#
-# CAIF transport drivers
-#
-CONFIG_ETHERNET=y
-CONFIG_NET_VENDOR_BROADCOM=y
-# CONFIG_B44 is not set
-CONFIG_NET_VENDOR_CHELSIO=y
-# CONFIG_DM9000 is not set
-# CONFIG_DNET is not set
-CONFIG_NET_VENDOR_DLINK=y
-# CONFIG_DE600 is not set
-# CONFIG_DE620 is not set
-# CONFIG_NET_VENDOR_FARADAY is not set
-# CONFIG_NET_VENDOR_INTEL is not set
-# CONFIG_NET_VENDOR_MARVELL is not set
-# CONFIG_NET_VENDOR_MICREL is not set
-# CONFIG_NET_VENDOR_MICROCHIP is not set
-CONFIG_NET_VENDOR_NATSEMI=y
-CONFIG_NET_VENDOR_8390=y
-# CONFIG_AX88796 is not set
-# CONFIG_ETHOC is not set
-# CONFIG_NET_VENDOR_SEEQ is not set
-CONFIG_NET_VENDOR_SMSC=y
-CONFIG_SMC91X=y
-# CONFIG_SMC911X is not set
-CONFIG_SMSC911X=y
-# CONFIG_SMSC911X_ARCH_HOOKS is not set
-# CONFIG_NET_VENDOR_STMICRO is not set
-CONFIG_NET_VENDOR_TI=y
-# CONFIG_TI_DAVINCI_EMAC is not set
-CONFIG_TI_DAVINCI_MDIO=y
-CONFIG_TI_DAVINCI_CPDMA=y
-CONFIG_TI_CPSW=y
-# CONFIG_TLK110_WORKAROUND is not set
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_QSEMI_PHY is not set
-# CONFIG_LXT_PHY is not set
-# CONFIG_CICADA_PHY is not set
-# CONFIG_VITESSE_PHY is not set
-CONFIG_SMSC_PHY=y
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
-# CONFIG_NATIONAL_PHY is not set
-# CONFIG_STE10XP is not set
-# CONFIG_LSI_ET1011C_PHY is not set
-# CONFIG_MICREL_PHY is not set
-# CONFIG_FIXED_PHY is not set
-# CONFIG_MDIO_BITBANG is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_MPPE=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPPOE=m
-CONFIG_PPTP=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_SLIP=m
-CONFIG_SLHC=m
-# CONFIG_SLIP_COMPRESSED is not set
-CONFIG_SLIP_SMART=y
-# CONFIG_SLIP_MODE_SLIP6 is not set
-
-#
-# USB Network Adapters
-#
-CONFIG_USB_CATC=y
-CONFIG_USB_KAWETH=y
-CONFIG_USB_PEGASUS=y
-CONFIG_USB_RTL8150=y
-CONFIG_USB_USBNET=y
-CONFIG_USB_NET_AX8817X=y
-CONFIG_USB_NET_CDCETHER=y
-# CONFIG_USB_NET_CDC_EEM is not set
-CONFIG_USB_NET_CDC_NCM=y
-CONFIG_USB_NET_DM9601=y
-CONFIG_USB_NET_SMSC75XX=m
-CONFIG_USB_NET_SMSC95XX=m
-CONFIG_USB_NET_GL620A=m
-CONFIG_USB_NET_NET1080=m
-CONFIG_USB_NET_PLUSB=m
-CONFIG_USB_NET_MCS7830=m
-CONFIG_USB_NET_RNDIS_HOST=m
-CONFIG_USB_NET_CDC_SUBSET=y
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_BELKIN=y
-CONFIG_USB_ARMLINUX=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_KC2190=y
-CONFIG_USB_NET_ZAURUS=y
-CONFIG_USB_NET_CX82310_ETH=m
-CONFIG_USB_NET_KALMIA=m
-CONFIG_USB_HSO=m
-CONFIG_USB_NET_INT51X1=m
-CONFIG_USB_IPHETH=m
-CONFIG_USB_SIERRA_NET=m
-CONFIG_USB_VL600=m
-CONFIG_WLAN=y
-# CONFIG_LIBERTAS_THINFIRM is not set
-CONFIG_AT76C50X_USB=m
-CONFIG_USB_ZD1201=m
-CONFIG_USB_NET_RNDIS_WLAN=m
-CONFIG_RTL8187=m
-# CONFIG_MAC80211_HWSIM is not set
-# CONFIG_ATH_COMMON is not set
-# CONFIG_B43 is not set
-# CONFIG_B43LEGACY is not set
-CONFIG_BRCMUTIL=m
-CONFIG_BRCMFMAC=m
-# CONFIG_BRCMDBG is not set
-# CONFIG_HOSTAP is not set
-# CONFIG_IWM is not set
-CONFIG_LIBERTAS=m
-CONFIG_LIBERTAS_USB=m
-CONFIG_LIBERTAS_SDIO=m
-# CONFIG_LIBERTAS_SPI is not set
-CONFIG_LIBERTAS_DEBUG=y
-# CONFIG_LIBERTAS_MESH is not set
-CONFIG_P54_COMMON=m
-CONFIG_P54_USB=m
-# CONFIG_P54_SPI is not set
-CONFIG_RT2X00=m
-CONFIG_RT2500USB=m
-CONFIG_RT73USB=m
-CONFIG_RT2800USB=m
-CONFIG_RT2800USB_RT33XX=y
-CONFIG_RT2800USB_RT35XX=y
-CONFIG_RT2800USB_RT53XX=y
-CONFIG_RT2800USB_UNKNOWN=y
-CONFIG_RT2800_LIB=m
-CONFIG_RT2X00_LIB_USB=m
-CONFIG_RT2X00_LIB=m
-CONFIG_RT2X00_LIB_FIRMWARE=y
-CONFIG_RT2X00_LIB_CRYPTO=y
-CONFIG_RT2X00_LIB_LEDS=y
-# CONFIG_RT2X00_DEBUG is not set
-CONFIG_RTL8192CU=m
-CONFIG_RTLWIFI=m
-CONFIG_RTL8192C_COMMON=m
-# CONFIG_WL1251 is not set
-CONFIG_WL12XX_MENU=m
-CONFIG_WL12XX=m
-CONFIG_WL12XX_SPI=m
-CONFIG_WL12XX_SDIO=m
-# CONFIG_WL12XX_SDIO_TEST is not set
-CONFIG_WL12XX_PLATFORM_DATA=y
-CONFIG_ZD1211RW=m
-# CONFIG_ZD1211RW_DEBUG is not set
-# CONFIG_MWIFIEX is not set
-
-#
-# WiMAX Wireless Broadband devices
-#
-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
-#
-CONFIG_INPUT=y
-CONFIG_INPUT_FF_MEMLESS=m
-CONFIG_INPUT_POLLDEV=m
-# CONFIG_INPUT_SPARSEKMAP is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_JOYDEV=m
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-# CONFIG_KEYBOARD_ADP5588 is not set
-# CONFIG_KEYBOARD_ADP5589 is not set
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_QT1070 is not set
-# CONFIG_KEYBOARD_QT2160 is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_KEYBOARD_TCA6416 is not set
-# CONFIG_KEYBOARD_MATRIX is not set
-# CONFIG_KEYBOARD_LM8323 is not set
-# CONFIG_KEYBOARD_MAX7359 is not set
-# CONFIG_KEYBOARD_MCS is not set
-# CONFIG_KEYBOARD_MPR121 is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_OPENCORES is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
-CONFIG_KEYBOARD_TWL4030=y
-# CONFIG_KEYBOARD_XTKBD is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-CONFIG_MOUSE_PS2_ALPS=y
-CONFIG_MOUSE_PS2_LOGIPS2PP=y
-CONFIG_MOUSE_PS2_SYNAPTICS=y
-CONFIG_MOUSE_PS2_TRACKPOINT=y
-# CONFIG_MOUSE_PS2_ELANTECH is not set
-# CONFIG_MOUSE_PS2_SENTELIC is not set
-# CONFIG_MOUSE_PS2_TOUCHKIT is not set
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_APPLETOUCH is not set
-# CONFIG_MOUSE_BCM5974 is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_MOUSE_GPIO is not set
-# CONFIG_MOUSE_SYNAPTICS_I2C is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-# CONFIG_TOUCHSCREEN_AD7877 is not set
-# CONFIG_TOUCHSCREEN_AD7879 is not set
-# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set
-# CONFIG_TOUCHSCREEN_BU21013 is not set
-# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
-# CONFIG_TOUCHSCREEN_DYNAPRO is not set
-# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
-# CONFIG_TOUCHSCREEN_EETI is not set
-# CONFIG_TOUCHSCREEN_FUJITSU is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
-# CONFIG_TOUCHSCREEN_MAX11801 is not set
-# CONFIG_TOUCHSCREEN_MCS5000 is not set
-# CONFIG_TOUCHSCREEN_MTOUCH is not set
-# CONFIG_TOUCHSCREEN_INEXIO is not set
-# CONFIG_TOUCHSCREEN_MK712 is not set
-# CONFIG_TOUCHSCREEN_PENMOUNT is not set
-# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
-# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-CONFIG_TOUCHSCREEN_TI_TSCADC=y
-CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
-CONFIG_TOUCHSCREEN_USB_EGALAX=y
-CONFIG_TOUCHSCREEN_USB_PANJIT=y
-CONFIG_TOUCHSCREEN_USB_3M=y
-CONFIG_TOUCHSCREEN_USB_ITM=y
-CONFIG_TOUCHSCREEN_USB_ETURBO=y
-CONFIG_TOUCHSCREEN_USB_GUNZE=y
-CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
-CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
-CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
-CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
-CONFIG_TOUCHSCREEN_USB_GOTOP=y
-CONFIG_TOUCHSCREEN_USB_JASTEC=y
-CONFIG_TOUCHSCREEN_USB_E2I=y
-CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y
-CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y
-CONFIG_TOUCHSCREEN_USB_NEXIO=y
-# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
-CONFIG_TOUCHSCREEN_TSC_SERIO=m
-CONFIG_TOUCHSCREEN_TSC2005=m
-CONFIG_TOUCHSCREEN_TSC2007=m
-# CONFIG_TOUCHSCREEN_W90X900 is not set
-# CONFIG_TOUCHSCREEN_ST1232 is not set
-# CONFIG_TOUCHSCREEN_TPS6507X is not set
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_AD714X=m
-CONFIG_INPUT_AD714X_I2C=m
-CONFIG_INPUT_AD714X_SPI=m
-CONFIG_INPUT_BMA150=m
-CONFIG_INPUT_MMA8450=m
-CONFIG_INPUT_MPU3050=m
-CONFIG_INPUT_ATI_REMOTE2=m
-CONFIG_INPUT_KEYSPAN_REMOTE=m
-CONFIG_INPUT_KXTJ9=m
-# CONFIG_INPUT_KXTJ9_POLLED_MODE is not set
-CONFIG_INPUT_POWERMATE=m
-CONFIG_INPUT_YEALINK=m
-CONFIG_INPUT_CM109=m
-CONFIG_INPUT_TWL4030_PWRBUTTON=y
-CONFIG_INPUT_TWL4030_VIBRA=m
-CONFIG_INPUT_TWL6040_VIBRA=m
-CONFIG_INPUT_UINPUT=m
-CONFIG_INPUT_PCF8574=m
-# CONFIG_INPUT_PWM_BEEPER is not set
-CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
-CONFIG_INPUT_ADXL34X=m
-CONFIG_INPUT_ADXL34X_I2C=m
-CONFIG_INPUT_ADXL34X_SPI=m
-CONFIG_INPUT_CMA3000=m
-CONFIG_INPUT_CMA3000_I2C=m
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PARKBD is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_SERIO_ALTERA_PS2 is not set
-# CONFIG_SERIO_PS2MULT is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_N_GSM is not set
-# CONFIG_TRACE_SINK is not set
-CONFIG_DEVKMEM=y
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_RSA=y
-# CONFIG_SERIAL_8250_DW is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_MAX3100 is not set
-# CONFIG_SERIAL_MAX3107 is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_OF_PLATFORM is not set
-CONFIG_SERIAL_OMAP=y
-CONFIG_SERIAL_OMAP_CONSOLE=y
-# CONFIG_SERIAL_TIMBERDALE is not set
-# CONFIG_SERIAL_ALTERA_JTAGUART is not set
-# CONFIG_SERIAL_ALTERA_UART is not set
-# CONFIG_SERIAL_IFX6X60 is not set
-# CONFIG_SERIAL_XILINX_PS_UART is not set
-# CONFIG_TTY_PRINTK is not set
-CONFIG_PRINTER=m
-# CONFIG_LP_CONSOLE is not set
-# CONFIG_PPDEV is not set
-# CONFIG_HVC_DCC is not set
-# CONFIG_VIRTIO_CONSOLE is not set
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
-# CONFIG_HW_RANDOM_TIMERIOMEM is not set
-# CONFIG_HW_RANDOM_VIRTIO is not set
-# CONFIG_R3964 is not set
-CONFIG_RAW_DRIVER=m
-CONFIG_MAX_RAW_DEVS=256
-# CONFIG_TCG_TPM is not set
-# CONFIG_RAMOOPS is not set
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_CHARDEV=y
-# CONFIG_I2C_MUX is not set
-CONFIG_I2C_HELPER_AUTO=y
-CONFIG_I2C_ALGOBIT=m
-
-#
-# I2C Hardware Bus support
-#
-
-#
-# I2C system bus drivers (mostly embedded / system-on-chip)
-#
-# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
-# CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_OCORES is not set
-CONFIG_I2C_OMAP=y
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_PXA_PCI is not set
-# CONFIG_I2C_SIMTEC is not set
-# CONFIG_I2C_XILINX is not set
-
-#
-# External I2C/SMBus adapter drivers
-#
-# CONFIG_I2C_DIOLAN_U2C is not set
-# CONFIG_I2C_PARPORT is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_TINY_USB is not set
-
-#
-# Other I2C/SMBus bus drivers
-#
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-CONFIG_SPI=y
-# CONFIG_SPI_DEBUG is not set
-CONFIG_SPI_MASTER=y
-
-#
-# SPI Master Controller Drivers
-#
-# CONFIG_SPI_ALTERA is not set
-CONFIG_SPI_BITBANG=m
-# CONFIG_SPI_BUTTERFLY is not set
-CONFIG_SPI_GPIO=m
-# CONFIG_SPI_LM70_LLP is not set
-# CONFIG_SPI_OC_TINY is not set
-CONFIG_SPI_OMAP24XX=y
-# CONFIG_SPI_PXA2XX_PCI is not set
-# CONFIG_SPI_XILINX is not set
-# CONFIG_SPI_DESIGNWARE is not set
-
-#
-# SPI Protocol Masters
-#
-CONFIG_SPI_SPIDEV=m
-# CONFIG_SPI_TLE62X0 is not set
-
-#
-# PPS support
-#
-# CONFIG_PPS is not set
-
-#
-# PPS generators support
-#
-
-#
-# PTP clock support
-#
-
-#
-# Enable Device Drivers -> PPS to see the PTP clock options.
-#
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-CONFIG_GPIOLIB=y
-CONFIG_DEBUG_GPIO=y
-CONFIG_GPIO_SYSFS=y
-
-#
-# Memory mapped GPIO drivers:
-#
-# CONFIG_GPIO_GENERIC_PLATFORM is not set
-# CONFIG_GPIO_IT8761E is not set
-
-#
-# I2C GPIO expanders:
-#
-# CONFIG_GPIO_MAX7300 is not set
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_PCF857X is not set
-# CONFIG_GPIO_SX150X is not set
-CONFIG_GPIO_TWL4030=y
-# CONFIG_GPIO_ADP5588 is not set
-
-#
-# PCI GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-# CONFIG_GPIO_MAX7301 is not set
-# CONFIG_GPIO_MCP23S08 is not set
-# CONFIG_GPIO_MC33880 is not set
-# CONFIG_GPIO_74X164 is not set
-
-#
-# AC97 GPIO expanders:
-#
-
-#
-# MODULbus GPIO expanders:
-#
-CONFIG_GENERIC_PWM=y
-CONFIG_DAVINCI_EHRPWM=y
-CONFIG_ECAP_PWM=y
-CONFIG_W1=y
-CONFIG_W1_CON=y
-
-#
-# 1-wire Bus Masters
-#
-CONFIG_W1_MASTER_DS2490=m
-CONFIG_W1_MASTER_DS2482=m
-CONFIG_W1_MASTER_DS1WM=m
-CONFIG_W1_MASTER_GPIO=y
-# CONFIG_HDQ_MASTER_OMAP is not set
-
-#
-# 1-wire Slaves
-#
-CONFIG_W1_SLAVE_THERM=y
-CONFIG_W1_SLAVE_SMEM=m
-CONFIG_W1_SLAVE_DS2408=m
-CONFIG_W1_SLAVE_DS2423=m
-CONFIG_W1_SLAVE_DS2431=m
-CONFIG_W1_SLAVE_DS2433=m
-CONFIG_W1_SLAVE_DS2433_CRC=y
-CONFIG_W1_SLAVE_DS2760=m
-CONFIG_W1_SLAVE_DS2780=m
-CONFIG_W1_SLAVE_BQ27000=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_DS2782 is not set
-# CONFIG_BATTERY_BQ20Z75 is not set
-# CONFIG_BATTERY_BQ27x00 is not set
-# CONFIG_BATTERY_MAX17040 is not set
-# CONFIG_BATTERY_MAX17042 is not set
-# CONFIG_CHARGER_ISP1704 is not set
-# CONFIG_CHARGER_MAX8903 is not set
-# CONFIG_CHARGER_TWL4030 is not set
-# CONFIG_CHARGER_GPIO is not set
-CONFIG_HWMON=y
-CONFIG_HWMON_VID=m
-# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Native drivers
-#
-CONFIG_SENSORS_AD7314=m
-CONFIG_SENSORS_AD7414=m
-CONFIG_SENSORS_AD7418=m
-CONFIG_SENSORS_ADCXX=m
-CONFIG_SENSORS_ADM1021=m
-CONFIG_SENSORS_ADM1025=m
-CONFIG_SENSORS_ADM1026=m
-CONFIG_SENSORS_ADM1029=m
-CONFIG_SENSORS_ADM1031=m
-CONFIG_SENSORS_ADM9240=m
-CONFIG_SENSORS_ADT7411=m
-CONFIG_SENSORS_ADT7462=m
-CONFIG_SENSORS_ADT7470=m
-CONFIG_SENSORS_ADT7475=m
-CONFIG_SENSORS_ASC7621=m
-CONFIG_SENSORS_ATXP1=m
-CONFIG_SENSORS_DS620=m
-CONFIG_SENSORS_DS1621=m
-CONFIG_SENSORS_F71805F=m
-CONFIG_SENSORS_F71882FG=m
-CONFIG_SENSORS_F75375S=m
-CONFIG_SENSORS_G760A=m
-CONFIG_SENSORS_GL518SM=m
-CONFIG_SENSORS_GL520SM=m
-CONFIG_SENSORS_GPIO_FAN=m
-CONFIG_SENSORS_IT87=m
-CONFIG_SENSORS_JC42=m
-CONFIG_SENSORS_LINEAGE=m
-CONFIG_SENSORS_LM63=m
-CONFIG_SENSORS_LM70=m
-CONFIG_SENSORS_LM73=m
-CONFIG_SENSORS_LM75=m
-CONFIG_SENSORS_LM77=m
-CONFIG_SENSORS_LM78=m
-CONFIG_SENSORS_LM80=m
-CONFIG_SENSORS_LM83=m
-CONFIG_SENSORS_LM85=m
-CONFIG_SENSORS_LM87=m
-CONFIG_SENSORS_LM90=m
-CONFIG_SENSORS_LM92=m
-CONFIG_SENSORS_LM93=m
-CONFIG_SENSORS_LTC4151=m
-CONFIG_SENSORS_LTC4215=m
-CONFIG_SENSORS_LTC4245=m
-CONFIG_SENSORS_LTC4261=m
-CONFIG_SENSORS_LM95241=m
-CONFIG_SENSORS_LM95245=m
-CONFIG_SENSORS_MAX1111=m
-CONFIG_SENSORS_MAX16065=m
-CONFIG_SENSORS_MAX1619=m
-CONFIG_SENSORS_MAX1668=m
-CONFIG_SENSORS_MAX6639=m
-CONFIG_SENSORS_MAX6642=m
-CONFIG_SENSORS_MAX6650=m
-CONFIG_SENSORS_NTC_THERMISTOR=m
-CONFIG_SENSORS_PC87360=m
-CONFIG_SENSORS_PC87427=m
-CONFIG_SENSORS_PCF8591=m
-CONFIG_PMBUS=m
-CONFIG_SENSORS_PMBUS=m
-# CONFIG_SENSORS_ADM1275 is not set
-# CONFIG_SENSORS_LM25066 is not set
-CONFIG_SENSORS_LTC2978=m
-# CONFIG_SENSORS_MAX16064 is not set
-# CONFIG_SENSORS_MAX34440 is not set
-# CONFIG_SENSORS_MAX8688 is not set
-# CONFIG_SENSORS_UCD9000 is not set
-# CONFIG_SENSORS_UCD9200 is not set
-CONFIG_SENSORS_ZL6100=m
-CONFIG_SENSORS_SHT15=m
-CONFIG_SENSORS_SHT21=m
-CONFIG_SENSORS_SMM665=m
-CONFIG_SENSORS_DME1737=m
-CONFIG_SENSORS_EMC1403=m
-CONFIG_SENSORS_EMC2103=m
-CONFIG_SENSORS_EMC6W201=m
-CONFIG_SENSORS_SMSC47M1=m
-CONFIG_SENSORS_SMSC47M192=m
-CONFIG_SENSORS_SMSC47B397=m
-CONFIG_SENSORS_SCH56XX_COMMON=m
-CONFIG_SENSORS_SCH5627=m
-CONFIG_SENSORS_SCH5636=m
-CONFIG_SENSORS_ADS1015=m
-CONFIG_SENSORS_ADS7828=m
-CONFIG_SENSORS_ADS7871=m
-CONFIG_SENSORS_AMC6821=m
-CONFIG_SENSORS_THMC50=m
-CONFIG_SENSORS_TMP102=m
-CONFIG_SENSORS_TMP401=m
-CONFIG_SENSORS_TMP421=m
-CONFIG_SENSORS_VT1211=m
-CONFIG_SENSORS_W83781D=m
-CONFIG_SENSORS_W83791D=m
-CONFIG_SENSORS_W83792D=m
-CONFIG_SENSORS_W83793=m
-CONFIG_SENSORS_W83795=m
-# CONFIG_SENSORS_W83795_FANCTRL is not set
-CONFIG_SENSORS_W83L785TS=m
-CONFIG_SENSORS_W83L786NG=m
-CONFIG_SENSORS_W83627HF=m
-CONFIG_SENSORS_W83627EHF=m
-# CONFIG_THERMAL is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_DW_WATCHDOG is not set
-CONFIG_OMAP_WATCHDOG=y
-CONFIG_TWL4030_WATCHDOG=y
-# CONFIG_MAX63XX_WATCHDOG is not set
-
-#
-# USB-based Watchdog Cards
-#
-# CONFIG_USBPCWATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
-CONFIG_BCMA_POSSIBLE=y
-
-#
-# Broadcom specific AMBA
-#
-# CONFIG_BCMA is not set
-
-#
-# Multifunction device drivers
-#
-CONFIG_MFD_CORE=y
-# CONFIG_MFD_88PM860X 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_TPS6105X is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_TPS6507X is not set
-CONFIG_MFD_TPS65217=y
-# CONFIG_MFD_TPS6586X 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=y
-# CONFIG_TWL4030_MADC is not set
-CONFIG_TWL4030_POWER=y
-CONFIG_MFD_TWL4030_AUDIO=y
-# CONFIG_TWL6030_PWM is not set
-CONFIG_TWL6040_CORE=y
-# CONFIG_MFD_STMPE is not set
-# CONFIG_MFD_TC3589X is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_T7L66XB is not set
-# CONFIG_MFD_TC6387XB is not set
-# CONFIG_MFD_TC6393XB is not set
-# CONFIG_PMIC_DA903X is not set
-# CONFIG_PMIC_ADP5520 is not set
-# CONFIG_MFD_MAX8925 is not set
-# CONFIG_MFD_MAX8997 is not set
-# CONFIG_MFD_MAX8998 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_ABX500_CORE is not set
-# CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_WL1273_CORE is not set
-# CONFIG_MFD_AAT2870_CORE is not set
-CONFIG_REGULATOR=y
-# CONFIG_REGULATOR_DEBUG is not set
-CONFIG_REGULATOR_DUMMY=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
-CONFIG_REGULATOR_USERSPACE_CONSUMER=y
-CONFIG_REGULATOR_GPIO=y
-# CONFIG_REGULATOR_BQ24022 is not set
-# CONFIG_REGULATOR_MAX1586 is not set
-# CONFIG_REGULATOR_MAX8649 is not set
-# CONFIG_REGULATOR_MAX8660 is not set
-# CONFIG_REGULATOR_MAX8952 is not set
-CONFIG_REGULATOR_TWL4030=y
-# CONFIG_REGULATOR_LP3971 is not set
-# CONFIG_REGULATOR_LP3972 is not set
-CONFIG_REGULATOR_TPS65023=y
-CONFIG_REGULATOR_TPS6507X=y
-CONFIG_REGULATOR_TPS65217=y
-# CONFIG_REGULATOR_ISL6271A is not set
-# CONFIG_REGULATOR_AD5398 is not set
-# CONFIG_REGULATOR_TPS6524X is not set
-CONFIG_MEDIA_SUPPORT=y
-
-#
-# Multimedia core support
-#
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_VIDEO_DEV=y
-CONFIG_VIDEO_V4L2_COMMON=y
-# CONFIG_VIDEO_V4L2_SUBDEV_API is not set
-CONFIG_DVB_CORE=m
-CONFIG_DVB_NET=y
-CONFIG_VIDEO_MEDIA=m
-
-#
-# Multimedia drivers
-#
-CONFIG_RC_CORE=y
-CONFIG_LIRC=y
-CONFIG_RC_MAP=y
-CONFIG_IR_NEC_DECODER=y
-CONFIG_IR_RC5_DECODER=y
-CONFIG_IR_RC6_DECODER=y
-CONFIG_IR_JVC_DECODER=y
-CONFIG_IR_SONY_DECODER=y
-CONFIG_IR_RC5_SZ_DECODER=y
-CONFIG_IR_MCE_KBD_DECODER=y
-CONFIG_IR_LIRC_CODEC=y
-CONFIG_RC_ATI_REMOTE=m
-# CONFIG_IR_IMON is not set
-# CONFIG_IR_MCEUSB is not set
-# CONFIG_IR_REDRAT3 is not set
-# CONFIG_IR_STREAMZAP is not set
-# CONFIG_RC_LOOPBACK is not set
-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=y
-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=y
-
-#
-# 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
-#
-# CONFIG_VIDEO_ADP1653 is not set
-
-#
-# 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=m
-# CONFIG_VIDEO_VPFE_CAPTURE is not set
-# CONFIG_VIDEO_OMAP2_VOUT is not set
-# CONFIG_VIDEO_BWQCAM is not set
-# CONFIG_VIDEO_CQCAM is not set
-# CONFIG_VIDEO_W9966 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=y
-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=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_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 is not set
-# CONFIG_RADIO_SI470X is not set
-# CONFIG_USB_MR800 is not set
-# 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_RADIO_WL128X is not set
-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 is not set
-# CONFIG_SMS_SIANO_MDTV is not set
-
-#
-# Supported FlexCopII (B2C2) Adapters
-#
-# CONFIG_DVB_B2C2_FLEXCOP 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
-
-#
-# 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
-
-#
-# 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
-#
-CONFIG_DRM=m
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
-# CONFIG_FB_DDC is not set
-# CONFIG_FB_BOOT_VESA_SUPPORT is not set
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
-CONFIG_FB_SYS_FILLRECT=y
-CONFIG_FB_SYS_COPYAREA=y
-CONFIG_FB_SYS_IMAGEBLIT=y
-CONFIG_FB_FOREIGN_ENDIAN=y
-CONFIG_FB_BOTH_ENDIAN=y
-# CONFIG_FB_BIG_ENDIAN is not set
-# CONFIG_FB_LITTLE_ENDIAN is not set
-CONFIG_FB_SYS_FOPS=y
-# CONFIG_FB_WMT_GE_ROPS is not set
-CONFIG_FB_DEFERRED_IO=y
-# CONFIG_FB_SVGALIB is not set
-# CONFIG_FB_MACMODES is not set
-# CONFIG_FB_BACKLIGHT is not set
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_TILEBLITTING=y
-
-#
-# Frame buffer hardware drivers
-#
-# CONFIG_FB_UVESA is not set
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_TMIO is not set
-CONFIG_FB_SMSCUFX=m
-CONFIG_FB_UDL=m
-CONFIG_FB_DA8XX=y
-CONFIG_FB_DA8XX_CONSISTENT_DMA_SIZE=5
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FB_METRONOME is not set
-# CONFIG_FB_BROADSHEET is not set
-CONFIG_FB_ST7735=y
-# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
-CONFIG_OMAP2_VRAM=y
-CONFIG_OMAP2_VRFB=y
-CONFIG_OMAP2_DSS=m
-CONFIG_OMAP2_VRAM_SIZE=0
-CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y
-# CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS is not set
-CONFIG_OMAP2_DSS_DPI=y
-CONFIG_OMAP2_DSS_RFBI=y
-CONFIG_OMAP2_DSS_VENC=y
-CONFIG_OMAP2_DSS_SDI=y
-CONFIG_OMAP2_DSS_DSI=y
-# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
-CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
-CONFIG_OMAP2_DSS_SLEEP_AFTER_VENC_RESET=y
-CONFIG_FB_OMAP2=m
-CONFIG_FB_OMAP2_DEBUG_SUPPORT=y
-CONFIG_FB_OMAP2_NUM_FBS=3
-
-#
-# OMAP2/3 Display Device Drivers
-#
-CONFIG_PANEL_GENERIC_DPI=m
-CONFIG_PANEL_DVI=m
-# CONFIG_PANEL_LGPHILIPS_LB035Q02 is not set
-CONFIG_PANEL_SHARP_LS037V7DW01=m
-CONFIG_PANEL_NEC_NL8048HL11_01B=m
-CONFIG_PANEL_PICODLP=m
-CONFIG_PANEL_TAAL=m
-CONFIG_PANEL_TPO_TD043MTEA1=m
-CONFIG_PANEL_ACX565AKM=m
-CONFIG_PANEL_N8X0=m
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-# CONFIG_LCD_L4F00242T03 is not set
-# CONFIG_LCD_LMS283GF05 is not set
-# CONFIG_LCD_LTV350QV is not set
-# CONFIG_LCD_TDO24M is not set
-# CONFIG_LCD_VGG2432A4 is not set
-CONFIG_LCD_PLATFORM=y
-# CONFIG_LCD_S6E63M0 is not set
-# CONFIG_LCD_LD9040 is not set
-# CONFIG_LCD_AMS369FG06 is not set
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_GENERIC=y
-CONFIG_BACKLIGHT_PWM=y
-# CONFIG_BACKLIGHT_ADP8860 is not set
-# CONFIG_BACKLIGHT_ADP8870 is not set
-# CONFIG_BACKLIGHT_TLC59108 is not set
-
-#
-# Display device support
-#
-CONFIG_DISPLAY_SUPPORT=y
-
-#
-# Display hardware drivers
-#
-
-#
-# Console display driver support
-#
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
-CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_7x14 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-# CONFIG_FONT_MINI_4x6 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_10x18 is not set
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_LOGO_LINUX_CLUT224=y
-CONFIG_SOUND=y
-# CONFIG_SOUND_OSS_CORE is not set
-CONFIG_SND=y
-CONFIG_SND_TIMER=y
-CONFIG_SND_PCM=y
-CONFIG_SND_HWDEP=y
-CONFIG_SND_RAWMIDI=y
-CONFIG_SND_JACK=y
-CONFIG_SND_SEQUENCER=m
-CONFIG_SND_SEQ_DUMMY=m
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_PCM_OSS is not set
-# CONFIG_SND_SEQUENCER_OSS is not set
-CONFIG_SND_HRTIMER=m
-CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
-# CONFIG_SND_DYNAMIC_MINORS is not set
-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_RAWMIDI_SEQ=m
-# CONFIG_SND_OPL3_LIB_SEQ is not set
-# CONFIG_SND_OPL4_LIB_SEQ is not set
-# CONFIG_SND_SBAWE_SEQ is not set
-# CONFIG_SND_EMU10K1_SEQ is not set
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_ALOOP is not set
-# CONFIG_SND_VIRMIDI is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_MTS64 is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-# CONFIG_SND_PORTMAN2X4 is not set
-CONFIG_SND_ARM=y
-CONFIG_SND_SPI=y
-CONFIG_SND_USB=y
-CONFIG_SND_USB_AUDIO=y
-# CONFIG_SND_USB_UA101 is not set
-# CONFIG_SND_USB_CAIAQ is not set
-# CONFIG_SND_USB_6FIRE is not set
-CONFIG_SND_SOC=y
-# CONFIG_SND_SOC_CACHE_LZO is not set
-CONFIG_SND_AM33XX_SOC=y
-CONFIG_SND_DAVINCI_SOC_MCASP=m
-CONFIG_SND_AM335X_SOC_EVM=m
-# CONFIG_SND_OMAP_SOC is not set
-CONFIG_SND_SOC_I2C_AND_SPI=y
-# CONFIG_SND_SOC_ALL_CODECS is not set
-CONFIG_SND_SOC_TLV320AIC3X=m
-# CONFIG_SOUND_PRIME is not set
-CONFIG_HID_SUPPORT=y
-CONFIG_HID=y
-# CONFIG_HIDRAW is not set
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=y
-# CONFIG_HID_PID is not set
-# CONFIG_USB_HIDDEV is not set
-
-#
-# Special HID drivers
-#
-# CONFIG_HID_A4TECH is not set
-# CONFIG_HID_ACRUX is not set
-# CONFIG_HID_APPLE is not set
-# CONFIG_HID_BELKIN is not set
-# CONFIG_HID_CHERRY is not set
-# CONFIG_HID_CHICONY is not set
-# CONFIG_HID_PRODIKEYS is not set
-# CONFIG_HID_CYPRESS is not set
-# CONFIG_HID_DRAGONRISE is not set
-# CONFIG_HID_EMS_FF is not set
-# CONFIG_HID_ELECOM is not set
-# CONFIG_HID_EZKEY is not set
-# CONFIG_HID_HOLTEK is not set
-# CONFIG_HID_KEYTOUCH is not set
-# CONFIG_HID_KYE is not set
-# CONFIG_HID_UCLOGIC is not set
-# CONFIG_HID_WALTOP is not set
-# CONFIG_HID_GYRATION is not set
-# CONFIG_HID_TWINHAN is not set
-# CONFIG_HID_KENSINGTON is not set
-# CONFIG_HID_LCPOWER is not set
-# CONFIG_HID_LOGITECH is not set
-# CONFIG_HID_MAGICMOUSE is not set
-# CONFIG_HID_MICROSOFT is not set
-# CONFIG_HID_MONTEREY is not set
-# CONFIG_HID_MULTITOUCH is not set
-# CONFIG_HID_NTRIG is not set
-# CONFIG_HID_ORTEK is not set
-# CONFIG_HID_PANTHERLORD is not set
-# CONFIG_HID_PETALYNX is not set
-# CONFIG_HID_PICOLCD is not set
-# CONFIG_HID_PRIMAX is not set
-# CONFIG_HID_QUANTA is not set
-# CONFIG_HID_ROCCAT is not set
-# CONFIG_HID_SAMSUNG is not set
-# CONFIG_HID_SONY is not set
-# CONFIG_HID_SPEEDLINK is not set
-# CONFIG_HID_SUNPLUS is not set
-# CONFIG_HID_GREENASIA is not set
-# CONFIG_HID_SMARTJOYPLUS is not set
-# CONFIG_HID_TOPSEED is not set
-# CONFIG_HID_THRUSTMASTER is not set
-# CONFIG_HID_WACOM is not set
-# CONFIG_HID_WIIMOTE is not set
-# CONFIG_HID_ZEROPLUS is not set
-# CONFIG_HID_ZYDACRON is not set
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-# CONFIG_USB_ARCH_HAS_XHCI is not set
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_DEVICE_CLASS=y
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND 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 is not set
-# CONFIG_USB_WUSB is not set
-# CONFIG_USB_WUSB_CBAF is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_C67X00_HCD is not set
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_OXU210HP_HCD is not set
-# CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_ISP1760_HCD is not set
-# CONFIG_USB_ISP1362_HCD is not set
-# CONFIG_USB_OHCI_HCD is not set
-# 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_MUSB_HDRC=y
-
-#
-# Platform Glue Layer
-#
-# CONFIG_USB_MUSB_TUSB6010_GLUE is not set
-# CONFIG_USB_MUSB_OMAP2PLUS_GLUE is not set
-# CONFIG_USB_MUSB_AM35X_GLUE is not set
-CONFIG_USB_MUSB_TI81XX_GLUE=y
-# CONFIG_USB_MUSB_DAVINCI is not set
-# CONFIG_USB_MUSB_DA8XX is not set
-# CONFIG_USB_MUSB_TUSB6010 is not set
-# CONFIG_USB_MUSB_OMAP2PLUS is not set
-# CONFIG_USB_MUSB_AM35X is not set
-CONFIG_USB_MUSB_TI81XX=y
-# CONFIG_USB_MUSB_BLACKFIN is not set
-# CONFIG_USB_MUSB_UX500 is not set
-CONFIG_MUSB_PIO_ONLY=y
-# CONFIG_USB_INVENTRA_DMA is not set
-# CONFIG_USB_TI_CPPI_DMA is not set
-# CONFIG_USB_TI_CPPI41_DMA is not set
-# CONFIG_USB_TUSB_OMAP_DMA is not set
-# CONFIG_USB_UX500_DMA is not set
-# CONFIG_USB_RENESAS_USBHS is not set
-
-#
-# USB Device Class drivers
-#
-CONFIG_USB_ACM=y
-CONFIG_USB_PRINTER=y
-CONFIG_USB_WDM=y
-# CONFIG_USB_TMC is not set
-
-#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
-#
-
-#
-# also be needed; see USB_STORAGE Help for more info
-#
-CONFIG_USB_STORAGE=y
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_REALTEK is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_ONETOUCH is not set
-# CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
-# CONFIG_USB_STORAGE_ENE_UB6250 is not set
-CONFIG_USB_UAS=y
-CONFIG_USB_LIBUSUAL=y
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-CONFIG_USB_SERIAL=m
-CONFIG_USB_EZUSB=y
-# CONFIG_USB_SERIAL_GENERIC is not set
-CONFIG_USB_SERIAL_AIRCABLE=m
-CONFIG_USB_SERIAL_ARK3116=m
-CONFIG_USB_SERIAL_BELKIN=m
-CONFIG_USB_SERIAL_CH341=m
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
-CONFIG_USB_SERIAL_CP210X=m
-CONFIG_USB_SERIAL_CYPRESS_M8=m
-CONFIG_USB_SERIAL_EMPEG=m
-CONFIG_USB_SERIAL_FTDI_SIO=m
-CONFIG_USB_SERIAL_FUNSOFT=m
-CONFIG_USB_SERIAL_VISOR=m
-CONFIG_USB_SERIAL_IPAQ=m
-CONFIG_USB_SERIAL_IR=m
-CONFIG_USB_SERIAL_EDGEPORT=m
-CONFIG_USB_SERIAL_EDGEPORT_TI=m
-CONFIG_USB_SERIAL_GARMIN=m
-CONFIG_USB_SERIAL_IPW=m
-CONFIG_USB_SERIAL_IUU=m
-CONFIG_USB_SERIAL_KEYSPAN_PDA=m
-CONFIG_USB_SERIAL_KEYSPAN=m
-# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
-CONFIG_USB_SERIAL_KLSI=m
-CONFIG_USB_SERIAL_KOBIL_SCT=m
-CONFIG_USB_SERIAL_MCT_U232=m
-CONFIG_USB_SERIAL_MOS7720=m
-# CONFIG_USB_SERIAL_MOS7715_PARPORT is not set
-CONFIG_USB_SERIAL_MOS7840=m
-CONFIG_USB_SERIAL_MOTOROLA=m
-CONFIG_USB_SERIAL_NAVMAN=m
-CONFIG_USB_SERIAL_PL2303=m
-CONFIG_USB_SERIAL_OTI6858=m
-CONFIG_USB_SERIAL_QCAUX=m
-CONFIG_USB_SERIAL_QUALCOMM=m
-CONFIG_USB_SERIAL_SPCP8X5=m
-CONFIG_USB_SERIAL_HP4X=m
-CONFIG_USB_SERIAL_SAFE=m
-# CONFIG_USB_SERIAL_SAFE_PADDED is not set
-CONFIG_USB_SERIAL_SIEMENS_MPI=m
-CONFIG_USB_SERIAL_SIERRAWIRELESS=m
-# CONFIG_USB_SERIAL_SYMBOL is not set
-# CONFIG_USB_SERIAL_TI is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-CONFIG_USB_SERIAL_WWAN=m
-# CONFIG_USB_SERIAL_OPTION is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-CONFIG_USB_SERIAL_OPTICON=m
-CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m
-CONFIG_USB_SERIAL_ZIO=m
-CONFIG_USB_SERIAL_SSU100=m
-CONFIG_USB_SERIAL_DEBUG=m
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_SEVSEG is not set
-# CONFIG_USB_RIO500 is not set
-CONFIG_USB_LEGOTOWER=m
-CONFIG_USB_LCD=m
-CONFIG_USB_LED=m
-CONFIG_USB_CYPRESS_CY7C63=m
-CONFIG_USB_CYTHERM=m
-CONFIG_USB_IDMOUSE=m
-CONFIG_USB_FTDI_ELAN=m
-CONFIG_USB_APPLEDISPLAY=m
-CONFIG_USB_SISUSBVGA=m
-CONFIG_USB_SISUSBVGA_CON=y
-# CONFIG_USB_LD is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_IOWARRIOR is not set
-CONFIG_USB_TEST=m
-# CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_YUREX is not set
-CONFIG_USB_GADGET=y
-# CONFIG_USB_GADGET_DEBUG is not set
-# CONFIG_USB_GADGET_DEBUG_FILES is not set
-# CONFIG_USB_GADGET_DEBUG_FS is not set
-CONFIG_USB_GADGET_VBUS_DRAW=2
-CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
-# CONFIG_USB_FUSB300 is not set
-# CONFIG_USB_OMAP is not set
-# CONFIG_USB_R8A66597 is not set
-CONFIG_USB_GADGET_MUSB_HDRC=y
-# CONFIG_USB_M66592 is not set
-# CONFIG_USB_NET2272 is not set
-# CONFIG_USB_DUMMY_HCD is not set
-CONFIG_USB_GADGET_DUALSPEED=y
-CONFIG_USB_ZERO=m
-CONFIG_USB_AUDIO=m
-CONFIG_USB_ETH=m
-CONFIG_USB_ETH_RNDIS=y
-# CONFIG_USB_ETH_EEM is not set
-CONFIG_USB_G_NCM=m
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_FUNCTIONFS=m
-# CONFIG_USB_FUNCTIONFS_ETH is not set
-CONFIG_USB_FUNCTIONFS_RNDIS=y
-# CONFIG_USB_FUNCTIONFS_GENERIC is not set
-CONFIG_USB_FILE_STORAGE=m
-# CONFIG_USB_FILE_STORAGE_TEST is not set
-CONFIG_USB_MASS_STORAGE=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_USB_MIDI_GADGET=m
-CONFIG_USB_G_PRINTER=m
-CONFIG_USB_CDC_COMPOSITE=m
-# CONFIG_USB_G_ACM_MS is not set
-CONFIG_USB_G_MULTI=m
-CONFIG_USB_G_MULTI_RNDIS=y
-# CONFIG_USB_G_MULTI_CDC is not set
-CONFIG_USB_G_HID=m
-CONFIG_USB_G_DBGP=m
-CONFIG_USB_G_DBGP_PRINTK=y
-# CONFIG_USB_G_DBGP_SERIAL is not set
-CONFIG_USB_G_WEBCAM=m
-
-#
-# OTG and related infrastructure
-#
-CONFIG_USB_OTG_UTILS=y
-# CONFIG_USB_GPIO_VBUS is not set
-# CONFIG_USB_ULPI is not set
-# CONFIG_TWL4030_USB is not set
-# CONFIG_TWL6030_USB is not set
-CONFIG_NOP_USB_XCEIV=y
-CONFIG_MMC=y
-# CONFIG_MMC_DEBUG is not set
-CONFIG_MMC_UNSAFE_RESUME=y
-# CONFIG_MMC_CLKGATE is not set
-
-#
-# MMC/SD/SDIO Card Drivers
-#
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_BLOCK_MINORS=8
-CONFIG_MMC_BLOCK_BOUNCE=y
-CONFIG_SDIO_UART=y
-# CONFIG_MMC_TEST is not set
-
-#
-# MMC/SD/SDIO Host Controller Drivers
-#
-# CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_SDHCI_PXAV3 is not set
-# CONFIG_MMC_SDHCI_PXAV2 is not set
-# CONFIG_MMC_OMAP is not set
-CONFIG_MMC_OMAP_HS=y
-# 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
-
-#
-# LED drivers
-#
-# CONFIG_LEDS_LM3530 is not set
-# CONFIG_LEDS_PCA9532 is not set
-CONFIG_LEDS_GPIO=y
-# 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_DAC124S085 is not set
-# CONFIG_LEDS_PWM is not set
-CONFIG_LEDS_REGULATOR=y
-# CONFIG_LEDS_BD2802 is not set
-# CONFIG_LEDS_LT3593 is not set
-# CONFIG_LEDS_RENESAS_TPU is not set
-CONFIG_LEDS_TRIGGERS=y
-
-#
-# LED Triggers
-#
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_LEDS_TRIGGER_BACKLIGHT=y
-CONFIG_LEDS_TRIGGER_GPIO=y
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
-
-#
-# iptables trigger is under Netfilter config (LED target)
-#
-# CONFIG_ACCESSIBILITY is not set
-CONFIG_RTC_LIB=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_HCTOSYS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
-# CONFIG_RTC_DEBUG is not set
-
-#
-# RTC interfaces
-#
-CONFIG_RTC_INTF_SYSFS=y
-CONFIG_RTC_INTF_PROC=y
-CONFIG_RTC_INTF_DEV=y
-# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
-# CONFIG_RTC_DRV_TEST is not set
-
-#
-# I2C RTC drivers
-#
-# CONFIG_RTC_DRV_DS1307 is not set
-# CONFIG_RTC_DRV_DS1374 is not set
-# CONFIG_RTC_DRV_DS1672 is not set
-# CONFIG_RTC_DRV_DS3232 is not set
-# CONFIG_RTC_DRV_MAX6900 is not set
-# CONFIG_RTC_DRV_RS5C372 is not set
-# CONFIG_RTC_DRV_ISL1208 is not set
-# CONFIG_RTC_DRV_ISL12022 is not set
-# CONFIG_RTC_DRV_X1205 is not set
-# CONFIG_RTC_DRV_PCF8563 is not set
-# CONFIG_RTC_DRV_PCF8583 is not set
-# CONFIG_RTC_DRV_M41T80 is not set
-# CONFIG_RTC_DRV_BQ32K is not set
-CONFIG_RTC_DRV_TWL4030=y
-# CONFIG_RTC_DRV_S35390A is not set
-# CONFIG_RTC_DRV_FM3130 is not set
-# CONFIG_RTC_DRV_RX8581 is not set
-# CONFIG_RTC_DRV_RX8025 is not set
-# CONFIG_RTC_DRV_EM3027 is not set
-# CONFIG_RTC_DRV_RV3029C2 is not set
-
-#
-# SPI RTC drivers
-#
-# CONFIG_RTC_DRV_M41T93 is not set
-# CONFIG_RTC_DRV_M41T94 is not set
-# CONFIG_RTC_DRV_DS1305 is not set
-# CONFIG_RTC_DRV_DS1390 is not set
-# CONFIG_RTC_DRV_MAX6902 is not set
-# CONFIG_RTC_DRV_R9701 is not set
-# CONFIG_RTC_DRV_RS5C348 is not set
-# CONFIG_RTC_DRV_DS3234 is not set
-# CONFIG_RTC_DRV_PCF2123 is not set
-
-#
-# Platform RTC drivers
-#
-# CONFIG_RTC_DRV_CMOS is not set
-# CONFIG_RTC_DRV_DS1286 is not set
-# CONFIG_RTC_DRV_DS1511 is not set
-# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_DS1742 is not set
-# CONFIG_RTC_DRV_STK17TA8 is not set
-# CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_M48T35 is not set
-# CONFIG_RTC_DRV_M48T59 is not set
-# CONFIG_RTC_DRV_MSM6242 is not set
-# CONFIG_RTC_DRV_BQ4802 is not set
-# CONFIG_RTC_DRV_RP5C01 is not set
-# CONFIG_RTC_DRV_V3020 is not set
-
-#
-# on-CPU RTC drivers
-#
-CONFIG_RTC_DRV_OMAP=y
-# CONFIG_DMADEVICES is not set
-# CONFIG_AUXDISPLAY is not set
-CONFIG_UIO=m
-CONFIG_UIO_PDRV=m
-CONFIG_UIO_PDRV_GENIRQ=m
-CONFIG_UIO_PRUSS=m
-CONFIG_VIRTIO=m
-CONFIG_VIRTIO_RING=m
-
-#
-# Virtio drivers
-#
-# CONFIG_VIRTIO_BALLOON is not set
-CONFIG_VIRTIO_MMIO=m
-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_PANEL is not set
-CONFIG_R8712U=m
-CONFIG_RTS5139=m
-# CONFIG_RTS5139_DEBUG is not set
-# CONFIG_TRANZPORT is not set
-# CONFIG_POHMELFS is not set
-# CONFIG_LINE6_USB is not set
-CONFIG_USB_SERIAL_QUATECH2=m
-CONFIG_USB_SERIAL_QUATECH_USB2=m
-# CONFIG_VT6656 is not set
-CONFIG_IIO=y
-CONFIG_IIO_BUFFER=y
-CONFIG_IIO_SW_RING=y
-CONFIG_IIO_KFIFO_BUF=y
-CONFIG_IIO_TRIGGER=y
-CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
-
-#
-# Accelerometers
-#
-# CONFIG_ADIS16201 is not set
-# CONFIG_ADIS16203 is not set
-# CONFIG_ADIS16204 is not set
-# CONFIG_ADIS16209 is not set
-# CONFIG_ADIS16220 is not set
-# CONFIG_ADIS16240 is not set
-# CONFIG_KXSD9 is not set
-# CONFIG_LIS3L02DQ is not set
-# CONFIG_SCA3000 is not set
-
-#
-# Analog to digital converters
-#
-# CONFIG_AD7291 is not set
-# CONFIG_AD7298 is not set
-# CONFIG_AD7606 is not set
-# CONFIG_AD799X is not set
-# CONFIG_AD7476 is not set
-# CONFIG_AD7887 is not set
-# CONFIG_AD7780 is not set
-# CONFIG_AD7793 is not set
-# CONFIG_AD7816 is not set
-CONFIG_AD7192=m
-# CONFIG_ADT7310 is not set
-# CONFIG_ADT7410 is not set
-CONFIG_AD7280=m
-# CONFIG_MAX1363 is not set
-
-#
-# Analog digital bi-direction converters
-#
-# CONFIG_ADT7316 is not set
-
-#
-# Capacitance to digital converters
-#
-# CONFIG_AD7150 is not set
-# CONFIG_AD7152 is not set
-CONFIG_AD7746=m
-
-#
-# Digital to analog converters
-#
-CONFIG_AD5064=m
-CONFIG_AD5360=m
-# CONFIG_AD5624R_SPI is not set
-# CONFIG_AD5446 is not set
-# CONFIG_AD5504 is not set
-# CONFIG_AD5791 is not set
-# CONFIG_AD5686 is not set
-# CONFIG_MAX517 is not set
-
-#
-# Direct Digital Synthesis
-#
-# CONFIG_AD5930 is not set
-# CONFIG_AD9832 is not set
-# CONFIG_AD9834 is not set
-# CONFIG_AD9850 is not set
-# CONFIG_AD9852 is not set
-# CONFIG_AD9910 is not set
-# CONFIG_AD9951 is not set
-
-#
-# Digital gyroscope sensors
-#
-# CONFIG_ADIS16060 is not set
-# CONFIG_ADIS16080 is not set
-# CONFIG_ADIS16130 is not set
-# CONFIG_ADIS16260 is not set
-# CONFIG_ADXRS450 is not set
-
-#
-# Network Analyzer, Impedance Converters
-#
-CONFIG_AD5933=m
-
-#
-# Inertial measurement units
-#
-# CONFIG_ADIS16400 is not set
-
-#
-# Light sensors
-#
-# CONFIG_SENSORS_ISL29018 is not set
-# CONFIG_SENSORS_TSL2563 is not set
-# CONFIG_TSL2583 is not set
-
-#
-# Magnetometer sensors
-#
-# CONFIG_SENSORS_AK8975 is not set
-# CONFIG_SENSORS_HMC5843 is not set
-
-#
-# Active energy metering IC
-#
-# CONFIG_ADE7753 is not set
-# CONFIG_ADE7754 is not set
-# CONFIG_ADE7758 is not set
-# CONFIG_ADE7759 is not set
-# CONFIG_ADE7854 is not set
-
-#
-# Resolver to digital converters
-#
-# CONFIG_AD2S90 is not set
-CONFIG_AD2S1200=m
-# CONFIG_AD2S1210 is not set
-
-#
-# Triggers - standalone
-#
-# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set
-# CONFIG_IIO_GPIO_TRIGGER is not set
-# CONFIG_IIO_SYSFS_TRIGGER is not set
-CONFIG_IIO_DUMMY_EVGEN=m
-CONFIG_IIO_SIMPLE_DUMMY=m
-CONFIG_IIO_SIMPLE_DUMMY_EVENTS=y
-CONFIG_IIO_SIMPLE_DUMMY_BUFFER=y
-# CONFIG_XVMALLOC is not set
-# CONFIG_ZRAM is not set
-# CONFIG_FB_SM7XX is not set
-# CONFIG_TIDSPBRIDGE is not set
-CONFIG_USB_ENESTORAGE=m
-# CONFIG_BCM_WIMAX is not set
-# CONFIG_FT1000 is not set
-
-#
-# Speakup console speech
-#
-# CONFIG_SPEAKUP is not set
-# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
-# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
-# CONFIG_STAGING_MEDIA is not set
-CONFIG_CLKDEV_LOOKUP=y
-
-#
-# Hardware Spinlock drivers
-#
-CONFIG_CLKSRC_MMIO=y
-CONFIG_IOMMU_API=y
-CONFIG_IOMMU_SUPPORT=y
-CONFIG_OMAP_IOMMU=y
-CONFIG_OMAP_IOVMM=y
-CONFIG_OMAP_IOMMU_DEBUG=y
-# CONFIG_VIRT_DRIVERS is not set
-CONFIG_PM_DEVFREQ=y
-
-#
-# DEVFREQ Governors
-#
-# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set
-# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
-# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
-CONFIG_DEVFREQ_GOV_USERSPACE=y
-
-#
-# DEVFREQ Drivers
-#
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=m
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_XATTR=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-# CONFIG_EXT4_FS_SECURITY is not set
-# CONFIG_EXT4_DEBUG is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_JBD2=y
-# CONFIG_JBD2_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_REISERFS_FS_XATTR is not set
-CONFIG_JFS_FS=m
-# CONFIG_JFS_POSIX_ACL is not set
-# CONFIG_JFS_SECURITY is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
-CONFIG_XFS_FS=m
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_DEBUG is not set
-CONFIG_GFS2_FS=m
-# CONFIG_GFS2_FS_LOCKING_DLM is not set
-CONFIG_BTRFS_FS=m
-# CONFIG_BTRFS_FS_POSIX_ACL is not set
-CONFIG_NILFS2_FS=m
-CONFIG_FS_POSIX_ACL=y
-CONFIG_EXPORTFS=y
-CONFIG_FILE_LOCKING=y
-CONFIG_FSNOTIFY=y
-CONFIG_DNOTIFY=y
-CONFIG_INOTIFY_USER=y
-CONFIG_FANOTIFY=y
-CONFIG_QUOTA=y
-# CONFIG_QUOTA_NETLINK_INTERFACE is not set
-CONFIG_PRINT_QUOTA_WARNING=y
-# CONFIG_QUOTA_DEBUG is not set
-CONFIG_QUOTA_TREE=m
-# CONFIG_QFMT_V1 is not set
-CONFIG_QFMT_V2=m
-CONFIG_QUOTACTL=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_FUSE_FS=m
-CONFIG_CUSE=m
-CONFIG_GENERIC_ACL=y
-
-#
-# Caches
-#
-# CONFIG_FSCACHE is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=m
-CONFIG_UDF_NLS=y
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_TMPFS_XATTR=y
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_ECRYPT_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_LOGFS is not set
-CONFIG_CRAMFS=m
-# CONFIG_SQUASHFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_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_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-# CONFIG_NFS_V4_1 is not set
-CONFIG_ROOT_NFS=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_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-CONFIG_NFSD_V4=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_NFS_ACL_SUPPORT=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-CONFIG_SUNRPC_GSS=y
-# CONFIG_CEPH_FS is not set
-CONFIG_CIFS=m
-CONFIG_CIFS_STATS=y
-# CONFIG_CIFS_STATS2 is not set
-CONFIG_CIFS_WEAK_PW_HASH=y
-# CONFIG_CIFS_UPCALL is not set
-CONFIG_CIFS_XATTR=y
-CONFIG_CIFS_POSIX=y
-# CONFIG_CIFS_DEBUG2 is not set
-# CONFIG_CIFS_DFS_UPCALL is not set
-# CONFIG_CIFS_ACL is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# 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 is not set
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=y
-
-#
-# Kernel hacking
-#
-CONFIG_PRINTK_TIME=y
-CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
-CONFIG_ENABLE_WARN_DEPRECATED=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_FRAME_WARN=1024
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_STRIP_ASM_SYMS is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_SECTION_MISMATCH is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SHIRQ is not set
-# CONFIG_LOCKUP_DETECTOR is not set
-# CONFIG_HARDLOCKUP_DETECTOR is not set
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
-# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
-CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
-# CONFIG_SCHED_DEBUG is not set
-CONFIG_SCHEDSTATS=y
-CONFIG_TIMER_STATS=y
-# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_KMEMLEAK is not set
-# CONFIG_DEBUG_PREEMPT is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_LOCK_ALLOC is not set
-# CONFIG_PROVE_LOCKING is not set
-# CONFIG_SPARSE_RCU_POINTER is not set
-# CONFIG_LOCK_STAT is not set
-# CONFIG_DEBUG_ATOMIC_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_WRITECOUNT is not set
-# CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_DEBUG_LIST is not set
-# CONFIG_TEST_LIST_SORT is not set
-# CONFIG_DEBUG_SG is not set
-# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_DEBUG_CREDENTIALS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
-# CONFIG_RCU_TORTURE_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_FAULT_INJECTION is not set
-# CONFIG_LATENCYTOP is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_RING_BUFFER=y
-CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING_SUPPORT=y
-CONFIG_FTRACE=y
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_PREEMPT_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_ENABLE_DEFAULT_TRACERS is not set
-CONFIG_BRANCH_PROFILE_NONE=y
-# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
-# CONFIG_PROFILE_ALL_BRANCHES is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_RING_BUFFER_BENCHMARK is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_DMA_API_DEBUG is not set
-# CONFIG_ATOMIC64_SELFTEST is not set
-# CONFIG_ASYNC_RAID6_TEST is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-# CONFIG_KGDB is not set
-# CONFIG_TEST_KSTRTOX is not set
-# CONFIG_STRICT_DEVMEM is not set
-CONFIG_ARM_UNWIND=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_LL is not set
-CONFIG_DEBUG_JTAG_ENABLE=y
-
-#
-# Security options
-#
-CONFIG_KEYS=y
-# CONFIG_ENCRYPTED_KEYS is not set
-# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
-# CONFIG_SECURITY_DMESG_RESTRICT is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-CONFIG_DEFAULT_SECURITY_DAC=y
-CONFIG_DEFAULT_SECURITY=""
-CONFIG_XOR_BLOCKS=m
-CONFIG_ASYNC_CORE=m
-CONFIG_ASYNC_MEMCPY=m
-CONFIG_ASYNC_XOR=m
-CONFIG_ASYNC_PQ=m
-CONFIG_ASYNC_RAID6_RECOV=m
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_ALGAPI2=y
-CONFIG_CRYPTO_AEAD=m
-CONFIG_CRYPTO_AEAD2=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_BLKCIPHER2=y
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_HASH2=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_PCOMP2=y
-CONFIG_CRYPTO_MANAGER=m
-CONFIG_CRYPTO_MANAGER2=y
-# CONFIG_CRYPTO_USER is not set
-CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_NULL is not set
-CONFIG_CRYPTO_WORKQUEUE=y
-# CONFIG_CRYPTO_CRYPTD is not set
-CONFIG_CRYPTO_AUTHENC=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Authenticated Encryption with Associated Data
-#
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_SEQIV is not set
-
-#
-# Block modes
-#
-CONFIG_CRYPTO_CBC=m
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_CTS is not set
-CONFIG_CRYPTO_ECB=m
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_XTS is not set
-
-#
-# Hash modes
-#
-CONFIG_CRYPTO_HMAC=m
-# CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_VMAC is not set
-
-#
-# Digest
-#
-CONFIG_CRYPTO_CRC32C=y
-# CONFIG_CRYPTO_GHASH is not set
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_MICHAEL_MIC=y
-# CONFIG_CRYPTO_RMD128 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RMD256 is not set
-# CONFIG_CRYPTO_RMD320 is not set
-CONFIG_CRYPTO_SHA1=m
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_WP512 is not set
-
-#
-# Ciphers
-#
-CONFIG_CRYPTO_AES=m
-# CONFIG_CRYPTO_ANUBIS is not set
-CONFIG_CRYPTO_ARC4=m
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-CONFIG_CRYPTO_DES=m
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_SALSA20 is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-
-#
-# Compression
-#
-CONFIG_CRYPTO_DEFLATE=y
-# CONFIG_CRYPTO_ZLIB is not set
-CONFIG_CRYPTO_LZO=y
-
-#
-# Random Number Generation
-#
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_USER_API_HASH is not set
-# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
-CONFIG_CRYPTO_HW=y
-# CONFIG_CRYPTO_DEV_OMAP_SHAM is not set
-# CONFIG_CRYPTO_DEV_OMAP_AES is not set
-# CONFIG_BINARY_PRINTF is not set
-
-#
-# Library routines
-#
-CONFIG_RAID6_PQ=m
-CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=y
-CONFIG_CRC16=y
-CONFIG_CRC_T10DIF=y
-CONFIG_CRC_ITU_T=y
-CONFIG_CRC32=y
-CONFIG_CRC7=y
-CONFIG_LIBCRC32C=y
-# CONFIG_CRC8 is not set
-CONFIG_AUDIT_GENERIC=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_XZ_DEC=y
-CONFIG_XZ_DEC_X86=y
-CONFIG_XZ_DEC_POWERPC=y
-CONFIG_XZ_DEC_IA64=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_ARMTHUMB=y
-CONFIG_XZ_DEC_SPARC=y
-CONFIG_XZ_DEC_BCJ=y
-# CONFIG_XZ_DEC_TEST is not set
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_DECOMPRESS_BZIP2=y
-CONFIG_DECOMPRESS_LZMA=y
-CONFIG_DECOMPRESS_XZ=y
-CONFIG_DECOMPRESS_LZO=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_NLATTR=y
-CONFIG_AVERAGE=y
-# CONFIG_CORDIC is not set
diff --git a/patches/linux-3.8.4/0001-Without-MACH_-option-Early-printk-DEBUG_LL.patch b/patches/linux-3.8.13/0001-Without-MACH_-option-Early-printk-DEBUG_LL.patch
index 85222c4..85222c4 100644
--- a/patches/linux-3.8.4/0001-Without-MACH_-option-Early-printk-DEBUG_LL.patch
+++ b/patches/linux-3.8.13/0001-Without-MACH_-option-Early-printk-DEBUG_LL.patch
diff --git a/patches/linux-3.8.4/0002-ARM-OMAP-Hack-AM33xx-clock-data-to-allow-JTAG-use.patch b/patches/linux-3.8.13/0002-ARM-OMAP-Hack-AM33xx-clock-data-to-allow-JTAG-use.patch
index 691f2c1..691f2c1 100644
--- a/patches/linux-3.8.4/0002-ARM-OMAP-Hack-AM33xx-clock-data-to-allow-JTAG-use.patch
+++ b/patches/linux-3.8.13/0002-ARM-OMAP-Hack-AM33xx-clock-data-to-allow-JTAG-use.patch
diff --git a/patches/linux-3.8.4/0003-video-st7735fb-add-st7735-framebuffer-driver.patch b/patches/linux-3.8.13/0003-video-st7735fb-add-st7735-framebuffer-driver.patch
index b707989..b707989 100644
--- a/patches/linux-3.8.4/0003-video-st7735fb-add-st7735-framebuffer-driver.patch
+++ b/patches/linux-3.8.13/0003-video-st7735fb-add-st7735-framebuffer-driver.patch
diff --git a/patches/linux-3.8.4/0004-dmaengine-add-helper-function-to-request-a-slave-DMA.patch b/patches/linux-3.8.13/0004-dmaengine-add-helper-function-to-request-a-slave-DMA.patch
index 3368d21..3368d21 100644
--- a/patches/linux-3.8.4/0004-dmaengine-add-helper-function-to-request-a-slave-DMA.patch
+++ b/patches/linux-3.8.13/0004-dmaengine-add-helper-function-to-request-a-slave-DMA.patch
diff --git a/patches/linux-3.8.4/0005-of-Add-generic-device-tree-DMA-helpers.patch b/patches/linux-3.8.13/0005-of-Add-generic-device-tree-DMA-helpers.patch
index 71a2fc0..71a2fc0 100644
--- a/patches/linux-3.8.4/0005-of-Add-generic-device-tree-DMA-helpers.patch
+++ b/patches/linux-3.8.13/0005-of-Add-generic-device-tree-DMA-helpers.patch
diff --git a/patches/linux-3.8.4/0006-of-dma-fix-build-break-for-CONFIG_OF.patch b/patches/linux-3.8.13/0006-of-dma-fix-build-break-for-CONFIG_OF.patch
index 04d864c..04d864c 100644
--- a/patches/linux-3.8.4/0006-of-dma-fix-build-break-for-CONFIG_OF.patch
+++ b/patches/linux-3.8.13/0006-of-dma-fix-build-break-for-CONFIG_OF.patch
diff --git a/patches/linux-3.8.4/0007-of-dma-fix-typos-in-generic-dma-binding-definition.patch b/patches/linux-3.8.13/0007-of-dma-fix-typos-in-generic-dma-binding-definition.patch
index bfbfad4..bfbfad4 100644
--- a/patches/linux-3.8.4/0007-of-dma-fix-typos-in-generic-dma-binding-definition.patch
+++ b/patches/linux-3.8.13/0007-of-dma-fix-typos-in-generic-dma-binding-definition.patch
diff --git a/patches/linux-3.8.4/0008-dmaengine-fix-build-failure-due-to-missing-semi-colo.patch b/patches/linux-3.8.13/0008-dmaengine-fix-build-failure-due-to-missing-semi-colo.patch
index 52ab593..52ab593 100644
--- a/patches/linux-3.8.4/0008-dmaengine-fix-build-failure-due-to-missing-semi-colo.patch
+++ b/patches/linux-3.8.13/0008-dmaengine-fix-build-failure-due-to-missing-semi-colo.patch
diff --git a/patches/linux-3.8.4/0009-dmaengine-edma-fix-slave-config-dependency-on-direct.patch b/patches/linux-3.8.13/0009-dmaengine-edma-fix-slave-config-dependency-on-direct.patch
index e0ff593..e0ff593 100644
--- a/patches/linux-3.8.4/0009-dmaengine-edma-fix-slave-config-dependency-on-direct.patch
+++ b/patches/linux-3.8.13/0009-dmaengine-edma-fix-slave-config-dependency-on-direct.patch
diff --git a/patches/linux-3.8.4/0010-dmaengine-add-dma_get_channel_caps.patch b/patches/linux-3.8.13/0010-dmaengine-add-dma_get_channel_caps.patch
index 53f84d4..53f84d4 100644
--- a/patches/linux-3.8.4/0010-dmaengine-add-dma_get_channel_caps.patch
+++ b/patches/linux-3.8.13/0010-dmaengine-add-dma_get_channel_caps.patch
diff --git a/patches/linux-3.8.4/0011-dma-edma-add-device_channel_caps-support.patch b/patches/linux-3.8.13/0011-dma-edma-add-device_channel_caps-support.patch
index 505ac29..505ac29 100644
--- a/patches/linux-3.8.4/0011-dma-edma-add-device_channel_caps-support.patch
+++ b/patches/linux-3.8.13/0011-dma-edma-add-device_channel_caps-support.patch
diff --git a/patches/linux-3.8.4/0012-mmc-davinci-get-SG-segment-limits-with-dma_get_chann.patch b/patches/linux-3.8.13/0012-mmc-davinci-get-SG-segment-limits-with-dma_get_chann.patch
index 368a583..368a583 100644
--- a/patches/linux-3.8.4/0012-mmc-davinci-get-SG-segment-limits-with-dma_get_chann.patch
+++ b/patches/linux-3.8.13/0012-mmc-davinci-get-SG-segment-limits-with-dma_get_chann.patch
diff --git a/patches/linux-3.8.4/0013-ARM-davinci-move-private-EDMA-API-to-arm-common.patch b/patches/linux-3.8.13/0013-ARM-davinci-move-private-EDMA-API-to-arm-common.patch
index 6c58818..6c58818 100644
--- a/patches/linux-3.8.4/0013-ARM-davinci-move-private-EDMA-API-to-arm-common.patch
+++ b/patches/linux-3.8.13/0013-ARM-davinci-move-private-EDMA-API-to-arm-common.patch
diff --git a/patches/linux-3.8.4/0014-ARM-edma-remove-unused-transfer-controller-handlers.patch b/patches/linux-3.8.13/0014-ARM-edma-remove-unused-transfer-controller-handlers.patch
index 0b07488..0b07488 100644
--- a/patches/linux-3.8.4/0014-ARM-edma-remove-unused-transfer-controller-handlers.patch
+++ b/patches/linux-3.8.13/0014-ARM-edma-remove-unused-transfer-controller-handlers.patch
diff --git a/patches/linux-3.8.4/0015-ARM-edma-add-AM33XX-support-to-the-private-EDMA-API.patch b/patches/linux-3.8.13/0015-ARM-edma-add-AM33XX-support-to-the-private-EDMA-API.patch
index fc41be5..fc41be5 100644
--- a/patches/linux-3.8.4/0015-ARM-edma-add-AM33XX-support-to-the-private-EDMA-API.patch
+++ b/patches/linux-3.8.13/0015-ARM-edma-add-AM33XX-support-to-the-private-EDMA-API.patch
diff --git a/patches/linux-3.8.4/0016-dmaengine-edma-enable-build-for-AM33XX.patch b/patches/linux-3.8.13/0016-dmaengine-edma-enable-build-for-AM33XX.patch
index b3d58ab..b3d58ab 100644
--- a/patches/linux-3.8.4/0016-dmaengine-edma-enable-build-for-AM33XX.patch
+++ b/patches/linux-3.8.13/0016-dmaengine-edma-enable-build-for-AM33XX.patch
diff --git a/patches/linux-3.8.4/0017-dmaengine-edma-Add-TI-EDMA-device-tree-binding.patch b/patches/linux-3.8.13/0017-dmaengine-edma-Add-TI-EDMA-device-tree-binding.patch
index b4a0772..b4a0772 100644
--- a/patches/linux-3.8.4/0017-dmaengine-edma-Add-TI-EDMA-device-tree-binding.patch
+++ b/patches/linux-3.8.13/0017-dmaengine-edma-Add-TI-EDMA-device-tree-binding.patch
diff --git a/patches/linux-3.8.4/0018-ARM-dts-add-AM33XX-EDMA-support.patch b/patches/linux-3.8.13/0018-ARM-dts-add-AM33XX-EDMA-support.patch
index 102ab48..102ab48 100644
--- a/patches/linux-3.8.4/0018-ARM-dts-add-AM33XX-EDMA-support.patch
+++ b/patches/linux-3.8.13/0018-ARM-dts-add-AM33XX-EDMA-support.patch
diff --git a/patches/linux-3.8.4/0019-dmaengine-add-dma_request_slave_channel_compat.patch b/patches/linux-3.8.13/0019-dmaengine-add-dma_request_slave_channel_compat.patch
index f03996a..f03996a 100644
--- a/patches/linux-3.8.4/0019-dmaengine-add-dma_request_slave_channel_compat.patch
+++ b/patches/linux-3.8.13/0019-dmaengine-add-dma_request_slave_channel_compat.patch
diff --git a/patches/linux-3.8.4/0020-mmc-omap_hsmmc-convert-to-dma_request_slave_channel_.patch b/patches/linux-3.8.13/0020-mmc-omap_hsmmc-convert-to-dma_request_slave_channel_.patch
index 261f813..261f813 100644
--- a/patches/linux-3.8.4/0020-mmc-omap_hsmmc-convert-to-dma_request_slave_channel_.patch
+++ b/patches/linux-3.8.13/0020-mmc-omap_hsmmc-convert-to-dma_request_slave_channel_.patch
diff --git a/patches/linux-3.8.4/0021-mmc-omap_hsmmc-set-max_segs-based-on-dma-engine-limi.patch b/patches/linux-3.8.13/0021-mmc-omap_hsmmc-set-max_segs-based-on-dma-engine-limi.patch
index d87faf0..d87faf0 100644
--- a/patches/linux-3.8.4/0021-mmc-omap_hsmmc-set-max_segs-based-on-dma-engine-limi.patch
+++ b/patches/linux-3.8.13/0021-mmc-omap_hsmmc-set-max_segs-based-on-dma-engine-limi.patch
diff --git a/patches/linux-3.8.4/0022-mmc-omap_hsmmc-add-generic-DMA-request-support-to-th.patch b/patches/linux-3.8.13/0022-mmc-omap_hsmmc-add-generic-DMA-request-support-to-th.patch
index 5246c41..5246c41 100644
--- a/patches/linux-3.8.4/0022-mmc-omap_hsmmc-add-generic-DMA-request-support-to-th.patch
+++ b/patches/linux-3.8.13/0022-mmc-omap_hsmmc-add-generic-DMA-request-support-to-th.patch
diff --git a/patches/linux-3.8.4/0023-ARM-dts-add-AM33XX-MMC-support.patch b/patches/linux-3.8.13/0023-ARM-dts-add-AM33XX-MMC-support.patch
index 6f625fa..6f625fa 100644
--- a/patches/linux-3.8.4/0023-ARM-dts-add-AM33XX-MMC-support.patch
+++ b/patches/linux-3.8.13/0023-ARM-dts-add-AM33XX-MMC-support.patch
diff --git a/patches/linux-3.8.4/0024-spi-omap2-mcspi-convert-to-dma_request_slave_channel.patch b/patches/linux-3.8.13/0024-spi-omap2-mcspi-convert-to-dma_request_slave_channel.patch
index 292f2ac..292f2ac 100644
--- a/patches/linux-3.8.4/0024-spi-omap2-mcspi-convert-to-dma_request_slave_channel.patch
+++ b/patches/linux-3.8.13/0024-spi-omap2-mcspi-convert-to-dma_request_slave_channel.patch
diff --git a/patches/linux-3.8.4/0025-spi-omap2-mcspi-add-generic-DMA-request-support-to-t.patch b/patches/linux-3.8.13/0025-spi-omap2-mcspi-add-generic-DMA-request-support-to-t.patch
index 450c402..450c402 100644
--- a/patches/linux-3.8.4/0025-spi-omap2-mcspi-add-generic-DMA-request-support-to-t.patch
+++ b/patches/linux-3.8.13/0025-spi-omap2-mcspi-add-generic-DMA-request-support-to-t.patch
diff --git a/patches/linux-3.8.4/0026-ARM-dts-add-AM33XX-SPI-DMA-support.patch b/patches/linux-3.8.13/0026-ARM-dts-add-AM33XX-SPI-DMA-support.patch
index 4277582..4277582 100644
--- a/patches/linux-3.8.4/0026-ARM-dts-add-AM33XX-SPI-DMA-support.patch
+++ b/patches/linux-3.8.13/0026-ARM-dts-add-AM33XX-SPI-DMA-support.patch
diff --git a/patches/linux-3.8.4/0027-ARM-dts-Add-SPI-Flash-support-to-am335x-evm.patch b/patches/linux-3.8.13/0027-ARM-dts-Add-SPI-Flash-support-to-am335x-evm.patch
index 7402d18..7402d18 100644
--- a/patches/linux-3.8.4/0027-ARM-dts-Add-SPI-Flash-support-to-am335x-evm.patch
+++ b/patches/linux-3.8.13/0027-ARM-dts-Add-SPI-Flash-support-to-am335x-evm.patch
diff --git a/patches/linux-3.8.4/0028-Documentation-bindings-add-spansion.patch b/patches/linux-3.8.13/0028-Documentation-bindings-add-spansion.patch
index 9715369..9715369 100644
--- a/patches/linux-3.8.4/0028-Documentation-bindings-add-spansion.patch
+++ b/patches/linux-3.8.13/0028-Documentation-bindings-add-spansion.patch
diff --git a/patches/linux-3.8.4/0029-ARM-dts-enable-spi1-node-and-pinmux-on-BeagleBone.patch b/patches/linux-3.8.13/0029-ARM-dts-enable-spi1-node-and-pinmux-on-BeagleBone.patch
index 058e066..058e066 100644
--- a/patches/linux-3.8.4/0029-ARM-dts-enable-spi1-node-and-pinmux-on-BeagleBone.patch
+++ b/patches/linux-3.8.13/0029-ARM-dts-enable-spi1-node-and-pinmux-on-BeagleBone.patch
diff --git a/patches/linux-3.8.4/0030-ARM-dts-add-BeagleBone-Adafruit-1.8-LCD-support.patch b/patches/linux-3.8.13/0030-ARM-dts-add-BeagleBone-Adafruit-1.8-LCD-support.patch
index 406bea2..406bea2 100644
--- a/patches/linux-3.8.4/0030-ARM-dts-add-BeagleBone-Adafruit-1.8-LCD-support.patch
+++ b/patches/linux-3.8.13/0030-ARM-dts-add-BeagleBone-Adafruit-1.8-LCD-support.patch
diff --git a/patches/linux-3.8.4/0031-misc-add-gpevt-driver.patch b/patches/linux-3.8.13/0031-misc-add-gpevt-driver.patch
index 757e48c..757e48c 100644
--- a/patches/linux-3.8.4/0031-misc-add-gpevt-driver.patch
+++ b/patches/linux-3.8.13/0031-misc-add-gpevt-driver.patch
diff --git a/patches/linux-3.8.4/0032-ARM-dts-add-BeagleBone-gpevt-support.patch b/patches/linux-3.8.13/0032-ARM-dts-add-BeagleBone-gpevt-support.patch
index d672e6b..d672e6b 100644
--- a/patches/linux-3.8.4/0032-ARM-dts-add-BeagleBone-gpevt-support.patch
+++ b/patches/linux-3.8.13/0032-ARM-dts-add-BeagleBone-gpevt-support.patch
diff --git a/patches/linux-3.8.4/0033-ARM-configs-working-dmaengine-configs-for-da8xx-and-.patch b/patches/linux-3.8.13/0033-ARM-configs-working-dmaengine-configs-for-da8xx-and-.patch
index e596ed1..e596ed1 100644
--- a/patches/linux-3.8.4/0033-ARM-configs-working-dmaengine-configs-for-da8xx-and-.patch
+++ b/patches/linux-3.8.13/0033-ARM-configs-working-dmaengine-configs-for-da8xx-and-.patch
diff --git a/patches/linux-3.8.4/0034-ARM-dts-Add-UART4-support-to-BeagleBone.patch b/patches/linux-3.8.13/0034-ARM-dts-Add-UART4-support-to-BeagleBone.patch
index e840c25..e840c25 100644
--- a/patches/linux-3.8.4/0034-ARM-dts-Add-UART4-support-to-BeagleBone.patch
+++ b/patches/linux-3.8.13/0034-ARM-dts-Add-UART4-support-to-BeagleBone.patch
diff --git a/patches/linux-3.8.13/0035-gpevnt-Remove-__devinit.patch b/patches/linux-3.8.13/0035-gpevnt-Remove-__devinit.patch
new file mode 100644
index 0000000..b771629
--- /dev/null
+++ b/patches/linux-3.8.13/0035-gpevnt-Remove-__devinit.patch
@@ -0,0 +1,42 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 1 May 2013 16:45:10 +0300
+Subject: [PATCH] gpevnt: Remove __devinit
+
+__devinit is gone now; remove it.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/misc/gpevt.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/misc/gpevt.c b/drivers/misc/gpevt.c
+index 4fe256c..aabcd48 100644
+--- a/drivers/misc/gpevt.c
++++ b/drivers/misc/gpevt.c
+@@ -41,7 +41,7 @@ static void gpevt_callback(void *data)
+ dev_info(dev, "*** DMA transfer failed ***\n");
+ }
+
+-static int __devinit gpevt_probe (struct platform_device *pdev)
++static int gpevt_probe (struct platform_device *pdev)
+ {
+ struct device_node *np = pdev->dev.of_node;
+ struct pinctrl *pinctrl;
+@@ -132,7 +132,7 @@ static int __devinit gpevt_probe (struct platform_device *pdev)
+ return 0;
+ }
+
+-static int __devexit gpevt_remove(struct platform_device *pdev)
++static int gpevt_remove(struct platform_device *pdev)
+ {
+ return 0;
+ }
+@@ -149,7 +149,7 @@ static struct platform_driver gpevt_driver = {
+ .of_match_table = gpevt_dt_ids,
+ },
+ .probe = gpevt_probe,
+- .remove = __devexit_p(gpevt_remove),
++ .remove = gpevt_remove,
+ };
+
+ static int __init gpevt_init(void)
diff --git a/patches/linux-3.8.4/0035-ARM-OMAP2-am33xx-hwmod-Fix-register-offset-NULL-chec.patch b/patches/linux-3.8.13/0036-ARM-OMAP2-am33xx-hwmod-Fix-register-offset-NULL-chec.patch
index 710a94b..710a94b 100644
--- a/patches/linux-3.8.4/0035-ARM-OMAP2-am33xx-hwmod-Fix-register-offset-NULL-chec.patch
+++ b/patches/linux-3.8.13/0036-ARM-OMAP2-am33xx-hwmod-Fix-register-offset-NULL-chec.patch
diff --git a/patches/linux-3.8.4/0036-rtc-OMAP-Add-system-pm_power_off-to-rtc-driver.patch b/patches/linux-3.8.13/0037-rtc-OMAP-Add-system-pm_power_off-to-rtc-driver.patch
index 1a1ce75..1a1ce75 100644
--- a/patches/linux-3.8.4/0036-rtc-OMAP-Add-system-pm_power_off-to-rtc-driver.patch
+++ b/patches/linux-3.8.13/0037-rtc-OMAP-Add-system-pm_power_off-to-rtc-driver.patch
diff --git a/patches/linux-3.8.4/0037-ARM-dts-AM33XX-Set-pmic-shutdown-controller-for-Beag.patch b/patches/linux-3.8.13/0038-ARM-dts-AM33XX-Set-pmic-shutdown-controller-for-Beag.patch
index f15d2d8..f15d2d8 100644
--- a/patches/linux-3.8.4/0037-ARM-dts-AM33XX-Set-pmic-shutdown-controller-for-Beag.patch
+++ b/patches/linux-3.8.13/0038-ARM-dts-AM33XX-Set-pmic-shutdown-controller-for-Beag.patch
diff --git a/patches/linux-3.8.4/0038-ARM-dts-AM33XX-Enable-system-power-off-control-in-am.patch b/patches/linux-3.8.13/0039-ARM-dts-AM33XX-Enable-system-power-off-control-in-am.patch
index f95a4b0..f95a4b0 100644
--- a/patches/linux-3.8.4/0038-ARM-dts-AM33XX-Enable-system-power-off-control-in-am.patch
+++ b/patches/linux-3.8.13/0039-ARM-dts-AM33XX-Enable-system-power-off-control-in-am.patch
diff --git a/patches/linux-3.8.4/0039-i2c-pinctrl-ify-i2c-omap.c.patch b/patches/linux-3.8.13/0040-i2c-pinctrl-ify-i2c-omap.c.patch
index 3ebeae1..3ebeae1 100644
--- a/patches/linux-3.8.4/0039-i2c-pinctrl-ify-i2c-omap.c.patch
+++ b/patches/linux-3.8.13/0040-i2c-pinctrl-ify-i2c-omap.c.patch
diff --git a/patches/linux-3.8.4/0040-arm-dts-AM33XX-Configure-pinmuxs-for-user-leds-contr.patch b/patches/linux-3.8.13/0041-arm-dts-AM33XX-Configure-pinmuxs-for-user-leds-contr.patch
index 1270795..1270795 100644
--- a/patches/linux-3.8.4/0040-arm-dts-AM33XX-Configure-pinmuxs-for-user-leds-contr.patch
+++ b/patches/linux-3.8.13/0041-arm-dts-AM33XX-Configure-pinmuxs-for-user-leds-contr.patch
diff --git a/patches/linux-3.8.4/0041-beaglebone-DT-set-default-triggers-for-LEDS.patch b/patches/linux-3.8.13/0042-beaglebone-DT-set-default-triggers-for-LEDS.patch
index f1d09d8..f1d09d8 100644
--- a/patches/linux-3.8.4/0041-beaglebone-DT-set-default-triggers-for-LEDS.patch
+++ b/patches/linux-3.8.13/0042-beaglebone-DT-set-default-triggers-for-LEDS.patch
diff --git a/patches/linux-3.8.4/0042-beaglebone-add-a-cpu-led-trigger.patch b/patches/linux-3.8.13/0043-beaglebone-add-a-cpu-led-trigger.patch
index 672ae73..672ae73 100644
--- a/patches/linux-3.8.4/0042-beaglebone-add-a-cpu-led-trigger.patch
+++ b/patches/linux-3.8.13/0043-beaglebone-add-a-cpu-led-trigger.patch
diff --git a/patches/linux-3.8.4/0043-am33xx-DT-add-commented-out-OPP-values-for-ES2.0.patch b/patches/linux-3.8.13/0044-am33xx-DT-add-commented-out-OPP-values-for-ES2.0.patch
index 549050e..549050e 100644
--- a/patches/linux-3.8.4/0043-am33xx-DT-add-commented-out-OPP-values-for-ES2.0.patch
+++ b/patches/linux-3.8.13/0044-am33xx-DT-add-commented-out-OPP-values-for-ES2.0.patch
diff --git a/patches/linux-3.8.13/0045-mfd-input-iio-ti_am335x_adc-use-one-structure-for-ti.patch b/patches/linux-3.8.13/0045-mfd-input-iio-ti_am335x_adc-use-one-structure-for-ti.patch
new file mode 100644
index 0000000..6415224
--- /dev/null
+++ b/patches/linux-3.8.13/0045-mfd-input-iio-ti_am335x_adc-use-one-structure-for-ti.patch
@@ -0,0 +1,136 @@
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Wed, 12 Jun 2013 18:58:02 +0200
+Subject: [PATCH] mfd: input: iio: ti_am335x_adc: use one structure for
+ ti_tscadc_dev
+
+The mfd driver creates platform data for the child devices and it is the
+ti_tscadc_dev struct. This struct is copied for the two devices.
+The copy of the structure makes a common lock in this structure a little
+less usefull. Therefore the platform data is not a pointer to the
+structure and the same structure is used.
+While doing the change I noticed that the suspend/resume code assumes
+the wrong pointer for ti_tscadc_dev and this has been fixed as well.
+
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/iio/adc/ti_am335x_adc.c | 5 +++--
+ drivers/input/touchscreen/ti_am335x_tsc.c | 16 +++++++++-------
+ drivers/mfd/ti_am335x_tscadc.c | 8 ++++----
+ include/linux/mfd/ti_am335x_tscadc.h | 7 +++++++
+ 4 files changed, 23 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
+index cd030e1..fde3822 100644
+--- a/drivers/iio/adc/ti_am335x_adc.c
++++ b/drivers/iio/adc/ti_am335x_adc.c
+@@ -140,7 +140,7 @@ static int tiadc_probe(struct platform_device *pdev)
+ {
+ struct iio_dev *indio_dev;
+ struct tiadc_device *adc_dev;
+- struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data;
++ struct ti_tscadc_dev *tscadc_dev = ti_tscadc_dev_get(pdev);
+ struct mfd_tscadc_board *pdata;
+ int err;
+
+@@ -205,9 +205,10 @@ static int tiadc_suspend(struct device *dev)
+ {
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct tiadc_device *adc_dev = iio_priv(indio_dev);
+- struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
++ struct ti_tscadc_dev *tscadc_dev;
+ unsigned int idle;
+
++ tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev));
+ if (!device_may_wakeup(tscadc_dev->dev)) {
+ idle = tiadc_readl(adc_dev, REG_CTRL);
+ idle &= ~(CNTRLREG_TSCSSENB);
+diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
+index 51e7b87..16077d3 100644
+--- a/drivers/input/touchscreen/ti_am335x_tsc.c
++++ b/drivers/input/touchscreen/ti_am335x_tsc.c
+@@ -262,7 +262,7 @@ static int titsc_probe(struct platform_device *pdev)
+ {
+ struct titsc *ts_dev;
+ struct input_dev *input_dev;
+- struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data;
++ struct ti_tscadc_dev *tscadc_dev = ti_tscadc_dev_get(pdev);
+ struct mfd_tscadc_board *pdata;
+ int err;
+
+@@ -329,8 +329,8 @@ err_free_mem:
+
+ static int titsc_remove(struct platform_device *pdev)
+ {
+- struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data;
+- struct titsc *ts_dev = tscadc_dev->tsc;
++ struct titsc *ts_dev = platform_get_drvdata(pdev);
++ u32 steps;
+
+ free_irq(ts_dev->irq, ts_dev);
+
+@@ -344,10 +344,11 @@ static int titsc_remove(struct platform_device *pdev)
+ #ifdef CONFIG_PM
+ static int titsc_suspend(struct device *dev)
+ {
+- struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
+- struct titsc *ts_dev = tscadc_dev->tsc;
++ struct titsc *ts_dev = dev_get_drvdata(dev);
++ struct ti_tscadc_dev *tscadc_dev;
+ unsigned int idle;
+
++ tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev));
+ if (device_may_wakeup(tscadc_dev->dev)) {
+ idle = titsc_readl(ts_dev, REG_IRQENABLE);
+ titsc_writel(ts_dev, REG_IRQENABLE,
+@@ -359,9 +360,10 @@ static int titsc_suspend(struct device *dev)
+
+ static int titsc_resume(struct device *dev)
+ {
+- struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
+- struct titsc *ts_dev = tscadc_dev->tsc;
++ struct titsc *ts_dev = dev_get_drvdata(dev);
++ struct ti_tscadc_dev *tscadc_dev;
+
++ tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev));
+ if (device_may_wakeup(tscadc_dev->dev)) {
+ titsc_writel(ts_dev, REG_IRQWAKEUP,
+ 0x00);
+diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
+index e9f3fb5..772ea2a 100644
+--- a/drivers/mfd/ti_am335x_tscadc.c
++++ b/drivers/mfd/ti_am335x_tscadc.c
+@@ -176,14 +176,14 @@ static int ti_tscadc_probe(struct platform_device *pdev)
+ /* TSC Cell */
+ cell = &tscadc->cells[TSC_CELL];
+ cell->name = "tsc";
+- cell->platform_data = tscadc;
+- cell->pdata_size = sizeof(*tscadc);
++ cell->platform_data = &tscadc;
++ cell->pdata_size = sizeof(tscadc);
+
+ /* ADC Cell */
+ cell = &tscadc->cells[ADC_CELL];
+ cell->name = "tiadc";
+- cell->platform_data = tscadc;
+- cell->pdata_size = sizeof(*tscadc);
++ cell->platform_data = &tscadc;
++ cell->pdata_size = sizeof(tscadc);
+
+ err = mfd_add_devices(&pdev->dev, pdev->id, tscadc->cells,
+ TSCADC_CELLS, NULL, 0, NULL);
+diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
+index c79ad5d..8114e4e 100644
+--- a/include/linux/mfd/ti_am335x_tscadc.h
++++ b/include/linux/mfd/ti_am335x_tscadc.h
+@@ -149,4 +149,11 @@ struct ti_tscadc_dev {
+ struct adc_device *adc;
+ };
+
++static inline struct ti_tscadc_dev *ti_tscadc_dev_get(struct platform_device *p)
++{
++ struct ti_tscadc_dev **tscadc_dev = p->dev.platform_data;
++
++ return *tscadc_dev;
++}
++
+ #endif
diff --git a/patches/linux-3.8.13/0046-input-ti_am33x_tsc-Step-enable-bits-made-configurabl.patch b/patches/linux-3.8.13/0046-input-ti_am33x_tsc-Step-enable-bits-made-configurabl.patch
new file mode 100644
index 0000000..6091b4c
--- /dev/null
+++ b/patches/linux-3.8.13/0046-input-ti_am33x_tsc-Step-enable-bits-made-configurabl.patch
@@ -0,0 +1,215 @@
+From: "Patil, Rachna" <rachna@ti.com>
+Date: Wed, 12 Jun 2013 18:58:03 +0200
+Subject: [PATCH] input: ti_am33x_tsc: Step enable bits made configurable
+
+Current code has hard coded value written to
+step enable bits. Now the bits are updated based
+on how many steps are needed to be configured got
+from platform data.
+
+The user needs to take care not to exceed
+the count more than 16. While using ADC and TSC
+one should take care to set this parameter correctly.
+
+Sebastian added the common lock and moved the code, that manipulates the
+steps, from into the mfd module.
+
+Signed-off-by: Patil, Rachna <rachna@ti.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/iio/adc/ti_am335x_adc.c | 20 ++++++++++++++++++--
+ drivers/input/touchscreen/ti_am335x_tsc.c | 12 ++++++++++--
+ drivers/mfd/ti_am335x_tscadc.c | 29 ++++++++++++++++++++++++++++-
+ include/linux/mfd/ti_am335x_tscadc.h | 8 ++++++--
+ 4 files changed, 62 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
+index fde3822..b47594d 100644
+--- a/drivers/iio/adc/ti_am335x_adc.c
++++ b/drivers/iio/adc/ti_am335x_adc.c
+@@ -42,10 +42,20 @@ static void tiadc_writel(struct tiadc_device *adc, unsigned int reg,
+ writel(val, adc->mfd_tscadc->tscadc_base + reg);
+ }
+
++static u32 get_adc_step_mask(struct tiadc_device *adc_dev)
++{
++ u32 step_en;
++
++ step_en = ((1 << adc_dev->channels) - 1);
++ step_en <<= TOTAL_STEPS - adc_dev->channels + 1;
++ return step_en;
++}
++
+ static void tiadc_step_config(struct tiadc_device *adc_dev)
+ {
+ unsigned int stepconfig;
+ int i, channels = 0, steps;
++ u32 step_en;
+
+ /*
+ * There are 16 configurable steps and 8 analog input
+@@ -69,7 +79,8 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
+ STEPCONFIG_OPENDLY);
+ channels++;
+ }
+- tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB);
++ step_en = get_adc_step_mask(adc_dev);
++ am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
+ }
+
+ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
+@@ -127,7 +138,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
+ if (i == chan->channel)
+ *val = readx1 & 0xfff;
+ }
+- tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB);
++ am335x_tsc_se_update(adc_dev->mfd_tscadc);
+
+ return IIO_VAL_INT;
+ }
+@@ -191,10 +202,15 @@ err_ret:
+ static int tiadc_remove(struct platform_device *pdev)
+ {
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
++ struct tiadc_device *adc_dev = iio_priv(indio_dev);
++ u32 step_en;
+
+ iio_device_unregister(indio_dev);
+ tiadc_channels_remove(indio_dev);
+
++ step_en = get_adc_step_mask(adc_dev);
++ am335x_tsc_se_clr(adc_dev->mfd_tscadc, step_en);
++
+ iio_device_free(indio_dev);
+
+ return 0;
+diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
+index 16077d3..23d6a4d 100644
+--- a/drivers/input/touchscreen/ti_am335x_tsc.c
++++ b/drivers/input/touchscreen/ti_am335x_tsc.c
+@@ -57,6 +57,7 @@ static void titsc_writel(struct titsc *tsc, unsigned int reg,
+ static void titsc_step_config(struct titsc *ts_dev)
+ {
+ unsigned int config;
++ unsigned int stepenable = 0;
+ int i, total_steps;
+
+ /* Configure the Step registers */
+@@ -128,7 +129,9 @@ static void titsc_step_config(struct titsc *ts_dev)
+ titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2),
+ STEPCONFIG_OPENDLY);
+
+- titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC);
++ /* The steps1 … end and bit 0 for TS_Charge */
++ stepenable = (1 << (total_steps + 2)) - 1;
++ am335x_tsc_se_set(ts_dev->mfd_tscadc, stepenable);
+ }
+
+ static void titsc_read_coordinates(struct titsc *ts_dev,
+@@ -250,7 +253,7 @@ static irqreturn_t titsc_irq(int irq, void *dev)
+
+ titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
+
+- titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC);
++ am335x_tsc_se_update(ts_dev->mfd_tscadc);
+ return IRQ_HANDLED;
+ }
+
+@@ -334,6 +337,11 @@ static int titsc_remove(struct platform_device *pdev)
+
+ free_irq(ts_dev->irq, ts_dev);
+
++ /* total steps followed by the enable mask */
++ steps = 2 * ts_dev->steps_to_configure + 2;
++ steps = (1 << steps) - 1;
++ am335x_tsc_se_clr(ts_dev->mfd_tscadc, steps);
++
+ input_unregister_device(ts_dev->input);
+
+ platform_set_drvdata(pdev, NULL);
+diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
+index 772ea2a..90ccfc0 100644
+--- a/drivers/mfd/ti_am335x_tscadc.c
++++ b/drivers/mfd/ti_am335x_tscadc.c
+@@ -48,6 +48,32 @@ static const struct regmap_config tscadc_regmap_config = {
+ .val_bits = 32,
+ };
+
++void am335x_tsc_se_update(struct ti_tscadc_dev *tsadc)
++{
++ tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache);
++}
++EXPORT_SYMBOL_GPL(am335x_tsc_se_update);
++
++void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val)
++{
++ spin_lock(&tsadc->reg_lock);
++ tsadc->reg_se_cache |= val;
++ spin_unlock(&tsadc->reg_lock);
++
++ am335x_tsc_se_update(tsadc);
++}
++EXPORT_SYMBOL_GPL(am335x_tsc_se_set);
++
++void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val)
++{
++ spin_lock(&tsadc->reg_lock);
++ tsadc->reg_se_cache &= ~val;
++ spin_unlock(&tsadc->reg_lock);
++
++ am335x_tsc_se_update(tsadc);
++}
++EXPORT_SYMBOL_GPL(am335x_tsc_se_clr);
++
+ static void tscadc_idle_config(struct ti_tscadc_dev *config)
+ {
+ unsigned int idleconfig;
+@@ -129,6 +155,7 @@ static int ti_tscadc_probe(struct platform_device *pdev)
+ goto ret;
+ }
+
++ spin_lock_init(&tscadc->reg_lock);
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+
+@@ -239,7 +266,7 @@ static int tscadc_resume(struct device *dev)
+ CNTRLREG_STEPID | CNTRLREG_4WIRE;
+ tscadc_writel(tscadc_dev, REG_CTRL, ctrl);
+ tscadc_idle_config(tscadc_dev);
+- tscadc_writel(tscadc_dev, REG_SE, STPENB_STEPENB);
++ am335x_tsc_se_update(tscadc_dev);
+ restore = tscadc_readl(tscadc_dev, REG_CTRL);
+ tscadc_writel(tscadc_dev, REG_CTRL,
+ (restore | CNTRLREG_TSCSSENB));
+diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
+index 8114e4e..4258627 100644
+--- a/include/linux/mfd/ti_am335x_tscadc.h
++++ b/include/linux/mfd/ti_am335x_tscadc.h
+@@ -46,8 +46,6 @@
+ /* Step Enable */
+ #define STEPENB_MASK (0x1FFFF << 0)
+ #define STEPENB(val) ((val) << 0)
+-#define STPENB_STEPENB STEPENB(0x1FFFF)
+-#define STPENB_STEPENB_TC STEPENB(0x1FFF)
+
+ /* IRQ enable */
+ #define IRQENB_HW_PEN BIT(0)
+@@ -141,6 +139,8 @@ struct ti_tscadc_dev {
+ void __iomem *tscadc_base;
+ int irq;
+ struct mfd_cell cells[TSCADC_CELLS];
++ u32 reg_se_cache;
++ spinlock_t reg_lock;
+
+ /* tsc device */
+ struct titsc *tsc;
+@@ -156,4 +156,8 @@ static inline struct ti_tscadc_dev *ti_tscadc_dev_get(struct platform_device *p)
+ return *tscadc_dev;
+ }
+
++void am335x_tsc_se_update(struct ti_tscadc_dev *tsadc);
++void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val);
++void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val);
++
+ #endif
diff --git a/patches/linux-3.8.4/0045-input-ti_am335x_tsc-Order-of-TSC-wires-made-configur.patch b/patches/linux-3.8.13/0047-input-ti_am33x_tsc-Order-of-TSC-wires-made-configura.patch
index 3a34c2e..c3c2e22 100644
--- a/patches/linux-3.8.4/0045-input-ti_am335x_tsc-Order-of-TSC-wires-made-configur.patch
+++ b/patches/linux-3.8.13/0047-input-ti_am33x_tsc-Order-of-TSC-wires-made-configura.patch
@@ -1,159 +1,111 @@
From: "Patil, Rachna" <rachna@ti.com>
-Date: Thu, 24 Jan 2013 03:45:06 +0000
-Subject: [PATCH] input: ti_am335x_tsc: Order of TSC wires, made configurable
+Date: Wed, 12 Jun 2013 18:58:04 +0200
+Subject: [PATCH] input: ti_am33x_tsc: Order of TSC wires, made configurable
The current driver expected touchscreen input
wires(XP,XN,YP,YN) to be connected in a particular order.
Making changes to accept this as platform data.
+Sebastian reworked the original patch and removed a lot of the not
+required pieces.
+
Signed-off-by: Patil, Rachna <rachna@ti.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- drivers/input/touchscreen/ti_am335x_tsc.c | 156 ++++++++++++++++++++++++++---
- include/linux/input/ti_am335x_tsc.h | 12 +++
- include/linux/mfd/ti_am335x_tscadc.h | 10 +-
- 3 files changed, 159 insertions(+), 19 deletions(-)
+ drivers/input/touchscreen/ti_am335x_tsc.c | 102 ++++++++++++++++++++++++-----
+ include/linux/input/ti_am335x_tsc.h | 12 ++++
+ include/linux/mfd/ti_am335x_tscadc.h | 3 -
+ 3 files changed, 98 insertions(+), 19 deletions(-)
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
-index da652e0..0c460f9 100644
+index 23d6a4d..2bdd66c 100644
--- a/drivers/input/touchscreen/ti_am335x_tsc.c
+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
-@@ -33,6 +33,17 @@
+@@ -33,6 +33,13 @@
#define SEQ_SETTLE 275
#define MAX_12BIT ((1 << 12) - 1)
-+/*
-+ * Refer to function regbit_map() to
-+ * map the values in the matrix.
-+ */
-+static int config[4][4] = {
-+ {1, 0, 1, 0},
-+ {2, 3, 2, 3},
-+ {4, 5, 4, 5},
-+ {0, 6, 0, 6}
++static const int config_pins[] = {
++ STEPCONFIG_XPP,
++ STEPCONFIG_XNN,
++ STEPCONFIG_YPP,
++ STEPCONFIG_YNN,
+};
+
struct titsc {
struct input_dev *input;
struct ti_tscadc_dev *mfd_tscadc;
-@@ -42,6 +53,9 @@ struct titsc {
- unsigned int enable_bits;
+@@ -41,6 +48,9 @@ struct titsc {
+ unsigned int x_plate_resistance;
bool pen_down;
int steps_to_configure;
-+ int config_inp[20];
-+ int bit_xp, bit_xn, bit_yp, bit_yn;
-+ int inp_xp, inp_xn, inp_yp, inp_yn;
++ u32 config_inp[4];
++ u32 bit_xp, bit_xn, bit_yp, bit_yn;
++ u32 inp_xp, inp_xn, inp_yp, inp_yn;
};
static unsigned int titsc_readl(struct titsc *ts, unsigned int reg)
-@@ -55,6 +69,107 @@ static void titsc_writel(struct titsc *tsc, unsigned int reg,
+@@ -54,6 +64,58 @@ static void titsc_writel(struct titsc *tsc, unsigned int reg,
writel(val, tsc->mfd_tscadc->tscadc_base + reg);
}
-+/*
-+ * Each of the analog lines are mapped
-+ * with one or two register bits,
-+ * which can be either pulled high/low
-+ * depending on the value to be read.
-+ */
-+static int regbit_map(int val)
-+{
-+ int map_bits = 0;
-+
-+ switch (val) {
-+ case 1:
-+ map_bits = XPP;
-+ break;
-+ case 2:
-+ map_bits = XNP;
-+ break;
-+ case 3:
-+ map_bits = XNN;
-+ break;
-+ case 4:
-+ map_bits = YPP;
-+ break;
-+ case 5:
-+ map_bits = YPN;
-+ break;
-+ case 6:
-+ map_bits = YNN;
-+ break;
-+ }
-+
-+ return map_bits;
-+}
-+
+static int titsc_config_wires(struct titsc *ts_dev)
+{
-+ int analog_line[10], wire_order[10];
-+ int i, temp_bits, err;
++ u32 analog_line[4];
++ u32 wire_order[4];
++ int i, bit_cfg;
+
+ for (i = 0; i < 4; i++) {
+ /*
+ * Get the order in which TSC wires are attached
+ * w.r.t. each of the analog input lines on the EVM.
+ */
-+ analog_line[i] = ts_dev->config_inp[i] & 0xF0;
-+ analog_line[i] = analog_line[i] >> 4;
-+
++ analog_line[i] = (ts_dev->config_inp[i] & 0xF0) >> 4;
+ wire_order[i] = ts_dev->config_inp[i] & 0x0F;
++ if (WARN_ON(analog_line[i] > 7))
++ return -EINVAL;
++ if (WARN_ON(wire_order[i] > ARRAY_SIZE(config_pins)))
++ return -EINVAL;
+ }
+
+ for (i = 0; i < 4; i++) {
-+ switch (wire_order[i]) {
++ int an_line;
++ int wi_order;
++
++ an_line = analog_line[i];
++ wi_order = wire_order[i];
++ bit_cfg = config_pins[wi_order];
++ if (bit_cfg == 0)
++ return -EINVAL;
++ switch (wi_order) {
+ case 0:
-+ temp_bits = config[analog_line[i]][0];
-+ if (temp_bits == 0) {
-+ err = -EINVAL;
-+ goto ret;
-+ } else {
-+ ts_dev->bit_xp = regbit_map(temp_bits);
-+ ts_dev->inp_xp = analog_line[i];
-+ break;
-+ }
++ ts_dev->bit_xp = bit_cfg;
++ ts_dev->inp_xp = an_line;
++ break;
++
+ case 1:
-+ temp_bits = config[analog_line[i]][1];
-+ if (temp_bits == 0) {
-+ err = -EINVAL;
-+ goto ret;
-+ } else {
-+ ts_dev->bit_xn = regbit_map(temp_bits);
-+ ts_dev->inp_xn = analog_line[i];
-+ break;
-+ }
++ ts_dev->bit_xn = bit_cfg;
++ ts_dev->inp_xn = an_line;
++ break;
++
+ case 2:
-+ temp_bits = config[analog_line[i]][2];
-+ if (temp_bits == 0) {
-+ err = -EINVAL;
-+ goto ret;
-+ } else {
-+ ts_dev->bit_yp = regbit_map(temp_bits);
-+ ts_dev->inp_yp = analog_line[i];
-+ break;
-+ }
++ ts_dev->bit_yp = bit_cfg;
++ ts_dev->inp_yp = an_line;
++ break;
+ case 3:
-+ temp_bits = config[analog_line[i]][3];
-+ if (temp_bits == 0) {
-+ err = -EINVAL;
-+ goto ret;
-+ } else {
-+ ts_dev->bit_yn = regbit_map(temp_bits);
-+ ts_dev->inp_yn = analog_line[i];
-+ break;
-+ }
++ ts_dev->bit_yn = bit_cfg;
++ ts_dev->inp_yn = an_line;
++ break;
+ }
+ }
-+
+ return 0;
-+
-+ret:
-+ return err;
+}
+
static void titsc_step_config(struct titsc *ts_dev)
{
unsigned int config;
-@@ -65,18 +180,18 @@ static void titsc_step_config(struct titsc *ts_dev)
+@@ -64,18 +126,18 @@ static void titsc_step_config(struct titsc *ts_dev)
total_steps = 2 * ts_dev->steps_to_configure;
config = STEPCONFIG_MODE_HWSYNC |
@@ -178,7 +130,7 @@ index da652e0..0c460f9 100644
break;
}
-@@ -87,18 +202,18 @@ static void titsc_step_config(struct titsc *ts_dev)
+@@ -86,18 +148,18 @@ static void titsc_step_config(struct titsc *ts_dev)
config = 0;
config = STEPCONFIG_MODE_HWSYNC |
@@ -202,7 +154,7 @@ index da652e0..0c460f9 100644
break;
}
-@@ -109,9 +224,9 @@ static void titsc_step_config(struct titsc *ts_dev)
+@@ -108,9 +170,9 @@ static void titsc_step_config(struct titsc *ts_dev)
config = 0;
/* Charge step configuration */
@@ -214,7 +166,7 @@ index da652e0..0c460f9 100644
titsc_writel(ts_dev, REG_CHARGECONFIG, config);
titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY);
-@@ -119,13 +234,14 @@ static void titsc_step_config(struct titsc *ts_dev)
+@@ -118,13 +180,14 @@ static void titsc_step_config(struct titsc *ts_dev)
config = 0;
/* Configure to calculate pressure */
config = STEPCONFIG_MODE_HWSYNC |
@@ -232,7 +184,7 @@ index da652e0..0c460f9 100644
titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config);
titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2),
STEPCONFIG_OPENDLY);
-@@ -295,6 +411,8 @@ static int titsc_probe(struct platform_device *pdev)
+@@ -292,6 +355,8 @@ static int titsc_probe(struct platform_device *pdev)
ts_dev->wires = pdata->tsc_init->wires;
ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance;
ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure;
@@ -241,7 +193,7 @@ index da652e0..0c460f9 100644
err = request_irq(ts_dev->irq, titsc_irq,
0, pdev->dev.driver->name, ts_dev);
-@@ -304,6 +422,11 @@ static int titsc_probe(struct platform_device *pdev)
+@@ -301,6 +366,11 @@ static int titsc_probe(struct platform_device *pdev)
}
titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES);
@@ -253,14 +205,6 @@ index da652e0..0c460f9 100644
titsc_step_config(ts_dev);
titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure);
-@@ -373,6 +496,7 @@ static int titsc_resume(struct device *dev)
- 0x00);
- titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN);
- }
-+ titsc_config_wires(ts_dev);
- titsc_step_config(ts_dev);
- titsc_writel(ts_dev, REG_FIFO0THR,
- ts_dev->steps_to_configure);
diff --git a/include/linux/input/ti_am335x_tsc.h b/include/linux/input/ti_am335x_tsc.h
index 49269a2..6a66b4d 100644
--- a/include/linux/input/ti_am335x_tsc.h
@@ -291,10 +235,10 @@ index 49269a2..6a66b4d 100644
#endif
diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
-index 23e4f33..9624fea 100644
+index 4258627..e36ae41 100644
--- a/include/linux/mfd/ti_am335x_tscadc.h
+++ b/include/linux/mfd/ti_am335x_tscadc.h
-@@ -72,8 +72,6 @@
+@@ -71,8 +71,6 @@
#define STEPCONFIG_INM_ADCREFM STEPCONFIG_INM(8)
#define STEPCONFIG_INP_MASK (0xF << 19)
#define STEPCONFIG_INP(val) ((val) << 19)
@@ -303,7 +247,7 @@ index 23e4f33..9624fea 100644
#define STEPCONFIG_INP_AN4 STEPCONFIG_INP(4)
#define STEPCONFIG_INP_ADCREFM STEPCONFIG_INP(8)
#define STEPCONFIG_FIFO1 BIT(26)
-@@ -95,7 +93,6 @@
+@@ -94,7 +92,6 @@
#define STEPCHARGE_INM_AN1 STEPCHARGE_INM(1)
#define STEPCHARGE_INP_MASK (0xF << 19)
#define STEPCHARGE_INP(val) ((val) << 19)
@@ -311,17 +255,3 @@ index 23e4f33..9624fea 100644
#define STEPCHARGE_RFM_MASK (3 << 23)
#define STEPCHARGE_RFM(val) ((val) << 23)
#define STEPCHARGE_RFM_XNUR STEPCHARGE_RFM(1)
-@@ -117,6 +114,13 @@
- #define CNTRLREG_8WIRE CNTRLREG_AFE_CTRL(3)
- #define CNTRLREG_TSCENB BIT(7)
-
-+#define XPP STEPCONFIG_XPP
-+#define XNP STEPCONFIG_XNP
-+#define XNN STEPCONFIG_XNN
-+#define YPP STEPCONFIG_YPP
-+#define YPN STEPCONFIG_YPN
-+#define YNN STEPCONFIG_YNN
-+
- #define ADC_CLK 3000000
- #define MAX_CLK_DIV 7
- #define TOTAL_STEPS 16
diff --git a/patches/linux-3.8.4/0046-input-touchscreen-ti_tsc-remove-unwanted-fifo-flush.patch b/patches/linux-3.8.13/0048-input-ti_am33x_tsc-remove-unwanted-fifo-flush.patch
index aa8f9d9..0f1364d 100644
--- a/patches/linux-3.8.4/0046-input-touchscreen-ti_tsc-remove-unwanted-fifo-flush.patch
+++ b/patches/linux-3.8.13/0048-input-ti_am33x_tsc-remove-unwanted-fifo-flush.patch
@@ -1,20 +1,22 @@
From: "Patil, Rachna" <rachna@ti.com>
-Date: Thu, 24 Jan 2013 03:45:07 +0000
-Subject: [PATCH] input: touchscreen: ti_tsc: remove unwanted fifo flush
+Date: Wed, 12 Jun 2013 18:58:05 +0200
+Subject: [PATCH] input: ti_am33x_tsc: remove unwanted fifo flush
When touchscreen and ADC are used together, this
unwanted fifo flush leads to loss of ADC data.
Signed-off-by: Patil, Rachna <rachna@ti.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
drivers/input/touchscreen/ti_am335x_tsc.c | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
-index 0c460f9..064d2b2 100644
+index 2bdd66c..7b7de60 100644
--- a/drivers/input/touchscreen/ti_am335x_tsc.c
+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
-@@ -308,8 +308,6 @@ static irqreturn_t titsc_irq(int irq, void *dev)
+@@ -252,8 +252,6 @@ static irqreturn_t titsc_irq(int irq, void *dev)
unsigned int x = 0, y = 0;
unsigned int z1, z2, z;
unsigned int fsm;
@@ -23,7 +25,7 @@ index 0c460f9..064d2b2 100644
status = titsc_readl(ts_dev, REG_IRQSTATUS);
if (status & IRQENB_FIFO0THRES) {
-@@ -318,14 +316,6 @@ static irqreturn_t titsc_irq(int irq, void *dev)
+@@ -262,14 +260,6 @@ static irqreturn_t titsc_irq(int irq, void *dev)
z1 = titsc_readl(ts_dev, REG_FIFO0) & 0xfff;
z2 = titsc_readl(ts_dev, REG_FIFO1) & 0xfff;
diff --git a/patches/linux-3.8.13/0049-input-ti_am33x_tsc-Add-DT-support.patch b/patches/linux-3.8.13/0049-input-ti_am33x_tsc-Add-DT-support.patch
new file mode 100644
index 0000000..2224465
--- /dev/null
+++ b/patches/linux-3.8.13/0049-input-ti_am33x_tsc-Add-DT-support.patch
@@ -0,0 +1,312 @@
+From: "Patil, Rachna" <rachna@ti.com>
+Date: Wed, 12 Jun 2013 18:58:06 +0200
+Subject: [PATCH] input: ti_am33x_tsc: Add DT support
+
+This patch adds DT support to touch driver. It also provides a binding
+document which is used by the MFD and IIO part of the device.
+This patch also renames steps_to_configure to coordinate_readouts
+because the original name misleads the purpose of the variable.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+Signed-off-by: Patil, Rachna <rachna@ti.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ .../bindings/input/touchscreen/ti-tsc-adc.txt | 44 ++++++++
+ drivers/input/touchscreen/ti_am335x_tsc.c | 105 +++++++++++++++-----
+ drivers/mfd/ti_am335x_tscadc.c | 1 +
+ include/linux/input/ti_am335x_tsc.h | 2 +-
+ 4 files changed, 128 insertions(+), 24 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
+
+diff --git a/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt b/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
+new file mode 100644
+index 0000000..6a69af6
+--- /dev/null
++++ b/Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
+@@ -0,0 +1,44 @@
++* TI - TSC ADC (Touschscreen and analog digital converter)
++~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
++
++Required properties:
++- child "tsc"
++ ti,wires: Wires refer to application modes i.e. 4/5/8 wire touchscreen
++ support on the platform.
++ ti,x-plate-resistance: X plate resistance
++ ti,coordinate-readouts: The sequencer supports a total of 16
++ programmable steps each step is used to
++ read a single coordinate. A single
++ readout is enough but multiple reads can
++ increase the quality.
++ A value of 5 means, 5 reads for X, 5 for
++ Y and 2 for Z (always). This utilises 12
++ of the 16 software steps available. The
++ remaining 4 can be used by the ADC.
++ ti,wire-config: Different boards could have a different order for
++ connecting wires on touchscreen. We need to provide an
++ 8 bit number where in the 1st four bits represent the
++ analog lines and the next 4 bits represent positive/
++ negative terminal on that input line. Notations to
++ represent the input lines and terminals resoectively
++ is as follows:
++ AIN0 = 0, AIN1 = 1 and so on till AIN7 = 7.
++ XP = 0, XN = 1, YP = 2, YN = 3.
++- child "adc"
++ ti,adc-channels: List of analog inputs available for ADC.
++ AIN0 = 0, AIN1 = 1 and so on till AIN7 = 7.
++
++Example:
++ tscadc: tscadc@44e0d000 {
++ compatible = "ti,ti-tscadc";
++ tsc {
++ ti,wires = <4>;
++ ti,x-plate-resistance = <200>;
++ ti,coordinate-readouts = <5>;
++ ti,wire-config = <0x00 0x11 0x22 0x33>;
++ };
++
++ adc {
++ ti,adc-channels = <4 5 6 7>;
++ };
++ }
+diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
+index 7b7de60..ae8a1ce 100644
+--- a/drivers/input/touchscreen/ti_am335x_tsc.c
++++ b/drivers/input/touchscreen/ti_am335x_tsc.c
+@@ -26,6 +26,8 @@
+ #include <linux/io.h>
+ #include <linux/input/ti_am335x_tsc.h>
+ #include <linux/delay.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
+
+ #include <linux/mfd/ti_am335x_tscadc.h>
+
+@@ -47,7 +49,7 @@ struct titsc {
+ unsigned int wires;
+ unsigned int x_plate_resistance;
+ bool pen_down;
+- int steps_to_configure;
++ int coordinate_readouts;
+ u32 config_inp[4];
+ u32 bit_xp, bit_xn, bit_yp, bit_yn;
+ u32 inp_xp, inp_xn, inp_yp, inp_yn;
+@@ -123,7 +125,7 @@ static void titsc_step_config(struct titsc *ts_dev)
+ int i, total_steps;
+
+ /* Configure the Step registers */
+- total_steps = 2 * ts_dev->steps_to_configure;
++ total_steps = 2 * ts_dev->coordinate_readouts;
+
+ config = STEPCONFIG_MODE_HWSYNC |
+ STEPCONFIG_AVG_16 | ts_dev->bit_xp;
+@@ -141,7 +143,7 @@ static void titsc_step_config(struct titsc *ts_dev)
+ break;
+ }
+
+- for (i = 1; i <= ts_dev->steps_to_configure; i++) {
++ for (i = 1; i <= ts_dev->coordinate_readouts; i++) {
+ titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
+ titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
+ }
+@@ -163,7 +165,7 @@ static void titsc_step_config(struct titsc *ts_dev)
+ break;
+ }
+
+- for (i = (ts_dev->steps_to_configure + 1); i <= total_steps; i++) {
++ for (i = (ts_dev->coordinate_readouts + 1); i <= total_steps; i++) {
+ titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
+ titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
+ }
+@@ -218,7 +220,7 @@ static void titsc_read_coordinates(struct titsc *ts_dev,
+ read = titsc_readl(ts_dev, REG_FIFO0);
+ channel = read & 0xf0000;
+ channel = channel >> 0x10;
+- if ((channel >= 0) && (channel < ts_dev->steps_to_configure)) {
++ if ((channel >= 0) && (channel < ts_dev->coordinate_readouts)) {
+ read &= 0xfff;
+ diff = abs(read - prev_val_x);
+ if (diff < prev_diff_x) {
+@@ -231,8 +233,8 @@ static void titsc_read_coordinates(struct titsc *ts_dev,
+ read = titsc_readl(ts_dev, REG_FIFO1);
+ channel = read & 0xf0000;
+ channel = channel >> 0x10;
+- if ((channel >= ts_dev->steps_to_configure) &&
+- (channel < (2 * ts_dev->steps_to_configure - 1))) {
++ if ((channel >= ts_dev->coordinate_readouts) &&
++ (channel < (2 * ts_dev->coordinate_readouts - 1))) {
+ read &= 0xfff;
+ diff = abs(read - prev_val_y);
+ if (diff < prev_diff_y) {
+@@ -310,6 +312,59 @@ static irqreturn_t titsc_irq(int irq, void *dev)
+ return IRQ_HANDLED;
+ }
+
++static int titsc_parse_dt(struct platform_device *pdev,
++ struct titsc *ts_dev)
++{
++ struct device_node *node = pdev->dev.of_node;
++ int err;
++
++ if (!node)
++ return -EINVAL;
++
++ err = of_property_read_u32(node, "ti,wires", &ts_dev->wires);
++ if (err < 0)
++ return err;
++ switch (ts_dev->wires) {
++ case 4:
++ case 5:
++ case 8:
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ err = of_property_read_u32(node, "ti,x-plate-resistance",
++ &ts_dev->x_plate_resistance);
++ if (err < 0)
++ return err;
++
++ err = of_property_read_u32(node, "ti,coordinate-readouts",
++ &ts_dev->coordinate_readouts);
++ if (err < 0)
++ return err;
++
++ return of_property_read_u32_array(node, "ti,wire-config",
++ ts_dev->config_inp, ARRAY_SIZE(ts_dev->config_inp));
++}
++
++static int titsc_parse_pdata(struct ti_tscadc_dev *tscadc_dev,
++ struct titsc *ts_dev)
++{
++ struct mfd_tscadc_board *pdata = tscadc_dev->dev->platform_data;
++
++ if (!pdata)
++ return -EINVAL;
++
++ ts_dev->wires = pdata->tsc_init->wires;
++ ts_dev->x_plate_resistance =
++ pdata->tsc_init->x_plate_resistance;
++ ts_dev->coordinate_readouts =
++ pdata->tsc_init->coordinate_readouts;
++ memcpy(ts_dev->config_inp, pdata->tsc_init->wire_config,
++ sizeof(pdata->tsc_init->wire_config));
++ return 0;
++}
++
+ /*
+ * The functions for inserting/removing driver as a module.
+ */
+@@ -319,16 +374,8 @@ static int titsc_probe(struct platform_device *pdev)
+ struct titsc *ts_dev;
+ struct input_dev *input_dev;
+ struct ti_tscadc_dev *tscadc_dev = ti_tscadc_dev_get(pdev);
+- struct mfd_tscadc_board *pdata;
+ int err;
+
+- pdata = tscadc_dev->dev->platform_data;
+-
+- if (!pdata) {
+- dev_err(&pdev->dev, "Could not find platform data\n");
+- return -EINVAL;
+- }
+-
+ /* Allocate memory for device */
+ ts_dev = kzalloc(sizeof(struct titsc), GFP_KERNEL);
+ input_dev = input_allocate_device();
+@@ -342,11 +389,16 @@ static int titsc_probe(struct platform_device *pdev)
+ ts_dev->mfd_tscadc = tscadc_dev;
+ ts_dev->input = input_dev;
+ ts_dev->irq = tscadc_dev->irq;
+- ts_dev->wires = pdata->tsc_init->wires;
+- ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance;
+- ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure;
+- memcpy(ts_dev->config_inp, pdata->tsc_init->wire_config,
+- sizeof(pdata->tsc_init->wire_config));
++
++ if (tscadc_dev->dev->platform_data)
++ err = titsc_parse_pdata(tscadc_dev, ts_dev);
++ else
++ err = titsc_parse_dt(pdev, ts_dev);
++
++ if (err) {
++ dev_err(&pdev->dev, "Could not find valid DT data.\n");
++ goto err_free_mem;
++ }
+
+ err = request_irq(ts_dev->irq, titsc_irq,
+ 0, pdev->dev.driver->name, ts_dev);
+@@ -362,7 +414,7 @@ static int titsc_probe(struct platform_device *pdev)
+ goto err_free_irq;
+ }
+ titsc_step_config(ts_dev);
+- titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure);
++ titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->coordinate_readouts);
+
+ input_dev->name = "ti-tsc";
+ input_dev->dev.parent = &pdev->dev;
+@@ -398,7 +450,7 @@ static int titsc_remove(struct platform_device *pdev)
+ free_irq(ts_dev->irq, ts_dev);
+
+ /* total steps followed by the enable mask */
+- steps = 2 * ts_dev->steps_to_configure + 2;
++ steps = 2 * ts_dev->coordinate_readouts + 2;
+ steps = (1 << steps) - 1;
+ am335x_tsc_se_clr(ts_dev->mfd_tscadc, steps);
+
+@@ -439,7 +491,7 @@ static int titsc_resume(struct device *dev)
+ }
+ titsc_step_config(ts_dev);
+ titsc_writel(ts_dev, REG_FIFO0THR,
+- ts_dev->steps_to_configure);
++ ts_dev->coordinate_readouts);
+ return 0;
+ }
+
+@@ -452,6 +504,12 @@ static const struct dev_pm_ops titsc_pm_ops = {
+ #define TITSC_PM_OPS NULL
+ #endif
+
++static const struct of_device_id ti_tsc_dt_ids[] = {
++ { .compatible = "ti,ti-tscadc", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ti_tsc_dt_ids);
++
+ static struct platform_driver ti_tsc_driver = {
+ .probe = titsc_probe,
+ .remove = titsc_remove,
+@@ -459,6 +517,7 @@ static struct platform_driver ti_tsc_driver = {
+ .name = "tsc",
+ .owner = THIS_MODULE,
+ .pm = TITSC_PM_OPS,
++ .of_match_table = of_match_ptr(ti_tsc_dt_ids),
+ },
+ };
+ module_platform_driver(ti_tsc_driver);
+diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
+index 90ccfc0..ebce3d39 100644
+--- a/drivers/mfd/ti_am335x_tscadc.c
++++ b/drivers/mfd/ti_am335x_tscadc.c
+@@ -203,6 +203,7 @@ static int ti_tscadc_probe(struct platform_device *pdev)
+ /* TSC Cell */
+ cell = &tscadc->cells[TSC_CELL];
+ cell->name = "tsc";
++ cell->of_compatible = "ti,ti-tscadc";
+ cell->platform_data = &tscadc;
+ cell->pdata_size = sizeof(tscadc);
+
+diff --git a/include/linux/input/ti_am335x_tsc.h b/include/linux/input/ti_am335x_tsc.h
+index 6a66b4d..c0bf08b 100644
+--- a/include/linux/input/ti_am335x_tsc.h
++++ b/include/linux/input/ti_am335x_tsc.h
+@@ -28,7 +28,7 @@
+ struct tsc_data {
+ int wires;
+ int x_plate_resistance;
+- int steps_to_configure;
++ int coordinate_readouts;
+ int wire_config[10];
+ };
+
diff --git a/patches/linux-3.8.13/0050-iio-ti_am335x_adc-Add-DT-support.patch b/patches/linux-3.8.13/0050-iio-ti_am335x_adc-Add-DT-support.patch
new file mode 100644
index 0000000..80b44a4
--- /dev/null
+++ b/patches/linux-3.8.13/0050-iio-ti_am335x_adc-Add-DT-support.patch
@@ -0,0 +1,96 @@
+From: "Patil, Rachna" <rachna@ti.com>
+Date: Wed, 12 Jun 2013 18:58:08 +0200
+Subject: [PATCH] iio: ti_am335x_adc: Add DT support
+
+Add DT support for client ADC driver.
+
+Acked-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Patil, Rachna <rachna@ti.com>
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/iio/adc/ti_am335x_adc.c | 29 ++++++++++++++++++++++++-----
+ drivers/mfd/ti_am335x_tscadc.c | 1 +
+ 2 files changed, 25 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
+index b47594d..4f4c82e 100644
+--- a/drivers/iio/adc/ti_am335x_adc.c
++++ b/drivers/iio/adc/ti_am335x_adc.c
+@@ -22,6 +22,8 @@
+ #include <linux/platform_device.h>
+ #include <linux/io.h>
+ #include <linux/iio/iio.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
+
+ #include <linux/mfd/ti_am335x_tscadc.h>
+ #include <linux/platform_data/ti_am335x_adc.h>
+@@ -152,11 +154,12 @@ static int tiadc_probe(struct platform_device *pdev)
+ struct iio_dev *indio_dev;
+ struct tiadc_device *adc_dev;
+ struct ti_tscadc_dev *tscadc_dev = ti_tscadc_dev_get(pdev);
+- struct mfd_tscadc_board *pdata;
++ struct mfd_tscadc_board *pdata = tscadc_dev->dev->platform_data;
++ struct device_node *node = tscadc_dev->dev->of_node;
+ int err;
++ u32 val32;
+
+- pdata = tscadc_dev->dev->platform_data;
+- if (!pdata || !pdata->adc_init) {
++ if (!pdata && !node) {
+ dev_err(&pdev->dev, "Could not find platform data\n");
+ return -EINVAL;
+ }
+@@ -169,8 +172,17 @@ static int tiadc_probe(struct platform_device *pdev)
+ }
+ adc_dev = iio_priv(indio_dev);
+
+- adc_dev->mfd_tscadc = tscadc_dev;
+- adc_dev->channels = pdata->adc_init->adc_channels;
++ adc_dev->mfd_tscadc = ti_tscadc_dev_get(pdev);
++
++ if (pdata)
++ adc_dev->channels = pdata->adc_init->adc_channels;
++ else {
++ err = of_property_read_u32(node,
++ "ti,adc-channels", &val32);
++ if (err < 0)
++ goto err_free_device;
++ adc_dev->channels = val32;
++ }
+
+ indio_dev->dev.parent = &pdev->dev;
+ indio_dev->name = dev_name(&pdev->dev);
+@@ -260,11 +272,18 @@ static const struct dev_pm_ops tiadc_pm_ops = {
+ #define TIADC_PM_OPS NULL
+ #endif
+
++static const struct of_device_id ti_adc_dt_ids[] = {
++ { .compatible = "ti,ti-tscadc", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ti_adc_dt_ids);
++
+ static struct platform_driver tiadc_driver = {
+ .driver = {
+ .name = "tiadc",
+ .owner = THIS_MODULE,
+ .pm = TIADC_PM_OPS,
++ .of_match_table = of_match_ptr(ti_adc_dt_ids),
+ },
+ .probe = tiadc_probe,
+ .remove = tiadc_remove,
+diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
+index ebce3d39..cca6a6c 100644
+--- a/drivers/mfd/ti_am335x_tscadc.c
++++ b/drivers/mfd/ti_am335x_tscadc.c
+@@ -210,6 +210,7 @@ static int ti_tscadc_probe(struct platform_device *pdev)
+ /* ADC Cell */
+ cell = &tscadc->cells[ADC_CELL];
+ cell->name = "tiadc";
++ cell->of_compatible = "ti,ti-tscadc";
+ cell->platform_data = &tscadc;
+ cell->pdata_size = sizeof(tscadc);
+
diff --git a/patches/linux-3.8.4/0051-arm-dts-AM335x-evm-Add-TSC-ADC-MFD-device-support.patch b/patches/linux-3.8.13/0051-arm-dts-AM335x-evm-Add-TSC-ADC-MFD-device-support.patch
index 00d8350..00d8350 100644
--- a/patches/linux-3.8.4/0051-arm-dts-AM335x-evm-Add-TSC-ADC-MFD-device-support.patch
+++ b/patches/linux-3.8.13/0051-arm-dts-AM335x-evm-Add-TSC-ADC-MFD-device-support.patch
diff --git a/patches/linux-3.8.4/0048-MFD-ti_am335x_tscadc-Add-DT-support.patch b/patches/linux-3.8.13/0052-mfd-ti_am335x_tscadc-Add-DT-support.patch
index 16c6d9b..32760dd 100644
--- a/patches/linux-3.8.4/0048-MFD-ti_am335x_tscadc-Add-DT-support.patch
+++ b/patches/linux-3.8.13/0052-mfd-ti_am335x_tscadc-Add-DT-support.patch
@@ -1,16 +1,22 @@
From: "Patil, Rachna" <rachna@ti.com>
-Date: Thu, 24 Jan 2013 03:45:09 +0000
-Subject: [PATCH] MFD: ti_am335x_tscadc: Add DT support
+Date: Wed, 12 Jun 2013 18:58:10 +0200
+Subject: [PATCH] mfd: ti_am335x_tscadc: Add DT support
-Make changes to add DT support in the MFD core driver.
+Add DT support in the MFD core driver. The node name is "am3359" because
+it was tested on this platform.
+Zubair Lutfullah: Reversed the change to am3359-tsc to ti-tscadc to keep from further changes in DT
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
Signed-off-by: Patil, Rachna <rachna@ti.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
- drivers/mfd/ti_am335x_tscadc.c | 28 +++++++++++++++++++++++-----
- 1 file changed, 23 insertions(+), 5 deletions(-)
+ drivers/mfd/ti_am335x_tscadc.c | 30 +++++++++++++++++++++++++-----
+ 1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
-index e9f3fb5..87b446b 100644
+index cca6a6c..0fc5867 100644
--- a/drivers/mfd/ti_am335x_tscadc.c
+++ b/drivers/mfd/ti_am335x_tscadc.c
@@ -22,6 +22,8 @@
@@ -22,7 +28,7 @@ index e9f3fb5..87b446b 100644
#include <linux/mfd/ti_am335x_tscadc.h>
#include <linux/input/ti_am335x_tsc.h>
-@@ -64,20 +66,31 @@ static int ti_tscadc_probe(struct platform_device *pdev)
+@@ -90,20 +92,31 @@ static int ti_tscadc_probe(struct platform_device *pdev)
struct resource *res;
struct clk *clk;
struct mfd_tscadc_board *pdata = pdev->dev.platform_data;
@@ -48,10 +54,10 @@ index e9f3fb5..87b446b 100644
+ if (pdata->adc_init)
+ adc_channels = pdata->adc_init->adc_channels;
+ } else {
-+ node = of_find_node_by_name(pdev->dev.of_node, "tsc");
++ node = of_get_child_by_name(pdev->dev.of_node, "tsc");
+ of_property_read_u32(node, "ti,wires", &tsc_wires);
+
-+ node = of_find_node_by_name(pdev->dev.of_node, "adc");
++ node = of_get_child_by_name(pdev->dev.of_node, "adc");
+ of_property_read_u32(node, "ti,adc-channels", &adc_channels);
+ }
@@ -59,13 +65,15 @@ index e9f3fb5..87b446b 100644
total_channels = tsc_wires + adc_channels;
if (total_channels > 8) {
-@@ -256,11 +269,16 @@ static const struct dev_pm_ops tscadc_pm_ops = {
+@@ -285,11 +298,18 @@ static const struct dev_pm_ops tscadc_pm_ops = {
#define TSCADC_PM_OPS NULL
#endif
+static const struct of_device_id ti_tscadc_dt_ids[] = {
+ { .compatible = "ti,ti-tscadc", },
++ { }
+};
++MODULE_DEVICE_TABLE(of, ti_tscadc_dt_ids);
+
static struct platform_driver ti_tscadc_driver = {
.driver = {
diff --git a/patches/linux-3.8.13/0053-iio-ti_tscadc-provide-datasheet_name-and-scan_type.patch b/patches/linux-3.8.13/0053-iio-ti_tscadc-provide-datasheet_name-and-scan_type.patch
new file mode 100644
index 0000000..8345713
--- /dev/null
+++ b/patches/linux-3.8.13/0053-iio-ti_tscadc-provide-datasheet_name-and-scan_type.patch
@@ -0,0 +1,85 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 12 Jun 2013 18:58:12 +0200
+Subject: [PATCH] iio: ti_tscadc: provide datasheet_name and scan_type
+
+This patch provides the members "datasheet_name" and scan_type. This is
+the remaining part of the earlier patch where I (bigeasy) removed iio_map
+because it is now supplied by the device tree. It also static names as
+suggested by Jonathan.
+
+ZubairLK. Channel Info mask tweaked to fit the old IIO usage.
+Tweaked surrounding code to patch the 3.8 tree.
+
+Acked-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/iio/adc/ti_am335x_adc.c | 29 ++++++++++++++++++++++++-----
+ 1 file changed, 24 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
+index 4f4c82e..25feb62 100644
+--- a/drivers/iio/adc/ti_am335x_adc.c
++++ b/drivers/iio/adc/ti_am335x_adc.c
+@@ -24,6 +24,8 @@
+ #include <linux/iio/iio.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
++#include <linux/iio/machine.h>
++#include <linux/iio/driver.h>
+
+ #include <linux/mfd/ti_am335x_tscadc.h>
+ #include <linux/platform_data/ti_am335x_adc.h>
+@@ -85,29 +87,46 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
+ am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
+ }
+
++static const char * const chan_name_ain[] = {
++ "AIN0",
++ "AIN1",
++ "AIN2",
++ "AIN3",
++ "AIN4",
++ "AIN5",
++ "AIN6",
++ "AIN7",
++};
++
+ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
+ {
++ struct tiadc_device *adc_dev = iio_priv(indio_dev);
+ struct iio_chan_spec *chan_array;
++ struct iio_chan_spec *chan;
+ int i;
+
+ indio_dev->num_channels = channels;
+- chan_array = kcalloc(indio_dev->num_channels,
++ chan_array = kcalloc(channels,
+ sizeof(struct iio_chan_spec), GFP_KERNEL);
+-
+ if (chan_array == NULL)
+ return -ENOMEM;
+
+- for (i = 0; i < (indio_dev->num_channels); i++) {
+- struct iio_chan_spec *chan = chan_array + i;
++ chan = chan_array;
++ for (i = 0; i < channels; i++, chan++) {
++
+ chan->type = IIO_VOLTAGE;
+ chan->indexed = 1;
+ chan->channel = i;
+ chan->info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT;
++ chan->datasheet_name = chan_name_ain[i];
++ chan->scan_type.sign = 'u';
++ chan->scan_type.realbits = 12;
++ chan->scan_type.storagebits = 32;
+ }
+
+ indio_dev->channels = chan_array;
+
+- return indio_dev->num_channels;
++ return 0;
+ }
+
+ static void tiadc_channels_remove(struct iio_dev *indio_dev)
diff --git a/patches/linux-3.8.13/0054-mfd-ti_tscadc-deal-with-partial-activation.patch b/patches/linux-3.8.13/0054-mfd-ti_tscadc-deal-with-partial-activation.patch
new file mode 100644
index 0000000..132ab96
--- /dev/null
+++ b/patches/linux-3.8.13/0054-mfd-ti_tscadc-deal-with-partial-activation.patch
@@ -0,0 +1,110 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 12 Jun 2013 18:58:13 +0200
+Subject: [PATCH] mfd: ti_tscadc: deal with partial activation
+
+Fix the mfd device in the case where a subdevice might not be activated.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/mfd/ti_am335x_tscadc.c | 38 ++++++++++++++++++++++------------
+ include/linux/mfd/ti_am335x_tscadc.h | 8 +++----
+ 2 files changed, 28 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
+index 0fc5867..58f0860 100644
+--- a/drivers/mfd/ti_am335x_tscadc.c
++++ b/drivers/mfd/ti_am335x_tscadc.c
+@@ -118,11 +118,14 @@ static int ti_tscadc_probe(struct platform_device *pdev)
+ }
+
+ total_channels = tsc_wires + adc_channels;
+-
+ if (total_channels > 8) {
+ dev_err(&pdev->dev, "Number of i/p channels more than 8\n");
+ return -EINVAL;
+ }
++ if (total_channels == 0) {
++ dev_err(&pdev->dev, "Need atleast one channel.\n");
++ return -EINVAL;
++ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+@@ -213,28 +216,37 @@ static int ti_tscadc_probe(struct platform_device *pdev)
+ ctrl |= CNTRLREG_TSCSSENB;
+ tscadc_writel(tscadc, REG_CTRL, ctrl);
+
++ tscadc->used_cells = 0;
++ tscadc->tsc_cell = -1;
++ tscadc->adc_cell = -1;
++
+ /* TSC Cell */
+- cell = &tscadc->cells[TSC_CELL];
+- cell->name = "tsc";
+- cell->of_compatible = "ti,ti-tscadc";
+- cell->platform_data = &tscadc;
+- cell->pdata_size = sizeof(tscadc);
++ if (tsc_wires > 0) {
++ tscadc->tsc_cell = tscadc->used_cells;
++ cell = &tscadc->cells[tscadc->used_cells++];
++ cell->name = "tsc";
++ cell->of_compatible = "ti,ti-tscadc";
++ cell->platform_data = &tscadc;
++ cell->pdata_size = sizeof(tscadc);
++ }
+
+ /* ADC Cell */
+- cell = &tscadc->cells[ADC_CELL];
+- cell->name = "tiadc";
+- cell->of_compatible = "ti,ti-tscadc";
+- cell->platform_data = &tscadc;
+- cell->pdata_size = sizeof(tscadc);
++ if (adc_channels > 0) {
++ tscadc->adc_cell = tscadc->used_cells;
++ cell = &tscadc->cells[tscadc->used_cells++];
++ cell->name = "tiadc";
++ cell->of_compatible = "ti,ti-tscadc";
++ cell->platform_data = &tscadc;
++ cell->pdata_size = sizeof(tscadc);
++ }
+
+ err = mfd_add_devices(&pdev->dev, pdev->id, tscadc->cells,
+- TSCADC_CELLS, NULL, 0, NULL);
++ tscadc->used_cells, NULL, 0, NULL);
+ if (err < 0)
+ goto err_disable_clk;
+
+ device_init_wakeup(&pdev->dev, true);
+ platform_set_drvdata(pdev, tscadc);
+-
+ return 0;
+
+ err_disable_clk:
+diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
+index e36ae41..fe54ba4 100644
+--- a/include/linux/mfd/ti_am335x_tscadc.h
++++ b/include/linux/mfd/ti_am335x_tscadc.h
+@@ -120,11 +120,6 @@
+
+ #define TSCADC_CELLS 2
+
+-enum tscadc_cells {
+- TSC_CELL,
+- ADC_CELL,
+-};
+-
+ struct mfd_tscadc_board {
+ struct tsc_data *tsc_init;
+ struct adc_data *adc_init;
+@@ -135,6 +130,9 @@ struct ti_tscadc_dev {
+ struct regmap *regmap_tscadc;
+ void __iomem *tscadc_base;
+ int irq;
++ int used_cells; /* 1-2 */
++ int tsc_cell; /* -1 if not used */
++ int adc_cell; /* -1 if not used */
+ struct mfd_cell cells[TSCADC_CELLS];
+ u32 reg_se_cache;
+ spinlock_t reg_lock;
diff --git a/patches/linux-3.8.13/0055-input-ti_am335x_adc-use-only-FIFO0-and-clean-up-a-li.patch b/patches/linux-3.8.13/0055-input-ti_am335x_adc-use-only-FIFO0-and-clean-up-a-li.patch
new file mode 100644
index 0000000..491482b
--- /dev/null
+++ b/patches/linux-3.8.13/0055-input-ti_am335x_adc-use-only-FIFO0-and-clean-up-a-li.patch
@@ -0,0 +1,261 @@
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Wed, 12 Jun 2013 18:58:18 +0200
+Subject: [PATCH] input: ti_am335x_adc: use only FIFO0 and clean up a little
+
+The driver programs a threshold of "coordinate_readouts" say 5. The
+REG_FIFO0THR registers says it should it be programmed to "threshold
+minus one". The driver does not expect just 5 coordinates but 5 * 2 + 2.
+Multiplied by two because 5 for X and 5 for Y and plus 2 because we have
+two Z.
+The whole thing kind of works because It reads the 5 coordinates for X
+and Y from FIFO0 and FIFO1 and the last element in each FIFO is ignored
+within the loop and read later.
+Nothing guaranties that FIFO1 is ready by the time it is read. In fact I
+could see that that FIFO1 reaturns for Y channels 8,9, 10, 12, 6 and for
+Y channel 7 for Z. The problem is that channel 7 and channel 12 got
+somehow mixed up.
+The other Problem is that FIFO1 is also used by the IIO part leading to
+wrong results if both (tsc & adc) are used.
+
+The patch tries to clean up the whole thing a little:
+- Remove the +1 and -1 in REG_STEPCONFIG, REG_STEPDELAY and its counter
+ part in the for loop. This is just confusing.
+
+- Use only FIFO0 in TSC. The fifo has space for 64 entries so should be
+ fine.
+
+- Read the whole FIFO in one function and check the channel.
+
+- in case we dawdle around, make sure we only read a multiple of our
+ coordinate set. On the second interrupt we will cleanup the remaining
+ enties.
+
+Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/iio/adc/ti_am335x_adc.c | 2 +-
+ drivers/input/touchscreen/ti_am335x_tsc.c | 78 +++++++++++++++--------------
+ include/linux/mfd/ti_am335x_tscadc.h | 4 +-
+ 3 files changed, 44 insertions(+), 40 deletions(-)
+
+diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
+index 25feb62..c4682d6 100644
+--- a/drivers/iio/adc/ti_am335x_adc.c
++++ b/drivers/iio/adc/ti_am335x_adc.c
+@@ -76,7 +76,7 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
+
+ stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
+
+- for (i = (steps + 1); i <= TOTAL_STEPS; i++) {
++ for (i = steps; i < TOTAL_STEPS; i++) {
+ tiadc_writel(adc_dev, REG_STEPCONFIG(i),
+ stepconfig | STEPCONFIG_INP(channels));
+ tiadc_writel(adc_dev, REG_STEPDELAY(i),
+diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
+index ae8a1ce..6c333af 100644
+--- a/drivers/input/touchscreen/ti_am335x_tsc.c
++++ b/drivers/input/touchscreen/ti_am335x_tsc.c
+@@ -121,11 +121,9 @@ static int titsc_config_wires(struct titsc *ts_dev)
+ static void titsc_step_config(struct titsc *ts_dev)
+ {
+ unsigned int config;
+- unsigned int stepenable = 0;
+- int i, total_steps;
+-
+- /* Configure the Step registers */
+- total_steps = 2 * ts_dev->coordinate_readouts;
++ int i;
++ int end_step;
++ u32 stepenable;
+
+ config = STEPCONFIG_MODE_HWSYNC |
+ STEPCONFIG_AVG_16 | ts_dev->bit_xp;
+@@ -143,7 +141,9 @@ static void titsc_step_config(struct titsc *ts_dev)
+ break;
+ }
+
+- for (i = 1; i <= ts_dev->coordinate_readouts; i++) {
++ /* 1 … coordinate_readouts is for X */
++ end_step = ts_dev->coordinate_readouts;
++ for (i = 0; i < end_step; i++) {
+ titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
+ titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
+ }
+@@ -151,7 +151,7 @@ static void titsc_step_config(struct titsc *ts_dev)
+ config = 0;
+ config = STEPCONFIG_MODE_HWSYNC |
+ STEPCONFIG_AVG_16 | ts_dev->bit_yn |
+- STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1;
++ STEPCONFIG_INM_ADCREFM;
+ switch (ts_dev->wires) {
+ case 4:
+ config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp);
+@@ -165,12 +165,13 @@ static void titsc_step_config(struct titsc *ts_dev)
+ break;
+ }
+
+- for (i = (ts_dev->coordinate_readouts + 1); i <= total_steps; i++) {
++ /* coordinate_readouts … coordinate_readouts * 2 is for Y */
++ end_step = ts_dev->coordinate_readouts * 2;
++ for (i = ts_dev->coordinate_readouts; i < end_step; i++) {
+ titsc_writel(ts_dev, REG_STEPCONFIG(i), config);
+ titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY);
+ }
+
+- config = 0;
+ /* Charge step configuration */
+ config = ts_dev->bit_xp | ts_dev->bit_yn |
+ STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR |
+@@ -179,35 +180,39 @@ static void titsc_step_config(struct titsc *ts_dev)
+ titsc_writel(ts_dev, REG_CHARGECONFIG, config);
+ titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY);
+
+- config = 0;
+- /* Configure to calculate pressure */
++ /* coordinate_readouts * 2 … coordinate_readouts * 2 + 2 is for Z */
+ config = STEPCONFIG_MODE_HWSYNC |
+ STEPCONFIG_AVG_16 | ts_dev->bit_yp |
+ ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM |
+ STEPCONFIG_INP(ts_dev->inp_xp);
+- titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config);
+- titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1),
++ titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config);
++ titsc_writel(ts_dev, REG_STEPDELAY(end_step),
+ STEPCONFIG_OPENDLY);
+
+- config |= STEPCONFIG_INP(ts_dev->inp_yn) | STEPCONFIG_FIFO1;
+- titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config);
+- titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2),
++ end_step++;
++ config |= STEPCONFIG_INP(ts_dev->inp_yn);
++ titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config);
++ titsc_writel(ts_dev, REG_STEPDELAY(end_step),
+ STEPCONFIG_OPENDLY);
+
+ /* The steps1 … end and bit 0 for TS_Charge */
+- stepenable = (1 << (total_steps + 2)) - 1;
++ stepenable = (1 << (end_step + 2)) - 1;
+ am335x_tsc_se_set(ts_dev->mfd_tscadc, stepenable);
+ }
+
+ static void titsc_read_coordinates(struct titsc *ts_dev,
+- unsigned int *x, unsigned int *y)
++ u32 *x, u32 *y, u32 *z1, u32 *z2)
+ {
+ unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT);
+ unsigned int prev_val_x = ~0, prev_val_y = ~0;
+ unsigned int prev_diff_x = ~0, prev_diff_y = ~0;
+ unsigned int read, diff;
+ unsigned int i, channel;
++ unsigned int creads = ts_dev->coordinate_readouts;
+
++ *z1 = *z2 = 0;
++ if (fifocount % (creads * 2 + 2))
++ fifocount -= fifocount % (creads * 2 + 2);
+ /*
+ * Delta filter is used to remove large variations in sampled
+ * values from ADC. The filter tries to predict where the next
+@@ -216,32 +221,32 @@ static void titsc_read_coordinates(struct titsc *ts_dev,
+ * algorithm compares the difference with that of a present value,
+ * if true the value is reported to the sub system.
+ */
+- for (i = 0; i < fifocount - 1; i++) {
++ for (i = 0; i < fifocount; i++) {
+ read = titsc_readl(ts_dev, REG_FIFO0);
+- channel = read & 0xf0000;
+- channel = channel >> 0x10;
+- if ((channel >= 0) && (channel < ts_dev->coordinate_readouts)) {
+- read &= 0xfff;
++
++ channel = (read & 0xf0000) >> 16;
++ read &= 0xfff;
++ if (channel < creads) {
+ diff = abs(read - prev_val_x);
+ if (diff < prev_diff_x) {
+ prev_diff_x = diff;
+ *x = read;
+ }
+ prev_val_x = read;
+- }
+
+- read = titsc_readl(ts_dev, REG_FIFO1);
+- channel = read & 0xf0000;
+- channel = channel >> 0x10;
+- if ((channel >= ts_dev->coordinate_readouts) &&
+- (channel < (2 * ts_dev->coordinate_readouts - 1))) {
+- read &= 0xfff;
++ } else if (channel < creads * 2) {
+ diff = abs(read - prev_val_y);
+ if (diff < prev_diff_y) {
+ prev_diff_y = diff;
+ *y = read;
+ }
+ prev_val_y = read;
++
++ } else if (channel < creads * 2 + 1) {
++ *z1 = read;
++
++ } else if (channel < creads * 2 + 2) {
++ *z2 = read;
+ }
+ }
+ }
+@@ -257,10 +262,8 @@ static irqreturn_t titsc_irq(int irq, void *dev)
+
+ status = titsc_readl(ts_dev, REG_IRQSTATUS);
+ if (status & IRQENB_FIFO0THRES) {
+- titsc_read_coordinates(ts_dev, &x, &y);
+
+- z1 = titsc_readl(ts_dev, REG_FIFO0) & 0xfff;
+- z2 = titsc_readl(ts_dev, REG_FIFO1) & 0xfff;
++ titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2);
+
+ if (ts_dev->pen_down && z1 != 0 && z2 != 0) {
+ /*
+@@ -268,10 +271,10 @@ static irqreturn_t titsc_irq(int irq, void *dev)
+ * Resistance(touch) = x plate resistance *
+ * x postion/4096 * ((z2 / z1) - 1)
+ */
+- z = z2 - z1;
++ z = z1 - z2;
+ z *= x;
+ z *= ts_dev->x_plate_resistance;
+- z /= z1;
++ z /= z2;
+ z = (z + 2047) >> 12;
+
+ if (z <= MAX_12BIT) {
+@@ -414,7 +417,8 @@ static int titsc_probe(struct platform_device *pdev)
+ goto err_free_irq;
+ }
+ titsc_step_config(ts_dev);
+- titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->coordinate_readouts);
++ titsc_writel(ts_dev, REG_FIFO0THR,
++ ts_dev->coordinate_readouts * 2 + 2 - 1);
+
+ input_dev->name = "ti-tsc";
+ input_dev->dev.parent = &pdev->dev;
+@@ -491,7 +495,7 @@ static int titsc_resume(struct device *dev)
+ }
+ titsc_step_config(ts_dev);
+ titsc_writel(ts_dev, REG_FIFO0THR,
+- ts_dev->coordinate_readouts);
++ ts_dev->coordinate_readouts * 2 + 2 - 1);
+ return 0;
+ }
+
+diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
+index fe54ba4..9598360 100644
+--- a/include/linux/mfd/ti_am335x_tscadc.h
++++ b/include/linux/mfd/ti_am335x_tscadc.h
+@@ -30,8 +30,8 @@
+ #define REG_IDLECONFIG 0x058
+ #define REG_CHARGECONFIG 0x05C
+ #define REG_CHARGEDELAY 0x060
+-#define REG_STEPCONFIG(n) (0x64 + ((n - 1) * 8))
+-#define REG_STEPDELAY(n) (0x68 + ((n - 1) * 8))
++#define REG_STEPCONFIG(n) (0x64 + ((n) * 8))
++#define REG_STEPDELAY(n) (0x68 + ((n) * 8))
+ #define REG_FIFO0CNT 0xE4
+ #define REG_FIFO0THR 0xE8
+ #define REG_FIFO1CNT 0xF0
diff --git a/patches/linux-3.8.13/0056-input-ti_am335x_tsc-ACK-the-HW_PEN-irq-in-ISR.patch b/patches/linux-3.8.13/0056-input-ti_am335x_tsc-ACK-the-HW_PEN-irq-in-ISR.patch
new file mode 100644
index 0000000..5fb73ed
--- /dev/null
+++ b/patches/linux-3.8.13/0056-input-ti_am335x_tsc-ACK-the-HW_PEN-irq-in-ISR.patch
@@ -0,0 +1,32 @@
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Wed, 12 Jun 2013 18:58:19 +0200
+Subject: [PATCH] input: ti_am335x_tsc: ACK the HW_PEN irq in ISR
+
+The interrupt source IRQENB_HW_PEN is enabled in suspend and suposed to
+be used as a wake up source. Once this interrupt source is unmaksed, the
+devices ends up in ISR and never continues.
+This change ACKs the interrupt and disables it so the system does not
+freeze.
+
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/input/touchscreen/ti_am335x_tsc.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
+index 6c333af..2e9a247 100644
+--- a/drivers/input/touchscreen/ti_am335x_tsc.c
++++ b/drivers/input/touchscreen/ti_am335x_tsc.c
+@@ -309,6 +309,12 @@ static irqreturn_t titsc_irq(int irq, void *dev)
+ irqclr |= IRQENB_PENUP;
+ }
+
++ if (status & IRQENB_HW_PEN) {
++
++ titsc_writel(ts_dev, REG_IRQWAKEUP, 0x00);
++ titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN);
++ }
++
+ titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
+
+ am335x_tsc_se_update(ts_dev->mfd_tscadc);
diff --git a/patches/linux-3.8.13/0057-input-ti_am335x_tsc-return-IRQ_NONE-if-there-was-no-.patch b/patches/linux-3.8.13/0057-input-ti_am335x_tsc-return-IRQ_NONE-if-there-was-no-.patch
new file mode 100644
index 0000000..31ea1d3
--- /dev/null
+++ b/patches/linux-3.8.13/0057-input-ti_am335x_tsc-return-IRQ_NONE-if-there-was-no-.patch
@@ -0,0 +1,37 @@
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Wed, 12 Jun 2013 18:58:20 +0200
+Subject: [PATCH] input: ti_am335x_tsc: return IRQ_NONE if there was no IRQ
+ for us
+
+The previous patch ("input/ti_am335x_tsc: ACK the HW_PEN irq in ISR")
+acked the interrupt so we don't freeze if we don't handle an enabled
+interrupt source. The interrupt core has a mechanism for this and to get
+it work one should only say that it handled an interrupt if it is
+actually the case.
+
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/input/touchscreen/ti_am335x_tsc.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
+index 2e9a247..5f9801c 100644
+--- a/drivers/input/touchscreen/ti_am335x_tsc.c
++++ b/drivers/input/touchscreen/ti_am335x_tsc.c
+@@ -315,10 +315,12 @@ static irqreturn_t titsc_irq(int irq, void *dev)
+ titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN);
+ }
+
+- titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
+-
+- am335x_tsc_se_update(ts_dev->mfd_tscadc);
+- return IRQ_HANDLED;
++ if (irqclr) {
++ titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
++ am335x_tsc_se_update(ts_dev->mfd_tscadc);
++ return IRQ_HANDLED;
++ }
++ return IRQ_NONE;
+ }
+
+ static int titsc_parse_dt(struct platform_device *pdev,
diff --git a/patches/linux-3.8.13/0058-iio-ti_am335x_adc-Allow-to-specify-input-line.patch b/patches/linux-3.8.13/0058-iio-ti_am335x_adc-Allow-to-specify-input-line.patch
new file mode 100644
index 0000000..1e2e82a
--- /dev/null
+++ b/patches/linux-3.8.13/0058-iio-ti_am335x_adc-Allow-to-specify-input-line.patch
@@ -0,0 +1,213 @@
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Wed, 12 Jun 2013 18:58:21 +0200
+Subject: [PATCH] iio: ti_am335x_adc: Allow to specify input line
+
+The TSC part allows to specify the input lines. The IIO part assumes
+that it usues always the last few, that means if IIO has adc-channels
+set to 2 it will use channel 6 and 7. However it might make sense to use
+only 6.
+This patch changes the device property (which was introduced recently
+and was never in an official release) in a way that the user can specify
+which of the AIN lines should be used. In Addition to this, the name is
+now AINx where x is the channel number i.e. for AIN6 we would have 6.
+Prior this, it always started counting at 0 which is confusing. In
+addition to this, it also checks for correct step number during reading
+and does not rely on proper FIFO depth.
+
+ZubairLK Tweaked channel info mask for old iio. Tweaked surrounding
+code to make it patch the 3.8 tree
+
+Acked-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ arch/arm/boot/dts/am335x-evm.dts | 2 +-
+ drivers/iio/adc/ti_am335x_adc.c | 58 +++++++++++++++++++++++++-------------
+ drivers/mfd/ti_am335x_tscadc.c | 19 ++++++++++++-
+ 3 files changed, 57 insertions(+), 22 deletions(-)
+
+diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
+index b1aeefb..5483e09 100644
+--- a/arch/arm/boot/dts/am335x-evm.dts
++++ b/arch/arm/boot/dts/am335x-evm.dts
+@@ -280,6 +280,6 @@
+ };
+
+ adc {
+- ti,adc-channels = <4>;
++ ti,adc-channels = <4 5 6 7>;
+ };
+ };
+diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
+index c4682d6..a2b6ebd 100644
+--- a/drivers/iio/adc/ti_am335x_adc.c
++++ b/drivers/iio/adc/ti_am335x_adc.c
+@@ -33,6 +33,8 @@
+ struct tiadc_device {
+ struct ti_tscadc_dev *mfd_tscadc;
+ int channels;
++ u8 channel_line[8];
++ u8 channel_step[8];
+ };
+
+ static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
+@@ -58,7 +60,7 @@ static u32 get_adc_step_mask(struct tiadc_device *adc_dev)
+ static void tiadc_step_config(struct tiadc_device *adc_dev)
+ {
+ unsigned int stepconfig;
+- int i, channels = 0, steps;
++ int i, steps;
+ u32 step_en;
+
+ /*
+@@ -72,16 +74,18 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
+ */
+
+ steps = TOTAL_STEPS - adc_dev->channels;
+- channels = TOTAL_CHANNELS - adc_dev->channels;
+-
+ stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
+
+- for (i = steps; i < TOTAL_STEPS; i++) {
+- tiadc_writel(adc_dev, REG_STEPCONFIG(i),
+- stepconfig | STEPCONFIG_INP(channels));
+- tiadc_writel(adc_dev, REG_STEPDELAY(i),
++ for (i = 0; i < adc_dev->channels; i++) {
++ int chan;
++
++ chan = adc_dev->channel_line[i];
++ tiadc_writel(adc_dev, REG_STEPCONFIG(steps),
++ stepconfig | STEPCONFIG_INP(chan));
++ tiadc_writel(adc_dev, REG_STEPDELAY(steps),
+ STEPCONFIG_OPENDLY);
+- channels++;
++ adc_dev->channel_step[i] = steps;
++ steps++;
+ }
+ step_en = get_adc_step_mask(adc_dev);
+ am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
+@@ -116,9 +120,9 @@ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
+
+ chan->type = IIO_VOLTAGE;
+ chan->indexed = 1;
+- chan->channel = i;
++ chan->channel = adc_dev->channel_line[i];
+ chan->info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT;
+- chan->datasheet_name = chan_name_ain[i];
++ chan->datasheet_name = chan_name_ain[chan->channel];
+ chan->scan_type.sign = 'u';
+ chan->scan_type.realbits = 12;
+ chan->scan_type.storagebits = 32;
+@@ -140,7 +144,8 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
+ {
+ struct tiadc_device *adc_dev = iio_priv(indio_dev);
+ int i;
+- unsigned int fifo1count, readx1;
++ unsigned int fifo1count, read;
++ u32 step = UINT_MAX;
+
+ /*
+ * When the sub-system is first enabled,
+@@ -153,11 +158,20 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
+ * Hence we need to flush out this data.
+ */
+
++ for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) {
++ if (chan->channel == adc_dev->channel_line[i]) {
++ step = adc_dev->channel_step[i];
++ break;
++ }
++ }
++ if (WARN_ON_ONCE(step == UINT_MAX))
++ return -EINVAL;
++
+ fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+ for (i = 0; i < fifo1count; i++) {
+- readx1 = tiadc_readl(adc_dev, REG_FIFO1);
+- if (i == chan->channel)
+- *val = readx1 & 0xfff;
++ read = tiadc_readl(adc_dev, REG_FIFO1);
++ if (read >> 16 == step)
++ *val = read & 0xfff;
+ }
+ am335x_tsc_se_update(adc_dev->mfd_tscadc);
+
+@@ -175,8 +189,11 @@ static int tiadc_probe(struct platform_device *pdev)
+ struct ti_tscadc_dev *tscadc_dev = ti_tscadc_dev_get(pdev);
+ struct mfd_tscadc_board *pdata = tscadc_dev->dev->platform_data;
+ struct device_node *node = tscadc_dev->dev->of_node;
++ struct property *prop;
++ const __be32 *cur;
+ int err;
+- u32 val32;
++ u32 val;
++ int channels = 0;
+
+ if (!pdata && !node) {
+ dev_err(&pdev->dev, "Could not find platform data\n");
+@@ -196,11 +213,12 @@ static int tiadc_probe(struct platform_device *pdev)
+ if (pdata)
+ adc_dev->channels = pdata->adc_init->adc_channels;
+ else {
+- err = of_property_read_u32(node,
+- "ti,adc-channels", &val32);
+- if (err < 0)
+- goto err_free_device;
+- adc_dev->channels = val32;
++ node = of_get_child_by_name(node, "adc");
++ of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
++ adc_dev->channel_line[channels] = val;
++ channels++;
++ }
++ adc_dev->channels = channels;
+ }
+
+ indio_dev->dev.parent = &pdev->dev;
+diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
+index 58f0860..640fe10 100644
+--- a/drivers/mfd/ti_am335x_tscadc.c
++++ b/drivers/mfd/ti_am335x_tscadc.c
+@@ -94,9 +94,13 @@ static int ti_tscadc_probe(struct platform_device *pdev)
+ struct mfd_tscadc_board *pdata = pdev->dev.platform_data;
+ struct device_node *node = pdev->dev.of_node;
+ struct mfd_cell *cell;
++ struct property *prop;
++ const __be32 *cur;
++ u32 val;
+ int err, ctrl;
+ int clk_value, clock_rate;
+ int tsc_wires = 0, adc_channels = 0, total_channels;
++ int readouts = 0;
+
+ if (!pdata && !pdev->dev.of_node) {
+ dev_err(&pdev->dev, "Could not find platform data\n");
+@@ -112,9 +116,17 @@ static int ti_tscadc_probe(struct platform_device *pdev)
+ } else {
+ node = of_get_child_by_name(pdev->dev.of_node, "tsc");
+ of_property_read_u32(node, "ti,wires", &tsc_wires);
++ of_property_read_u32(node, "ti,coordinate-readouts", &readouts);
+
+ node = of_get_child_by_name(pdev->dev.of_node, "adc");
+- of_property_read_u32(node, "ti,adc-channels", &adc_channels);
++ of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
++ adc_channels++;
++ if (val > 7) {
++ dev_err(&pdev->dev, " PIN numbers are 0..7 (not %d)\n",
++ val);
++ return -EINVAL;
++ }
++ }
+ }
+
+ total_channels = tsc_wires + adc_channels;
+@@ -127,6 +139,11 @@ static int ti_tscadc_probe(struct platform_device *pdev)
+ return -EINVAL;
+ }
+
++ if (readouts * 2 + 2 + adc_channels > 16) {
++ dev_err(&pdev->dev, "Too many step configurations requested\n");
++ return -EINVAL;
++ }
++
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "no memory resource defined.\n");
diff --git a/patches/linux-3.8.13/0059-iio-ti_am335x_adc-check-if-we-found-the-value.patch b/patches/linux-3.8.13/0059-iio-ti_am335x_adc-check-if-we-found-the-value.patch
new file mode 100644
index 0000000..f904553
--- /dev/null
+++ b/patches/linux-3.8.13/0059-iio-ti_am335x_adc-check-if-we-found-the-value.patch
@@ -0,0 +1,43 @@
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Wed, 12 Jun 2013 18:58:22 +0200
+Subject: [PATCH] iio: ti_am335x_adc: check if we found the value
+
+Usually we get all the values we wanted but it is possible, that te ADC
+unit is busy performing the conversation for the HW events. In that case
+-EBUSY is returned and the user may re-call the function.
+
+Acked-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/iio/adc/ti_am335x_adc.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
+index a2b6ebd..624935c 100644
+--- a/drivers/iio/adc/ti_am335x_adc.c
++++ b/drivers/iio/adc/ti_am335x_adc.c
+@@ -146,6 +146,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
+ int i;
+ unsigned int fifo1count, read;
+ u32 step = UINT_MAX;
++ bool found = false;
+
+ /*
+ * When the sub-system is first enabled,
+@@ -170,11 +171,14 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
+ fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+ for (i = 0; i < fifo1count; i++) {
+ read = tiadc_readl(adc_dev, REG_FIFO1);
+- if (read >> 16 == step)
++ if (read >> 16 == step) {
+ *val = read & 0xfff;
++ found = true;
++ }
+ }
+ am335x_tsc_se_update(adc_dev->mfd_tscadc);
+-
++ if (found == false)
++ return -EBUSY;
+ return IIO_VAL_INT;
+ }
+
diff --git a/patches/linux-3.8.13/0060-MFD-ti_tscadc-disable-TSC-control.patch b/patches/linux-3.8.13/0060-MFD-ti_tscadc-disable-TSC-control.patch
new file mode 100644
index 0000000..165455a
--- /dev/null
+++ b/patches/linux-3.8.13/0060-MFD-ti_tscadc-disable-TSC-control.patch
@@ -0,0 +1,59 @@
+From: ZubairLK <zubair.lutfullah@gmail.com>
+Date: Thu, 27 Jun 2013 22:47:13 +0100
+Subject: [PATCH] MFD: ti_tscadc: disable TSC control
+
+Register bits when TSC not in use
+
+AFE Pen Ctrl and TouchScreen transistors enabling is not
+
+required when only ADC mode is being used, so check for availability of
+
+TSC driver before accessing control register.
+Original Commit No in Arago tree 2c67698139cceee19d2205ad34d11c74e758b307
+ZubairLK. Forward ported the changes to 3.8
+
+Signed-off-by: Zubair Lutfullah <zubair.lutfullah@gmail.com>
+---
+ drivers/mfd/ti_am335x_tscadc.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
+index 640fe10..408e859 100644
+--- a/drivers/mfd/ti_am335x_tscadc.c
++++ b/drivers/mfd/ti_am335x_tscadc.c
+@@ -220,13 +220,14 @@ static int ti_tscadc_probe(struct platform_device *pdev)
+
+ /* Set the control register bits */
+ ctrl = CNTRLREG_STEPCONFIGWRT |
+- CNTRLREG_TSCENB |
+- CNTRLREG_STEPID |
+- CNTRLREG_4WIRE;
++ CNTRLREG_STEPID;
++ if (tsc_wires > 0)
++ ctrl |= CNTRLREG_4WIRE | CNTRLREG_TSCENB;
+ tscadc_writel(tscadc, REG_CTRL, ctrl);
+
+ /* Set register bits for Idle Config Mode */
+- tscadc_idle_config(tscadc);
++ if (tsc_wires > 0)
++ tscadc_idle_config(tscadc);
+
+ /* Enable the TSC module enable bit */
+ ctrl = tscadc_readl(tscadc, REG_CTRL);
+@@ -306,10 +307,13 @@ static int tscadc_resume(struct device *dev)
+ pm_runtime_get_sync(dev);
+
+ /* context restore */
+- ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_TSCENB |
+- CNTRLREG_STEPID | CNTRLREG_4WIRE;
++ ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_STEPID;
++ if (tscadc_dev->tsc_cell != -1)
++ ctrl |= CNTRLREG_TSCENB | CNTRLREG_4WIRE;
+ tscadc_writel(tscadc_dev, REG_CTRL, ctrl);
+- tscadc_idle_config(tscadc_dev);
++
++ if (tscadc_dev->tsc_cell != -1)
++ tscadc_idle_config(tscadc_dev);
+ am335x_tsc_se_update(tscadc_dev);
+ restore = tscadc_readl(tscadc_dev, REG_CTRL);
+ tscadc_writel(tscadc_dev, REG_CTRL,
diff --git a/patches/linux-3.8.13/0061-IIO-ADC-ti_adc-Fix-1st-sample-read.patch b/patches/linux-3.8.13/0061-IIO-ADC-ti_adc-Fix-1st-sample-read.patch
new file mode 100644
index 0000000..f0b9604
--- /dev/null
+++ b/patches/linux-3.8.13/0061-IIO-ADC-ti_adc-Fix-1st-sample-read.patch
@@ -0,0 +1,119 @@
+From: ZubairLK <zubair.lutfullah@gmail.com>
+Date: Thu, 27 Jun 2013 23:49:41 +0100
+Subject: [PATCH] IIO: ADC: ti_adc: Fix 1st sample read
+
+Previously we tried to read data form ADC even before ADC sequencer
+
+finished sampling. This led to wrong samples.
+
+We now wait on ADC status register idle bit to be set.
+
+Original Commit in Arago tree : 663aa2e74f36a5a8000224b37a74c11ee729550d
+ZubairLK Forward ported the changes to 3.8
+
+Signed-off-by: Zubair Lutfullah <zubair.lutfullah@gmail.com>
+---
+ drivers/iio/adc/ti_am335x_adc.c | 29 +++++++++++++++++++++--------
+ include/linux/mfd/ti_am335x_tscadc.h | 17 +++++++++++++++++
+ 2 files changed, 38 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
+index 624935c..f78d2c1 100644
+--- a/drivers/iio/adc/ti_am335x_adc.c
++++ b/drivers/iio/adc/ti_am335x_adc.c
+@@ -61,7 +61,6 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
+ {
+ unsigned int stepconfig;
+ int i, steps;
+- u32 step_en;
+
+ /*
+ * There are 16 configurable steps and 8 analog input
+@@ -87,8 +86,7 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
+ adc_dev->channel_step[i] = steps;
+ steps++;
+ }
+- step_en = get_adc_step_mask(adc_dev);
+- am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
++
+ }
+
+ static const char * const chan_name_ain[] = {
+@@ -143,11 +141,22 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
+ int *val, int *val2, long mask)
+ {
+ struct tiadc_device *adc_dev = iio_priv(indio_dev);
+- int i;
+- unsigned int fifo1count, read;
++ int i, map_val;
++ unsigned int fifo1count, read, stepid;
+ u32 step = UINT_MAX;
+ bool found = false;
++ u32 step_en;
++ unsigned long timeout = jiffies + usecs_to_jiffies
++ (IDLE_TIMEOUT * adc_dev->channels);
++ step_en = get_adc_step_mask(adc_dev);
++ am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
+
++ /* Wait for ADC sequencer to complete sampling */
++ while (tiadc_readl(adc_dev, REG_ADCFSM) & SEQ_STATUS) {
++ if (time_after(jiffies, timeout))
++ return -EAGAIN;
++ }
++ map_val = chan->channel + TOTAL_CHANNELS;
+ /*
+ * When the sub-system is first enabled,
+ * the sequencer will always start with the
+@@ -171,12 +180,16 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
+ fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+ for (i = 0; i < fifo1count; i++) {
+ read = tiadc_readl(adc_dev, REG_FIFO1);
+- if (read >> 16 == step) {
+- *val = read & 0xfff;
++ stepid = read & FIFOREAD_CHNLID_MASK;
++ stepid = stepid >> 0x10;
++
++ if (stepid == map_val) {
++ read = read & FIFOREAD_DATA_MASK;
+ found = true;
++ *val = read;
+ }
+ }
+- am335x_tsc_se_update(adc_dev->mfd_tscadc);
++
+ if (found == false)
+ return -EBUSY;
+ return IIO_VAL_INT;
+diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
+index 9598360..17c0cba 100644
+--- a/include/linux/mfd/ti_am335x_tscadc.h
++++ b/include/linux/mfd/ti_am335x_tscadc.h
+@@ -113,11 +113,28 @@
+ #define CNTRLREG_8WIRE CNTRLREG_AFE_CTRL(3)
+ #define CNTRLREG_TSCENB BIT(7)
+
++/* FIFO READ Register */
++#define FIFOREAD_DATA_MASK (0xfff << 0)
++#define FIFOREAD_CHNLID_MASK (0xf << 16)
++
++/* Sequencer Status */
++#define SEQ_STATUS BIT(5)
++
+ #define ADC_CLK 3000000
+ #define MAX_CLK_DIV 7
+ #define TOTAL_STEPS 16
+ #define TOTAL_CHANNELS 8
+
++/*
++* ADC runs at 3MHz, and it takes
++* 15 cycles to latch one data output.
++* Hence the idle time for ADC to
++* process one sample data would be
++* around 5 micro seconds.
++*/
++#define IDLE_TIMEOUT 5 /* microsec */
++
++
+ #define TSCADC_CELLS 2
+
+ struct mfd_tscadc_board {
diff --git a/patches/linux-3.8.13/0062-input-ti_tsc-Enable-shared-IRQ-TSC.patch b/patches/linux-3.8.13/0062-input-ti_tsc-Enable-shared-IRQ-TSC.patch
new file mode 100644
index 0000000..6aa870c
--- /dev/null
+++ b/patches/linux-3.8.13/0062-input-ti_tsc-Enable-shared-IRQ-TSC.patch
@@ -0,0 +1,61 @@
+From: ZubairLK <zubairlk@zubairlk-HP-G62-Notebook-PC.(none)>
+Date: Fri, 28 Jun 2013 00:45:20 +0100
+Subject: [PATCH] input : ti_tsc : Enable shared IRQ TSC
+
+Touchscreen and ADC share the same IRQ line from parent MFD core.
+
+Previously only Touchscreen was interrupt based.
+
+With continuous mode support added in ADC driver, now driver requires
+
+interrupt to process the ADC samples, so enable shared IRQ flag bit for
+
+touchscreen.
+
+Original Commit in Arago tree : 09597d7a244a8e6f5ea79da3c5dced3a5ea620c4
+ZubairLK Forward ported the changes to 3.8
+
+Signed-off-by: Zubair Lutfullah <zubair.lutfullah@gmail.com>S
+---
+ drivers/input/touchscreen/ti_am335x_tsc.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
+index 5f9801c..fd6a7b9 100644
+--- a/drivers/input/touchscreen/ti_am335x_tsc.c
++++ b/drivers/input/touchscreen/ti_am335x_tsc.c
+@@ -261,7 +261,15 @@ static irqreturn_t titsc_irq(int irq, void *dev)
+ unsigned int fsm;
+
+ status = titsc_readl(ts_dev, REG_IRQSTATUS);
+- if (status & IRQENB_FIFO0THRES) {
++ /*
++ * ADC and touchscreen share the IRQ line.
++ * FIFO1 threshold interrupt is used by ADC,
++ * hence return from touchscreen IRQ handler if FIFO1
++ * threshold interrupt occurred.
++ */
++ if (status & IRQENB_FIFO1THRES)
++ return IRQ_NONE;
++ else if (status & IRQENB_FIFO0THRES) {
+
+ titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2);
+
+@@ -316,7 +324,7 @@ static irqreturn_t titsc_irq(int irq, void *dev)
+ }
+
+ if (irqclr) {
+- titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
++ titsc_writel(ts_dev, REG_IRQSTATUS, (status | irqclr));
+ am335x_tsc_se_update(ts_dev->mfd_tscadc);
+ return IRQ_HANDLED;
+ }
+@@ -412,7 +420,7 @@ static int titsc_probe(struct platform_device *pdev)
+ }
+
+ err = request_irq(ts_dev->irq, titsc_irq,
+- 0, pdev->dev.driver->name, ts_dev);
++ IRQF_SHARED, pdev->dev.driver->name, ts_dev);
+ if (err) {
+ dev_err(&pdev->dev, "failed to allocate irq.\n");
+ goto err_free_mem;
diff --git a/patches/linux-3.8.13/0063-Revert.-Backport-IIO.patch b/patches/linux-3.8.13/0063-Revert.-Backport-IIO.patch
new file mode 100644
index 0000000..e2dab7f
--- /dev/null
+++ b/patches/linux-3.8.13/0063-Revert.-Backport-IIO.patch
@@ -0,0 +1,49 @@
+From: ZubairLK <zubair.lutfullah@gmail.com>
+Date: Sat, 29 Jun 2013 00:07:44 +0100
+Subject: [PATCH] Revert. Backport IIO
+
+Touchscreen side of things reverted to 3.8 compatible iio.
+
+Signed-off-by: Zubair Lutfullah <zubair.lutfullah@gmail.com>
+---
+ drivers/input/touchscreen/ti_am335x_tsc.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
+index fd6a7b9..f498211 100644
+--- a/drivers/input/touchscreen/ti_am335x_tsc.c
++++ b/drivers/input/touchscreen/ti_am335x_tsc.c
+@@ -331,15 +331,15 @@ static irqreturn_t titsc_irq(int irq, void *dev)
+ return IRQ_NONE;
+ }
+
+-static int titsc_parse_dt(struct platform_device *pdev,
++static int titsc_parse_dt(struct ti_tscadc_dev *tscadc_dev,
+ struct titsc *ts_dev)
+ {
+- struct device_node *node = pdev->dev.of_node;
++ struct device_node *node = tscadc_dev->dev->of_node;
+ int err;
+
+ if (!node)
+ return -EINVAL;
+-
++ node = of_get_child_by_name(node, "tsc");
+ err = of_property_read_u32(node, "ti,wires", &ts_dev->wires);
+ if (err < 0)
+ return err;
+@@ -409,10 +409,10 @@ static int titsc_probe(struct platform_device *pdev)
+ ts_dev->input = input_dev;
+ ts_dev->irq = tscadc_dev->irq;
+
+- if (tscadc_dev->dev->platform_data)
+- err = titsc_parse_pdata(tscadc_dev, ts_dev);
+- else
+- err = titsc_parse_dt(pdev, ts_dev);
++ //if (tscadc_dev->dev->platform_data)
++ // err = titsc_parse_pdata(tscadc_dev, ts_dev);
++ //else
++ err = titsc_parse_dt(tscadc_dev, ts_dev);
+
+ if (err) {
+ dev_err(&pdev->dev, "Could not find valid DT data.\n");
diff --git a/patches/linux-3.8.13/0064-iio-ti_am335x_adc-Added-iio_voltageX_scale.patch b/patches/linux-3.8.13/0064-iio-ti_am335x_adc-Added-iio_voltageX_scale.patch
new file mode 100644
index 0000000..0d8e7e7
--- /dev/null
+++ b/patches/linux-3.8.13/0064-iio-ti_am335x_adc-Added-iio_voltageX_scale.patch
@@ -0,0 +1,60 @@
+From: ZubairLK <zubair.lutfullah@gmail.com>
+Date: Sat, 29 Jun 2013 19:05:54 +0100
+Subject: [PATCH] iio: ti_am335x_adc: Added iio_voltageX_scale
+
+The bone-helper driver tried to display the voltage in the range 1800mV
+which represents the actual ADC range of the BBB. This feature is available
+in the IIO system. in_voltageX_raw points to unscaled raw values
+which give the output of the ADC register directly.
+
+in_voltageX_scale is supposed to give scaled voltages. This was
+missing in the TI driver and has been added.
+
+Signed-off-by: Zubair Lutfullah <zubair.lutfullah@gmail.com>
+---
+ drivers/iio/adc/ti_am335x_adc.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
+index f78d2c1..c030078 100644
+--- a/drivers/iio/adc/ti_am335x_adc.c
++++ b/drivers/iio/adc/ti_am335x_adc.c
+@@ -26,6 +26,7 @@
+ #include <linux/of_device.h>
+ #include <linux/iio/machine.h>
+ #include <linux/iio/driver.h>
++#include <linux/math64.h>
+
+ #include <linux/mfd/ti_am335x_tscadc.h>
+ #include <linux/platform_data/ti_am335x_adc.h>
+@@ -119,7 +120,8 @@ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
+ chan->type = IIO_VOLTAGE;
+ chan->indexed = 1;
+ chan->channel = adc_dev->channel_line[i];
+- chan->info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT;
++ chan->info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT
++ | IIO_CHAN_INFO_SCALE_SEPARATE_BIT;
+ chan->datasheet_name = chan_name_ain[chan->channel];
+ chan->scan_type.sign = 'u';
+ chan->scan_type.realbits = 12;
+@@ -189,7 +191,19 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
+ *val = read;
+ }
+ }
+-
++
++ switch (mask){
++ case IIO_CHAN_INFO_RAW : /*Do nothing. Above code works fine.*/
++ break;
++ case IIO_CHAN_INFO_SCALE : {
++ /*12 Bit adc. Scale value for 1800mV AVDD. Ideally
++ AVDD should come from DT.*/
++ *val = div_u64( (u64)(*val) * 1800 , 4096);
++ break;
++ }
++ default: break;
++ }
++
+ if (found == false)
+ return -EBUSY;
+ return IIO_VAL_INT;
diff --git a/patches/linux-3.8.13/0065-iio-ti_am335x_adc-Add-the-in-kernel-IIO-map-interfac.patch b/patches/linux-3.8.13/0065-iio-ti_am335x_adc-Add-the-in-kernel-IIO-map-interfac.patch
new file mode 100644
index 0000000..7ade689
--- /dev/null
+++ b/patches/linux-3.8.13/0065-iio-ti_am335x_adc-Add-the-in-kernel-IIO-map-interfac.patch
@@ -0,0 +1,122 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 11 Jul 2013 20:53:00 +0300
+Subject: [PATCH] iio: ti_am335x_adc: Add the in-kernel IIO map interface back
+ in.
+
+Without an IIO map the in-kernel users cannot find their
+AINx named ADC channels. So reintroduce.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/iio/adc/ti_am335x_adc.c | 53 +++++++++++++++++++++++++++++++++++----
+ 1 file changed, 48 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
+index c030078..83180fc 100644
+--- a/drivers/iio/adc/ti_am335x_adc.c
++++ b/drivers/iio/adc/ti_am335x_adc.c
+@@ -34,6 +34,7 @@
+ struct tiadc_device {
+ struct ti_tscadc_dev *mfd_tscadc;
+ int channels;
++ struct iio_map *map;
+ u8 channel_line[8];
+ u8 channel_step[8];
+ };
+@@ -106,13 +107,16 @@ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
+ struct tiadc_device *adc_dev = iio_priv(indio_dev);
+ struct iio_chan_spec *chan_array;
+ struct iio_chan_spec *chan;
+- int i;
++ struct iio_map *map;
++ int i, ret;
+
+ indio_dev->num_channels = channels;
+ chan_array = kcalloc(channels,
+ sizeof(struct iio_chan_spec), GFP_KERNEL);
+- if (chan_array == NULL)
+- return -ENOMEM;
++ if (chan_array == NULL) {
++ ret = -ENOMEM;
++ goto err_no_chan_array;
++ }
+
+ chan = chan_array;
+ for (i = 0; i < channels; i++, chan++) {
+@@ -130,12 +134,43 @@ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
+
+ indio_dev->channels = chan_array;
+
++ map = kcalloc(channels + 1, sizeof(struct iio_map), GFP_KERNEL);
++ if (map == NULL) {
++ ret = -ENOMEM;
++ goto err_no_iio_map;
++ }
++ adc_dev->map = map;
++
++ for (i = 0, chan = chan_array; i < channels; i++, chan++, map++) {
++ map->adc_channel_label = chan->datasheet_name;
++ map->consumer_dev_name = "any";
++ map->consumer_channel = chan->datasheet_name;
++ }
++ map->adc_channel_label = NULL;
++ map->consumer_dev_name = NULL;
++ map->consumer_channel = NULL;
++
++ ret = iio_map_array_register(indio_dev, adc_dev->map);
++ if (ret != 0)
++ goto err_iio_map_register_fail;
++
+ return 0;
++
++err_iio_map_register_fail:
++ kfree(adc_dev->map);
++ adc_dev->map = NULL;
++err_no_iio_map:
++ kfree(chan_array);
++ indio_dev->channels = NULL;
++err_no_chan_array:
++ return ret;
+ }
+
+ static void tiadc_channels_remove(struct iio_dev *indio_dev)
+ {
++ struct tiadc_device *adc_dev = iio_priv(indio_dev);
+ kfree(indio_dev->channels);
++ kfree(adc_dev->map);
+ }
+
+ static int tiadc_read_raw(struct iio_dev *indio_dev,
+@@ -252,6 +287,8 @@ static int tiadc_probe(struct platform_device *pdev)
+ adc_dev->channels = channels;
+ }
+
++ dev_info(&pdev->dev, "channels=%d\n", adc_dev->channels);
++
+ indio_dev->dev.parent = &pdev->dev;
+ indio_dev->name = dev_name(&pdev->dev);
+ indio_dev->modes = INDIO_DIRECT_MODE;
+@@ -260,15 +297,21 @@ static int tiadc_probe(struct platform_device *pdev)
+ tiadc_step_config(adc_dev);
+
+ err = tiadc_channel_init(indio_dev, adc_dev->channels);
+- if (err < 0)
++ if (err < 0) {
++ dev_err(&pdev->dev, "tiadc_channel_init() failed\n");
+ goto err_free_device;
++ }
+
+ err = iio_device_register(indio_dev);
+- if (err)
++ if (err) {
++ dev_err(&pdev->dev, "iio_device_register() failed\n");
+ goto err_free_channels;
++ }
+
+ platform_set_drvdata(pdev, indio_dev);
+
++ dev_info(&pdev->dev, "loaded OK\n");
++
+ return 0;
+
+ err_free_channels:
diff --git a/patches/linux-3.8.4/0058-pinctrl-pinctrl-single-must-be-initialized-early.patch b/patches/linux-3.8.13/0066-pinctrl-pinctrl-single-must-be-initialized-early.patch
index 2a85976..2a85976 100644
--- a/patches/linux-3.8.4/0058-pinctrl-pinctrl-single-must-be-initialized-early.patch
+++ b/patches/linux-3.8.13/0066-pinctrl-pinctrl-single-must-be-initialized-early.patch
diff --git a/patches/linux-3.8.4/0059-Bone-DTS-working-i2c2-i2c3-in-the-tree.patch b/patches/linux-3.8.13/0067-Bone-DTS-working-i2c2-i2c3-in-the-tree.patch
index 8636924..8636924 100644
--- a/patches/linux-3.8.4/0059-Bone-DTS-working-i2c2-i2c3-in-the-tree.patch
+++ b/patches/linux-3.8.13/0067-Bone-DTS-working-i2c2-i2c3-in-the-tree.patch
diff --git a/patches/linux-3.8.4/0060-am33xx-Convert-I2C-from-omap-to-am33xx-names.patch b/patches/linux-3.8.13/0068-am33xx-Convert-I2C-from-omap-to-am33xx-names.patch
index ff492f5..d4041e5 100644
--- a/patches/linux-3.8.4/0060-am33xx-Convert-I2C-from-omap-to-am33xx-names.patch
+++ b/patches/linux-3.8.13/0068-am33xx-Convert-I2C-from-omap-to-am33xx-names.patch
@@ -48,7 +48,7 @@ index 813ac04..874997b 100644
clock-frequency = <100000>;
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
-index b1aeefb..132b59d 100644
+index 5483e09..7ef38f6 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -61,7 +61,7 @@
diff --git a/patches/linux-3.8.4/0061-am335x-evm-hack-around-i2c-node-names.patch b/patches/linux-3.8.13/0069-am335x-evm-hack-around-i2c-node-names.patch
index 0c2b52c..cf73bec 100644
--- a/patches/linux-3.8.4/0061-am335x-evm-hack-around-i2c-node-names.patch
+++ b/patches/linux-3.8.13/0069-am335x-evm-hack-around-i2c-node-names.patch
@@ -9,7 +9,7 @@ Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
-index 132b59d..d4dd1af 100644
+index 7ef38f6..f4a07f8 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -70,7 +70,7 @@
diff --git a/patches/linux-3.8.13/0070-tsl2550-fix-lux1_input-error-in-low-light.patch b/patches/linux-3.8.13/0070-tsl2550-fix-lux1_input-error-in-low-light.patch
new file mode 100644
index 0000000..ea180e9
--- /dev/null
+++ b/patches/linux-3.8.13/0070-tsl2550-fix-lux1_input-error-in-low-light.patch
@@ -0,0 +1,31 @@
+From: Matt Ranostay <mranostay@gmail.com>
+Date: Mon, 3 Jun 2013 22:38:49 +0000
+Subject: [PATCH] tsl2550: fix lux1_input error in low light
+
+ADC channel 0 photodiode detects both infrared + visible light,
+but ADC channel 1 just detects infrared. However, the latter is a bit
+more sensitive in that range so complete darkness or low light causes
+a error condition in which the chan0 - chan1 is negative that
+results in a -EAGAIN.
+
+This patch changes the resulting lux1_input sysfs attribute message from
+"Resource temporarily unavailable" to a user-grokable lux value of 0.
+
+Signed-off-by: Matt Ranostay <mranostay@gmail.com>
+---
+ drivers/misc/tsl2550.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/misc/tsl2550.c b/drivers/misc/tsl2550.c
+index 1e7bc0e..9255074 100644
+--- a/drivers/misc/tsl2550.c
++++ b/drivers/misc/tsl2550.c
+@@ -178,7 +178,7 @@ static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
+ } else
+ lux = 0;
+ else
+- return -EAGAIN;
++ return 0;
+
+ /* LUX range check */
+ return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
diff --git a/patches/linux-3.8.4/0062-viafb-rename-display_timing-to-via_display_timing.patch b/patches/linux-3.8.13/0071-viafb-rename-display_timing-to-via_display_timing.patch
index 99bb651..99bb651 100644
--- a/patches/linux-3.8.4/0062-viafb-rename-display_timing-to-via_display_timing.patch
+++ b/patches/linux-3.8.13/0071-viafb-rename-display_timing-to-via_display_timing.patch
diff --git a/patches/linux-3.8.4/0063-video-add-display_timing-and-videomode.patch b/patches/linux-3.8.13/0072-video-add-display_timing-and-videomode.patch
index c38b3f2..c38b3f2 100644
--- a/patches/linux-3.8.4/0063-video-add-display_timing-and-videomode.patch
+++ b/patches/linux-3.8.13/0072-video-add-display_timing-and-videomode.patch
diff --git a/patches/linux-3.8.4/0064-video-add-of-helper-for-display-timings-videomode.patch b/patches/linux-3.8.13/0073-video-add-of-helper-for-display-timings-videomode.patch
index 70158b6..70158b6 100644
--- a/patches/linux-3.8.4/0064-video-add-of-helper-for-display-timings-videomode.patch
+++ b/patches/linux-3.8.13/0073-video-add-of-helper-for-display-timings-videomode.patch
diff --git a/patches/linux-3.8.4/0065-fbmon-add-videomode-helpers.patch b/patches/linux-3.8.13/0074-fbmon-add-videomode-helpers.patch
index b0a1dda..b0a1dda 100644
--- a/patches/linux-3.8.4/0065-fbmon-add-videomode-helpers.patch
+++ b/patches/linux-3.8.13/0074-fbmon-add-videomode-helpers.patch
diff --git a/patches/linux-3.8.4/0066-fbmon-add-of_videomode-helpers.patch b/patches/linux-3.8.13/0075-fbmon-add-of_videomode-helpers.patch
index f6034f5..f6034f5 100644
--- a/patches/linux-3.8.4/0066-fbmon-add-of_videomode-helpers.patch
+++ b/patches/linux-3.8.13/0075-fbmon-add-of_videomode-helpers.patch
diff --git a/patches/linux-3.8.4/0067-drm_modes-add-videomode-helpers.patch b/patches/linux-3.8.13/0076-drm_modes-add-videomode-helpers.patch
index 76872f2..c1da52f 100644
--- a/patches/linux-3.8.4/0067-drm_modes-add-videomode-helpers.patch
+++ b/patches/linux-3.8.13/0076-drm_modes-add-videomode-helpers.patch
@@ -72,7 +72,7 @@ index d8da30e..9f3f20b 100644
* drm_mode_set_name - set the name on a mode
* @mode: name will be set in this mode
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
-index fad21c9..d5c06ff 100644
+index 881fb15..24ef0cf 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -85,6 +85,8 @@ struct module;
diff --git a/patches/linux-3.8.4/0068-drm_modes-add-of_videomode-helpers.patch b/patches/linux-3.8.13/0077-drm_modes-add-of_videomode-helpers.patch
index 2ad8e3a..b1091d8 100644
--- a/patches/linux-3.8.4/0068-drm_modes-add-of_videomode-helpers.patch
+++ b/patches/linux-3.8.13/0077-drm_modes-add-of_videomode-helpers.patch
@@ -68,7 +68,7 @@ index 9f3f20b..04fa6f1 100644
* drm_mode_set_name - set the name on a mode
* @mode: name will be set in this mode
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
-index d5c06ff..fcc9d23 100644
+index 24ef0cf..98efdde 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -85,6 +85,7 @@ struct module;
diff --git a/patches/linux-3.8.4/0069-fbmon-fix-build-error.patch b/patches/linux-3.8.13/0078-fbmon-fix-build-error.patch
index d462dbe..d462dbe 100644
--- a/patches/linux-3.8.4/0069-fbmon-fix-build-error.patch
+++ b/patches/linux-3.8.13/0078-fbmon-fix-build-error.patch
diff --git a/patches/linux-3.8.4/0070-of-display-timings-use-of_get_child_by_name.patch b/patches/linux-3.8.13/0079-of-display-timings-use-of_get_child_by_name.patch
index 61f6fb9..61f6fb9 100644
--- a/patches/linux-3.8.4/0070-of-display-timings-use-of_get_child_by_name.patch
+++ b/patches/linux-3.8.13/0079-of-display-timings-use-of_get_child_by_name.patch
diff --git a/patches/linux-3.8.4/0071-da8xx-Allow-use-by-am33xx-based-devices.patch b/patches/linux-3.8.13/0080-da8xx-Allow-use-by-am33xx-based-devices.patch
index bd6a211..bd6a211 100644
--- a/patches/linux-3.8.4/0071-da8xx-Allow-use-by-am33xx-based-devices.patch
+++ b/patches/linux-3.8.13/0080-da8xx-Allow-use-by-am33xx-based-devices.patch
diff --git a/patches/linux-3.8.4/0072-video-da8xx-fb-fb_check_var-enhancement.patch b/patches/linux-3.8.13/0081-video-da8xx-fb-fb_check_var-enhancement.patch
index 26b4d1f..26b4d1f 100644
--- a/patches/linux-3.8.4/0072-video-da8xx-fb-fb_check_var-enhancement.patch
+++ b/patches/linux-3.8.13/0081-video-da8xx-fb-fb_check_var-enhancement.patch
diff --git a/patches/linux-3.8.4/0073-video-da8xx-fb-simplify-lcd_reset.patch b/patches/linux-3.8.13/0082-video-da8xx-fb-simplify-lcd_reset.patch
index fe37dfb..fe37dfb 100644
--- a/patches/linux-3.8.4/0073-video-da8xx-fb-simplify-lcd_reset.patch
+++ b/patches/linux-3.8.13/0082-video-da8xx-fb-simplify-lcd_reset.patch
diff --git a/patches/linux-3.8.4/0074-video-da8xx-fb-use-modedb-helper-to-update-var.patch b/patches/linux-3.8.13/0083-video-da8xx-fb-use-modedb-helper-to-update-var.patch
index 79f1767..79f1767 100644
--- a/patches/linux-3.8.4/0074-video-da8xx-fb-use-modedb-helper-to-update-var.patch
+++ b/patches/linux-3.8.13/0083-video-da8xx-fb-use-modedb-helper-to-update-var.patch
diff --git a/patches/linux-3.8.4/0075-video-da8xx-fb-remove-unneeded-var-initialization.patch b/patches/linux-3.8.13/0084-video-da8xx-fb-remove-unneeded-var-initialization.patch
index 2c704f1..2c704f1 100644
--- a/patches/linux-3.8.4/0075-video-da8xx-fb-remove-unneeded-var-initialization.patch
+++ b/patches/linux-3.8.13/0084-video-da8xx-fb-remove-unneeded-var-initialization.patch
diff --git a/patches/linux-3.8.4/0076-video-da8xx-fb-store-current-display-information.patch b/patches/linux-3.8.13/0085-video-da8xx-fb-store-current-display-information.patch
index bed8d30..bed8d30 100644
--- a/patches/linux-3.8.4/0076-video-da8xx-fb-store-current-display-information.patch
+++ b/patches/linux-3.8.13/0085-video-da8xx-fb-store-current-display-information.patch
diff --git a/patches/linux-3.8.4/0077-video-da8xx-fb-store-clk-rate-even-if-CPUFREQ.patch b/patches/linux-3.8.13/0086-video-da8xx-fb-store-clk-rate-even-if-CPUFREQ.patch
index bca2443..bca2443 100644
--- a/patches/linux-3.8.4/0077-video-da8xx-fb-store-clk-rate-even-if-CPUFREQ.patch
+++ b/patches/linux-3.8.13/0086-video-da8xx-fb-store-clk-rate-even-if-CPUFREQ.patch
diff --git a/patches/linux-3.8.4/0078-video-da8xx-fb-pix-clk-and-clk-div-handling-cleanup.patch b/patches/linux-3.8.13/0087-video-da8xx-fb-pix-clk-and-clk-div-handling-cleanup.patch
index 5eabb6a..5eabb6a 100644
--- a/patches/linux-3.8.4/0078-video-da8xx-fb-pix-clk-and-clk-div-handling-cleanup.patch
+++ b/patches/linux-3.8.13/0087-video-da8xx-fb-pix-clk-and-clk-div-handling-cleanup.patch
diff --git a/patches/linux-3.8.4/0079-video-da8xx-fb-store-struct-device.patch b/patches/linux-3.8.13/0088-video-da8xx-fb-store-struct-device.patch
index a22c61c..a22c61c 100644
--- a/patches/linux-3.8.4/0079-video-da8xx-fb-store-struct-device.patch
+++ b/patches/linux-3.8.13/0088-video-da8xx-fb-store-struct-device.patch
diff --git a/patches/linux-3.8.4/0080-video-da8xx-fb-report-correct-pixclock.patch b/patches/linux-3.8.13/0089-video-da8xx-fb-report-correct-pixclock.patch
index cc5abcf..cc5abcf 100644
--- a/patches/linux-3.8.4/0080-video-da8xx-fb-report-correct-pixclock.patch
+++ b/patches/linux-3.8.13/0089-video-da8xx-fb-report-correct-pixclock.patch
diff --git a/patches/linux-3.8.4/0081-video-da8xx-fb-fb_set_par-support.patch b/patches/linux-3.8.13/0090-video-da8xx-fb-fb_set_par-support.patch
index dbfdc1c..dbfdc1c 100644
--- a/patches/linux-3.8.4/0081-video-da8xx-fb-fb_set_par-support.patch
+++ b/patches/linux-3.8.13/0090-video-da8xx-fb-fb_set_par-support.patch
diff --git a/patches/linux-3.8.4/0082-ARM-dts-AM33XX-Add-lcdc-node.patch b/patches/linux-3.8.13/0091-ARM-dts-AM33XX-Add-lcdc-node.patch
index 69a4c8c..69a4c8c 100644
--- a/patches/linux-3.8.4/0082-ARM-dts-AM33XX-Add-lcdc-node.patch
+++ b/patches/linux-3.8.13/0091-ARM-dts-AM33XX-Add-lcdc-node.patch
diff --git a/patches/linux-3.8.4/0083-ARM-dts-AM33XX-Add-am335x-evm-lcdc-panel-timings.patch b/patches/linux-3.8.13/0092-ARM-dts-AM33XX-Add-am335x-evm-lcdc-panel-timings.patch
index de379d6..db26925 100644
--- a/patches/linux-3.8.4/0083-ARM-dts-AM33XX-Add-am335x-evm-lcdc-panel-timings.patch
+++ b/patches/linux-3.8.13/0092-ARM-dts-AM33XX-Add-am335x-evm-lcdc-panel-timings.patch
@@ -10,11 +10,11 @@ Signed-off-by: Afzal Mohammed <afzal@ti.com>
1 file changed, 20 insertions(+)
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
-index d4dd1af..9415b31 100644
+index f4a07f8..d1a34cc 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -283,3 +283,23 @@
- ti,adc-channels = <4>;
+ ti,adc-channels = <4 5 6 7>;
};
};
+
diff --git a/patches/linux-3.8.4/0084-ARM-dts-AM33XX-Add-am335x-evm-lcdc-pincontrol-info.patch b/patches/linux-3.8.13/0093-ARM-dts-AM33XX-Add-am335x-evm-lcdc-pincontrol-info.patch
index 5e8954e..cec6999 100644
--- a/patches/linux-3.8.4/0084-ARM-dts-AM33XX-Add-am335x-evm-lcdc-pincontrol-info.patch
+++ b/patches/linux-3.8.13/0093-ARM-dts-AM33XX-Add-am335x-evm-lcdc-pincontrol-info.patch
@@ -13,7 +13,7 @@ Signed-off-by: Afzal Mohammed <afzal@ti.com>
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
-index 9415b31..af69e81 100644
+index d1a34cc..5eadd1e 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -26,7 +26,7 @@
diff --git a/patches/linux-3.8.4/0085-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-panel-timings.patch b/patches/linux-3.8.13/0094-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-panel-timings.patch
index a3abf05..a3abf05 100644
--- a/patches/linux-3.8.4/0085-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-panel-timings.patch
+++ b/patches/linux-3.8.13/0094-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-panel-timings.patch
diff --git a/patches/linux-3.8.4/0086-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-pincontrol-info.patch b/patches/linux-3.8.13/0095-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-pincontrol-info.patch
index 33b7c72..33b7c72 100644
--- a/patches/linux-3.8.4/0086-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-pincontrol-info.patch
+++ b/patches/linux-3.8.13/0095-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-pincontrol-info.patch
diff --git a/patches/linux-3.8.4/0087-ARM-OMAP-AM33xx-hwmod-Corrects-PWM-subsystem-HWMOD-e.patch b/patches/linux-3.8.13/0096-ARM-OMAP-AM33xx-hwmod-Corrects-PWM-subsystem-HWMOD-e.patch
index 3a567b2..3a567b2 100644
--- a/patches/linux-3.8.4/0087-ARM-OMAP-AM33xx-hwmod-Corrects-PWM-subsystem-HWMOD-e.patch
+++ b/patches/linux-3.8.13/0096-ARM-OMAP-AM33xx-hwmod-Corrects-PWM-subsystem-HWMOD-e.patch
diff --git a/patches/linux-3.8.4/0088-ARM-OMAP-AM33xx-hwmod-Add-parent-child-relationship-.patch b/patches/linux-3.8.13/0097-ARM-OMAP-AM33xx-hwmod-Add-parent-child-relationship-.patch
index 7beb98d..7beb98d 100644
--- a/patches/linux-3.8.4/0088-ARM-OMAP-AM33xx-hwmod-Add-parent-child-relationship-.patch
+++ b/patches/linux-3.8.13/0097-ARM-OMAP-AM33xx-hwmod-Add-parent-child-relationship-.patch
diff --git a/patches/linux-3.8.4/0089-ARM-dts-AM33XX-Add-PWMSS-device-tree-nodes.patch b/patches/linux-3.8.13/0098-ARM-dts-AM33XX-Add-PWMSS-device-tree-nodes.patch
index d19f5d7..d19f5d7 100644
--- a/patches/linux-3.8.4/0089-ARM-dts-AM33XX-Add-PWMSS-device-tree-nodes.patch
+++ b/patches/linux-3.8.13/0098-ARM-dts-AM33XX-Add-PWMSS-device-tree-nodes.patch
diff --git a/patches/linux-3.8.4/0090-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch b/patches/linux-3.8.13/0099-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch
index d23d228..9ac684d 100644
--- a/patches/linux-3.8.4/0090-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch
+++ b/patches/linux-3.8.13/0099-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch
@@ -16,7 +16,7 @@ Conflicts:
1 file changed, 23 insertions(+)
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
-index af69e81..1f6b157 100644
+index 5eadd1e..65ae57f 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -86,6 +86,12 @@
diff --git a/patches/linux-3.8.4/0091-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch b/patches/linux-3.8.13/0100-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch
index bd95a08..bd95a08 100644
--- a/patches/linux-3.8.4/0091-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch
+++ b/patches/linux-3.8.13/0100-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch
diff --git a/patches/linux-3.8.4/0092-clk-divider-prepare-for-minimum-divider.patch b/patches/linux-3.8.13/0101-clk-divider-prepare-for-minimum-divider.patch
index 8614dd6..8614dd6 100644
--- a/patches/linux-3.8.4/0092-clk-divider-prepare-for-minimum-divider.patch
+++ b/patches/linux-3.8.13/0101-clk-divider-prepare-for-minimum-divider.patch
diff --git a/patches/linux-3.8.4/0093-clk-divider-handle-minimum-divider.patch b/patches/linux-3.8.13/0102-clk-divider-handle-minimum-divider.patch
index 5fabb56..5fabb56 100644
--- a/patches/linux-3.8.4/0093-clk-divider-handle-minimum-divider.patch
+++ b/patches/linux-3.8.13/0102-clk-divider-handle-minimum-divider.patch
diff --git a/patches/linux-3.8.4/0094-ARM-OMAP2-dpll-round-rate-to-closest-value.patch b/patches/linux-3.8.13/0103-ARM-OMAP2-dpll-round-rate-to-closest-value.patch
index d3db493..d3db493 100644
--- a/patches/linux-3.8.4/0094-ARM-OMAP2-dpll-round-rate-to-closest-value.patch
+++ b/patches/linux-3.8.13/0103-ARM-OMAP2-dpll-round-rate-to-closest-value.patch
diff --git a/patches/linux-3.8.4/0095-ARM-OMAP2-dpll-am335x-avoid-freqsel.patch b/patches/linux-3.8.13/0104-ARM-OMAP2-dpll-am335x-avoid-freqsel.patch
index 3faefaa..3faefaa 100644
--- a/patches/linux-3.8.4/0095-ARM-OMAP2-dpll-am335x-avoid-freqsel.patch
+++ b/patches/linux-3.8.13/0104-ARM-OMAP2-dpll-am335x-avoid-freqsel.patch
diff --git a/patches/linux-3.8.4/0096-ARM-OMAP2-clock-DEFINE_STRUCT_CLK_FLAGS-helper.patch b/patches/linux-3.8.13/0105-ARM-OMAP2-clock-DEFINE_STRUCT_CLK_FLAGS-helper.patch
index 4feb473..4feb473 100644
--- a/patches/linux-3.8.4/0096-ARM-OMAP2-clock-DEFINE_STRUCT_CLK_FLAGS-helper.patch
+++ b/patches/linux-3.8.13/0105-ARM-OMAP2-clock-DEFINE_STRUCT_CLK_FLAGS-helper.patch
diff --git a/patches/linux-3.8.4/0097-ARM-AM33XX-clock-SET_RATE_PARENT-in-lcd-path.patch b/patches/linux-3.8.13/0106-ARM-AM33XX-clock-SET_RATE_PARENT-in-lcd-path.patch
index 63850ab..63850ab 100644
--- a/patches/linux-3.8.4/0097-ARM-AM33XX-clock-SET_RATE_PARENT-in-lcd-path.patch
+++ b/patches/linux-3.8.13/0106-ARM-AM33XX-clock-SET_RATE_PARENT-in-lcd-path.patch
diff --git a/patches/linux-3.8.4/0098-video-da8xx-fb-make-io-operations-safe.patch b/patches/linux-3.8.13/0107-video-da8xx-fb-make-io-operations-safe.patch
index 1c89df5..1c89df5 100644
--- a/patches/linux-3.8.4/0098-video-da8xx-fb-make-io-operations-safe.patch
+++ b/patches/linux-3.8.13/0107-video-da8xx-fb-make-io-operations-safe.patch
diff --git a/patches/linux-3.8.4/0099-video-da8xx-fb-fix-24bpp-raster-configuration.patch b/patches/linux-3.8.13/0108-video-da8xx-fb-fix-24bpp-raster-configuration.patch
index a2e8581..a2e8581 100644
--- a/patches/linux-3.8.4/0099-video-da8xx-fb-fix-24bpp-raster-configuration.patch
+++ b/patches/linux-3.8.13/0108-video-da8xx-fb-fix-24bpp-raster-configuration.patch
diff --git a/patches/linux-3.8.4/0100-video-da8xx-fb-enable-sync-lost-intr-for-v2-ip.patch b/patches/linux-3.8.13/0109-video-da8xx-fb-enable-sync-lost-intr-for-v2-ip.patch
index f5bcedc..f5bcedc 100644
--- a/patches/linux-3.8.4/0100-video-da8xx-fb-enable-sync-lost-intr-for-v2-ip.patch
+++ b/patches/linux-3.8.13/0109-video-da8xx-fb-enable-sync-lost-intr-for-v2-ip.patch
diff --git a/patches/linux-3.8.4/0101-video-da8xx-fb-use-devres.patch b/patches/linux-3.8.13/0110-video-da8xx-fb-use-devres.patch
index 51e0aa4..51e0aa4 100644
--- a/patches/linux-3.8.4/0101-video-da8xx-fb-use-devres.patch
+++ b/patches/linux-3.8.13/0110-video-da8xx-fb-use-devres.patch
diff --git a/patches/linux-3.8.4/0102-video-da8xx-fb-ensure-non-null-cfg-in-pdata.patch b/patches/linux-3.8.13/0111-video-da8xx-fb-ensure-non-null-cfg-in-pdata.patch
index 90b6022..90b6022 100644
--- a/patches/linux-3.8.4/0102-video-da8xx-fb-ensure-non-null-cfg-in-pdata.patch
+++ b/patches/linux-3.8.13/0111-video-da8xx-fb-ensure-non-null-cfg-in-pdata.patch
diff --git a/patches/linux-3.8.4/0103-video-da8xx-fb-reorganize-panel-detection.patch b/patches/linux-3.8.13/0112-video-da8xx-fb-reorganize-panel-detection.patch
index 253344b..253344b 100644
--- a/patches/linux-3.8.4/0103-video-da8xx-fb-reorganize-panel-detection.patch
+++ b/patches/linux-3.8.13/0112-video-da8xx-fb-reorganize-panel-detection.patch
diff --git a/patches/linux-3.8.4/0104-video-da8xx-fb-minimal-dt-support.patch b/patches/linux-3.8.13/0113-video-da8xx-fb-minimal-dt-support.patch
index a17826f..a17826f 100644
--- a/patches/linux-3.8.4/0104-video-da8xx-fb-minimal-dt-support.patch
+++ b/patches/linux-3.8.13/0113-video-da8xx-fb-minimal-dt-support.patch
diff --git a/patches/linux-3.8.4/0105-video-da8xx-fb-invoke-platform-callback-safely.patch b/patches/linux-3.8.13/0114-video-da8xx-fb-invoke-platform-callback-safely.patch
index e5fa674..e5fa674 100644
--- a/patches/linux-3.8.4/0105-video-da8xx-fb-invoke-platform-callback-safely.patch
+++ b/patches/linux-3.8.13/0114-video-da8xx-fb-invoke-platform-callback-safely.patch
diff --git a/patches/linux-3.8.4/0106-video-da8xx-fb-obtain-fb_videomode-info-from-dt.patch b/patches/linux-3.8.13/0115-video-da8xx-fb-obtain-fb_videomode-info-from-dt.patch
index 4276bbb..4276bbb 100644
--- a/patches/linux-3.8.4/0106-video-da8xx-fb-obtain-fb_videomode-info-from-dt.patch
+++ b/patches/linux-3.8.13/0115-video-da8xx-fb-obtain-fb_videomode-info-from-dt.patch
diff --git a/patches/linux-3.8.4/0107-video-da8xx-fb-ensure-pdata-only-for-non-dt.patch b/patches/linux-3.8.13/0116-video-da8xx-fb-ensure-pdata-only-for-non-dt.patch
index d0aa079..d0aa079 100644
--- a/patches/linux-3.8.4/0107-video-da8xx-fb-ensure-pdata-only-for-non-dt.patch
+++ b/patches/linux-3.8.13/0116-video-da8xx-fb-ensure-pdata-only-for-non-dt.patch
diff --git a/patches/linux-3.8.4/0108-video-da8xx-fb-setup-struct-lcd_ctrl_config-for-dt.patch b/patches/linux-3.8.13/0117-video-da8xx-fb-setup-struct-lcd_ctrl_config-for-dt.patch
index 48c97ea..48c97ea 100644
--- a/patches/linux-3.8.4/0108-video-da8xx-fb-setup-struct-lcd_ctrl_config-for-dt.patch
+++ b/patches/linux-3.8.13/0117-video-da8xx-fb-setup-struct-lcd_ctrl_config-for-dt.patch
diff --git a/patches/linux-3.8.4/0109-video-da8xx-fb-CCF-clock-divider-handling.patch b/patches/linux-3.8.13/0118-video-da8xx-fb-CCF-clock-divider-handling.patch
index 5495935..5495935 100644
--- a/patches/linux-3.8.4/0109-video-da8xx-fb-CCF-clock-divider-handling.patch
+++ b/patches/linux-3.8.13/0118-video-da8xx-fb-CCF-clock-divider-handling.patch
diff --git a/patches/linux-3.8.4/0110-pwm_backlight-Add-device-tree-support-for-Low-Thresh.patch b/patches/linux-3.8.13/0119-pwm_backlight-Add-device-tree-support-for-Low-Thresh.patch
index 8e5d982..8e5d982 100644
--- a/patches/linux-3.8.4/0110-pwm_backlight-Add-device-tree-support-for-Low-Thresh.patch
+++ b/patches/linux-3.8.13/0119-pwm_backlight-Add-device-tree-support-for-Low-Thresh.patch
diff --git a/patches/linux-3.8.4/0111-Control-module-EHRPWM-clk-enabling.patch b/patches/linux-3.8.13/0120-Control-module-EHRPWM-clk-enabling.patch
index 667f0d2..667f0d2 100644
--- a/patches/linux-3.8.4/0111-Control-module-EHRPWM-clk-enabling.patch
+++ b/patches/linux-3.8.13/0120-Control-module-EHRPWM-clk-enabling.patch
diff --git a/patches/linux-3.8.4/0112-pwm-pwm_test-Driver-support-for-PWM-module-testing.patch b/patches/linux-3.8.13/0121-pwm-pwm_test-Driver-support-for-PWM-module-testing.patch
index 119cfe2..119cfe2 100644
--- a/patches/linux-3.8.4/0112-pwm-pwm_test-Driver-support-for-PWM-module-testing.patch
+++ b/patches/linux-3.8.13/0121-pwm-pwm_test-Driver-support-for-PWM-module-testing.patch
diff --git a/patches/linux-3.8.4/0113-ARM-OMAP2-PWM-limit-am33xx_register_ehrpwm-to-soc_is.patch b/patches/linux-3.8.13/0122-ARM-OMAP2-PWM-limit-am33xx_register_ehrpwm-to-soc_is.patch
index 800f770..800f770 100644
--- a/patches/linux-3.8.4/0113-ARM-OMAP2-PWM-limit-am33xx_register_ehrpwm-to-soc_is.patch
+++ b/patches/linux-3.8.13/0122-ARM-OMAP2-PWM-limit-am33xx_register_ehrpwm-to-soc_is.patch
diff --git a/patches/linux-3.8.4/0114-pwm-export-of_pwm_request.patch b/patches/linux-3.8.13/0123-pwm-export-of_pwm_request.patch
index 70e84e4..70e84e4 100644
--- a/patches/linux-3.8.4/0114-pwm-export-of_pwm_request.patch
+++ b/patches/linux-3.8.13/0123-pwm-export-of_pwm_request.patch
diff --git a/patches/linux-3.8.4/0115-pwm-pwm-tiehrpwm-Update-the-clock-handling-of-pwm-ti.patch b/patches/linux-3.8.13/0124-pwm-pwm-tiehrpwm-Update-the-clock-handling-of-pwm-ti.patch
index b1eaa79..b1eaa79 100644
--- a/patches/linux-3.8.4/0115-pwm-pwm-tiehrpwm-Update-the-clock-handling-of-pwm-ti.patch
+++ b/patches/linux-3.8.13/0124-pwm-pwm-tiehrpwm-Update-the-clock-handling-of-pwm-ti.patch
diff --git a/patches/linux-3.8.4/0116-ARM-AM33XX-clk-Add-clock-node-for-EHRPWM-TBCLK.patch b/patches/linux-3.8.13/0125-ARM-AM33XX-clk-Add-clock-node-for-EHRPWM-TBCLK.patch
index 8620ad3..8620ad3 100644
--- a/patches/linux-3.8.4/0116-ARM-AM33XX-clk-Add-clock-node-for-EHRPWM-TBCLK.patch
+++ b/patches/linux-3.8.13/0125-ARM-AM33XX-clk-Add-clock-node-for-EHRPWM-TBCLK.patch
diff --git a/patches/linux-3.8.4/0117-HACK-am33xx.dtsi-turn-on-all-PWMs.patch b/patches/linux-3.8.13/0126-HACK-am33xx.dtsi-turn-on-all-PWMs.patch
index 58a7027..58a7027 100644
--- a/patches/linux-3.8.4/0117-HACK-am33xx.dtsi-turn-on-all-PWMs.patch
+++ b/patches/linux-3.8.13/0126-HACK-am33xx.dtsi-turn-on-all-PWMs.patch
diff --git a/patches/linux-3.8.13/0127-pwm-add-sysfs-interface.patch b/patches/linux-3.8.13/0127-pwm-add-sysfs-interface.patch
new file mode 100644
index 0000000..61f2992
--- /dev/null
+++ b/patches/linux-3.8.13/0127-pwm-add-sysfs-interface.patch
@@ -0,0 +1,790 @@
+From: Lars Poeschel <poeschel@lemonage.de>
+Date: Wed, 3 Apr 2013 15:58:55 +0200
+Subject: [PATCH] pwm: add sysfs interface
+
+This adds a simple sysfs interface to the pwm subsystem. It is
+heavily inspired by the gpio sysfs interface.
+
+ /sys/class/pwm
+ /export ... asks the kernel to export a PWM to userspace
+ /unexport ... to return a PWM to the kernel
+ /pwmN ... for each exported PWM #N
+ /duty_ns ... r/w, length of duty portion
+ /period_ns ... r/w, length of the pwm period
+ /polarity ... r/w, normal(0) or inverse(1) polarity
+ only created if driver supports it
+ /run ... r/w, write 1 to start and 0 to stop the pwm
+ /pwmchipN ... for each pwmchip; #N is its first PWM
+ /base ... (r/o) same as N
+ /ngpio ... (r/o) number of PWM; numbered N .. MAX_PWMS
+
+Signed-off-by: Lars Poeschel <poeschel@lemonage.de>
+
+--
+---
+ Documentation/ABI/testing/sysfs-class-pwm | 37 +++
+ Documentation/pwm.txt | 46 +++
+ drivers/pwm/Kconfig | 12 +
+ drivers/pwm/core.c | 494 ++++++++++++++++++++++++++++-
+ include/linux/pwm.h | 27 +-
+ 5 files changed, 610 insertions(+), 6 deletions(-)
+ create mode 100644 Documentation/ABI/testing/sysfs-class-pwm
+
+diff --git a/Documentation/ABI/testing/sysfs-class-pwm b/Documentation/ABI/testing/sysfs-class-pwm
+new file mode 100644
+index 0000000..e9be1a3
+--- /dev/null
++++ b/Documentation/ABI/testing/sysfs-class-pwm
+@@ -0,0 +1,37 @@
++What: /sys/class/pwm/
++Date: March 2013
++KernelVersion: 3.11
++Contact: Lars Poeschel <poeschel@lemonage.de>
++Description:
++
++ The sysfs interface for PWM is selectable as a Kconfig option.
++ If a driver successfully probed a pwm chip, it appears at
++ /sys/class/pwm/pwmchipN/ where N is the number of it's first PWM channel. A
++ single driver may probe multiple chips. PWMs are identified as they are
++ inside the kernel, using integers in the range 0..MAX_PWMS. To use an
++ individual PWM, you have to explicitly export it by writing it's kernel
++ global number into the /sys/class/pwm/export file. Write it's number to
++ /sys/class/pwm/unexport to make the pwm available for other uses.
++ After a PWM channel is exported, it is available under
++ /sys/class/pwm/pwmN/. Under this directory you can set the parameters for
++ this PWM channel and at least let it start running.
++ See below for the parameters.
++ It is recommended to set the period_ns at first and the duty_ns after that.
++
++ See Documentation/pwm.txt for more information.
++
++Directory structure:
++
++ /sys/class/pwm
++ /export ... asks the kernel to export a PWM to userspace
++ /unexport ... to return a PWM to the kernel
++ /pwmN ... for each exported PWM #N
++ /duty_ns ... r/w, length of duty portion
++ /period_ns ... r/w, length of the pwm period
++ /polarity ... r/w, normal(0) or inverse(1) polarity
++ only created if driver supports it
++ /run ... r/w, write 1 to start and 0 to stop the pwm
++ /pwmchipN ... for each pwmchip; #N is its first PWM
++ /base ... (r/o) same as N
++ /ngpio ... (r/o) number of PWM; numbered N .. MAX_PWMS
++
+diff --git a/Documentation/pwm.txt b/Documentation/pwm.txt
+index 7d2b4c9..b349d16 100644
+--- a/Documentation/pwm.txt
++++ b/Documentation/pwm.txt
+@@ -45,6 +45,52 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);
+
+ To start/stop toggling the PWM output use pwm_enable()/pwm_disable().
+
++Using PWMs with the sysfs interface
++-----------------------------------
++
++You have to enable CONFIG_PWM_SYSFS in your kernel configuration to use
++the sysfs interface. It is exposed at /sys/class/pwm/. If there are pwm
++drivers loaded and these drivers successfully probed a chip, this chip
++is exported as pwmchipX . Note that a single driver can probe multiple chips.
++Inside the directory you can read these properties:
++
++base - This is the linux global start where the chips pwm channels get
++exposed.
++
++npwm - This is the number of pwm channels this chip supports.
++
++If you want to start using a pwm channel with sysfs first you have to
++export it. If you are finished with it and want to free the pwm for other
++uses, you can unexport it:
++
++export - Write the global pwm channel number to this file to start using
++the channel with sysfs.
++
++unexport - Write the global pwm channel number of the channel you are finshed
++with to this file to make the channel available for other uses.
++
++Once a pwm is exported a pwmX (X ranging from 0 to MAX_PWMS) directory appears
++with the following read/write properties inside to control the pwm:
++
++duty_ns - Write the number of nanoseconds the active portion of the pwm period
++should last to this file. This can not be longer than the period_ns.
++
++period_ns - Write the length of the pwm period in nanoseconds to this file.
++This includes the active and inactive portion of the pwm period and can not
++be smaller than duty_ns.
++
++polarity - The normal behaviour is to put out a high for the active portion of
++the pwm period. Write a 1 to this file to inverse the signal and output a low
++on the active portion. Write a 0 to switch back to the normal behaviour. The
++polarity can only be changed if the pwm is not running. This file is only
++visible if the underlying driver/device supports changing the polarity.
++
++run - Write a 1 to this file to start the pwm signal generation, write a 0 to
++stop it. Set your desired period_ns, duty_ns and polarity before starting the
++pwm.
++
++It is recommend to set the period_ns at first and duty_ns after that.
++
+ Implementing a PWM driver
+ -------------------------
+
+diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
+index 74f5084..6755f2b 100644
+--- a/drivers/pwm/Kconfig
++++ b/drivers/pwm/Kconfig
+@@ -28,6 +28,18 @@ menuconfig PWM
+
+ if PWM
+
++config PWM_SYSFS
++ bool "/sys/class/pwm/... (sysfs interface)"
++ depends on SYSFS
++ help
++ Say Y here to use a sysfs interface to control PWMs.
++
++ For every instance of an PWM capable device there is a pwmchipX
++ directory exported to /sys/class/pwm. If you want to use a PWM, you
++ have to export it to sysfs, which is done by writing the number into
++ /sys/class/pwm/export. After that /sys/class/pwm/pwmX is ready to be
++ used.
++
+ config PWM_AB8500
+ tristate "AB8500 PWM support"
+ depends on AB8500_CORE && ARCH_U8500
+diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
+index 0478442..7d13e67 100644
+--- a/drivers/pwm/core.c
++++ b/drivers/pwm/core.c
+@@ -30,8 +30,6 @@
+ #include <linux/debugfs.h>
+ #include <linux/seq_file.h>
+
+-#define MAX_PWMS 1024
+-
+ /* flags in the third cell of the DT PWM specifier */
+ #define PWM_SPEC_POLARITY (1 << 0)
+
+@@ -42,6 +40,465 @@ static LIST_HEAD(pwm_chips);
+ static DECLARE_BITMAP(allocated_pwms, MAX_PWMS);
+ static RADIX_TREE(pwm_tree, GFP_KERNEL);
+
++
++#ifdef CONFIG_PWM_SYSFS
++
++/* lock protects against unexport_pwm() being called while
++ * sysfs files are active.
++ */
++static DEFINE_MUTEX(sysfs_lock);
++static struct class pwm_class;
++static struct pwm_device *pwm_table[MAX_PWMS];
++
++/*
++ * /sys/class/pwm/pwm... only for PWMs that are exported
++ * /polarity
++ * * only visible if the underlying driver has registered a
++ * set_polarity function
++ * * always readable
++ * * may be written as "1" for inverted polarity or "0" for
++ * normal polarity
++ * * can only be written if PWM is not running
++ * /period_ns
++ * * always readable
++ * * write with desired pwm period in nanoseconds
++ * * may return with error depending on duty_ns
++ * /duty_ns
++ * * always readable
++ * * write with desired duty portion in nanoseconds
++ * * may return with error depending on period_ns
++ * /run
++ * * always readable
++ * * write with "1" to start generating pwm signal, "0" to stop it
++ */
++static ssize_t pwm_polarity_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ const struct pwm_device *pwm = dev_get_drvdata(dev);
++ ssize_t status;
++
++ mutex_lock(&sysfs_lock);
++
++ if (!test_bit(PWMF_EXPORT, &pwm->flags))
++ status = -EIO;
++ else
++ status = sprintf(buf, "%d\n", pwm->polarity);
++
++ mutex_unlock(&sysfs_lock);
++
++ return status;
++}
++
++static ssize_t pwm_polarity_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
++{
++ struct pwm_device *pwm = dev_get_drvdata(dev);
++ ssize_t status;
++
++ mutex_lock(&sysfs_lock);
++
++ if (!test_bit(PWMF_EXPORT, &pwm->flags))
++ status = -EIO;
++ else {
++ long value;
++
++ status = kstrtol(buf, 0, &value);
++ if (status == 0) {
++ if (value == 0) {
++ if (pwm->polarity == PWM_POLARITY_NORMAL)
++ goto fail_unlock;
++ status = pwm_set_polarity(pwm,
++ PWM_POLARITY_NORMAL);
++ } else {
++ if (pwm->polarity == PWM_POLARITY_INVERSED)
++ goto fail_unlock;
++ status = pwm_set_polarity(pwm,
++ PWM_POLARITY_INVERSED);
++ }
++ }
++ }
++
++fail_unlock:
++ mutex_unlock(&sysfs_lock);
++ return status ? : size;
++}
++
++static const DEVICE_ATTR(polarity, 0644,
++ pwm_polarity_show, pwm_polarity_store);
++
++
++static ssize_t pwm_period_ns_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ const struct pwm_device *pwm = dev_get_drvdata(dev);
++ ssize_t status;
++
++ mutex_lock(&sysfs_lock);
++
++ if (!test_bit(PWMF_EXPORT, &pwm->flags))
++ status = -EIO;
++ else
++ status = sprintf(buf, "%d\n", pwm->period);
++
++ mutex_unlock(&sysfs_lock);
++
++ return status;
++}
++
++static ssize_t pwm_period_ns_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
++{
++ struct pwm_device *pwm = dev_get_drvdata(dev);
++ ssize_t status;
++
++ mutex_lock(&sysfs_lock);
++
++ if (!test_bit(PWMF_EXPORT, &pwm->flags))
++ status = -EIO;
++ else {
++ long value;
++
++ status = kstrtol(buf, 0, &value);
++ if (status == 0) {
++ if (pwm->duty < 0)
++ pwm->period = value;
++ else
++ status = pwm_config(pwm, pwm->duty, value);
++ }
++ }
++
++ mutex_unlock(&sysfs_lock);
++
++ return status ? : size;
++}
++
++static ssize_t pwm_duty_ns_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ const struct pwm_device *pwm = dev_get_drvdata(dev);
++ ssize_t status;
++
++ mutex_lock(&sysfs_lock);
++
++ if (!test_bit(PWMF_EXPORT, &pwm->flags))
++ status = -EIO;
++ else
++ status = sprintf(buf, "%d\n", pwm->duty);
++
++ mutex_unlock(&sysfs_lock);
++
++ return status;
++}
++
++static ssize_t pwm_duty_ns_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
++{
++ struct pwm_device *pwm = dev_get_drvdata(dev);
++ ssize_t status;
++
++ mutex_lock(&sysfs_lock);
++
++ if (!test_bit(PWMF_EXPORT, &pwm->flags))
++ status = -EIO;
++ else {
++ long value;
++
++ status = kstrtol(buf, 0, &value);
++ if (status == 0) {
++ if (pwm->period <= 0)
++ pwm->duty = value;
++ else
++ status = pwm_config(pwm, value, pwm->period);
++ }
++ }
++
++ mutex_unlock(&sysfs_lock);
++
++ return status ? : size;
++}
++
++static ssize_t pwm_run_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ const struct pwm_device *pwm = dev_get_drvdata(dev);
++ ssize_t status;
++
++ mutex_lock(&sysfs_lock);
++
++ if (!test_bit(PWMF_EXPORT, &pwm->flags))
++ status = -EIO;
++ else
++ status = sprintf(buf, "%d\n",
++ !!test_bit(PWMF_ENABLED, &pwm->flags));
++
++ mutex_unlock(&sysfs_lock);
++
++ return status;
++}
++
++static ssize_t pwm_run_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
++{
++ struct pwm_device *pwm = dev_get_drvdata(dev);
++ ssize_t status;
++
++ mutex_lock(&sysfs_lock);
++
++ if (!test_bit(PWMF_EXPORT, &pwm->flags))
++ status = -EIO;
++ else {
++ long value;
++
++ status = kstrtol(buf, 0, &value);
++ if (status == 0) {
++ if (value)
++ status = pwm_enable(pwm);
++ else
++ pwm_disable(pwm);
++ }
++ }
++
++ mutex_unlock(&sysfs_lock);
++
++ return status ? : size;
++}
++
++static struct device_attribute pwm_dev_attrs[] = {
++ __ATTR(period_ns, 0644, pwm_period_ns_show, pwm_period_ns_store),
++ __ATTR(duty_ns, 0644, pwm_duty_ns_show, pwm_duty_ns_store),
++ __ATTR(run, 0644, pwm_run_show, pwm_run_store),
++ __ATTR_NULL,
++};
++
++/*
++ * /sys/class/pwm/pwmchipN/
++ * /base ... matching pwm_chip.base (N)
++ * /ngpio ... matching pwm_chip.npwm
++ */
++
++static ssize_t chip_base_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ const struct pwm_chip *chip = dev_get_drvdata(dev);
++
++ return sprintf(buf, "%d\n", chip->base);
++}
++
++static ssize_t chip_npwm_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ const struct pwm_chip *chip = dev_get_drvdata(dev);
++
++ return sprintf(buf, "%u\n", chip->npwm);
++}
++
++static int pwm_export(struct pwm_device *pwm)
++{
++ struct device *dev;
++ int status;
++
++ mutex_lock(&sysfs_lock);
++
++ if (!test_bit(PWMF_REQUESTED, &pwm->flags) ||
++ test_bit(PWMF_EXPORT, &pwm->flags)) {
++ pr_debug("pwm %d unavailable (requested=%d, exported=%d)\n",
++ pwm->pwm,
++ test_bit(PWMF_REQUESTED, &pwm->flags),
++ test_bit(PWMF_EXPORT, &pwm->flags));
++
++ status = -EPERM;
++ goto fail_unlock;
++ }
++
++ pwm_class.class_attrs = NULL;
++ pwm_class.dev_attrs = pwm_dev_attrs;
++ dev = device_create(&pwm_class, pwm->chip->dev, MKDEV(0, 0),
++ pwm, "pwm%u", pwm->pwm);
++ if (IS_ERR(dev)) {
++ status = PTR_ERR(dev);
++ goto fail_unlock;
++ }
++
++ if (pwm->chip->ops->set_polarity) {
++ status = device_create_file(dev, &dev_attr_polarity);
++ if (status)
++ goto fail_unregister_device;
++ }
++
++ set_bit(PWMF_EXPORT, &pwm->flags);
++ mutex_unlock(&sysfs_lock);
++ return 0;
++
++fail_unregister_device:
++ device_unregister(dev);
++fail_unlock:
++ mutex_unlock(&sysfs_lock);
++ return status;
++}
++
++static int match_export(struct device *dev, void *data)
++{
++ return dev_get_drvdata(dev) == data;
++}
++
++/*
++ * /sys/class/pwm/export ... write-only
++ * integer N ... number of pwm to export (full access)
++ * /sys/class/pwm/unexport ... write-only
++ * integer N ... number of pwm to unexport
++ */
++static ssize_t export_store(struct class *class,
++ struct class_attribute *attr,
++ const char *buf, size_t len)
++{
++ long pwm;
++ int status;
++ struct pwm_device *dev;
++ struct pwm_chip *chip;
++
++ status = kstrtol(buf, 0, &pwm);
++ if (status < 0)
++ goto done;
++
++ if (!pwm_is_valid(pwm) || !pwm_table[pwm]) {
++ status = -ENODEV;
++ goto done;
++ }
++ chip = pwm_table[pwm]->chip;
++ if (!chip) {
++ status = -ENODEV;
++ goto done;
++ }
++ dev = pwm_request_from_chip(chip, pwm - chip->base, "sysfs");
++ if (IS_ERR(dev)) {
++ status = -ENODEV;
++ goto done;
++ }
++ status = pwm_export(dev);
++ if (status < 0)
++ pwm_free(dev);
++done:
++ if (status)
++ pr_debug("%s: status %d\n", __func__, status);
++ return status ? : len;
++}
++
++static ssize_t unexport_store(struct class *class,
++ struct class_attribute *attr,
++ const char *buf, size_t len)
++{
++ long pwm;
++ int status;
++ struct pwm_device *dev;
++ struct device *d;
++
++ status = kstrtol(buf, 0, &pwm);
++ if (status < 0)
++ goto done;
++
++ status = -EINVAL;
++
++ /* reject bogus pwms */
++ if (!pwm_is_valid(pwm))
++ goto done;
++
++ dev = pwm_table[pwm];
++ if (dev && test_and_clear_bit(PWMF_EXPORT, &dev->flags)) {
++ d = class_find_device(&pwm_class, NULL, dev, match_export);
++ if (d)
++ device_unregister(d);
++ status = 0;
++ pwm_put(dev);
++ }
++done:
++ if (status)
++ pr_debug("%s: status %d\n", __func__, status);
++ return status ? : len;
++}
++
++static struct class_attribute pwmchip_class_attrs[] = {
++ __ATTR(export, 0200, NULL, export_store),
++ __ATTR(unexport, 0200, NULL, unexport_store),
++ __ATTR_NULL,
++};
++
++static struct device_attribute pwmchip_dev_attrs[] = {
++ __ATTR(base, 0444, chip_base_show, NULL),
++ __ATTR(npwm, 0444, chip_npwm_show, NULL),
++ __ATTR_NULL,
++};
++
++static struct class pwm_class = {
++ .name = "pwm",
++ .owner = THIS_MODULE,
++ .class_attrs = pwmchip_class_attrs,
++ .dev_attrs = pwmchip_dev_attrs,
++};
++
++static int pwmchip_export(struct pwm_chip *chip)
++{
++ struct device *dev;
++
++ mutex_lock(&sysfs_lock);
++ pwm_class.class_attrs = pwmchip_class_attrs;
++ pwm_class.dev_attrs = pwmchip_dev_attrs;
++ dev = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip,
++ "pwmchip%d", chip->base);
++
++ chip->exported = (!IS_ERR(dev));
++ mutex_unlock(&sysfs_lock);
++
++ if (chip->exported)
++ return 0;
++
++ return PTR_ERR(dev);
++}
++
++static void pwmchip_unexport(struct pwm_chip *chip)
++{
++ int status, i;
++ struct device *dev;
++
++ mutex_lock(&sysfs_lock);
++ dev = class_find_device(&pwm_class, NULL, chip, match_export);
++ if (dev) {
++ put_device(dev);
++ device_unregister(dev);
++ for (i = chip->base; i < chip->base + chip->npwm; i++)
++ pwm_table[i] = NULL;
++ chip->exported = 0;
++ status = 0;
++ } else
++ status = -ENODEV;
++ mutex_unlock(&sysfs_lock);
++
++ if (status)
++ pr_debug("%s: pwm chip status %d\n", __func__, status);
++}
++
++static int __init pwmlib_sysfs_init(void)
++{
++ int status;
++
++ status = class_register(&pwm_class);
++
++ return status;
++}
++postcore_initcall(pwmlib_sysfs_init);
++
++#else
++static inline int pwmchip_export(struct pwm_chip *chip)
++{
++ return 0;
++}
++
++static inline void pwmchip_unexport(struct pwm_chip *chip)
++{
++}
++
++#endif /* CONFIG_PWM_SYSFS */
++
++
+ static struct pwm_device *pwm_to_device(unsigned int pwm)
+ {
+ return radix_tree_lookup(&pwm_tree, pwm);
+@@ -77,8 +534,10 @@ static void free_pwms(struct pwm_chip *chip)
+ for (i = 0; i < chip->npwm; i++) {
+ struct pwm_device *pwm = &chip->pwms[i];
+ radix_tree_delete(&pwm_tree, pwm->pwm);
++#ifdef CONFIG_PWM_SYSFS
++ pwm_table[i + chip->base]->chip = NULL;
++#endif
+ }
+-
+ bitmap_clear(allocated_pwms, chip->base, chip->npwm);
+
+ kfree(chip->pwms);
+@@ -258,6 +717,9 @@ int pwmchip_add(struct pwm_chip *chip)
+ pwm->chip = chip;
+ pwm->pwm = chip->base + i;
+ pwm->hwpwm = i;
++#ifdef CONFIG_PWM_SYSFS
++ pwm_table[i + chip->base] = pwm;
++#endif
+
+ radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
+ }
+@@ -272,6 +734,8 @@ int pwmchip_add(struct pwm_chip *chip)
+ if (IS_ENABLED(CONFIG_OF))
+ of_pwmchip_add(chip);
+
++ ret = pwmchip_export(chip);
++
+ out:
+ mutex_unlock(&pwm_lock);
+ return ret;
+@@ -307,6 +771,7 @@ int pwmchip_remove(struct pwm_chip *chip)
+ of_pwmchip_remove(chip);
+
+ free_pwms(chip);
++ pwmchip_unexport(chip);
+
+ out:
+ mutex_unlock(&pwm_lock);
+@@ -400,10 +865,19 @@ EXPORT_SYMBOL_GPL(pwm_free);
+ */
+ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+ {
++ int status;
++
+ if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns)
+ return -EINVAL;
+
+- return pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
++ status = pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
++#ifdef CONFIG_PWM_SYSFS
++ if (status == 0) {
++ pwm->period = period_ns;
++ pwm->duty = duty_ns;
++ }
++#endif
++ return status;
+ }
+ EXPORT_SYMBOL_GPL(pwm_config);
+
+@@ -416,6 +890,8 @@ EXPORT_SYMBOL_GPL(pwm_config);
+ */
+ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
+ {
++ int status;
++
+ if (!pwm || !pwm->chip->ops)
+ return -EINVAL;
+
+@@ -425,7 +901,12 @@ int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
+ if (test_bit(PWMF_ENABLED, &pwm->flags))
+ return -EBUSY;
+
+- return pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
++ status = pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
++#ifdef CONFIG_PWM_SYSFS
++ if (!status)
++ pwm->polarity = polarity;
++#endif
++ return status;
+ }
+ EXPORT_SYMBOL_GPL(pwm_set_polarity);
+
+@@ -753,6 +1234,9 @@ static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
+ if (test_bit(PWMF_ENABLED, &pwm->flags))
+ seq_printf(s, " enabled");
+
++ if (test_bit(PWMF_EXPORT, &pwm->flags))
++ seq_printf(s, " sysfs_exported");
++
+ seq_printf(s, "\n");
+ }
+ }
+diff --git a/include/linux/pwm.h b/include/linux/pwm.h
+index b21c020..9165922 100644
+--- a/include/linux/pwm.h
++++ b/include/linux/pwm.h
+@@ -4,10 +4,27 @@
+ #include <linux/err.h>
+ #include <linux/of.h>
+
++#define MAX_PWMS 1024
++
+ struct pwm_device;
+ struct seq_file;
+
+ #if IS_ENABLED(CONFIG_PWM) || IS_ENABLED(CONFIG_HAVE_PWM)
++
++/*
++ * "valid" PWM numbers are nonnegative and may be passed to
++ * setup routines like pwm_get(). only some valid numbers
++ * can successfully be requested and used.
++ *
++ * Invalid PWM numbers are useful for indicating no-such-PWM in
++ * platform data and other tables.
++ */
++
++static inline bool pwm_is_valid(int number)
++{
++ return number >= 0 && number < MAX_PWMS;
++}
++
+ /*
+ * pwm_request - request a PWM device
+ */
+@@ -75,7 +92,8 @@ enum pwm_polarity {
+
+ enum {
+ PWMF_REQUESTED = 1 << 0,
+- PWMF_ENABLED = 1 << 1,
++ PWMF_ENABLED = 1 << 1, /* set running via /sys/class/pwm/pwmX/run */
++ PWMF_EXPORT = 1 << 2, /* exported via /sys/class/pwm/export */
+ };
+
+ struct pwm_device {
+@@ -87,6 +105,10 @@ struct pwm_device {
+ void *chip_data;
+
+ unsigned int period; /* in nanoseconds */
++#ifdef CONFIG_PWM_SYSFS
++ unsigned int duty; /* in nanoseconds */
++ enum pwm_polarity polarity;
++#endif
+ };
+
+ static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
+@@ -159,6 +181,9 @@ struct pwm_chip {
+ struct pwm_device * (*of_xlate)(struct pwm_chip *pc,
+ const struct of_phandle_args *args);
+ unsigned int of_pwm_n_cells;
++#ifdef CONFIG_PWM_SYSFS
++ unsigned exported:1;
++#endif
+ };
+
+ #if IS_ENABLED(CONFIG_PWM)
diff --git a/patches/linux-3.8.4/0118-am33xx.dtsi-enable-MMC-HSPE-bit-for-all-3-controller.patch b/patches/linux-3.8.13/0128-am33xx.dtsi-enable-MMC-HSPE-bit-for-all-3-controller.patch
index 29bb1c5..29bb1c5 100644
--- a/patches/linux-3.8.4/0118-am33xx.dtsi-enable-MMC-HSPE-bit-for-all-3-controller.patch
+++ b/patches/linux-3.8.13/0128-am33xx.dtsi-enable-MMC-HSPE-bit-for-all-3-controller.patch
diff --git a/patches/linux-3.8.4/0119-omap-hsmmc-Correct-usage-of-of_find_node_by_name.patch b/patches/linux-3.8.13/0129-omap-hsmmc-Correct-usage-of-of_find_node_by_name.patch
index d17a3f2..d17a3f2 100644
--- a/patches/linux-3.8.4/0119-omap-hsmmc-Correct-usage-of-of_find_node_by_name.patch
+++ b/patches/linux-3.8.13/0129-omap-hsmmc-Correct-usage-of-of_find_node_by_name.patch
diff --git a/patches/linux-3.8.4/0120-ARM-OMAP2xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch b/patches/linux-3.8.13/0130-ARM-OMAP2xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch
index 22f0d01..22f0d01 100644
--- a/patches/linux-3.8.4/0120-ARM-OMAP2xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch
+++ b/patches/linux-3.8.13/0130-ARM-OMAP2xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch
diff --git a/patches/linux-3.8.4/0121-ARM-OMAP2xxx-hwmod-Add-DMA-support-for-SHAM-module.patch b/patches/linux-3.8.13/0131-ARM-OMAP2xxx-hwmod-Add-DMA-support-for-SHAM-module.patch
index 1298783..1298783 100644
--- a/patches/linux-3.8.4/0121-ARM-OMAP2xxx-hwmod-Add-DMA-support-for-SHAM-module.patch
+++ b/patches/linux-3.8.13/0131-ARM-OMAP2xxx-hwmod-Add-DMA-support-for-SHAM-module.patch
diff --git a/patches/linux-3.8.4/0122-ARM-OMAP3xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch b/patches/linux-3.8.13/0132-ARM-OMAP3xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch
index 85fb388..4396efd 100644
--- a/patches/linux-3.8.4/0122-ARM-OMAP3xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch
+++ b/patches/linux-3.8.13/0132-ARM-OMAP3xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch
@@ -91,7 +91,7 @@ index fc93642..3d1693b 100644
#if defined(CONFIG_CRYPTO_DEV_OMAP_AES) || defined(CONFIG_CRYPTO_DEV_OMAP_AES_MODULE)
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
-index 8bb2628..122b4dc 100644
+index 8bb2628..122b4dc6 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -3540,6 +3540,71 @@ static struct omap_hwmod_ocp_if omap3xxx_l3_main__gpmc = {
diff --git a/patches/linux-3.8.4/0123-ARM-OMAP2-Remove-unnecessary-message-when-no-SHA-IP-.patch b/patches/linux-3.8.13/0133-ARM-OMAP2-Remove-unnecessary-message-when-no-SHA-IP-.patch
index 1fac8e7..1fac8e7 100644
--- a/patches/linux-3.8.4/0123-ARM-OMAP2-Remove-unnecessary-message-when-no-SHA-IP-.patch
+++ b/patches/linux-3.8.13/0133-ARM-OMAP2-Remove-unnecessary-message-when-no-SHA-IP-.patch
diff --git a/patches/linux-3.8.4/0124-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch b/patches/linux-3.8.13/0134-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch
index 11e178e..11e178e 100644
--- a/patches/linux-3.8.4/0124-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch
+++ b/patches/linux-3.8.13/0134-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch
diff --git a/patches/linux-3.8.4/0125-ARM-AM33XX-Add-sha0-crypto-clock-data.patch b/patches/linux-3.8.13/0135-ARM-AM33XX-Add-sha0-crypto-clock-data.patch
index 1b1ed2d..1b1ed2d 100644
--- a/patches/linux-3.8.4/0125-ARM-AM33XX-Add-sha0-crypto-clock-data.patch
+++ b/patches/linux-3.8.13/0135-ARM-AM33XX-Add-sha0-crypto-clock-data.patch
diff --git a/patches/linux-3.8.4/0126-ARM-AM33XX-hwmod-Update-and-uncomment-SHA0-module-da.patch b/patches/linux-3.8.13/0136-ARM-AM33XX-hwmod-Update-and-uncomment-SHA0-module-da.patch
index 2e5a0da..2e5a0da 100644
--- a/patches/linux-3.8.4/0126-ARM-AM33XX-hwmod-Update-and-uncomment-SHA0-module-da.patch
+++ b/patches/linux-3.8.13/0136-ARM-AM33XX-hwmod-Update-and-uncomment-SHA0-module-da.patch
diff --git a/patches/linux-3.8.4/0127-ARM-dts-Add-SHAM-data-and-documentation-for-AM33XX.patch b/patches/linux-3.8.13/0137-ARM-dts-Add-SHAM-data-and-documentation-for-AM33XX.patch
index f929b4e..b56faae 100644
--- a/patches/linux-3.8.4/0127-ARM-dts-Add-SHAM-data-and-documentation-for-AM33XX.patch
+++ b/patches/linux-3.8.13/0137-ARM-dts-Add-SHAM-data-and-documentation-for-AM33XX.patch
@@ -72,7 +72,7 @@ index 874997b..5254b64 100644
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
-index 1f6b157..b8cb5be 100644
+index 65ae57f..5d33c20 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -358,3 +358,7 @@
diff --git a/patches/linux-3.8.4/0128-ARM-OMAP2xxx-hwmod-Convert-AES-crypto-devcie-data-to.patch b/patches/linux-3.8.13/0138-ARM-OMAP2xxx-hwmod-Convert-AES-crypto-devcie-data-to.patch
index 74fc72d..b6b70b1 100644
--- a/patches/linux-3.8.4/0128-ARM-OMAP2xxx-hwmod-Convert-AES-crypto-devcie-data-to.patch
+++ b/patches/linux-3.8.13/0138-ARM-OMAP2xxx-hwmod-Convert-AES-crypto-devcie-data-to.patch
@@ -118,7 +118,7 @@ index 3c19b08..4ce999e 100644
&omap2430_l3__gpmc,
NULL,
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c
-index 510f584..8d4d53d 100644
+index 510f584..8d4d53d5 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_interconnect_data.c
@@ -147,6 +147,15 @@ struct omap_hwmod_addr_space omap2xxx_sham_addrs[] = {
diff --git a/patches/linux-3.8.4/0129-ARM-OMAP3xxx-hwmod-Convert-AES-crypto-device-data-to.patch b/patches/linux-3.8.13/0139-ARM-OMAP3xxx-hwmod-Convert-AES-crypto-device-data-to.patch
index 154c7c1..6373016 100644
--- a/patches/linux-3.8.4/0129-ARM-OMAP3xxx-hwmod-Convert-AES-crypto-device-data-to.patch
+++ b/patches/linux-3.8.13/0139-ARM-OMAP3xxx-hwmod-Convert-AES-crypto-device-data-to.patch
@@ -95,7 +95,7 @@ index fe5e6a2..91e5a21 100644
#if defined(CONFIG_VIDEO_OMAP2_VOUT) || \
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
-index 122b4dc..85d1b08 100644
+index 122b4dc6..85d1b08 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -3605,6 +3605,67 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__sham = {
diff --git a/patches/linux-3.8.4/0130-ARM-OMAP2-Remove-unnecessary-message-when-no-AES-IP-.patch b/patches/linux-3.8.13/0140-ARM-OMAP2-Remove-unnecessary-message-when-no-AES-IP-.patch
index 45e47cc..45e47cc 100644
--- a/patches/linux-3.8.4/0130-ARM-OMAP2-Remove-unnecessary-message-when-no-AES-IP-.patch
+++ b/patches/linux-3.8.13/0140-ARM-OMAP2-Remove-unnecessary-message-when-no-AES-IP-.patch
diff --git a/patches/linux-3.8.4/0131-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch b/patches/linux-3.8.13/0141-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch
index 551a982..551a982 100644
--- a/patches/linux-3.8.4/0131-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch
+++ b/patches/linux-3.8.13/0141-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch
diff --git a/patches/linux-3.8.4/0132-ARM-AM33XX-Add-aes0-crypto-clock-data.patch b/patches/linux-3.8.13/0142-ARM-AM33XX-Add-aes0-crypto-clock-data.patch
index 4391020..4391020 100644
--- a/patches/linux-3.8.4/0132-ARM-AM33XX-Add-aes0-crypto-clock-data.patch
+++ b/patches/linux-3.8.13/0142-ARM-AM33XX-Add-aes0-crypto-clock-data.patch
diff --git a/patches/linux-3.8.4/0133-ARM-AM33XX-hwmod-Update-and-uncomment-AES0-module-da.patch b/patches/linux-3.8.13/0143-ARM-AM33XX-hwmod-Update-and-uncomment-AES0-module-da.patch
index cc11b2f..cc11b2f 100644
--- a/patches/linux-3.8.4/0133-ARM-AM33XX-hwmod-Update-and-uncomment-AES0-module-da.patch
+++ b/patches/linux-3.8.13/0143-ARM-AM33XX-hwmod-Update-and-uncomment-AES0-module-da.patch
diff --git a/patches/linux-3.8.4/0134-ARM-dts-Add-AES-data-and-documentation-for-AM33XX.patch b/patches/linux-3.8.13/0144-ARM-dts-Add-AES-data-and-documentation-for-AM33XX.patch
index 898446b..65d2784 100644
--- a/patches/linux-3.8.4/0134-ARM-dts-Add-AES-data-and-documentation-for-AM33XX.patch
+++ b/patches/linux-3.8.13/0144-ARM-dts-Add-AES-data-and-documentation-for-AM33XX.patch
@@ -74,7 +74,7 @@ index 5254b64..bf87ceb 100644
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
-index b8cb5be..d562b33 100644
+index 5d33c20..d83be11 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -362,3 +362,7 @@
diff --git a/patches/linux-3.8.4/0135-crypto-omap-sham-Remove-unnecessary-pr_info-noise.patch b/patches/linux-3.8.13/0145-crypto-omap-sham-Remove-unnecessary-pr_info-noise.patch
index 7c53b4e..7c53b4e 100644
--- a/patches/linux-3.8.4/0135-crypto-omap-sham-Remove-unnecessary-pr_info-noise.patch
+++ b/patches/linux-3.8.13/0145-crypto-omap-sham-Remove-unnecessary-pr_info-noise.patch
diff --git a/patches/linux-3.8.4/0136-crypto-omap-sham-Convert-to-use-pm_runtime-API.patch b/patches/linux-3.8.13/0146-crypto-omap-sham-Convert-to-use-pm_runtime-API.patch
index 9153e7d..9153e7d 100644
--- a/patches/linux-3.8.4/0136-crypto-omap-sham-Convert-to-use-pm_runtime-API.patch
+++ b/patches/linux-3.8.13/0146-crypto-omap-sham-Convert-to-use-pm_runtime-API.patch
diff --git a/patches/linux-3.8.4/0137-crypto-omap-sham-Add-suspend-resume-support.patch b/patches/linux-3.8.13/0147-crypto-omap-sham-Add-suspend-resume-support.patch
index 76342ff..76342ff 100644
--- a/patches/linux-3.8.4/0137-crypto-omap-sham-Add-suspend-resume-support.patch
+++ b/patches/linux-3.8.13/0147-crypto-omap-sham-Add-suspend-resume-support.patch
diff --git a/patches/linux-3.8.4/0138-crypto-omap-sham-Add-code-to-use-dmaengine-API.patch b/patches/linux-3.8.13/0148-crypto-omap-sham-Add-code-to-use-dmaengine-API.patch
index a71dcbb..a71dcbb 100644
--- a/patches/linux-3.8.4/0138-crypto-omap-sham-Add-code-to-use-dmaengine-API.patch
+++ b/patches/linux-3.8.13/0148-crypto-omap-sham-Add-code-to-use-dmaengine-API.patch
diff --git a/patches/linux-3.8.4/0139-crypto-omap-sham-Remove-usage-of-private-DMA-API.patch b/patches/linux-3.8.13/0149-crypto-omap-sham-Remove-usage-of-private-DMA-API.patch
index f9371b6..f9371b6 100644
--- a/patches/linux-3.8.4/0139-crypto-omap-sham-Remove-usage-of-private-DMA-API.patch
+++ b/patches/linux-3.8.13/0149-crypto-omap-sham-Remove-usage-of-private-DMA-API.patch
diff --git a/patches/linux-3.8.4/0140-crypto-omap-sham-Add-Device-Tree-Support.patch b/patches/linux-3.8.13/0150-crypto-omap-sham-Add-Device-Tree-Support.patch
index acfd815..acfd815 100644
--- a/patches/linux-3.8.4/0140-crypto-omap-sham-Add-Device-Tree-Support.patch
+++ b/patches/linux-3.8.13/0150-crypto-omap-sham-Add-Device-Tree-Support.patch
diff --git a/patches/linux-3.8.4/0141-crypto-omap-sham-Convert-to-dma_request_slave_channe.patch b/patches/linux-3.8.13/0151-crypto-omap-sham-Convert-to-dma_request_slave_channe.patch
index 43d76b6..43d76b6 100644
--- a/patches/linux-3.8.4/0141-crypto-omap-sham-Convert-to-dma_request_slave_channe.patch
+++ b/patches/linux-3.8.13/0151-crypto-omap-sham-Convert-to-dma_request_slave_channe.patch
diff --git a/patches/linux-3.8.4/0142-crypto-omap-sham-Add-OMAP4-AM33XX-SHAM-Support.patch b/patches/linux-3.8.13/0152-crypto-omap-sham-Add-OMAP4-AM33XX-SHAM-Support.patch
index a6308b5..a6308b5 100644
--- a/patches/linux-3.8.4/0142-crypto-omap-sham-Add-OMAP4-AM33XX-SHAM-Support.patch
+++ b/patches/linux-3.8.13/0152-crypto-omap-sham-Add-OMAP4-AM33XX-SHAM-Support.patch
diff --git a/patches/linux-3.8.4/0143-crypto-omap-sham-Add-SHA224-and-SHA256-Support.patch b/patches/linux-3.8.13/0153-crypto-omap-sham-Add-SHA224-and-SHA256-Support.patch
index b695641..b695641 100644
--- a/patches/linux-3.8.4/0143-crypto-omap-sham-Add-SHA224-and-SHA256-Support.patch
+++ b/patches/linux-3.8.13/0153-crypto-omap-sham-Add-SHA224-and-SHA256-Support.patch
diff --git a/patches/linux-3.8.4/0144-crypto-omap-aes-Remmove-unnecessary-pr_info-noise.patch b/patches/linux-3.8.13/0154-crypto-omap-aes-Remmove-unnecessary-pr_info-noise.patch
index d8be9ee..d8be9ee 100644
--- a/patches/linux-3.8.4/0144-crypto-omap-aes-Remmove-unnecessary-pr_info-noise.patch
+++ b/patches/linux-3.8.13/0154-crypto-omap-aes-Remmove-unnecessary-pr_info-noise.patch
diff --git a/patches/linux-3.8.4/0145-crypto-omap-aes-Don-t-reset-controller-for-every-ope.patch b/patches/linux-3.8.13/0155-crypto-omap-aes-Don-t-reset-controller-for-every-ope.patch
index 6c07d75..6c07d75 100644
--- a/patches/linux-3.8.4/0145-crypto-omap-aes-Don-t-reset-controller-for-every-ope.patch
+++ b/patches/linux-3.8.13/0155-crypto-omap-aes-Don-t-reset-controller-for-every-ope.patch
diff --git a/patches/linux-3.8.4/0146-crypto-omap-aes-Convert-to-use-pm_runtime-API.patch b/patches/linux-3.8.13/0156-crypto-omap-aes-Convert-to-use-pm_runtime-API.patch
index f962ed6..f962ed6 100644
--- a/patches/linux-3.8.4/0146-crypto-omap-aes-Convert-to-use-pm_runtime-API.patch
+++ b/patches/linux-3.8.13/0156-crypto-omap-aes-Convert-to-use-pm_runtime-API.patch
diff --git a/patches/linux-3.8.4/0147-crypto-omap-aes-Add-suspend-resume-support.patch b/patches/linux-3.8.13/0157-crypto-omap-aes-Add-suspend-resume-support.patch
index 35c1a40..35c1a40 100644
--- a/patches/linux-3.8.4/0147-crypto-omap-aes-Add-suspend-resume-support.patch
+++ b/patches/linux-3.8.13/0157-crypto-omap-aes-Add-suspend-resume-support.patch
diff --git a/patches/linux-3.8.4/0148-crypto-omap-aes-Add-code-to-use-dmaengine-API.patch b/patches/linux-3.8.13/0158-crypto-omap-aes-Add-code-to-use-dmaengine-API.patch
index 0df4e50..0df4e50 100644
--- a/patches/linux-3.8.4/0148-crypto-omap-aes-Add-code-to-use-dmaengine-API.patch
+++ b/patches/linux-3.8.13/0158-crypto-omap-aes-Add-code-to-use-dmaengine-API.patch
diff --git a/patches/linux-3.8.4/0149-crypto-omap-aes-Remove-usage-of-private-DMA-API.patch b/patches/linux-3.8.13/0159-crypto-omap-aes-Remove-usage-of-private-DMA-API.patch
index 1d183ca..1d183ca 100644
--- a/patches/linux-3.8.4/0149-crypto-omap-aes-Remove-usage-of-private-DMA-API.patch
+++ b/patches/linux-3.8.13/0159-crypto-omap-aes-Remove-usage-of-private-DMA-API.patch
diff --git a/patches/linux-3.8.4/0150-crypto-omap-aes-Add-Device-Tree-Support.patch b/patches/linux-3.8.13/0160-crypto-omap-aes-Add-Device-Tree-Support.patch
index d4dba9f..d4dba9f 100644
--- a/patches/linux-3.8.4/0150-crypto-omap-aes-Add-Device-Tree-Support.patch
+++ b/patches/linux-3.8.13/0160-crypto-omap-aes-Add-Device-Tree-Support.patch
diff --git a/patches/linux-3.8.4/0151-crypto-omap-aes-Convert-to-dma_request_slave_channel.patch b/patches/linux-3.8.13/0161-crypto-omap-aes-Convert-to-dma_request_slave_channel.patch
index 8eebf49..8eebf49 100644
--- a/patches/linux-3.8.4/0151-crypto-omap-aes-Convert-to-dma_request_slave_channel.patch
+++ b/patches/linux-3.8.13/0161-crypto-omap-aes-Convert-to-dma_request_slave_channel.patch
diff --git a/patches/linux-3.8.4/0152-crypto-omap-aes-Add-OMAP4-AM33XX-AES-Support.patch b/patches/linux-3.8.13/0162-crypto-omap-aes-Add-OMAP4-AM33XX-AES-Support.patch
index 85fa086..85fa086 100644
--- a/patches/linux-3.8.4/0152-crypto-omap-aes-Add-OMAP4-AM33XX-AES-Support.patch
+++ b/patches/linux-3.8.13/0162-crypto-omap-aes-Add-OMAP4-AM33XX-AES-Support.patch
diff --git a/patches/linux-3.8.4/0153-crypto-omap-aes-Add-CTR-algorithm-Support.patch b/patches/linux-3.8.13/0163-crypto-omap-aes-Add-CTR-algorithm-Support.patch
index 6e3b33f..6e3b33f 100644
--- a/patches/linux-3.8.4/0153-crypto-omap-aes-Add-CTR-algorithm-Support.patch
+++ b/patches/linux-3.8.13/0163-crypto-omap-aes-Add-CTR-algorithm-Support.patch
diff --git a/patches/linux-3.8.13/0164-6lowpan-Refactor-packet-delivery-into-a-function.patch b/patches/linux-3.8.13/0164-6lowpan-Refactor-packet-delivery-into-a-function.patch
new file mode 100644
index 0000000..1aaadec
--- /dev/null
+++ b/patches/linux-3.8.13/0164-6lowpan-Refactor-packet-delivery-into-a-function.patch
@@ -0,0 +1,72 @@
+From: Alan Ott <alan@signal11.us>
+Date: Wed, 16 Jan 2013 19:09:47 +0000
+Subject: [PATCH] 6lowpan: Refactor packet delivery into a function
+
+Refactor the handing of the skb's to the individual lowpan devices into a
+function.
+
+Signed-off-by: Alan Ott <alan@signal11.us>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ net/ieee802154/6lowpan.c | 38 ++++++++++++++++++++++++--------------
+ 1 file changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
+index 76c3d0a..9d39f5b 100644
+--- a/net/ieee802154/6lowpan.c
++++ b/net/ieee802154/6lowpan.c
+@@ -594,10 +594,32 @@ static int lowpan_header_create(struct sk_buff *skb,
+ }
+ }
+
++static int lowpan_give_skb_to_devices(struct sk_buff *skb)
++{
++ struct lowpan_dev_record *entry;
++ struct sk_buff *skb_cp;
++ int stat = NET_RX_SUCCESS;
++
++ rcu_read_lock();
++ list_for_each_entry_rcu(entry, &lowpan_devices, list)
++ if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) {
++ skb_cp = skb_copy(skb, GFP_ATOMIC);
++ if (!skb_cp) {
++ stat = -ENOMEM;
++ break;
++ }
++
++ skb_cp->dev = entry->ldev;
++ stat = netif_rx(skb_cp);
++ }
++ rcu_read_unlock();
++
++ return stat;
++}
++
+ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr)
+ {
+ struct sk_buff *new;
+- struct lowpan_dev_record *entry;
+ int stat = NET_RX_SUCCESS;
+
+ new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb),
+@@ -614,19 +636,7 @@ static int lowpan_skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr)
+ new->protocol = htons(ETH_P_IPV6);
+ new->pkt_type = PACKET_HOST;
+
+- rcu_read_lock();
+- list_for_each_entry_rcu(entry, &lowpan_devices, list)
+- if (lowpan_dev_info(entry->ldev)->real_dev == new->dev) {
+- skb = skb_copy(new, GFP_ATOMIC);
+- if (!skb) {
+- stat = -ENOMEM;
+- break;
+- }
+-
+- skb->dev = entry->ldev;
+- stat = netif_rx(skb);
+- }
+- rcu_read_unlock();
++ stat = lowpan_give_skb_to_devices(new);
+
+ kfree_skb(new);
+
diff --git a/patches/linux-3.8.13/0165-6lowpan-Handle-uncompressed-IPv6-packets-over-6LoWPA.patch b/patches/linux-3.8.13/0165-6lowpan-Handle-uncompressed-IPv6-packets-over-6LoWPA.patch
new file mode 100644
index 0000000..c64fc75
--- /dev/null
+++ b/patches/linux-3.8.13/0165-6lowpan-Handle-uncompressed-IPv6-packets-over-6LoWPA.patch
@@ -0,0 +1,68 @@
+From: Alan Ott <alan@signal11.us>
+Date: Wed, 16 Jan 2013 19:09:48 +0000
+Subject: [PATCH] 6lowpan: Handle uncompressed IPv6 packets over 6LoWPAN
+
+Handle the reception of uncompressed packets (dispatch type = IPv6).
+
+Signed-off-by: Alan Ott <alan@signal11.us>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ net/ieee802154/6lowpan.c | 41 ++++++++++++++++++++++++++++++++---------
+ 1 file changed, 32 insertions(+), 9 deletions(-)
+
+diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
+index 9d39f5b..f62c3b9 100644
+--- a/net/ieee802154/6lowpan.c
++++ b/net/ieee802154/6lowpan.c
+@@ -1147,19 +1147,42 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
+ goto drop;
+
+ /* check that it's our buffer */
+- switch (skb->data[0] & 0xe0) {
+- case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
+- case LOWPAN_DISPATCH_FRAG1: /* first fragment header */
+- case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */
+- local_skb = skb_clone(skb, GFP_ATOMIC);
++ if (skb->data[0] == LOWPAN_DISPATCH_IPV6) {
++ /* Copy the packet so that the IPv6 header is
++ * properly aligned.
++ */
++ local_skb = skb_copy_expand(skb, NET_SKB_PAD - 1,
++ skb_tailroom(skb), GFP_ATOMIC);
+ if (!local_skb)
+ goto drop;
+- lowpan_process_data(local_skb);
+
++ local_skb->protocol = htons(ETH_P_IPV6);
++ local_skb->pkt_type = PACKET_HOST;
++
++ /* Pull off the 1-byte of 6lowpan header. */
++ skb_pull(local_skb, 1);
++ skb_reset_network_header(local_skb);
++ skb_set_transport_header(local_skb, sizeof(struct ipv6hdr));
++
++ lowpan_give_skb_to_devices(local_skb);
++
++ kfree_skb(local_skb);
+ kfree_skb(skb);
+- break;
+- default:
+- break;
++ } else {
++ switch (skb->data[0] & 0xe0) {
++ case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
++ case LOWPAN_DISPATCH_FRAG1: /* first fragment header */
++ case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */
++ local_skb = skb_clone(skb, GFP_ATOMIC);
++ if (!local_skb)
++ goto drop;
++ lowpan_process_data(local_skb);
++
++ kfree_skb(skb);
++ break;
++ default:
++ break;
++ }
+ }
+
+ return NET_RX_SUCCESS;
diff --git a/patches/linux-3.8.13/0166-wpan-whitespace-fix.patch b/patches/linux-3.8.13/0166-wpan-whitespace-fix.patch
new file mode 100644
index 0000000..9a63bbb
--- /dev/null
+++ b/patches/linux-3.8.13/0166-wpan-whitespace-fix.patch
@@ -0,0 +1,23 @@
+From: Alexander Aring <alex.aring@gmail.com>
+Date: Tue, 5 Feb 2013 04:25:35 +0000
+Subject: [PATCH] wpan: whitespace fix
+
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ net/mac802154/wpan.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c
+index 199b922..98c867b 100644
+--- a/net/mac802154/wpan.c
++++ b/net/mac802154/wpan.c
+@@ -41,7 +41,7 @@ static inline int mac802154_fetch_skb_u8(struct sk_buff *skb, u8 *val)
+ return -EINVAL;
+
+ *val = skb->data[0];
+- skb_pull(skb, 1);
++ skb_pull(skb, 1);
+
+ return 0;
+ }
diff --git a/patches/linux-3.8.13/0167-6lowpan-use-stack-buffer-instead-of-heap.patch b/patches/linux-3.8.13/0167-6lowpan-use-stack-buffer-instead-of-heap.patch
new file mode 100644
index 0000000..d02957c
--- /dev/null
+++ b/patches/linux-3.8.13/0167-6lowpan-use-stack-buffer-instead-of-heap.patch
@@ -0,0 +1,50 @@
+From: Alexander Aring <alex.aring@gmail.com>
+Date: Tue, 5 Feb 2013 10:23:43 +0000
+Subject: [PATCH] 6lowpan: use stack buffer instead of heap
+
+head buffer is only temporary available in lowpan_header_create.
+So it's not necessary to put it on the heap.
+
+Also fixed a comment codestyle issue.
+
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ net/ieee802154/6lowpan.c | 13 ++++---------
+ 1 file changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
+index f62c3b9..43b95ca 100644
+--- a/net/ieee802154/6lowpan.c
++++ b/net/ieee802154/6lowpan.c
+@@ -377,17 +377,14 @@ static int lowpan_header_create(struct sk_buff *skb,
+ struct ipv6hdr *hdr;
+ const u8 *saddr = _saddr;
+ const u8 *daddr = _daddr;
+- u8 *head;
++ u8 head[100];
+ struct ieee802154_addr sa, da;
+
++ /* TODO:
++ * if this package isn't ipv6 one, where should it be routed?
++ */
+ if (type != ETH_P_IPV6)
+ return 0;
+- /* TODO:
+- * if this package isn't ipv6 one, where should it be routed?
+- */
+- head = kzalloc(100, GFP_KERNEL);
+- if (head == NULL)
+- return -ENOMEM;
+
+ hdr = ipv6_hdr(skb);
+ hc06_ptr = head + 2;
+@@ -561,8 +558,6 @@ static int lowpan_header_create(struct sk_buff *skb,
+ skb_pull(skb, sizeof(struct ipv6hdr));
+ memcpy(skb_push(skb, hc06_ptr - head), head, hc06_ptr - head);
+
+- kfree(head);
+-
+ lowpan_raw_dump_table(__func__, "raw skb data dump", skb->data,
+ skb->len);
+
diff --git a/patches/linux-3.8.13/0168-wpan-use-stack-buffer-instead-of-heap.patch b/patches/linux-3.8.13/0168-wpan-use-stack-buffer-instead-of-heap.patch
new file mode 100644
index 0000000..658ca85
--- /dev/null
+++ b/patches/linux-3.8.13/0168-wpan-use-stack-buffer-instead-of-heap.patch
@@ -0,0 +1,43 @@
+From: Alexander Aring <alex.aring@gmail.com>
+Date: Tue, 5 Feb 2013 10:23:44 +0000
+Subject: [PATCH] wpan: use stack buffer instead of heap
+
+head buffer is only temporary available in mac802154_header_create.
+So it's not necessary to put it on the heap.
+
+Signed-off-by: Alexander Aring <alex.aring@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ net/mac802154/wpan.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c
+index 98c867b..d20c6d3 100644
+--- a/net/mac802154/wpan.c
++++ b/net/mac802154/wpan.c
+@@ -137,16 +137,12 @@ static int mac802154_header_create(struct sk_buff *skb,
+ struct ieee802154_addr dev_addr;
+ struct mac802154_sub_if_data *priv = netdev_priv(dev);
+ int pos = 2;
+- u8 *head;
++ u8 head[MAC802154_FRAME_HARD_HEADER_LEN];
+ u16 fc;
+
+ if (!daddr)
+ return -EINVAL;
+
+- head = kzalloc(MAC802154_FRAME_HARD_HEADER_LEN, GFP_KERNEL);
+- if (head == NULL)
+- return -ENOMEM;
+-
+ head[pos++] = mac_cb(skb)->seq; /* DSN/BSN */
+ fc = mac_cb_type(skb);
+
+@@ -210,7 +206,6 @@ static int mac802154_header_create(struct sk_buff *skb,
+ head[1] = fc >> 8;
+
+ memcpy(skb_push(skb, pos), head, pos);
+- kfree(head);
+
+ return pos;
+ }
diff --git a/patches/linux-3.8.13/0169-mrf24j40-pinctrl-support.patch b/patches/linux-3.8.13/0169-mrf24j40-pinctrl-support.patch
new file mode 100644
index 0000000..1d23e02
--- /dev/null
+++ b/patches/linux-3.8.13/0169-mrf24j40-pinctrl-support.patch
@@ -0,0 +1,43 @@
+From: Alan Ott <alan@signal11.us>
+Date: Mon, 18 Mar 2013 00:39:48 -0400
+Subject: [PATCH] mrf24j40: pinctrl support
+
+Activate pinctrl settings when used with a DT system.
+
+Signed-off-by: Alan Ott <alan@signal11.us>
+---
+ drivers/net/ieee802154/mrf24j40.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c
+index 3f2c7aa..3106895 100644
+--- a/drivers/net/ieee802154/mrf24j40.c
++++ b/drivers/net/ieee802154/mrf24j40.c
+@@ -22,6 +22,7 @@
+ #include <linux/spi/spi.h>
+ #include <linux/interrupt.h>
+ #include <linux/module.h>
++#include <linux/pinctrl/consumer.h>
+ #include <net/wpan-phy.h>
+ #include <net/mac802154.h>
+
+@@ -623,6 +624,7 @@ static int mrf24j40_probe(struct spi_device *spi)
+ int ret = -ENOMEM;
+ u8 val;
+ struct mrf24j40 *devrec;
++ struct pinctrl *pinctrl;
+
+ printk(KERN_INFO "mrf24j40: probe(). IRQ: %d\n", spi->irq);
+
+@@ -633,6 +635,11 @@ static int mrf24j40_probe(struct spi_device *spi)
+ if (!devrec->buf)
+ goto err_buf;
+
++ pinctrl = devm_pinctrl_get_select_default(&spi->dev);
++ if (IS_ERR(pinctrl))
++ dev_warn(&spi->dev,
++ "pinctrl pins are not configured from the driver");
++
+ spi->mode = SPI_MODE_0; /* TODO: Is this appropriate for right here? */
+ if (spi->max_speed_hz > MAX_SPI_SPEED_HZ)
+ spi->max_speed_hz = MAX_SPI_SPEED_HZ;
diff --git a/patches/linux-3.8.13/0170-mrf24j40-Warn-if-transmit-interrupts-timeout.patch b/patches/linux-3.8.13/0170-mrf24j40-Warn-if-transmit-interrupts-timeout.patch
new file mode 100644
index 0000000..0d03705
--- /dev/null
+++ b/patches/linux-3.8.13/0170-mrf24j40-Warn-if-transmit-interrupts-timeout.patch
@@ -0,0 +1,23 @@
+From: Alan Ott <alan@signal11.us>
+Date: Mon, 18 Mar 2013 00:49:02 -0400
+Subject: [PATCH] mrf24j40: Warn if transmit interrupts timeout
+
+Issue a warning if a transmit complete interrupt doesn't happen in time.
+
+Signed-off-by: Alan Ott <alan@signal11.us>
+---
+ drivers/net/ieee802154/mrf24j40.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c
+index 3106895..bb7e613 100644
+--- a/drivers/net/ieee802154/mrf24j40.c
++++ b/drivers/net/ieee802154/mrf24j40.c
+@@ -363,6 +363,7 @@ static int mrf24j40_tx(struct ieee802154_dev *dev, struct sk_buff *skb)
+ goto err;
+ if (ret == 0) {
+ ret = -ETIMEDOUT;
++ dev_warn(printdev(devrec), "Timeout waiting for TX interrupt\n");
+ goto err;
+ }
+
diff --git a/patches/linux-3.8.13/0171-mrf24j40-Increase-max-SPI-speed-to-10MHz.patch b/patches/linux-3.8.13/0171-mrf24j40-Increase-max-SPI-speed-to-10MHz.patch
new file mode 100644
index 0000000..54fa7a6
--- /dev/null
+++ b/patches/linux-3.8.13/0171-mrf24j40-Increase-max-SPI-speed-to-10MHz.patch
@@ -0,0 +1,28 @@
+From: Alan Ott <alan@signal11.us>
+Date: Mon, 18 Mar 2013 01:17:05 -0400
+Subject: [PATCH] mrf24j40: Increase max SPI speed to 10MHz
+
+Upon consulting the datasheet further, it does indicates a maximum speed
+for SCK at 10MHz.
+
+Signed-off-by: Alan Ott <alan@signal11.us>
+---
+ drivers/net/ieee802154/mrf24j40.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c
+index bb7e613..f6e723e 100644
+--- a/drivers/net/ieee802154/mrf24j40.c
++++ b/drivers/net/ieee802154/mrf24j40.c
+@@ -92,9 +92,8 @@ struct mrf24j40 {
+ #define MRF24J40_READLONG(reg) (1 << 15 | (reg) << 5)
+ #define MRF24J40_WRITELONG(reg) (1 << 15 | (reg) << 5 | 1 << 4)
+
+-/* Maximum speed to run the device at. TODO: Get the real max value from
+- * someone at Microchip since it isn't in the datasheet. */
+-#define MAX_SPI_SPEED_HZ 1000000
++/* The datasheet indicates the theoretical maximum for SCK to be 10MHz */
++#define MAX_SPI_SPEED_HZ 10000000
+
+ #define printdev(X) (&X->spi->dev)
+
diff --git a/patches/linux-3.8.13/0172-mrf24j40-Fix-byte-order-of-IEEE-address.patch b/patches/linux-3.8.13/0172-mrf24j40-Fix-byte-order-of-IEEE-address.patch
new file mode 100644
index 0000000..1d79313
--- /dev/null
+++ b/patches/linux-3.8.13/0172-mrf24j40-Fix-byte-order-of-IEEE-address.patch
@@ -0,0 +1,25 @@
+From: Alan Ott <alan@signal11.us>
+Date: Mon, 18 Mar 2013 01:26:01 -0400
+Subject: [PATCH] mrf24j40: Fix byte-order of IEEE address
+
+Load the 64-bit Extended (IEEE) address into the hardware in the proper
+byte order.
+
+Signed-off-by: Alan Ott <alan@signal11.us>
+---
+ drivers/net/ieee802154/mrf24j40.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c
+index f6e723e..6481faf 100644
+--- a/drivers/net/ieee802154/mrf24j40.c
++++ b/drivers/net/ieee802154/mrf24j40.c
+@@ -478,7 +478,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev,
+ int i;
+ for (i = 0; i < 8; i++)
+ write_short_reg(devrec, REG_EADR0+i,
+- filt->ieee_addr[i]);
++ filt->ieee_addr[7-i]);
+
+ #ifdef DEBUG
+ printk(KERN_DEBUG "Set long addr to: ");
diff --git a/patches/linux-3.8.4/0154-6lowpan-lowpan_is_iid_16_bit_compressable-does-not-d.patch b/patches/linux-3.8.13/0173-6lowpan-lowpan_is_iid_16_bit_compressable-does-not-d.patch
index a5b8b92..7448343 100644
--- a/patches/linux-3.8.4/0154-6lowpan-lowpan_is_iid_16_bit_compressable-does-not-d.patch
+++ b/patches/linux-3.8.13/0173-6lowpan-lowpan_is_iid_16_bit_compressable-does-not-d.patch
@@ -1,30 +1,22 @@
From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Mon, 25 Jun 2012 19:45:33 +0000
+Date: Mon, 25 Mar 2013 23:59:21 -0400
Subject: [PATCH] 6lowpan: lowpan_is_iid_16_bit_compressable() does not detect
- compressable address correctly
+ compressible address correctly
The current test is not RFC6282 compliant. The same issue has been found
-out and fixed in Contiki. This patch is basicaly a port of their fix.
+and fixed in Contiki. This patch is basically a port of their fix.
Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
---
- net/ieee802154/6lowpan.h | 14 ++++++++------
- 1 file changed, 8 insertions(+), 6 deletions(-)
+ net/ieee802154/6lowpan.h | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/ieee802154/6lowpan.h b/net/ieee802154/6lowpan.h
-index bba5f83..8f421a8 100644
+index bba5f83..4b8f917 100644
--- a/net/ieee802154/6lowpan.h
+++ b/net/ieee802154/6lowpan.h
-@@ -87,14 +87,16 @@
- #define is_addr_link_local(a) (((a)->s6_addr16[0]) == htons(0xFE80))
-
- /*
-- * check whether we can compress the IID to 16 bits,
-- * it's possible for unicast adresses with first 49 bits are zero only.
-- */
-+* check whether we can compress the IID to 16 bits,
-+* it's possible for unicast adresses with first 49 bits are zero only.
-+*/
+@@ -92,9 +92,10 @@
+ */
#define lowpan_is_iid_16_bit_compressable(a) \
((((a)->s6_addr16[4]) == 0) && \
- (((a)->s6_addr16[5]) == 0) && \
@@ -34,7 +26,6 @@ index bba5f83..8f421a8 100644
+ (((a)->s6_addr[11]) == 0xff) && \
+ (((a)->s6_addr[12]) == 0xfe) && \
+ (((a)->s6_addr[13]) == 0))
-+
/* multicast address */
#define is_addr_mcast(a) (((a)->s6_addr[0]) == 0xFF)
diff --git a/patches/linux-3.8.4/0155-6lowpan-next-header-is-not-properly-set-upon-decompr.patch b/patches/linux-3.8.13/0174-6lowpan-next-header-is-not-properly-set-upon-decompr.patch
index 2595289..cfe24ef 100644
--- a/patches/linux-3.8.4/0155-6lowpan-next-header-is-not-properly-set-upon-decompr.patch
+++ b/patches/linux-3.8.13/0174-6lowpan-next-header-is-not-properly-set-upon-decompr.patch
@@ -1,5 +1,5 @@
From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Mon, 25 Jun 2012 19:45:45 +0000
+Date: Mon, 25 Mar 2013 23:59:22 -0400
Subject: [PATCH] 6lowpan: next header is not properly set upon decompression
of a UDP header.
@@ -7,14 +7,14 @@ This causes a drop of the UDP packet.
Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
---
- net/ieee802154/6lowpan.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
+ net/ieee802154/6lowpan.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
-index 76c3d0a..e77e455 100644
+index 43b95ca..9f53904 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
-@@ -913,9 +913,12 @@ lowpan_process_data(struct sk_buff *skb)
+@@ -918,9 +918,11 @@ lowpan_process_data(struct sk_buff *skb)
}
/* UDP data uncompression */
@@ -24,7 +24,6 @@ index 76c3d0a..e77e455 100644
goto drop;
+ hdr.nexthdr = UIP_PROTO_UDP;
+ }
-+
/* Not fragmented package */
hdr.payload_len = htons(skb->len);
diff --git a/patches/linux-3.8.4/0156-6lowpan-always-enable-link-layer-acknowledgments.patch b/patches/linux-3.8.13/0175-6lowpan-always-enable-link-layer-acknowledgments.patch
index ff43ead..989bd60 100644
--- a/patches/linux-3.8.4/0156-6lowpan-always-enable-link-layer-acknowledgments.patch
+++ b/patches/linux-3.8.13/0175-6lowpan-always-enable-link-layer-acknowledgments.patch
@@ -1,12 +1,12 @@
From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Mon, 25 Jun 2012 19:48:12 +0000
+Date: Mon, 25 Mar 2013 23:59:23 -0400
Subject: [PATCH] 6lowpan: always enable link-layer acknowledgments
This feature is especially important when using fragmentation, because
-the reassembly mechanism can not recover from the loss of a fragment.
+the reassembly mechanism cannot recover from the loss of a fragment.
-Note that some hardware ignore this flag and not will not transmit any
-acknowledgments if this is set.
+Note that some hardware ignore this flag and not will not transmit
+acknowledgments even if this is set.
Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
---
@@ -14,10 +14,10 @@ Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
1 file changed, 4 insertions(+)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
-index e77e455..fee0d82 100644
+index 9f53904..e7f61de 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
-@@ -589,6 +589,10 @@ static int lowpan_header_create(struct sk_buff *skb,
+@@ -584,6 +584,10 @@ static int lowpan_header_create(struct sk_buff *skb,
mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA;
diff --git a/patches/linux-3.8.4/0157-mac802154-turn-on-ACK-when-enabled-by-the-upper-laye.patch b/patches/linux-3.8.13/0176-mac802154-turn-on-ACK-when-enabled-by-the-upper-laye.patch
index 0e3a6af..a96b6ef 100644
--- a/patches/linux-3.8.4/0157-mac802154-turn-on-ACK-when-enabled-by-the-upper-laye.patch
+++ b/patches/linux-3.8.13/0176-mac802154-turn-on-ACK-when-enabled-by-the-upper-laye.patch
@@ -1,5 +1,5 @@
From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Tue, 17 Jul 2012 17:59:39 -0400
+Date: Mon, 25 Mar 2013 23:59:24 -0400
Subject: [PATCH] mac802154: turn on ACK when enabled by the upper layers
Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
@@ -8,10 +8,10 @@ Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
1 file changed, 2 insertions(+)
diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c
-index 199b922..fdf482a 100644
+index d20c6d3..7d3f659 100644
--- a/net/mac802154/wpan.c
+++ b/net/mac802154/wpan.c
-@@ -149,6 +149,8 @@ static int mac802154_header_create(struct sk_buff *skb,
+@@ -145,6 +145,8 @@ static int mac802154_header_create(struct sk_buff *skb,
head[pos++] = mac_cb(skb)->seq; /* DSN/BSN */
fc = mac_cb_type(skb);
diff --git a/patches/linux-3.8.4/0158-6lowpan-use-short-IEEE-802.15.4-addresses-for-broadc.patch b/patches/linux-3.8.13/0177-6lowpan-use-short-IEEE-802.15.4-addresses-for-broadc.patch
index a3ce13b..5e832d8 100644
--- a/patches/linux-3.8.4/0158-6lowpan-use-short-IEEE-802.15.4-addresses-for-broadc.patch
+++ b/patches/linux-3.8.13/0177-6lowpan-use-short-IEEE-802.15.4-addresses-for-broadc.patch
@@ -1,21 +1,21 @@
From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Tue, 4 Sep 2012 23:48:13 -0400
+Date: Mon, 25 Mar 2013 23:59:25 -0400
Subject: [PATCH] 6lowpan: use short IEEE 802.15.4 addresses for broadcast
destination
-It is intended that the IEEE 802.15.4 standard uses the 0xFFFF short address (2
-bytes) for message broadcasting.
+The IEEE 802.15.4 standard uses the 0xFFFF short address (2 bytes) for message
+broadcasting.
Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
---
- net/ieee802154/6lowpan.c | 21 +++++++++++++--------
- 1 file changed, 13 insertions(+), 8 deletions(-)
+ net/ieee802154/6lowpan.c | 23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
-index fee0d82..b4d8588 100644
+index e7f61de..0eebb96 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
-@@ -577,21 +577,26 @@ static int lowpan_header_create(struct sk_buff *skb,
+@@ -572,21 +572,28 @@ static int lowpan_header_create(struct sk_buff *skb,
* this isn't implemented in mainline yet, so currently we assign 0xff
*/
{
@@ -33,8 +33,10 @@ index fee0d82..b4d8588 100644
- mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA;
+ da.pan_id = 0xff;
-+ /* if the destination address is the broadcast address,
-+ use short address */
++ /*
++ * if the destination address is the broadcast address, use the
++ * corresponding short address
++ */
+ if (lowpan_is_addr_broadcast(daddr)) {
+ da.addr_type = IEEE802154_ADDR_SHORT;
+ da.short_addr = IEEE802154_ADDR_BROADCAST;
diff --git a/patches/linux-3.8.4/0159-6lowpan-fix-first-fragment-FRAG1-handling.patch b/patches/linux-3.8.13/0178-6lowpan-fix-first-fragment-FRAG1-handling.patch
index c2777bc..cbc0d86 100644
--- a/patches/linux-3.8.4/0159-6lowpan-fix-first-fragment-FRAG1-handling.patch
+++ b/patches/linux-3.8.13/0178-6lowpan-fix-first-fragment-FRAG1-handling.patch
@@ -1,25 +1,31 @@
From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Sat, 8 Sep 2012 00:15:54 -0400
+Date: Mon, 25 Mar 2013 23:59:26 -0400
Subject: [PATCH] 6lowpan: fix first fragment (FRAG1) handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
The first fragment, FRAG1, must contain some payload according to the
specs. However, as it is currently written, the first fragment will
remain empty and only contain the 6lowpan headers.
-This patch also extract the transport layer information from the first
-fragment. This information is later on use when uncompressing UDP
+This patch also extracts the transport layer information from the first
+fragment. This information is used later on when uncompressing UDP
header.
+Thanks to Wolf-Bastian Pöttner for noticing that the offset value was
+not properly initialized.
+
Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
---
- net/ieee802154/6lowpan.c | 54 +++++++++++++++++++++++++++++++++++-----------
- 1 file changed, 42 insertions(+), 12 deletions(-)
+ net/ieee802154/6lowpan.c | 36 +++++++++++++++++++++++-------------
+ 1 file changed, 23 insertions(+), 13 deletions(-)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
-index b4d8588..7bd8c67 100644
+index 0eebb96..4a62289 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
-@@ -654,7 +654,7 @@ static void lowpan_fragment_timer_expired(unsigned long entry_addr)
+@@ -661,7 +661,7 @@ static void lowpan_fragment_timer_expired(unsigned long entry_addr)
}
static struct lowpan_fragment *
@@ -28,33 +34,29 @@ index b4d8588..7bd8c67 100644
{
struct lowpan_fragment *frame;
-@@ -735,6 +735,18 @@ lowpan_process_data(struct sk_buff *skb)
+@@ -731,7 +731,7 @@ lowpan_process_data(struct sk_buff *skb)
+ {
+ struct lowpan_fragment *frame;
+ /* slen stores the rightmost 8 bits of the 11 bits length */
+- u8 slen, offset;
++ u8 slen, offset = 0;
+ u16 len, tag;
+ bool found = false;
+
+@@ -742,6 +742,12 @@ lowpan_process_data(struct sk_buff *skb)
/* adds the 3 MSB to the 8 LSB to retrieve the 11 bits length */
len = ((iphc0 & 7) << 8) | slen;
-+ if ((iphc0 & LOWPAN_DISPATCH_MASK) == LOWPAN_DISPATCH_FRAG1) {
-+ pr_debug("%s received a FRAG1 packet (tag: %d, "
-+ "size of the entire IP packet: %d)"
-+ , __func__, tag, len);
-+ } else { /* FRAGN */
++ /* FRAGN */
++ if ((iphc0 & LOWPAN_DISPATCH_MASK) != LOWPAN_DISPATCH_FRAG1) {
+ if (lowpan_fetch_skb_u8(skb, &offset))
+ goto unlock_and_drop;
-+ pr_debug("%s received a FRAGN packet (tag: %d, "
-+ "size of the entire IP packet: %d, "
-+ "offset: %d)", __func__, tag, len, offset * 8);
+ }
+
/*
* check if frame assembling with the same tag is
* already in progress
-@@ -749,17 +761,13 @@ lowpan_process_data(struct sk_buff *skb)
-
- /* alloc new frame structure */
- if (!found) {
-+ pr_debug("%s first fragment received for tag %d, "
-+ "begin packet reassembly", __func__, tag);
- frame = lowpan_alloc_new_frame(skb, len, tag);
- if (!frame)
+@@ -761,12 +767,6 @@ lowpan_process_data(struct sk_buff *skb)
goto unlock_and_drop;
}
@@ -67,18 +69,7 @@ index b4d8588..7bd8c67 100644
/* if payload fits buffer, copy it */
if (likely((offset * 8 + skb->len) <= frame->length))
skb_copy_to_linear_data_offset(frame->skb, offset * 8,
-@@ -777,6 +785,10 @@ lowpan_process_data(struct sk_buff *skb)
- list_del(&frame->list);
- spin_unlock_bh(&flist_lock);
-
-+ pr_debug("%s successfully reassembled fragment "
-+ "(tag %d)", __func__, tag);
-+
-+
- dev_kfree_skb(skb);
- skb = frame->skb;
- kfree(frame);
-@@ -976,13 +988,13 @@ static int lowpan_get_mac_header_length(struct sk_buff *skb)
+@@ -982,13 +982,13 @@ static int lowpan_get_mac_header_length(struct sk_buff *skb)
static int
lowpan_fragment_xmit(struct sk_buff *skb, u8 *head,
@@ -90,12 +81,12 @@ index b4d8588..7bd8c67 100644
- /* if payload length is zero, therefore it's a first fragment */
- hlen = (plen == 0 ? LOWPAN_FRAG1_HEAD_SIZE : LOWPAN_FRAGN_HEAD_SIZE);
-+ hlen = (type == LOWPAN_DISPATCH_FRAG1 ? LOWPAN_FRAG1_HEAD_SIZE :
-+ LOWPAN_FRAGN_HEAD_SIZE);
++ hlen = (type == LOWPAN_DISPATCH_FRAG1) ?
++ LOWPAN_FRAG1_HEAD_SIZE : LOWPAN_FRAGN_HEAD_SIZE;
lowpan_raw_dump_inline(__func__, "6lowpan fragment header", head, hlen);
-@@ -1025,7 +1037,18 @@ lowpan_skb_fragmentation(struct sk_buff *skb)
+@@ -1031,7 +1031,13 @@ lowpan_skb_fragmentation(struct sk_buff *skb)
head[2] = tag >> 8;
head[3] = tag & 0xff;
@@ -103,29 +94,21 @@ index b4d8588..7bd8c67 100644
+ err = lowpan_fragment_xmit(skb, head, header_length, LOWPAN_FRAG_SIZE,
+ 0, LOWPAN_DISPATCH_FRAG1);
+
-+ if (err) {
-+#if DEBUG
-+ pr_debug("%s unable to send FRAG1 packet (tag: %d)",
-+ __func__, tag);
-+#endif /* DEBUG */
++ if (err)
+ goto exit;
-+ }
+
+ offset = LOWPAN_FRAG_SIZE;
/* next fragment header */
head[0] &= ~LOWPAN_DISPATCH_FRAG1;
-@@ -1040,10 +1063,17 @@ lowpan_skb_fragmentation(struct sk_buff *skb)
+@@ -1046,10 +1052,14 @@ lowpan_skb_fragmentation(struct sk_buff *skb)
len = payload_length - offset;
err = lowpan_fragment_xmit(skb, head, header_length,
- len, offset);
+ len, offset, LOWPAN_DISPATCH_FRAGN);
-+ if (err) {
-+ pr_debug("%s unable to send a subsequent FRAGN packet "
-+ "(tag: %d, offset: %d", __func__, tag, offset);
++ if (err)
+ goto exit;
-+ }
+
offset += len;
}
diff --git a/patches/linux-3.8.13/0179-6lowpan-add-debug-messages-for-6LoWPAN-fragmentation.patch b/patches/linux-3.8.13/0179-6lowpan-add-debug-messages-for-6LoWPAN-fragmentation.patch
new file mode 100644
index 0000000..06e0a71
--- /dev/null
+++ b/patches/linux-3.8.13/0179-6lowpan-add-debug-messages-for-6LoWPAN-fragmentation.patch
@@ -0,0 +1,80 @@
+From: Tony Cheneau <tony.cheneau@amnesiak.org>
+Date: Mon, 25 Mar 2013 23:59:27 -0400
+Subject: [PATCH] 6lowpan: add debug messages for 6LoWPAN fragmentation
+
+Add pr_debug() call in order to debug 6LoWPAN fragmentation and
+reassembly.
+
+Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
+---
+ net/ieee802154/6lowpan.c | 25 +++++++++++++++++++++----
+ 1 file changed, 21 insertions(+), 4 deletions(-)
+
+diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
+index 4a62289..61eee9d 100644
+--- a/net/ieee802154/6lowpan.c
++++ b/net/ieee802154/6lowpan.c
+@@ -742,10 +742,16 @@ lowpan_process_data(struct sk_buff *skb)
+ /* adds the 3 MSB to the 8 LSB to retrieve the 11 bits length */
+ len = ((iphc0 & 7) << 8) | slen;
+
+- /* FRAGN */
+- if ((iphc0 & LOWPAN_DISPATCH_MASK) != LOWPAN_DISPATCH_FRAG1) {
++ if ((iphc0 & LOWPAN_DISPATCH_MASK) == LOWPAN_DISPATCH_FRAG1) {
++ pr_debug("%s received a FRAG1 packet (tag: %d, "
++ "size of the entire IP packet: %d)",
++ __func__, tag, len);
++ } else { /* FRAGN */
+ if (lowpan_fetch_skb_u8(skb, &offset))
+ goto unlock_and_drop;
++ pr_debug("%s received a FRAGN packet (tag: %d, "
++ "size of the entire IP packet: %d, "
++ "offset: %d)", __func__, tag, len, offset * 8);
+ }
+
+ /*
+@@ -762,6 +768,8 @@ lowpan_process_data(struct sk_buff *skb)
+
+ /* alloc new frame structure */
+ if (!found) {
++ pr_debug("%s first fragment received for tag %d, "
++ "begin packet reassembly", __func__, tag);
+ frame = lowpan_alloc_new_frame(skb, len, tag);
+ if (!frame)
+ goto unlock_and_drop;
+@@ -784,6 +792,9 @@ lowpan_process_data(struct sk_buff *skb)
+ list_del(&frame->list);
+ spin_unlock_bh(&flist_lock);
+
++ pr_debug("%s successfully reassembled fragment "
++ "(tag %d)", __func__, tag);
++
+ dev_kfree_skb(skb);
+ skb = frame->skb;
+ kfree(frame);
+@@ -1034,8 +1045,11 @@ lowpan_skb_fragmentation(struct sk_buff *skb)
+ err = lowpan_fragment_xmit(skb, head, header_length, LOWPAN_FRAG_SIZE,
+ 0, LOWPAN_DISPATCH_FRAG1);
+
+- if (err)
++ if (err) {
++ pr_debug("%s unable to send FRAG1 packet (tag: %d)",
++ __func__, tag);
+ goto exit;
++ }
+
+ offset = LOWPAN_FRAG_SIZE;
+
+@@ -1053,8 +1067,11 @@ lowpan_skb_fragmentation(struct sk_buff *skb)
+
+ err = lowpan_fragment_xmit(skb, head, header_length,
+ len, offset, LOWPAN_DISPATCH_FRAGN);
+- if (err)
++ if (err) {
++ pr_debug("%s unable to send a subsequent FRAGN packet "
++ "(tag: %d, offset: %d", __func__, tag, offset);
+ goto exit;
++ }
+
+ offset += len;
+ }
diff --git a/patches/linux-3.8.4/0160-6lowpan-store-fragment-tag-values-per-device-instead.patch b/patches/linux-3.8.13/0180-6lowpan-store-fragment-tag-values-per-device-instead.patch
index 9f0a29a..5248522 100644
--- a/patches/linux-3.8.4/0160-6lowpan-store-fragment-tag-values-per-device-instead.patch
+++ b/patches/linux-3.8.13/0180-6lowpan-store-fragment-tag-values-per-device-instead.patch
@@ -1,5 +1,5 @@
From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Fri, 6 Jul 2012 17:39:22 -0400
+Date: Mon, 25 Mar 2013 23:59:28 -0400
Subject: [PATCH] 6lowpan: store fragment tag values per device instead of net
stack wide
@@ -9,7 +9,7 @@ Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
-index 7bd8c67..fc62906 100644
+index 61eee9d..f952451 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -104,6 +104,7 @@ static const u8 lowpan_llprefix[] = {0xfe, 0x80};
@@ -28,7 +28,7 @@ index 7bd8c67..fc62906 100644
static LIST_HEAD(lowpan_fragments);
static DEFINE_SPINLOCK(flist_lock);
-@@ -1022,14 +1022,14 @@ lowpan_fragment_xmit(struct sk_buff *skb, u8 *head,
+@@ -1027,14 +1027,14 @@ lowpan_fragment_xmit(struct sk_buff *skb, u8 *head,
}
static int
@@ -45,7 +45,7 @@ index 7bd8c67..fc62906 100644
/* first fragment header */
head[0] = LOWPAN_DISPATCH_FRAG1 | ((payload_length >> 8) & 0x7);
-@@ -1096,7 +1096,7 @@ static netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev)
+@@ -1099,7 +1099,7 @@ static netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev)
}
pr_debug("frame is too big, fragmentation is needed\n");
@@ -54,7 +54,7 @@ index 7bd8c67..fc62906 100644
error:
dev_kfree_skb(skb);
out:
-@@ -1217,6 +1217,7 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev,
+@@ -1243,6 +1243,7 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev,
return -ENODEV;
lowpan_dev_info(dev)->real_dev = real_dev;
diff --git a/patches/linux-3.8.13/0181-mac802154-add-mac802154_dev_get_dsn.patch b/patches/linux-3.8.13/0181-mac802154-add-mac802154_dev_get_dsn.patch
new file mode 100644
index 0000000..e1c8c23
--- /dev/null
+++ b/patches/linux-3.8.13/0181-mac802154-add-mac802154_dev_get_dsn.patch
@@ -0,0 +1,57 @@
+From: Tony Cheneau <tony.cheneau@amnesiak.org>
+Date: Mon, 25 Mar 2013 23:59:29 -0400
+Subject: [PATCH] mac802154: add mac802154_dev_get_dsn()
+
+Bring-over mac802154_dev_get_dsn() function that was present in the
+Linux ZigBee kernel. This function is called by the 6LoWPAN code in
+order to properly set the DSN (Data Sequence Number) value in the IEEE
+802.15.4 frame.
+
+Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
+---
+ net/mac802154/mac802154.h | 1 +
+ net/mac802154/mac_cmd.c | 1 +
+ net/mac802154/mib.c | 9 +++++++++
+ 3 files changed, 11 insertions(+)
+
+diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h
+index a4dcaf1..21fa386 100644
+--- a/net/mac802154/mac802154.h
++++ b/net/mac802154/mac802154.h
+@@ -114,5 +114,6 @@ void mac802154_dev_set_ieee_addr(struct net_device *dev);
+ u16 mac802154_dev_get_pan_id(const struct net_device *dev);
+ void mac802154_dev_set_pan_id(struct net_device *dev, u16 val);
+ void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan);
++u8 mac802154_dev_get_dsn(const struct net_device *dev);
+
+ #endif /* MAC802154_H */
+diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c
+index d8d2770..a99910d 100644
+--- a/net/mac802154/mac_cmd.c
++++ b/net/mac802154/mac_cmd.c
+@@ -73,4 +73,5 @@ struct ieee802154_mlme_ops mac802154_mlme_wpan = {
+ .start_req = mac802154_mlme_start_req,
+ .get_pan_id = mac802154_dev_get_pan_id,
+ .get_short_addr = mac802154_dev_get_short_addr,
++ .get_dsn = mac802154_dev_get_dsn,
+ };
+diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c
+index f47781a..f03e55f 100644
+--- a/net/mac802154/mib.c
++++ b/net/mac802154/mib.c
+@@ -159,6 +159,15 @@ void mac802154_dev_set_pan_id(struct net_device *dev, u16 val)
+ }
+ }
+
++u8 mac802154_dev_get_dsn(const struct net_device *dev)
++{
++ struct mac802154_sub_if_data *priv = netdev_priv(dev);
++
++ BUG_ON(dev->type != ARPHRD_IEEE802154);
++
++ return priv->dsn++;
++}
++
+ static void phy_chan_notify(struct work_struct *work)
+ {
+ struct phy_chan_notify_work *nw = container_of(work,
diff --git a/patches/linux-3.8.4/0161-6lowpan-obtain-IEEE802.15.4-sequence-number-from-the.patch b/patches/linux-3.8.13/0182-6lowpan-obtain-IEEE802.15.4-sequence-number-from-the.patch
index b8fd87a..ac3a3a3 100644
--- a/patches/linux-3.8.4/0161-6lowpan-obtain-IEEE802.15.4-sequence-number-from-the.patch
+++ b/patches/linux-3.8.13/0182-6lowpan-obtain-IEEE802.15.4-sequence-number-from-the.patch
@@ -1,11 +1,10 @@
From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Fri, 6 Jul 2012 17:46:37 -0400
+Date: Mon, 25 Mar 2013 23:59:30 -0400
Subject: [PATCH] 6lowpan: obtain IEEE802.15.4 sequence number from the MAC
layer
-This patch sets the sequence number in the frame format. Without this
-fix, the sequence number is always set to 0. This makes trafic analysis
-very hard.
+Sets the sequence number in the frame format. Without this fix, the sequence
+number is always set to 0. This makes trafic analysis very hard.
Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
---
@@ -13,10 +12,10 @@ Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
1 file changed, 8 insertions(+)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
-index fc62906..665ddcf 100644
+index f952451..d1d4ee6 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
-@@ -578,6 +578,7 @@ static int lowpan_header_create(struct sk_buff *skb,
+@@ -573,6 +573,7 @@ static int lowpan_header_create(struct sk_buff *skb,
*/
{
mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA;
@@ -24,7 +23,7 @@ index fc62906..665ddcf 100644
/* prepare wpan address data */
sa.addr_type = IEEE802154_ADDR_LONG;
-@@ -1124,6 +1125,12 @@ static u16 lowpan_get_short_addr(const struct net_device *dev)
+@@ -1127,6 +1128,12 @@ static u16 lowpan_get_short_addr(const struct net_device *dev)
return ieee802154_mlme_ops(real_dev)->get_short_addr(real_dev);
}
@@ -37,7 +36,7 @@ index fc62906..665ddcf 100644
static struct header_ops lowpan_header_ops = {
.create = lowpan_header_create,
};
-@@ -1137,6 +1144,7 @@ static struct ieee802154_mlme_ops lowpan_mlme = {
+@@ -1140,6 +1147,7 @@ static struct ieee802154_mlme_ops lowpan_mlme = {
.get_pan_id = lowpan_get_pan_id,
.get_phy = lowpan_get_phy,
.get_short_addr = lowpan_get_short_addr,
diff --git a/patches/linux-3.8.4/0163-6lowpan-use-the-PANID-provided-by-the-device-instead.patch b/patches/linux-3.8.13/0183-6lowpan-use-the-PANID-provided-by-the-device-instead.patch
index 11bc025..c1b5f8e 100644
--- a/patches/linux-3.8.4/0163-6lowpan-use-the-PANID-provided-by-the-device-instead.patch
+++ b/patches/linux-3.8.13/0183-6lowpan-use-the-PANID-provided-by-the-device-instead.patch
@@ -1,5 +1,5 @@
From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Mon, 24 Sep 2012 23:11:46 -0400
+Date: Mon, 25 Mar 2013 23:59:31 -0400
Subject: [PATCH] 6lowpan: use the PANID provided by the device instead of a
static value
@@ -9,10 +9,10 @@ Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
-index a71452e..63dd8638 100644
+index d1d4ee6..276971b 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
-@@ -584,10 +584,12 @@ static int lowpan_header_create(struct sk_buff *skb,
+@@ -577,10 +577,12 @@ static int lowpan_header_create(struct sk_buff *skb,
/* prepare wpan address data */
sa.addr_type = IEEE802154_ADDR_LONG;
@@ -24,6 +24,6 @@ index a71452e..63dd8638 100644
+ da.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev);
- da.pan_id = 0xff;
- /* if the destination address is the broadcast address,
- use short address */
- if (lowpan_is_addr_broadcast(daddr)) {
+ /*
+ * if the destination address is the broadcast address, use the
+ * corresponding short address
diff --git a/patches/linux-3.8.4/0164-6lowpan-modify-udp-compression-uncompression-to-matc.patch b/patches/linux-3.8.13/0184-6lowpan-modify-udp-compression-uncompression-to-matc.patch
index 9c8cffc..2e1a8e7 100644
--- a/patches/linux-3.8.4/0164-6lowpan-modify-udp-compression-uncompression-to-matc.patch
+++ b/patches/linux-3.8.13/0184-6lowpan-modify-udp-compression-uncompression-to-matc.patch
@@ -1,5 +1,5 @@
From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Mon, 24 Sep 2012 22:56:51 -0400
+Date: Mon, 25 Mar 2013 23:59:32 -0400
Subject: [PATCH] 6lowpan: modify udp compression/uncompression to match the
standard
@@ -8,14 +8,14 @@ UDP header along with the uncompressed one.
Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
---
- net/ieee802154/6lowpan.c | 36 +++++++++++++++++++++++++++++++++---
- 1 file changed, 33 insertions(+), 3 deletions(-)
+ net/ieee802154/6lowpan.c | 39 ++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 36 insertions(+), 3 deletions(-)
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
-index 63dd8638..7cba1a6 100644
+index 276971b..c9c3f3d 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
-@@ -286,6 +286,9 @@ lowpan_compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb)
+@@ -284,6 +284,9 @@ lowpan_compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb)
/* checksum is always inline */
memcpy(*hc06_ptr, &uh->check, 2);
*hc06_ptr += 2;
@@ -25,7 +25,7 @@ index 63dd8638..7cba1a6 100644
}
static inline int lowpan_fetch_skb_u8(struct sk_buff *skb, u8 *val)
-@@ -311,9 +314,8 @@ static inline int lowpan_fetch_skb_u16(struct sk_buff *skb, u16 *val)
+@@ -309,9 +312,8 @@ static inline int lowpan_fetch_skb_u16(struct sk_buff *skb, u16 *val)
}
static int
@@ -36,27 +36,22 @@ index 63dd8638..7cba1a6 100644
u8 tmp;
if (!uh)
-@@ -354,12 +356,19 @@ lowpan_uncompress_udp_header(struct sk_buff *skb)
- break;
- }
-
-+
- pr_debug("uncompressed UDP ports: src = %d, dst = %d\n",
- uh->source, uh->dest);
-
+@@ -358,6 +360,14 @@ lowpan_uncompress_udp_header(struct sk_buff *skb)
/* copy checksum */
memcpy(&uh->check, &skb->data[0], 2);
skb_pull(skb, 2);
+
-+ /* UDP lenght needs to be infered from the lower layers
-+ here, we obtain the hint from the remaining size of the
-+ frame */
++ /*
++ * UDP lenght needs to be infered from the lower layers
++ * here, we obtain the hint from the remaining size of the
++ * frame
++ */
+ uh->len = htons(skb->len + sizeof(struct udphdr));
+ pr_debug("uncompressed UDP length: src = %d", uh->len);
} else {
pr_debug("ERROR: unsupported NH format\n");
goto err;
-@@ -941,8 +950,29 @@ lowpan_process_data(struct sk_buff *skb)
+@@ -944,8 +954,31 @@ lowpan_process_data(struct sk_buff *skb)
/* UDP data uncompression */
if (iphc0 & LOWPAN_IPHC_NH_C) {
@@ -66,8 +61,10 @@ index 63dd8638..7cba1a6 100644
+ if (lowpan_uncompress_udp_header(skb, &uh))
goto drop;
+
-+ /* place the real UDP header instead of the
-+ compressed UDP header */
++ /*
++ * replace the compressed UDP head by the uncompressed UDP
++ * header
++ */
+ new = skb_copy_expand(skb, sizeof(struct udphdr),
+ skb_tailroom(skb), GFP_ATOMIC);
+ kfree_skb(skb);
@@ -75,7 +72,7 @@ index 63dd8638..7cba1a6 100644
+ if (!new)
+ return -ENOMEM;
+
-+ skb = new ;
++ skb = new;
+
+ skb_push(skb, sizeof(struct udphdr));
+ skb_reset_transport_header(skb);
diff --git a/patches/linux-3.8.13/0185-6lowpan-fix-a-small-formatting-issue.patch b/patches/linux-3.8.13/0185-6lowpan-fix-a-small-formatting-issue.patch
new file mode 100644
index 0000000..6bf3e92
--- /dev/null
+++ b/patches/linux-3.8.13/0185-6lowpan-fix-a-small-formatting-issue.patch
@@ -0,0 +1,25 @@
+From: Tony Cheneau <tony.cheneau@amnesiak.org>
+Date: Wed, 27 Mar 2013 00:09:24 -0400
+Subject: [PATCH] 6lowpan: fix a small formatting issue
+
+This formatting issue was introduced with commit
+d4ac32365dcbfd341a87eae444c26679f889249a
+
+Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
+---
+ net/ieee802154/6lowpan.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
+index c9c3f3d..f4969d7 100644
+--- a/net/ieee802154/6lowpan.c
++++ b/net/ieee802154/6lowpan.c
+@@ -104,7 +104,7 @@ static const u8 lowpan_llprefix[] = {0xfe, 0x80};
+ struct lowpan_dev_info {
+ struct net_device *real_dev; /* real WPAN device ptr */
+ struct mutex dev_list_mtx; /* mutex for list ops */
+- unsigned short fragment_tag;
++ unsigned short fragment_tag;
+ };
+
+ struct lowpan_dev_record {
diff --git a/patches/linux-3.8.13/0186-6lowpan-use-IEEE802154_ADDR_LEN-instead-of-a-magic-n.patch b/patches/linux-3.8.13/0186-6lowpan-use-IEEE802154_ADDR_LEN-instead-of-a-magic-n.patch
new file mode 100644
index 0000000..866f68a
--- /dev/null
+++ b/patches/linux-3.8.13/0186-6lowpan-use-IEEE802154_ADDR_LEN-instead-of-a-magic-n.patch
@@ -0,0 +1,22 @@
+From: Tony Cheneau <tony.cheneau@amnesiak.org>
+Date: Wed, 27 Mar 2013 00:09:25 -0400
+Subject: [PATCH] 6lowpan: use IEEE802154_ADDR_LEN instead of a magic number
+
+Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
+---
+ net/ieee802154/6lowpan.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
+index f4969d7..e1b4580 100644
+--- a/net/ieee802154/6lowpan.c
++++ b/net/ieee802154/6lowpan.c
+@@ -602,7 +602,7 @@ static int lowpan_header_create(struct sk_buff *skb,
+ da.short_addr = IEEE802154_ADDR_BROADCAST;
+ } else {
+ da.addr_type = IEEE802154_ADDR_LONG;
+- memcpy(&(da.hwaddr), daddr, 8);
++ memcpy(&(da.hwaddr), daddr, IEEE802154_ADDR_LEN);
+
+ /* request acknowledgment */
+ mac_cb(skb)->flags |= MAC_CB_FLAG_ACKREQ;
diff --git a/patches/linux-3.8.4/0170-gpio-keys-Pinctrl-fy.patch b/patches/linux-3.8.13/0187-gpio-keys-Pinctrl-fy.patch
index e9e90c7..e9e90c7 100644
--- a/patches/linux-3.8.4/0170-gpio-keys-Pinctrl-fy.patch
+++ b/patches/linux-3.8.13/0187-gpio-keys-Pinctrl-fy.patch
diff --git a/patches/linux-3.8.4/0171-tps65217-Allow-placement-elsewhere-than-parent-mfd-d.patch b/patches/linux-3.8.13/0188-tps65217-Allow-placement-elsewhere-than-parent-mfd-d.patch
index 2ae0319..2ae0319 100644
--- a/patches/linux-3.8.4/0171-tps65217-Allow-placement-elsewhere-than-parent-mfd-d.patch
+++ b/patches/linux-3.8.13/0188-tps65217-Allow-placement-elsewhere-than-parent-mfd-d.patch
diff --git a/patches/linux-3.8.4/0172-pwm-backlight-Pinctrl-fy.patch b/patches/linux-3.8.13/0189-pwm-backlight-Pinctrl-fy.patch
index c18e0d5..c18e0d5 100644
--- a/patches/linux-3.8.4/0172-pwm-backlight-Pinctrl-fy.patch
+++ b/patches/linux-3.8.13/0189-pwm-backlight-Pinctrl-fy.patch
diff --git a/patches/linux-3.8.4/0173-ARM-CUSTOM-Build-a-uImage-with-dtb-already-appended.patch b/patches/linux-3.8.13/0190-ARM-CUSTOM-Build-a-uImage-with-dtb-already-appended.patch
index 57fafa6..57fafa6 100644
--- a/patches/linux-3.8.4/0173-ARM-CUSTOM-Build-a-uImage-with-dtb-already-appended.patch
+++ b/patches/linux-3.8.13/0190-ARM-CUSTOM-Build-a-uImage-with-dtb-already-appended.patch
diff --git a/patches/linux-3.8.4/0174-beaglebone-create-a-shared-dtsi-for-beaglebone-based.patch b/patches/linux-3.8.13/0191-beaglebone-create-a-shared-dtsi-for-beaglebone-based.patch
index 1615a2c..1615a2c 100644
--- a/patches/linux-3.8.4/0174-beaglebone-create-a-shared-dtsi-for-beaglebone-based.patch
+++ b/patches/linux-3.8.13/0191-beaglebone-create-a-shared-dtsi-for-beaglebone-based.patch
diff --git a/patches/linux-3.8.4/0175-beaglebone-enable-emmc-for-bonelt.patch b/patches/linux-3.8.13/0192-beaglebone-enable-emmc-for-bonelt.patch
index ccaaff5..ccaaff5 100644
--- a/patches/linux-3.8.4/0175-beaglebone-enable-emmc-for-bonelt.patch
+++ b/patches/linux-3.8.13/0192-beaglebone-enable-emmc-for-bonelt.patch
diff --git a/patches/linux-3.8.4/0176-Fix-appended-dtb-rule.patch b/patches/linux-3.8.13/0193-Fix-appended-dtb-rule.patch
index c28db15..c28db15 100644
--- a/patches/linux-3.8.4/0176-Fix-appended-dtb-rule.patch
+++ b/patches/linux-3.8.13/0193-Fix-appended-dtb-rule.patch
diff --git a/patches/linux-3.8.4/0177-deb-pkg-Simplify-architecture-matching-for-cross-bui.patch b/patches/linux-3.8.13/0194-deb-pkg-Simplify-architecture-matching-for-cross-bui.patch
index 3fc1c21..3fc1c21 100644
--- a/patches/linux-3.8.4/0177-deb-pkg-Simplify-architecture-matching-for-cross-bui.patch
+++ b/patches/linux-3.8.13/0194-deb-pkg-Simplify-architecture-matching-for-cross-bui.patch
diff --git a/patches/linux-3.8.4/0178-Without-MACH_-option-Early-printk-DEBUG_LL.patch b/patches/linux-3.8.13/0195-Without-MACH_-option-Early-printk-DEBUG_LL.patch
index 4f2ae41..4f2ae41 100644
--- a/patches/linux-3.8.4/0178-Without-MACH_-option-Early-printk-DEBUG_LL.patch
+++ b/patches/linux-3.8.13/0195-Without-MACH_-option-Early-printk-DEBUG_LL.patch
diff --git a/patches/linux-3.8.13/0196-ARM-7668-1-fix-memset-related-crashes-caused-by-rece.patch b/patches/linux-3.8.13/0196-ARM-7668-1-fix-memset-related-crashes-caused-by-rece.patch
new file mode 100644
index 0000000..240530a
--- /dev/null
+++ b/patches/linux-3.8.13/0196-ARM-7668-1-fix-memset-related-crashes-caused-by-rece.patch
@@ -0,0 +1,252 @@
+From: Ivan Djelic <ivan.djelic@parrot.com>
+Date: Wed, 6 Mar 2013 20:09:27 +0100
+Subject: [PATCH] ARM: 7668/1: fix memset-related crashes caused by recent GCC
+ (4.7.2) optimizations
+
+Recent GCC versions (e.g. GCC-4.7.2) perform optimizations based on
+assumptions about the implementation of memset and similar functions.
+The current ARM optimized memset code does not return the value of
+its first argument, as is usually expected from standard implementations.
+
+For instance in the following function:
+
+void debug_mutex_lock_common(struct mutex *lock, struct mutex_waiter *waiter)
+{
+ memset(waiter, MUTEX_DEBUG_INIT, sizeof(*waiter));
+ waiter->magic = waiter;
+ INIT_LIST_HEAD(&waiter->list);
+}
+
+compiled as:
+
+800554d0 <debug_mutex_lock_common>:
+800554d0: e92d4008 push {r3, lr}
+800554d4: e1a00001 mov r0, r1
+800554d8: e3a02010 mov r2, #16 ; 0x10
+800554dc: e3a01011 mov r1, #17 ; 0x11
+800554e0: eb04426e bl 80165ea0 <memset>
+800554e4: e1a03000 mov r3, r0
+800554e8: e583000c str r0, [r3, #12]
+800554ec: e5830000 str r0, [r3]
+800554f0: e5830004 str r0, [r3, #4]
+800554f4: e8bd8008 pop {r3, pc}
+
+GCC assumes memset returns the value of pointer 'waiter' in register r0; causing
+register/memory corruptions.
+
+This patch fixes the return value of the assembly version of memset.
+It adds a 'mov' instruction and merges an additional load+store into
+existing load/store instructions.
+For ease of review, here is a breakdown of the patch into 4 simple steps:
+
+Step 1
+======
+Perform the following substitutions:
+ip -> r8, then
+r0 -> ip,
+and insert 'mov ip, r0' as the first statement of the function.
+At this point, we have a memset() implementation returning the proper result,
+but corrupting r8 on some paths (the ones that were using ip).
+
+Step 2
+======
+Make sure r8 is saved and restored when (! CALGN(1)+0) == 1:
+
+save r8:
+- str lr, [sp, #-4]!
++ stmfd sp!, {r8, lr}
+
+and restore r8 on both exit paths:
+- ldmeqfd sp!, {pc} @ Now <64 bytes to go.
++ ldmeqfd sp!, {r8, pc} @ Now <64 bytes to go.
+(...)
+ tst r2, #16
+ stmneia ip!, {r1, r3, r8, lr}
+- ldr lr, [sp], #4
++ ldmfd sp!, {r8, lr}
+
+Step 3
+======
+Make sure r8 is saved and restored when (! CALGN(1)+0) == 0:
+
+save r8:
+- stmfd sp!, {r4-r7, lr}
++ stmfd sp!, {r4-r8, lr}
+
+and restore r8 on both exit paths:
+ bgt 3b
+- ldmeqfd sp!, {r4-r7, pc}
++ ldmeqfd sp!, {r4-r8, pc}
+(...)
+ tst r2, #16
+ stmneia ip!, {r4-r7}
+- ldmfd sp!, {r4-r7, lr}
++ ldmfd sp!, {r4-r8, lr}
+
+Step 4
+======
+Rewrite register list "r4-r7, r8" as "r4-r8".
+
+Signed-off-by: Ivan Djelic <ivan.djelic@parrot.com>
+Reviewed-by: Nicolas Pitre <nico@linaro.org>
+Signed-off-by: Dirk Behme <dirk.behme@gmail.com>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ arch/arm/lib/memset.S | 85 +++++++++++++++++++++++++------------------------
+ 1 file changed, 44 insertions(+), 41 deletions(-)
+
+diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S
+index 650d592..d912e73 100644
+--- a/arch/arm/lib/memset.S
++++ b/arch/arm/lib/memset.S
+@@ -19,9 +19,9 @@
+ 1: subs r2, r2, #4 @ 1 do we have enough
+ blt 5f @ 1 bytes to align with?
+ cmp r3, #2 @ 1
+- strltb r1, [r0], #1 @ 1
+- strleb r1, [r0], #1 @ 1
+- strb r1, [r0], #1 @ 1
++ strltb r1, [ip], #1 @ 1
++ strleb r1, [ip], #1 @ 1
++ strb r1, [ip], #1 @ 1
+ add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
+ /*
+ * The pointer is now aligned and the length is adjusted. Try doing the
+@@ -29,10 +29,14 @@
+ */
+
+ ENTRY(memset)
+- ands r3, r0, #3 @ 1 unaligned?
++/*
++ * Preserve the contents of r0 for the return value.
++ */
++ mov ip, r0
++ ands r3, ip, #3 @ 1 unaligned?
+ bne 1b @ 1
+ /*
+- * we know that the pointer in r0 is aligned to a word boundary.
++ * we know that the pointer in ip is aligned to a word boundary.
+ */
+ orr r1, r1, r1, lsl #8
+ orr r1, r1, r1, lsl #16
+@@ -43,29 +47,28 @@ ENTRY(memset)
+ #if ! CALGN(1)+0
+
+ /*
+- * We need an extra register for this loop - save the return address and
+- * use the LR
++ * We need 2 extra registers for this loop - use r8 and the LR
+ */
+- str lr, [sp, #-4]!
+- mov ip, r1
++ stmfd sp!, {r8, lr}
++ mov r8, r1
+ mov lr, r1
+
+ 2: subs r2, r2, #64
+- stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time.
+- stmgeia r0!, {r1, r3, ip, lr}
+- stmgeia r0!, {r1, r3, ip, lr}
+- stmgeia r0!, {r1, r3, ip, lr}
++ stmgeia ip!, {r1, r3, r8, lr} @ 64 bytes at a time.
++ stmgeia ip!, {r1, r3, r8, lr}
++ stmgeia ip!, {r1, r3, r8, lr}
++ stmgeia ip!, {r1, r3, r8, lr}
+ bgt 2b
+- ldmeqfd sp!, {pc} @ Now <64 bytes to go.
++ ldmeqfd sp!, {r8, pc} @ Now <64 bytes to go.
+ /*
+ * No need to correct the count; we're only testing bits from now on
+ */
+ tst r2, #32
+- stmneia r0!, {r1, r3, ip, lr}
+- stmneia r0!, {r1, r3, ip, lr}
++ stmneia ip!, {r1, r3, r8, lr}
++ stmneia ip!, {r1, r3, r8, lr}
+ tst r2, #16
+- stmneia r0!, {r1, r3, ip, lr}
+- ldr lr, [sp], #4
++ stmneia ip!, {r1, r3, r8, lr}
++ ldmfd sp!, {r8, lr}
+
+ #else
+
+@@ -74,54 +77,54 @@ ENTRY(memset)
+ * whole cache lines at once.
+ */
+
+- stmfd sp!, {r4-r7, lr}
++ stmfd sp!, {r4-r8, lr}
+ mov r4, r1
+ mov r5, r1
+ mov r6, r1
+ mov r7, r1
+- mov ip, r1
++ mov r8, r1
+ mov lr, r1
+
+ cmp r2, #96
+- tstgt r0, #31
++ tstgt ip, #31
+ ble 3f
+
+- and ip, r0, #31
+- rsb ip, ip, #32
+- sub r2, r2, ip
+- movs ip, ip, lsl #(32 - 4)
+- stmcsia r0!, {r4, r5, r6, r7}
+- stmmiia r0!, {r4, r5}
+- tst ip, #(1 << 30)
+- mov ip, r1
+- strne r1, [r0], #4
++ and r8, ip, #31
++ rsb r8, r8, #32
++ sub r2, r2, r8
++ movs r8, r8, lsl #(32 - 4)
++ stmcsia ip!, {r4, r5, r6, r7}
++ stmmiia ip!, {r4, r5}
++ tst r8, #(1 << 30)
++ mov r8, r1
++ strne r1, [ip], #4
+
+ 3: subs r2, r2, #64
+- stmgeia r0!, {r1, r3-r7, ip, lr}
+- stmgeia r0!, {r1, r3-r7, ip, lr}
++ stmgeia ip!, {r1, r3-r8, lr}
++ stmgeia ip!, {r1, r3-r8, lr}
+ bgt 3b
+- ldmeqfd sp!, {r4-r7, pc}
++ ldmeqfd sp!, {r4-r8, pc}
+
+ tst r2, #32
+- stmneia r0!, {r1, r3-r7, ip, lr}
++ stmneia ip!, {r1, r3-r8, lr}
+ tst r2, #16
+- stmneia r0!, {r4-r7}
+- ldmfd sp!, {r4-r7, lr}
++ stmneia ip!, {r4-r7}
++ ldmfd sp!, {r4-r8, lr}
+
+ #endif
+
+ 4: tst r2, #8
+- stmneia r0!, {r1, r3}
++ stmneia ip!, {r1, r3}
+ tst r2, #4
+- strne r1, [r0], #4
++ strne r1, [ip], #4
+ /*
+ * When we get here, we've got less than 4 bytes to zero. We
+ * may have an unaligned pointer as well.
+ */
+ 5: tst r2, #2
+- strneb r1, [r0], #1
+- strneb r1, [r0], #1
++ strneb r1, [ip], #1
++ strneb r1, [ip], #1
+ tst r2, #1
+- strneb r1, [r0], #1
++ strneb r1, [ip], #1
+ mov pc, lr
+ ENDPROC(memset)
diff --git a/patches/linux-3.8.13/0197-ARM-7670-1-fix-the-memset-fix.patch b/patches/linux-3.8.13/0197-ARM-7670-1-fix-the-memset-fix.patch
new file mode 100644
index 0000000..b13ef7e
--- /dev/null
+++ b/patches/linux-3.8.13/0197-ARM-7670-1-fix-the-memset-fix.patch
@@ -0,0 +1,79 @@
+From: Nicolas Pitre <nicolas.pitre@linaro.org>
+Date: Tue, 12 Mar 2013 13:00:42 +0100
+Subject: [PATCH] ARM: 7670/1: fix the memset fix
+
+Commit 455bd4c430b0 ("ARM: 7668/1: fix memset-related crashes caused by
+recent GCC (4.7.2) optimizations") attempted to fix a compliance issue
+with the memset return value. However the memset itself became broken
+by that patch for misaligned pointers.
+
+This fixes the above by branching over the entry code from the
+misaligned fixup code to avoid reloading the original pointer.
+
+Also, because the function entry alignment is wrong in the Thumb mode
+compilation, that fixup code is moved to the end.
+
+While at it, the entry instructions are slightly reworked to help dual
+issue pipelines.
+
+Signed-off-by: Nicolas Pitre <nico@linaro.org>
+Tested-by: Alexander Holler <holler@ahsoftware.de>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+ arch/arm/lib/memset.S | 33 +++++++++++++--------------------
+ 1 file changed, 13 insertions(+), 20 deletions(-)
+
+diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S
+index d912e73..94b0650 100644
+--- a/arch/arm/lib/memset.S
++++ b/arch/arm/lib/memset.S
+@@ -14,31 +14,15 @@
+
+ .text
+ .align 5
+- .word 0
+-
+-1: subs r2, r2, #4 @ 1 do we have enough
+- blt 5f @ 1 bytes to align with?
+- cmp r3, #2 @ 1
+- strltb r1, [ip], #1 @ 1
+- strleb r1, [ip], #1 @ 1
+- strb r1, [ip], #1 @ 1
+- add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
+-/*
+- * The pointer is now aligned and the length is adjusted. Try doing the
+- * memset again.
+- */
+
+ ENTRY(memset)
+-/*
+- * Preserve the contents of r0 for the return value.
+- */
+- mov ip, r0
+- ands r3, ip, #3 @ 1 unaligned?
+- bne 1b @ 1
++ ands r3, r0, #3 @ 1 unaligned?
++ mov ip, r0 @ preserve r0 as return value
++ bne 6f @ 1
+ /*
+ * we know that the pointer in ip is aligned to a word boundary.
+ */
+- orr r1, r1, r1, lsl #8
++1: orr r1, r1, r1, lsl #8
+ orr r1, r1, r1, lsl #16
+ mov r3, r1
+ cmp r2, #16
+@@ -127,4 +111,13 @@ ENTRY(memset)
+ tst r2, #1
+ strneb r1, [ip], #1
+ mov pc, lr
++
++6: subs r2, r2, #4 @ 1 do we have enough
++ blt 5b @ 1 bytes to align with?
++ cmp r3, #2 @ 1
++ strltb r1, [ip], #1 @ 1
++ strleb r1, [ip], #1 @ 1
++ strb r1, [ip], #1 @ 1
++ add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
++ b 1b
+ ENDPROC(memset)
diff --git a/patches/linux-3.8.4/0179-regulator-core-if-voltage-scaling-fails-restore-orig.patch b/patches/linux-3.8.13/0198-regulator-core-if-voltage-scaling-fails-restore-orig.patch
index e82553c..8e274e3 100644
--- a/patches/linux-3.8.4/0179-regulator-core-if-voltage-scaling-fails-restore-orig.patch
+++ b/patches/linux-3.8.13/0198-regulator-core-if-voltage-scaling-fails-restore-orig.patch
@@ -9,7 +9,7 @@ Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
-index 2785843..53abc98 100644
+index 5a0f54a..8e7ec07 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2294,6 +2294,7 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
diff --git a/patches/linux-3.8.4/0180-omap2-twl-common-Add-default-power-configuration.patch b/patches/linux-3.8.13/0199-omap2-twl-common-Add-default-power-configuration.patch
index 32be8ab..32be8ab 100644
--- a/patches/linux-3.8.4/0180-omap2-twl-common-Add-default-power-configuration.patch
+++ b/patches/linux-3.8.13/0199-omap2-twl-common-Add-default-power-configuration.patch
diff --git a/patches/linux-3.8.13/0200-omap2-irq-fix-interrupt-latency.patch b/patches/linux-3.8.13/0200-omap2-irq-fix-interrupt-latency.patch
new file mode 100644
index 0000000..72300bf
--- /dev/null
+++ b/patches/linux-3.8.13/0200-omap2-irq-fix-interrupt-latency.patch
@@ -0,0 +1,22 @@
+From: =?UTF-8?q?H=C3=A5kan=20Engblom?= <hkengblom@gmail.com>
+Date: Wed, 24 Apr 2013 10:53:46 +0200
+Subject: [PATCH] omap2 irq: fix interrupt latency
+
+The problem in my system was that interrutp latency for GPIO interrupts (GPIO used as interrupt source by use of "echo rising > /sys/class/gpio/gpioXX/edge") was _very_ long, probably until somother interrupt made GPIO interrupts "visable". The problem that the patch corrects is that also a AM33XX has four registers to check in the interrupt controller to find out which interrupt that caused the controlled to assert an interrupt.
+---
+ arch/arm/mach-omap2/irq.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
+index 3926f37..57d1b7d 100644
+--- a/arch/arm/mach-omap2/irq.c
++++ b/arch/arm/mach-omap2/irq.c
+@@ -233,7 +233,7 @@ static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs
+ goto out;
+
+ irqnr = readl_relaxed(base_addr + 0xd8);
+-#ifdef CONFIG_SOC_TI81XX
++#if defined(CONFIG_SOC_TI81XX) || defined(CONFIG_SOC_AM33XX)
+ if (irqnr)
+ goto out;
+ irqnr = readl_relaxed(base_addr + 0xf8);
diff --git a/patches/linux-3.8.4/0181-OMAP-DSS2-add-bootarg-for-selecting-svideo.patch b/patches/linux-3.8.13/0201-OMAP-DSS2-add-bootarg-for-selecting-svideo.patch
index 7ccd5c3..7ccd5c3 100644
--- a/patches/linux-3.8.4/0181-OMAP-DSS2-add-bootarg-for-selecting-svideo.patch
+++ b/patches/linux-3.8.13/0201-OMAP-DSS2-add-bootarg-for-selecting-svideo.patch
diff --git a/patches/linux-3.8.4/0182-video-add-timings-for-hd720.patch b/patches/linux-3.8.13/0202-video-add-timings-for-hd720.patch
index 9034278..9034278 100644
--- a/patches/linux-3.8.4/0182-video-add-timings-for-hd720.patch
+++ b/patches/linux-3.8.13/0202-video-add-timings-for-hd720.patch
diff --git a/patches/linux-3.8.4/0183-Beagle-expansion-add-buddy-param-for-expansionboard-.patch b/patches/linux-3.8.13/0203-Beagle-expansion-add-buddy-param-for-expansionboard-.patch
index 1626e04..1626e04 100644
--- a/patches/linux-3.8.4/0183-Beagle-expansion-add-buddy-param-for-expansionboard-.patch
+++ b/patches/linux-3.8.13/0203-Beagle-expansion-add-buddy-param-for-expansionboard-.patch
diff --git a/patches/linux-3.8.4/0184-Beagle-expansion-add-zippy.patch b/patches/linux-3.8.13/0204-Beagle-expansion-add-zippy.patch
index 3e36ea6..3e36ea6 100644
--- a/patches/linux-3.8.4/0184-Beagle-expansion-add-zippy.patch
+++ b/patches/linux-3.8.13/0204-Beagle-expansion-add-zippy.patch
diff --git a/patches/linux-3.8.4/0185-Beagle-expansion-add-zippy2.patch b/patches/linux-3.8.13/0205-Beagle-expansion-add-zippy2.patch
index 98cc40f..98cc40f 100644
--- a/patches/linux-3.8.4/0185-Beagle-expansion-add-zippy2.patch
+++ b/patches/linux-3.8.13/0205-Beagle-expansion-add-zippy2.patch
diff --git a/patches/linux-3.8.4/0186-Beagle-expansion-add-trainer.patch b/patches/linux-3.8.13/0206-Beagle-expansion-add-trainer.patch
index ddb2f26..ddb2f26 100644
--- a/patches/linux-3.8.4/0186-Beagle-expansion-add-trainer.patch
+++ b/patches/linux-3.8.13/0206-Beagle-expansion-add-trainer.patch
diff --git a/patches/linux-3.8.4/0187-Beagle-expansion-add-CircuitCo-ulcd-Support.patch b/patches/linux-3.8.13/0207-Beagle-expansion-add-CircuitCo-ulcd-Support.patch
index 0ad8781..0ad8781 100644
--- a/patches/linux-3.8.4/0187-Beagle-expansion-add-CircuitCo-ulcd-Support.patch
+++ b/patches/linux-3.8.13/0207-Beagle-expansion-add-CircuitCo-ulcd-Support.patch
diff --git a/patches/linux-3.8.4/0188-Beagle-expansion-add-wifi.patch b/patches/linux-3.8.13/0208-Beagle-expansion-add-wifi.patch
index e49deb2..e49deb2 100644
--- a/patches/linux-3.8.4/0188-Beagle-expansion-add-wifi.patch
+++ b/patches/linux-3.8.13/0208-Beagle-expansion-add-wifi.patch
diff --git a/patches/linux-3.8.4/0189-Beagle-expansion-add-beaglefpga.patch b/patches/linux-3.8.13/0209-Beagle-expansion-add-beaglefpga.patch
index c13900c..c13900c 100644
--- a/patches/linux-3.8.4/0189-Beagle-expansion-add-beaglefpga.patch
+++ b/patches/linux-3.8.13/0209-Beagle-expansion-add-beaglefpga.patch
diff --git a/patches/linux-3.8.4/0190-Beagle-expansion-add-spidev.patch b/patches/linux-3.8.13/0210-Beagle-expansion-add-spidev.patch
index fe415e4..fe415e4 100644
--- a/patches/linux-3.8.4/0190-Beagle-expansion-add-spidev.patch
+++ b/patches/linux-3.8.13/0210-Beagle-expansion-add-spidev.patch
diff --git a/patches/linux-3.8.4/0191-Beagle-expansion-add-Aptina-li5m03-camera.patch b/patches/linux-3.8.13/0211-Beagle-expansion-add-Aptina-li5m03-camera.patch
index aa1debb..aa1debb 100644
--- a/patches/linux-3.8.4/0191-Beagle-expansion-add-Aptina-li5m03-camera.patch
+++ b/patches/linux-3.8.13/0211-Beagle-expansion-add-Aptina-li5m03-camera.patch
diff --git a/patches/linux-3.8.4/0192-Beagle-expansion-add-LSR-COM6L-Adapter-Board.patch b/patches/linux-3.8.13/0212-Beagle-expansion-add-LSR-COM6L-Adapter-Board.patch
index 54233a3..54233a3 100644
--- a/patches/linux-3.8.4/0192-Beagle-expansion-add-LSR-COM6L-Adapter-Board.patch
+++ b/patches/linux-3.8.13/0212-Beagle-expansion-add-LSR-COM6L-Adapter-Board.patch
diff --git a/patches/linux-3.8.4/0193-meego-modedb-add-Toshiba-LTA070B220F-800x480-support.patch b/patches/linux-3.8.13/0213-meego-modedb-add-Toshiba-LTA070B220F-800x480-support.patch
index 2e4e312..2e4e312 100644
--- a/patches/linux-3.8.4/0193-meego-modedb-add-Toshiba-LTA070B220F-800x480-support.patch
+++ b/patches/linux-3.8.13/0213-meego-modedb-add-Toshiba-LTA070B220F-800x480-support.patch
diff --git a/patches/linux-3.8.4/0194-backlight-Add-TLC59108-backlight-control-driver.patch b/patches/linux-3.8.13/0214-backlight-Add-TLC59108-backlight-control-driver.patch
index 4ae5392..4ae5392 100644
--- a/patches/linux-3.8.4/0194-backlight-Add-TLC59108-backlight-control-driver.patch
+++ b/patches/linux-3.8.13/0214-backlight-Add-TLC59108-backlight-control-driver.patch
diff --git a/patches/linux-3.8.4/0195-tlc59108-adjust-for-beagleboard-uLCD7.patch b/patches/linux-3.8.13/0215-tlc59108-adjust-for-beagleboard-uLCD7.patch
index 2e14b13..2e14b13 100644
--- a/patches/linux-3.8.4/0195-tlc59108-adjust-for-beagleboard-uLCD7.patch
+++ b/patches/linux-3.8.13/0215-tlc59108-adjust-for-beagleboard-uLCD7.patch
diff --git a/patches/linux-3.8.4/0196-zeroMAP-Open-your-eyes.patch b/patches/linux-3.8.13/0216-zeroMAP-Open-your-eyes.patch
index c1fb323..c1fb323 100644
--- a/patches/linux-3.8.4/0196-zeroMAP-Open-your-eyes.patch
+++ b/patches/linux-3.8.13/0216-zeroMAP-Open-your-eyes.patch
diff --git a/patches/linux-3.8.4/0197-ARM-OMAP-Beagle-use-TWL4030-generic-reset-script.patch b/patches/linux-3.8.13/0217-ARM-OMAP-Beagle-use-TWL4030-generic-reset-script.patch
index 146f454..146f454 100644
--- a/patches/linux-3.8.4/0197-ARM-OMAP-Beagle-use-TWL4030-generic-reset-script.patch
+++ b/patches/linux-3.8.13/0217-ARM-OMAP-Beagle-use-TWL4030-generic-reset-script.patch
diff --git a/patches/linux-3.8.13/0218-panda-fix-wl12xx-regulator.patch b/patches/linux-3.8.13/0218-panda-fix-wl12xx-regulator.patch
new file mode 100644
index 0000000..151ce40
--- /dev/null
+++ b/patches/linux-3.8.13/0218-panda-fix-wl12xx-regulator.patch
@@ -0,0 +1,23 @@
+From: Robert Nelson <robertcnelson@gmail.com>
+Date: Tue, 2 Aug 2011 21:55:34 -0500
+Subject: [PATCH] panda: fix wl12xx regulator
+
+pulled from: http://elinux.org/Panda_How_to_kernel_3_0_rel
+
+Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
+---
+ arch/arm/mach-omap2/twl-common.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
+index f096beb..4b2b254 100644
+--- a/arch/arm/mach-omap2/twl-common.c
++++ b/arch/arm/mach-omap2/twl-common.c
+@@ -398,6 +398,7 @@ static struct regulator_init_data omap4_vusb_idata = {
+ static struct regulator_init_data omap4_clk32kg_idata = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
++ .always_on = true,
+ },
+ };
+
diff --git a/patches/linux-3.8.13/0219-ti-st-st-kim-fixing-firmware-path.patch b/patches/linux-3.8.13/0219-ti-st-st-kim-fixing-firmware-path.patch
new file mode 100644
index 0000000..0edaa92
--- /dev/null
+++ b/patches/linux-3.8.13/0219-ti-st-st-kim-fixing-firmware-path.patch
@@ -0,0 +1,32 @@
+From: Ricardo Salveti de Araujo <ricardo.salveti@linaro.org>
+Date: Tue, 25 Oct 2011 10:06:39 +0200
+Subject: [PATCH] ti-st/st-kim: fixing firmware path
+
+Signed-off-by: Ricardo Salveti de Araujo <ricardo.salveti@linaro.org>
+Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
+---
+ drivers/misc/ti-st/st_kim.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c
+index 83269f1..d48b9e0 100644
+--- a/drivers/misc/ti-st/st_kim.c
++++ b/drivers/misc/ti-st/st_kim.c
+@@ -244,7 +244,7 @@ static long read_local_version(struct kim_data_s *kim_gdata, char *bts_scr_name)
+ if (version & 0x8000)
+ maj_ver |= 0x0008;
+
+- sprintf(bts_scr_name, "TIInit_%d.%d.%d.bts", chip, maj_ver, min_ver);
++ sprintf(bts_scr_name, "ti-connectivity/TIInit_%d.%d.%d.bts", chip, maj_ver, min_ver);
+
+ /* to be accessed later via sysfs entry */
+ kim_gdata->version.full = version;
+@@ -287,7 +287,7 @@ static long download_firmware(struct kim_data_s *kim_gdata)
+ long len = 0;
+ unsigned char *ptr = NULL;
+ unsigned char *action_ptr = NULL;
+- unsigned char bts_scr_name[30] = { 0 }; /* 30 char long bts scr name? */
++ unsigned char bts_scr_name[50] = { 0 }; /* 50 char long bts scr name? */
+ int wr_room_space;
+ int cmd_size;
+ unsigned long timeout;
diff --git a/patches/linux-3.8.4/0198-am33xx-cpsw-default-to-ethernet-hwaddr-from-efuse-if.patch b/patches/linux-3.8.13/0220-am33xx-cpsw-default-to-ethernet-hwaddr-from-efuse-if.patch
index d17d9ec..d17d9ec 100644
--- a/patches/linux-3.8.4/0198-am33xx-cpsw-default-to-ethernet-hwaddr-from-efuse-if.patch
+++ b/patches/linux-3.8.13/0220-am33xx-cpsw-default-to-ethernet-hwaddr-from-efuse-if.patch
diff --git a/patches/linux-3.8.4/0199-Attempted-SMC911x-BQL-patch.patch b/patches/linux-3.8.13/0221-Attempted-SMC911x-BQL-patch.patch
index 9e34e76..9e34e76 100644
--- a/patches/linux-3.8.4/0199-Attempted-SMC911x-BQL-patch.patch
+++ b/patches/linux-3.8.13/0221-Attempted-SMC911x-BQL-patch.patch
diff --git a/patches/linux-3.8.4/0200-cpsw-Fix-interrupt-storm-among-other-things.patch b/patches/linux-3.8.13/0222-cpsw-Fix-interrupt-storm-among-other-things.patch
index 82aa5c6..84f5118 100644
--- a/patches/linux-3.8.4/0200-cpsw-Fix-interrupt-storm-among-other-things.patch
+++ b/patches/linux-3.8.13/0222-cpsw-Fix-interrupt-storm-among-other-things.patch
@@ -28,7 +28,7 @@ index 6ddd028..d46b293 100644
Optional properties:
- ti,hwmods : Must be "cpgmac0"
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
-index 40aff68..b6ca4af 100644
+index 3b1be52..21ba53e 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -148,10 +148,37 @@ struct cpsw_wr_regs {
diff --git a/patches/linux-3.8.13/0223-beaglebone-TT3201-MCP2515-fixes.patch b/patches/linux-3.8.13/0223-beaglebone-TT3201-MCP2515-fixes.patch
new file mode 100644
index 0000000..cb9b159
--- /dev/null
+++ b/patches/linux-3.8.13/0223-beaglebone-TT3201-MCP2515-fixes.patch
@@ -0,0 +1,162 @@
+From: Alessandro Zummo <a.zummo@towertech.it>
+Date: Thu, 23 May 2013 20:57:04 +0200
+Subject: [PATCH] beaglebone: TT3201 MCP2515 fixes
+
+Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
+---
+ drivers/net/can/mcp251x.c | 47 +++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 37 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c
+index 42b6d69..3555ef44 100644
+--- a/drivers/net/can/mcp251x.c
++++ b/drivers/net/can/mcp251x.c
+@@ -98,8 +98,9 @@
+ # define CANCTRL_REQOP_LOOPBACK 0x40
+ # define CANCTRL_REQOP_SLEEP 0x20
+ # define CANCTRL_REQOP_NORMAL 0x00
+-# define CANCTRL_OSM 0x08
+ # define CANCTRL_ABAT 0x10
++# define CANCTRL_OSM 0x08
++# define CANCTRL_CLKEN 0x04
+ #define TEC 0x1c
+ #define REC 0x1d
+ #define CNF1 0x2a
+@@ -292,7 +293,7 @@ static void mcp251x_clean(struct net_device *net)
+ /*
+ * Note about handling of error return of mcp251x_spi_trans: accessing
+ * registers via SPI is not really different conceptually than using
+- * normal I/O assembler instructions, although it's much more
++ * normal I/O assembly instructions, although it's much more
+ * complicated from a practical POV. So it's not advisable to always
+ * check the return value of this function. Imagine that every
+ * read{b,l}, write{b,l} and friends would be bracketed in "if ( < 0)
+@@ -499,7 +500,7 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx)
+
+ static void mcp251x_hw_sleep(struct spi_device *spi)
+ {
+- mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_SLEEP);
++// mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_SLEEP);
+ }
+
+ static netdev_tx_t mcp251x_hard_start_xmit(struct sk_buff *skb,
+@@ -556,13 +557,16 @@ static int mcp251x_set_normal_mode(struct spi_device *spi)
+
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
+ /* Put device into loopback mode */
+- mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LOOPBACK);
++ mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LOOPBACK | CANCTRL_CLKEN);
+ } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
+ /* Put device into listen-only mode */
+- mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LISTEN_ONLY);
++ mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LISTEN_ONLY | CANCTRL_CLKEN);
+ } else {
+ /* Put device into normal mode */
+- mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL);
++ mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL | CANCTRL_CLKEN);
++
++ netdev_info(priv->net, "CANCTRL: 0x%02x\n",
++ mcp251x_read_reg(spi, CANCTRL));
+
+ /* Wait for the device to enter normal mode */
+ timeout = jiffies + HZ;
+@@ -594,11 +598,15 @@ static int mcp251x_do_set_bittiming(struct net_device *net)
+ (bt->prop_seg - 1));
+ mcp251x_write_bits(spi, CNF3, CNF3_PHSEG2_MASK,
+ (bt->phase_seg2 - 1));
+- dev_info(&spi->dev, "CNF: 0x%02x 0x%02x 0x%02x\n",
++
++ netdev_info(net, "CNF: 0x%02x 0x%02x 0x%02x\n",
+ mcp251x_read_reg(spi, CNF1),
+ mcp251x_read_reg(spi, CNF2),
+ mcp251x_read_reg(spi, CNF3));
+
++ netdev_info(net, "CANCTRL: 0x%02x\n",
++ mcp251x_read_reg(spi, CANCTRL));
++
+ return 0;
+ }
+
+@@ -609,6 +617,7 @@ static int mcp251x_setup(struct net_device *net, struct mcp251x_priv *priv,
+
+ mcp251x_write_reg(spi, RXBCTRL(0),
+ RXBCTRL_BUKT | RXBCTRL_RXM0 | RXBCTRL_RXM1);
++
+ mcp251x_write_reg(spi, RXBCTRL(1),
+ RXBCTRL_RXM0 | RXBCTRL_RXM1);
+ return 0;
+@@ -736,7 +745,9 @@ static void mcp251x_tx_work_handler(struct work_struct *ws)
+ mutex_lock(&priv->mcp_lock);
+ if (priv->tx_skb) {
+ if (priv->can.state == CAN_STATE_BUS_OFF) {
++
+ mcp251x_clean(net);
++
+ } else {
+ frame = (struct can_frame *)priv->tx_skb->data;
+
+@@ -835,21 +846,37 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
+
+ /* Update can state */
+ if (eflag & EFLG_TXBO) {
++
++ netdev_err(net, "err: bus off\n");
++
+ new_state = CAN_STATE_BUS_OFF;
+ can_id |= CAN_ERR_BUSOFF;
+ } else if (eflag & EFLG_TXEP) {
++
++ netdev_err(net, "err: txep\n");
++
+ new_state = CAN_STATE_ERROR_PASSIVE;
+ can_id |= CAN_ERR_CRTL;
+ data1 |= CAN_ERR_CRTL_TX_PASSIVE;
++
+ } else if (eflag & EFLG_RXEP) {
++
++ netdev_err(net, "err: rxep\n");
++
+ new_state = CAN_STATE_ERROR_PASSIVE;
+ can_id |= CAN_ERR_CRTL;
+ data1 |= CAN_ERR_CRTL_RX_PASSIVE;
+ } else if (eflag & EFLG_TXWAR) {
++
++ netdev_err(net, "err: txwar\n");
++
+ new_state = CAN_STATE_ERROR_WARNING;
+ can_id |= CAN_ERR_CRTL;
+ data1 |= CAN_ERR_CRTL_TX_WARNING;
+ } else if (eflag & EFLG_RXWAR) {
++
++ netdev_err(net, "err: rxwar\n");
++
+ new_state = CAN_STATE_ERROR_WARNING;
+ can_id |= CAN_ERR_CRTL;
+ data1 |= CAN_ERR_CRTL_RX_WARNING;
+@@ -927,7 +954,7 @@ static int mcp251x_open(struct net_device *net)
+
+ ret = open_candev(net);
+ if (ret) {
+- dev_err(&spi->dev, "unable to set initial baudrate!\n");
++ netdev_err(net, "failed to open can device\n");
+ return ret;
+ }
+
+@@ -948,7 +975,7 @@ static int mcp251x_open(struct net_device *net)
+ ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
+ flags, DEVICE_NAME, priv);
+ if (ret) {
+- dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
++ netdev_err(net, "failed to acquire irq %d\n", spi->irq);
+ if (pdata->transceiver_enable)
+ pdata->transceiver_enable(0);
+ close_candev(net);
+@@ -1084,7 +1111,7 @@ static int mcp251x_can_probe(struct spi_device *spi)
+
+ ret = register_candev(net);
+ if (!ret) {
+- dev_info(&spi->dev, "probed\n");
++ netdev_info(priv->net, "probed\n");
+ return ret;
+ }
+ error_probe:
diff --git a/patches/linux-3.8.13/0224-add-proper-db.txt-for-CRDA.patch b/patches/linux-3.8.13/0224-add-proper-db.txt-for-CRDA.patch
new file mode 100644
index 0000000..4adc542
--- /dev/null
+++ b/patches/linux-3.8.13/0224-add-proper-db.txt-for-CRDA.patch
@@ -0,0 +1,830 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Thu, 28 Mar 2013 11:10:40 +0100
+Subject: [PATCH] add proper db.txt for CRDA
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ net/wireless/db.txt | 816 +++++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 799 insertions(+), 17 deletions(-)
+
+diff --git a/net/wireless/db.txt b/net/wireless/db.txt
+index a2fc3a0..c5861b8 100644
+--- a/net/wireless/db.txt
++++ b/net/wireless/db.txt
+@@ -1,17 +1,799 @@
+-#
+-# This file is a placeholder to prevent accidental build breakage if someone
+-# enables CONFIG_CFG80211_INTERNAL_REGDB. Almost no one actually needs to
+-# enable that build option.
+-#
+-# You should be using CRDA instead. It is even better if you use the CRDA
+-# package provided by your distribution, since they will probably keep it
+-# up-to-date on your behalf.
+-#
+-# If you _really_ intend to use CONFIG_CFG80211_INTERNAL_REGDB then you will
+-# need to replace this file with one containing appropriately formatted
+-# regulatory rules that cover the regulatory domains you will be using. Your
+-# best option is to extract the db.txt file from the wireless-regdb git
+-# repository:
+-#
+-# git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-regdb.git
+-#
++# This is the world regulatory domain
++country 00:
++ (2402 - 2472 @ 40), (3, 20)
++ # Channel 12 - 13.
++ (2457 - 2482 @ 40), (3, 20), PASSIVE-SCAN, NO-IBSS
++ # Channel 14. Only JP enables this and for 802.11b only
++ (2474 - 2494 @ 20), (3, 20), PASSIVE-SCAN, NO-IBSS, NO-OFDM
++ # Channel 36 - 48
++ (5170 - 5250 @ 40), (3, 20), PASSIVE-SCAN, NO-IBSS
++ # NB: 5260 MHz - 5700 MHz requies DFS
++ # Channel 149 - 165
++ (5735 - 5835 @ 40), (3, 20), PASSIVE-SCAN, NO-IBSS
++
++
++country AD:
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country AE:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++
++country AL:
++ (2402 - 2482 @ 20), (N/A, 20)
++
++country AM:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 20), (N/A, 18)
++ (5250 - 5330 @ 20), (N/A, 18), DFS
++
++country AN:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++
++country AR:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 20), DFS
++ (5490 - 5710 @ 40), (3, 20), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country AT: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country AU:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (3, 23)
++ (5250 - 5330 @ 40), (3, 23), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country AW:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++
++country AZ:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 18)
++ (5250 - 5330 @ 40), (N/A, 18), DFS
++
++country BA: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country BB:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (3, 23)
++ (5250 - 5330 @ 40), (3, 23), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country BD:
++ (2402 - 2482 @ 40), (N/A, 20)
++
++country BE: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country BG: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 23)
++ (5250 - 5290 @ 40), (N/A, 23), DFS
++ (5490 - 5710 @ 40), (N/A, 30), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country BH:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 20), (N/A, 20)
++ (5250 - 5330 @ 20), (N/A, 20), DFS
++ (5735 - 5835 @ 20), (N/A, 20)
++
++country BL:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 18)
++ (5250 - 5330 @ 40), (N/A, 18), DFS
++
++country BN:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5735 - 5835 @ 40), (N/A, 30)
++
++country BO:
++ (2402 - 2482 @ 40), (N/A, 30)
++ (5735 - 5835 @ 40), (N/A, 30)
++
++country BR:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 20), DFS
++ (5490 - 5710 @ 40), (3, 20), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country BY:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++
++country BZ:
++ (2402 - 2482 @ 40), (N/A, 30)
++ (5735 - 5835 @ 40), (N/A, 30)
++
++country CA:
++ (2402 - 2472 @ 40), (3, 27)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 20), DFS
++ (5490 - 5710 @ 40), (3, 20), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country CH: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country CL:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5735 - 5835 @ 40), (N/A, 20)
++
++country CN:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5735 - 5835 @ 40), (N/A, 30)
++ # 60 gHz band channels 1,4: 28dBm, channels 2,3: 44dBm
++ # ref: http://www.miit.gov.cn/n11293472/n11505629/n11506593/n11960250/n11960606/n11960700/n12330791.files/n12330790.pdf
++ (57240 - 59400 @ 2160), (N/A, 28)
++ (59400 - 63720 @ 2160), (N/A, 44)
++ (63720 - 65880 @ 2160), (N/A, 28)
++
++country CO:
++ (2402 - 2472 @ 40), (3, 27)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 23), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country CR:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 20), (3, 17)
++ (5250 - 5330 @ 20), (3, 23), DFS
++ (5735 - 5835 @ 20), (3, 30)
++
++country CS:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++
++country CY: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++# Data from http://www.ctu.eu/164/download/VOR/VOR-12-08-2005-34.pdf
++# and http://www.ctu.eu/164/download/VOR/VOR-12-05-2007-6-AN.pdf
++# Power at 5250 - 5350 MHz and 5470 - 5725 MHz can be doubled if TPC is
++# implemented.
++country CZ: DFS-ETSI
++ (2400 - 2483.5 @ 40), (N/A, 100 mW)
++ (5150 - 5250 @ 40), (N/A, 200 mW), NO-OUTDOOR
++ (5250 - 5350 @ 40), (N/A, 100 mW), NO-OUTDOOR, DFS
++ (5470 - 5725 @ 40), (N/A, 500 mW), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++# Data from "Frequenznutzungsplan" (as published in April 2008), downloaded from
++# http://www.bundesnetzagentur.de/cae/servlet/contentblob/38448/publicationFile/2659/Frequenznutzungsplan2008_Id17448pdf.pdf
++# For the 5GHz range also see
++# http://www.bundesnetzagentur.de/cae/servlet/contentblob/38216/publicationFile/6579/WLAN5GHzVfg7_2010_28042010pdf.pdf
++# The values have been reduced by a factor of 2 (3db) for non TPC devices
++# (in other words: devices with TPC can use twice the tx power of this table).
++# Note that the docs do not require TPC for 5150--5250; the reduction to
++# 100mW thus is not strictly required -- however the conservative 100mW
++# limit is used here as the non-interference with radar and satellite
++# apps relies on the attenuation by the building walls only in the
++# absence of DFS; the neighbour countries have 100mW limit here as well.
++
++country DE: DFS-ETSI
++ # entries 279004 and 280006
++ (2400 - 2483.5 @ 40), (N/A, 100 mW)
++ # entry 303005
++ (5150 - 5250 @ 40), (N/A, 100 mW), NO-OUTDOOR
++ # entries 304002 and 305002
++ (5250 - 5350 @ 40), (N/A, 100 mW), NO-OUTDOOR, DFS
++ # entries 308002, 309001 and 310003
++ (5470 - 5725 @ 40), (N/A, 500 mW), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country DK: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country DO:
++ (2402 - 2472 @ 40), (3, 27)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 23), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country DZ:
++ (2402 - 2482 @ 40), (N/A, 20)
++
++country EC:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 20), (3, 17)
++ (5250 - 5330 @ 20), (3, 23), DFS
++ (5735 - 5835 @ 20), (3, 30)
++
++country EE: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country EG:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 20), (N/A, 20)
++ (5250 - 5330 @ 20), (N/A, 20), DFS
++
++country ES: DFS-ETSI
++ (2400 - 2483.5 @ 40), (N/A, 100 mW)
++ (5150 - 5250 @ 40), (N/A, 100 mW), NO-OUTDOOR
++ (5250 - 5350 @ 40), (N/A, 100 mW), NO-OUTDOOR, DFS
++ (5470 - 5725 @ 40), (N/A, 500 mW), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country FI: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country FR: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country GE:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 18)
++ (5250 - 5330 @ 40), (N/A, 18), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country GB: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country GD:
++ (2402 - 2472 @ 40), (3, 27)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 20), DFS
++ (5490 - 5710 @ 40), (3, 20), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country GR: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country GL: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 20), (N/A, 20)
++ (5250 - 5330 @ 20), (N/A, 20), DFS
++ (5490 - 5710 @ 20), (N/A, 27), DFS
++
++country GT:
++ (2402 - 2472 @ 40), (3, 27)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 23), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country GU:
++ (2402 - 2472 @ 40), (3, 27)
++ (5170 - 5250 @ 20), (3, 17)
++ (5250 - 5330 @ 20), (3, 23), DFS
++ (5735 - 5835 @ 20), (3, 30)
++
++country HN:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 20), DFS
++ (5490 - 5710 @ 40), (3, 20), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country HK:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 20), DFS
++ (5490 - 5710 @ 40), (3, 20), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country HR: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country HT:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++
++country HU: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country ID:
++ (2402 - 2482 @ 40), (N/A, 20)
++
++country IE: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country IL:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5150 - 5250 @ 40), (N/A, 200 mW), NO-OUTDOOR
++ (5250 - 5350 @ 40), (N/A, 200 mW), NO-OUTDOOR, DFS
++
++country IN:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5735 - 5835 @ 40), (N/A, 20)
++
++country IS: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country IR:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5735 - 5835 @ 40), (N/A, 30)
++
++country IT: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country JM:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 20), DFS
++ (5490 - 5710 @ 40), (3, 20), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country JP:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (2474 - 2494 @ 20), (N/A, 20), NO-OFDM
++ (4910 - 4990 @ 40), (N/A, 23)
++ (5030 - 5090 @ 40), (N/A, 23)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 23), DFS
++
++country JO:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 18)
++
++country KE:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5735 - 5835 @ 40), (N/A, 30)
++
++country KH:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++
++country KP:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5330 @ 40), (3, 20)
++ (5160 - 5250 @ 40), (3, 20), DFS
++ (5490 - 5630 @ 40), (3, 30), DFS
++ (5735 - 5815 @ 40), (3, 30)
++
++country KR:
++ (2402 - 2482 @ 20), (N/A, 20)
++ (5170 - 5250 @ 20), (3, 20)
++ (5250 - 5330 @ 20), (3, 20), DFS
++ (5490 - 5630 @ 20), (3, 30), DFS
++ (5735 - 5815 @ 20), (3, 30)
++
++country KW:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++
++country KZ:
++ (2402 - 2482 @ 40), (N/A, 20)
++
++country LB:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5735 - 5835 @ 40), (N/A, 30)
++
++country LI: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++
++country LK:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 20), (3, 17)
++ (5250 - 5330 @ 20), (3, 20), DFS
++ (5490 - 5710 @ 20), (3, 20), DFS
++ (5735 - 5835 @ 20), (3, 30)
++
++country LT: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country LU: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country LV: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country MC: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 18)
++ (5250 - 5330 @ 40), (N/A, 18), DFS
++
++country MA:
++ (2402 - 2482 @ 40), (N/A, 20)
++
++country MO:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (3, 23)
++ (5250 - 5330 @ 40), (3, 23), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country MK: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country MT: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country MY:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 30), DFS
++ (5735 - 5835 @ 40), (N/A, 30)
++
++country MX:
++ (2402 - 2472 @ 40), (3, 27)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 23), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country NL: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20), NO-OUTDOOR
++ (5250 - 5330 @ 40), (N/A, 20), NO-OUTDOOR, DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country NO: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country NP:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5735 - 5835 @ 40), (N/A, 30)
++
++country NZ:
++ (2402 - 2482 @ 40), (N/A, 30)
++ (5170 - 5250 @ 20), (3, 23)
++ (5250 - 5330 @ 20), (3, 23), DFS
++ (5735 - 5835 @ 20), (3, 30)
++
++country OM:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 20), DFS
++ (5490 - 5710 @ 40), (3, 20), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country PA:
++ (2402 - 2472 @ 40), (3, 27)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 23), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country PE:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5735 - 5835 @ 40), (N/A, 30)
++
++country PG:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 23), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country PH:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5735 - 5835 @ 40), (N/A, 30)
++
++country PK:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5735 - 5835 @ 40), (N/A, 30)
++
++country PL: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country PT: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country PR:
++ (2402 - 2472 @ 40), (3, 27)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 23), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country QA:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5735 - 5835 @ 40), (N/A, 30)
++
++country RO: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++
++# Source:
++# http://www.ratel.rs/upload/documents/Plan_namene/Plan_namene-sl_glasnik.pdf
++country RS:
++ (2400 - 2483.5 @ 40), (N/A, 100 mW)
++ (5150 - 5350 @ 40), (N/A, 200 mW), NO-OUTDOOR
++ (5470 - 5725 @ 20), (3, 1000 mW), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country RU:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5735 - 5835 @ 20), (N/A, 30)
++
++country RW:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5735 - 5835 @ 40), (N/A, 30)
++
++country SA:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 20), (3, 23)
++ (5250 - 5330 @ 20), (3, 23), DFS
++ (5735 - 5835 @ 20), (3, 30)
++
++country SE: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country SG:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5735 - 5835 @ 40), (N/A, 20)
++
++country SI: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country SK: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++ (5490 - 5710 @ 40), (N/A, 27), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country SV:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 20), (3, 17)
++ (5250 - 5330 @ 20), (3, 23), DFS
++ (5735 - 5835 @ 20), (3, 30)
++
++country SY:
++ (2402 - 2482 @ 40), (N/A, 20)
++
++country TW:
++ (2402 - 2472 @ 40), (3, 27)
++ (5270 - 5330 @ 40), (3, 17), DFS
++ (5735 - 5815 @ 40), (3, 30)
++
++country TH:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 20), DFS
++ (5490 - 5710 @ 40), (3, 20), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country TT:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 20), DFS
++ (5490 - 5710 @ 40), (3, 20), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country TN:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 20), (N/A, 20)
++ (5250 - 5330 @ 20), (N/A, 20), DFS
++
++country TR: DFS-ETSI
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 20), (N/A, 20)
++ (5250 - 5330 @ 20), (N/A, 20), DFS
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++# Source:
++# #914 / 06 Sep 2007: http://www.ucrf.gov.ua/uk/doc/nkrz/1196068874
++# #1174 / 23 Oct 2008: http://www.nkrz.gov.ua/uk/activities/ruling/1225269361
++# (appendix 8)
++# Listed 5GHz range is a lowest common denominator for all related
++# rules in the referenced laws. Such a range is used because of
++# disputable definitions there.
++country UA:
++ (2400 - 2483.5 @ 40), (N/A, 20), NO-OUTDOOR
++ (5150 - 5350 @ 40), (N/A, 20), NO-OUTDOOR
++ # 60 gHz band channels 1-4, ref: Etsi En 302 567
++ (57240 - 65880 @ 2160), (N/A, 40), NO-OUTDOOR
++
++country US: DFS-FCC
++ (2402 - 2472 @ 40), (3, 27)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 20), DFS
++ (5490 - 5600 @ 40), (3, 20), DFS
++ (5650 - 5710 @ 40), (3, 20), DFS
++ (5735 - 5835 @ 40), (3, 30)
++ # 60g band
++ # reference: http://cfr.regstoday.com/47cfr15.aspx#47_CFR_15p255
++ # channels 1,2,3, EIRP=40dBm(43dBm peak)
++ (57240 - 63720 @ 2160), (N/A, 40)
++
++country UY:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 20), DFS
++ (5490 - 5710 @ 40), (3, 20), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country UZ:
++ (2402 - 2472 @ 40), (3, 27)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 20), DFS
++ (5490 - 5710 @ 40), (3, 20), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country VE:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5735 - 5815 @ 40), (N/A, 23)
++
++country VN:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (N/A, 20)
++ (5250 - 5330 @ 40), (N/A, 20), DFS
++
++country YE:
++ (2402 - 2482 @ 40), (N/A, 20)
++
++country ZA:
++ (2402 - 2482 @ 40), (N/A, 20)
++ (5170 - 5250 @ 40), (3, 17)
++ (5250 - 5330 @ 40), (3, 20), DFS
++ (5490 - 5710 @ 40), (3, 20), DFS
++ (5735 - 5835 @ 40), (3, 30)
++
++country ZW:
++ (2402 - 2482 @ 40), (N/A, 20)
++
diff --git a/patches/linux-3.8.13/0225-mcp251x-add-device-tree-support.patch b/patches/linux-3.8.13/0225-mcp251x-add-device-tree-support.patch
new file mode 100644
index 0000000..6b8eb7c
--- /dev/null
+++ b/patches/linux-3.8.13/0225-mcp251x-add-device-tree-support.patch
@@ -0,0 +1,349 @@
+From: Alessandro Zummo <a.zummo@towertech.it>
+Date: Sat, 25 May 2013 18:20:33 +0200
+Subject: [PATCH] mcp251x: add device tree support
+
+ drivers/net/can/mcp251x.c | 133 +++++++++++++++++++++++++++-------
+ include/linux/can/platform/mcp251x.h | 4 +
+ 2 files changed, 110 insertions(+), 27 deletions(-)
+---
+ drivers/net/can/mcp251x.c | 133 +++++++++++++++++++++++++++-------
+ include/linux/can/platform/mcp251x.h | 4 +
+ 2 files changed, 110 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c
+index 3555ef44..a7f2418 100644
+--- a/drivers/net/can/mcp251x.c
++++ b/drivers/net/can/mcp251x.c
+@@ -1,6 +1,9 @@
+ /*
+ * CAN bus driver for Microchip 251x CAN Controller with SPI Interface
+ *
++ * Copyright (C) 2013 Tower Technologies
++ * Device Tree by Alessandro Zummo <a.zummo@towertech.it>
++ *
+ * MCP2510 support and bug fixes by Christian Pellegrin
+ * <chripell@evolware.org>
+ *
+@@ -72,6 +75,10 @@
+ #include <linux/module.h>
+ #include <linux/netdevice.h>
+ #include <linux/platform_device.h>
++#include <linux/of.h>
++#include <linux/of_platform.h>
++#include <linux/of_gpio.h>
++#include <linux/pinctrl/consumer.h>
+ #include <linux/slab.h>
+ #include <linux/spi/spi.h>
+ #include <linux/uaccess.h>
+@@ -238,9 +245,13 @@ enum mcp251x_model {
+ };
+
+ struct mcp251x_priv {
++
+ struct can_priv can;
+ struct net_device *net;
+ struct spi_device *spi;
++
++ struct mcp251x_platform_data *pdata;
++
+ enum mcp251x_model model;
+
+ struct mutex mcp_lock; /* SPI device lock */
+@@ -500,7 +511,10 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx)
+
+ static void mcp251x_hw_sleep(struct spi_device *spi)
+ {
+-// mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_SLEEP);
++ struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
++
++ if (!priv->pdata->stay_awake)
++ mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_SLEEP);
+ }
+
+ static netdev_tx_t mcp251x_hard_start_xmit(struct sk_buff *skb,
+@@ -557,16 +571,18 @@ static int mcp251x_set_normal_mode(struct spi_device *spi)
+
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
+ /* Put device into loopback mode */
+- mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LOOPBACK | CANCTRL_CLKEN);
++ mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LOOPBACK | (priv->pdata->enable_clkout ? CANCTRL_CLKEN : 0));
++
+ } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) {
+ /* Put device into listen-only mode */
+- mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LISTEN_ONLY | CANCTRL_CLKEN);
++ mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_LISTEN_ONLY | (priv->pdata->enable_clkout ? CANCTRL_CLKEN : 0));
++
+ } else {
+ /* Put device into normal mode */
+- mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL | CANCTRL_CLKEN);
++ mcp251x_write_reg(spi, CANCTRL, CANCTRL_REQOP_NORMAL | (priv->pdata->enable_clkout ? CANCTRL_CLKEN : 0));
+
+- netdev_info(priv->net, "CANCTRL: 0x%02x\n",
+- mcp251x_read_reg(spi, CANCTRL));
++ netdev_info(priv->net, "CANCTRL: 0x%02x\n",
++ mcp251x_read_reg(spi, CANCTRL));
+
+ /* Wait for the device to enter normal mode */
+ timeout = jiffies + HZ;
+@@ -676,7 +692,7 @@ static void mcp251x_open_clean(struct net_device *net)
+ {
+ struct mcp251x_priv *priv = netdev_priv(net);
+ struct spi_device *spi = priv->spi;
+- struct mcp251x_platform_data *pdata = spi->dev.platform_data;
++ struct mcp251x_platform_data *pdata = priv->pdata;
+
+ free_irq(spi->irq, priv);
+ mcp251x_hw_sleep(spi);
+@@ -689,7 +705,7 @@ static int mcp251x_stop(struct net_device *net)
+ {
+ struct mcp251x_priv *priv = netdev_priv(net);
+ struct spi_device *spi = priv->spi;
+- struct mcp251x_platform_data *pdata = spi->dev.platform_data;
++ struct mcp251x_platform_data *pdata = priv->pdata;
+
+ close_candev(net);
+
+@@ -847,13 +863,13 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
+ /* Update can state */
+ if (eflag & EFLG_TXBO) {
+
+- netdev_err(net, "err: bus off\n");
++ netdev_err(net, "err: bus off\n");
+
+ new_state = CAN_STATE_BUS_OFF;
+ can_id |= CAN_ERR_BUSOFF;
+ } else if (eflag & EFLG_TXEP) {
+
+- netdev_err(net, "err: txep\n");
++ netdev_err(net, "err: txep\n");
+
+ new_state = CAN_STATE_ERROR_PASSIVE;
+ can_id |= CAN_ERR_CRTL;
+@@ -861,21 +877,21 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
+
+ } else if (eflag & EFLG_RXEP) {
+
+- netdev_err(net, "err: rxep\n");
++ netdev_err(net, "err: rxep\n");
+
+ new_state = CAN_STATE_ERROR_PASSIVE;
+ can_id |= CAN_ERR_CRTL;
+ data1 |= CAN_ERR_CRTL_RX_PASSIVE;
+ } else if (eflag & EFLG_TXWAR) {
+
+- netdev_err(net, "err: txwar\n");
++ netdev_err(net, "err: txwar\n");
+
+ new_state = CAN_STATE_ERROR_WARNING;
+ can_id |= CAN_ERR_CRTL;
+ data1 |= CAN_ERR_CRTL_TX_WARNING;
+ } else if (eflag & EFLG_RXWAR) {
+
+- netdev_err(net, "err: rxwar\n");
++ netdev_err(net, "err: rxwar\n");
+
+ new_state = CAN_STATE_ERROR_WARNING;
+ can_id |= CAN_ERR_CRTL;
+@@ -948,8 +964,8 @@ static int mcp251x_open(struct net_device *net)
+ {
+ struct mcp251x_priv *priv = netdev_priv(net);
+ struct spi_device *spi = priv->spi;
+- struct mcp251x_platform_data *pdata = spi->dev.platform_data;
+- unsigned long flags;
++ struct mcp251x_platform_data *pdata = priv->pdata;
++ unsigned long flags = 0;
+ int ret;
+
+ ret = open_candev(net);
+@@ -966,14 +982,13 @@ static int mcp251x_open(struct net_device *net)
+ priv->tx_skb = NULL;
+ priv->tx_len = 0;
+
+- flags = IRQF_ONESHOT;
+ if (pdata->irq_flags)
+ flags |= pdata->irq_flags;
+ else
+ flags |= IRQF_TRIGGER_FALLING;
+
+ ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
+- flags, DEVICE_NAME, priv);
++ IRQF_ONESHOT | flags, dev_name(&net->dev), priv);
+ if (ret) {
+ netdev_err(net, "failed to acquire irq %d\n", spi->irq);
+ if (pdata->transceiver_enable)
+@@ -1014,21 +1029,79 @@ static const struct net_device_ops mcp251x_netdev_ops = {
+ .ndo_start_xmit = mcp251x_hard_start_xmit,
+ };
+
++static struct mcp251x_platform_data *
++mcp251x_platform_data_dt_get(struct device *dev)
++{
++ struct device_node *np = dev->of_node;
++ struct mcp251x_platform_data *pd;
++
++ u32 tmp;
++ int err, gpio;
++
++ dev_dbg(dev, "reading device tree\n");
++
++ if (!np) {
++ dev_err(dev, "no device tree node defined\n");
++ return NULL;
++ }
++
++ pd = devm_kzalloc(dev, sizeof(struct mcp251x_platform_data), GFP_KERNEL);
++ if (!pd) {
++ dev_err(dev, "cannot allocate platform data memory\n");
++ return NULL;
++ }
++
++ of_property_read_u32(np, "mcp251x,oscillator-frequency", &tmp);
++ pd->oscillator_frequency = tmp;
++
++ pd->stay_awake = of_property_read_bool(np, "mcp251x,stay-awake");
++ pd->enable_clkout = of_property_read_bool(np, "mcp251x,enable-clkout");
++
++ gpio = of_get_named_gpio(np, "mcp251x,irq-gpios", 0);
++ if (gpio_is_valid(gpio)) {
++ err = devm_gpio_request_one(dev, gpio, GPIOF_DIR_IN, "mcp251x-irq");
++ if (err) {
++ dev_err(dev, "cannot request gpio %d\n", gpio);
++ return NULL;
++ }
++ } else {
++ dev_warn(dev, "mcp251x,irq-gpios missing or invalid\n");
++ }
++
++ return pd;
++}
++
+ static int mcp251x_can_probe(struct spi_device *spi)
+ {
+ struct net_device *net;
+ struct mcp251x_priv *priv;
+ struct mcp251x_platform_data *pdata = spi->dev.platform_data;
++ struct pinctrl *pinctrl;
+ int ret = -ENODEV;
+
+- if (!pdata)
++ dev_dbg(&spi->dev, "probing\n");
++
++ if (!pdata && IS_ENABLED(CONFIG_OF))
++ pdata = mcp251x_platform_data_dt_get(&spi->dev);
++
++ if (!pdata) {
+ /* Platform data is required for osc freq */
++ dev_err(&spi->dev, "missing platform data\n");
+ goto error_out;
++ }
++
++ dev_info(&spi->dev, "mode %d, irq %d, awake %d, clkout %d, oscillator freq %ld\n",
++ spi->mode, spi->irq, pdata->stay_awake, pdata->enable_clkout, pdata->oscillator_frequency);
++
++ pinctrl = devm_pinctrl_get_select_default(&spi->dev);
++ if (IS_ERR(pinctrl))
++ dev_warn(&spi->dev, "pinctrl pins are not configured from the driver");
+
+ /* Allocate can/net device */
+ net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX);
+ if (!net) {
+ ret = -ENOMEM;
++ dev_err(&spi->dev, "alloc_candev failed\n");
+ goto error_alloc;
+ }
+
+@@ -1036,16 +1109,22 @@ static int mcp251x_can_probe(struct spi_device *spi)
+ net->flags |= IFF_ECHO;
+
+ priv = netdev_priv(net);
+- priv->can.bittiming_const = &mcp251x_bittiming_const;
++
++ priv->net = net;
++ priv->spi = spi;
++ priv->pdata = pdata;
++
++ priv->model = spi_get_device_id(spi)->driver_data;
++
+ priv->can.do_set_mode = mcp251x_do_set_mode;
+ priv->can.clock.freq = pdata->oscillator_frequency / 2;
++ priv->can.bittiming_const = &mcp251x_bittiming_const;
++
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
+ CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
+- priv->model = spi_get_device_id(spi)->driver_data;
+- priv->net = net;
++
+ dev_set_drvdata(&spi->dev, priv);
+
+- priv->spi = spi;
+ mutex_init(&priv->mcp_lock);
+
+ /* If requested, allocate DMA buffers */
+@@ -1095,13 +1174,13 @@ static int mcp251x_can_probe(struct spi_device *spi)
+ SET_NETDEV_DEV(net, &spi->dev);
+
+ /* Configure the SPI bus */
+- spi->mode = SPI_MODE_0;
++ //spi->mode = SPI_MODE_0;
+ spi->bits_per_word = 8;
+ spi_setup(spi);
+
+ /* Here is OK to not lock the MCP, no one knows about it yet */
+ if (!mcp251x_hw_probe(spi)) {
+- dev_info(&spi->dev, "Probe failed\n");
++ dev_info(&spi->dev, "hw probe failed\n");
+ goto error_probe;
+ }
+ mcp251x_hw_sleep(spi);
+@@ -1135,8 +1214,8 @@ error_out:
+
+ static int mcp251x_can_remove(struct spi_device *spi)
+ {
+- struct mcp251x_platform_data *pdata = spi->dev.platform_data;
+ struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
++ struct mcp251x_platform_data *pdata = priv->pdata;
+ struct net_device *net = priv->net;
+
+ unregister_candev(net);
+@@ -1159,8 +1238,8 @@ static int mcp251x_can_remove(struct spi_device *spi)
+ #ifdef CONFIG_PM
+ static int mcp251x_can_suspend(struct spi_device *spi, pm_message_t state)
+ {
+- struct mcp251x_platform_data *pdata = spi->dev.platform_data;
+ struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
++ struct mcp251x_platform_data *pdata = priv->pdata;
+ struct net_device *net = priv->net;
+
+ priv->force_quit = 1;
+@@ -1190,8 +1269,8 @@ static int mcp251x_can_suspend(struct spi_device *spi, pm_message_t state)
+
+ static int mcp251x_can_resume(struct spi_device *spi)
+ {
+- struct mcp251x_platform_data *pdata = spi->dev.platform_data;
+ struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
++ struct mcp251x_platform_data *pdata = priv->pdata;
+
+ if (priv->after_suspend & AFTER_SUSPEND_POWER) {
+ pdata->power_enable(1);
+diff --git a/include/linux/can/platform/mcp251x.h b/include/linux/can/platform/mcp251x.h
+index 089fe43..c017922 100644
+--- a/include/linux/can/platform/mcp251x.h
++++ b/include/linux/can/platform/mcp251x.h
+@@ -13,6 +13,8 @@
+ * struct mcp251x_platform_data - MCP251X SPI CAN controller platform data
+ * @oscillator_frequency: - oscillator frequency in Hz
+ * @irq_flags: - IRQF configuration flags
++ * @stay_awake: - avoid entering sleep mode
++ * @enable_clkout: - enable clock output
+ * @board_specific_setup: - called before probing the chip (power,reset)
+ * @transceiver_enable: - called to power on/off the transceiver
+ * @power_enable: - called to power on/off the mcp *and* the
+@@ -26,6 +28,8 @@
+ struct mcp251x_platform_data {
+ unsigned long oscillator_frequency;
+ unsigned long irq_flags;
++ bool stay_awake;
++ bool enable_clkout;
+ int (*board_specific_setup)(struct spi_device *spi);
+ int (*transceiver_enable)(int enable);
+ int (*power_enable) (int enable);
diff --git a/patches/linux-3.8.4/0201-am33xx-Add-clock-for-the-lcdc-DRM-driver.patch b/patches/linux-3.8.13/0226-am33xx-Add-clock-for-the-lcdc-DRM-driver.patch
index 07c4c02..07c4c02 100644
--- a/patches/linux-3.8.4/0201-am33xx-Add-clock-for-the-lcdc-DRM-driver.patch
+++ b/patches/linux-3.8.13/0226-am33xx-Add-clock-for-the-lcdc-DRM-driver.patch
diff --git a/patches/linux-3.8.4/0202-drm-small-fix-in-drm_send_vblank_event.patch b/patches/linux-3.8.13/0227-drm-small-fix-in-drm_send_vblank_event.patch
index 5da4786..5da4786 100644
--- a/patches/linux-3.8.4/0202-drm-small-fix-in-drm_send_vblank_event.patch
+++ b/patches/linux-3.8.13/0227-drm-small-fix-in-drm_send_vblank_event.patch
diff --git a/patches/linux-3.8.4/0203-drm-cma-add-debugfs-helpers.patch b/patches/linux-3.8.13/0228-drm-cma-add-debugfs-helpers.patch
index 4b2e193..4b2e193 100644
--- a/patches/linux-3.8.4/0203-drm-cma-add-debugfs-helpers.patch
+++ b/patches/linux-3.8.13/0228-drm-cma-add-debugfs-helpers.patch
diff --git a/patches/linux-3.8.4/0204-drm-i2c-encoder-helper-wrappers.patch b/patches/linux-3.8.13/0229-drm-i2c-encoder-helper-wrappers.patch
index 20b4185..20b4185 100644
--- a/patches/linux-3.8.4/0204-drm-i2c-encoder-helper-wrappers.patch
+++ b/patches/linux-3.8.13/0229-drm-i2c-encoder-helper-wrappers.patch
diff --git a/patches/linux-3.8.4/0205-drm-nouveau-use-i2c-encoder-helper-wrappers.patch b/patches/linux-3.8.13/0230-drm-nouveau-use-i2c-encoder-helper-wrappers.patch
index 3947e61..3947e61 100644
--- a/patches/linux-3.8.4/0205-drm-nouveau-use-i2c-encoder-helper-wrappers.patch
+++ b/patches/linux-3.8.13/0230-drm-nouveau-use-i2c-encoder-helper-wrappers.patch
diff --git a/patches/linux-3.8.4/0206-drm-i2c-give-i2c-it-s-own-Kconfig.patch b/patches/linux-3.8.13/0231-drm-i2c-give-i2c-it-s-own-Kconfig.patch
index 0bcc67a..0bcc67a 100644
--- a/patches/linux-3.8.4/0206-drm-i2c-give-i2c-it-s-own-Kconfig.patch
+++ b/patches/linux-3.8.13/0231-drm-i2c-give-i2c-it-s-own-Kconfig.patch
diff --git a/patches/linux-3.8.4/0207-drm-tilcdc-add-TI-LCD-Controller-DRM-driver-v4.patch b/patches/linux-3.8.13/0232-drm-tilcdc-add-TI-LCD-Controller-DRM-driver-v4.patch
index 95c1426..95c1426 100644
--- a/patches/linux-3.8.4/0207-drm-tilcdc-add-TI-LCD-Controller-DRM-driver-v4.patch
+++ b/patches/linux-3.8.13/0232-drm-tilcdc-add-TI-LCD-Controller-DRM-driver-v4.patch
diff --git a/patches/linux-3.8.4/0208-drm-i2c-nxp-tda998x-v3.patch b/patches/linux-3.8.13/0233-drm-i2c-nxp-tda998x-v3.patch
index baf650e..baf650e 100644
--- a/patches/linux-3.8.4/0208-drm-i2c-nxp-tda998x-v3.patch
+++ b/patches/linux-3.8.13/0233-drm-i2c-nxp-tda998x-v3.patch
diff --git a/patches/linux-3.8.4/0209-drm-tilcdc-add-encoder-slave.patch b/patches/linux-3.8.13/0234-drm-tilcdc-add-encoder-slave.patch
index 77df96a..77df96a 100644
--- a/patches/linux-3.8.4/0209-drm-tilcdc-add-encoder-slave.patch
+++ b/patches/linux-3.8.13/0234-drm-tilcdc-add-encoder-slave.patch
diff --git a/patches/linux-3.8.4/0210-drm-tilcdc-add-support-for-LCD-panels-v5.patch b/patches/linux-3.8.13/0235-drm-tilcdc-add-support-for-LCD-panels-v5.patch
index 600c74d..600c74d 100644
--- a/patches/linux-3.8.4/0210-drm-tilcdc-add-support-for-LCD-panels-v5.patch
+++ b/patches/linux-3.8.13/0235-drm-tilcdc-add-support-for-LCD-panels-v5.patch
diff --git a/patches/linux-3.8.4/0211-drm-lcdc-Power-control-GPIO-support.patch b/patches/linux-3.8.13/0236-drm-lcdc-Power-control-GPIO-support.patch
index 7db0077..7db0077 100644
--- a/patches/linux-3.8.4/0211-drm-lcdc-Power-control-GPIO-support.patch
+++ b/patches/linux-3.8.13/0236-drm-lcdc-Power-control-GPIO-support.patch
diff --git a/patches/linux-3.8.13/0237-drm-tilcdc-Fix-scheduling-while-atomic-from-irq-hand.patch b/patches/linux-3.8.13/0237-drm-tilcdc-Fix-scheduling-while-atomic-from-irq-hand.patch
new file mode 100644
index 0000000..11bba34
--- /dev/null
+++ b/patches/linux-3.8.13/0237-drm-tilcdc-Fix-scheduling-while-atomic-from-irq-hand.patch
@@ -0,0 +1,53 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 3 Jun 2013 17:57:18 +0300
+Subject: [PATCH] drm: tilcdc: Fix scheduling while atomic from irq handler.
+
+Fix the crash by not making pm_runtime calls while in the irq.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+index 5dd3c7d..9f10f05 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+@@ -66,7 +66,6 @@ static void set_scanout(struct drm_crtc *crtc, int n)
+ struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+
+- pm_runtime_get_sync(dev->dev);
+ tilcdc_write(dev, base_reg[n], tilcdc_crtc->start);
+ tilcdc_write(dev, ceil_reg[n], tilcdc_crtc->end);
+ if (tilcdc_crtc->scanout[n]) {
+@@ -82,7 +81,6 @@ static void set_scanout(struct drm_crtc *crtc, int n)
+ tilcdc_crtc->scanout[n] = crtc->fb;
+ drm_framebuffer_reference(tilcdc_crtc->scanout[n]);
+ tilcdc_crtc->dirty &= ~stat[n];
+- pm_runtime_put_sync(dev->dev);
+ }
+
+ static void update_scanout(struct drm_crtc *crtc)
+@@ -165,7 +163,9 @@ static int tilcdc_crtc_page_flip(struct drm_crtc *crtc,
+
+ crtc->fb = fb;
+ tilcdc_crtc->event = event;
++ pm_runtime_get_sync(dev->dev);
+ update_scanout(crtc);
++ pm_runtime_put_sync(dev->dev);
+
+ return 0;
+ }
+@@ -380,7 +380,11 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
+ static int tilcdc_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+ struct drm_framebuffer *old_fb)
+ {
++ struct drm_device *dev = crtc->dev;
++
++ pm_runtime_get_sync(dev->dev);
+ update_scanout(crtc);
++ pm_runtime_put_sync(dev->dev);
+ return 0;
+ }
+
diff --git a/patches/linux-3.8.4/0212-add-dvi-pinmuxes-to-am33xx.dtsi.patch b/patches/linux-3.8.13/0238-add-dvi-pinmuxes-to-am33xx.dtsi.patch
index 01405b4..01405b4 100644
--- a/patches/linux-3.8.4/0212-add-dvi-pinmuxes-to-am33xx.dtsi.patch
+++ b/patches/linux-3.8.13/0238-add-dvi-pinmuxes-to-am33xx.dtsi.patch
diff --git a/patches/linux-3.8.4/0213-add-defconfig-file-to-use-as-.config.patch b/patches/linux-3.8.13/0239-add-defconfig-file-to-use-as-.config.patch
index d4c4b14..d4c4b14 100644
--- a/patches/linux-3.8.4/0213-add-defconfig-file-to-use-as-.config.patch
+++ b/patches/linux-3.8.13/0239-add-defconfig-file-to-use-as-.config.patch
diff --git a/patches/linux-3.8.4/0214-am33xx-musb-Add-OF-definitions.patch b/patches/linux-3.8.13/0240-am33xx-musb-Add-OF-definitions.patch
index 0613a09..0613a09 100644
--- a/patches/linux-3.8.4/0214-am33xx-musb-Add-OF-definitions.patch
+++ b/patches/linux-3.8.13/0240-am33xx-musb-Add-OF-definitions.patch
diff --git a/patches/linux-3.8.4/0215-Mark-the-device-as-PRIVATE.patch b/patches/linux-3.8.13/0241-Mark-the-device-as-PRIVATE.patch
index 6f83bb1..6f83bb1 100644
--- a/patches/linux-3.8.4/0215-Mark-the-device-as-PRIVATE.patch
+++ b/patches/linux-3.8.13/0241-Mark-the-device-as-PRIVATE.patch
diff --git a/patches/linux-3.8.4/0216-omap_hsmmc-Bug-fixes-pinctl-gpio-reset.patch b/patches/linux-3.8.13/0242-omap_hsmmc-Bug-fixes-pinctl-gpio-reset.patch
index 3cee9e0..3cee9e0 100644
--- a/patches/linux-3.8.4/0216-omap_hsmmc-Bug-fixes-pinctl-gpio-reset.patch
+++ b/patches/linux-3.8.13/0242-omap_hsmmc-Bug-fixes-pinctl-gpio-reset.patch
diff --git a/patches/linux-3.8.4/0217-tps65217-bl-Locate-backlight-node-correctly.patch b/patches/linux-3.8.13/0243-tps65217-bl-Locate-backlight-node-correctly.patch
index 18c903b..18c903b 100644
--- a/patches/linux-3.8.4/0217-tps65217-bl-Locate-backlight-node-correctly.patch
+++ b/patches/linux-3.8.13/0243-tps65217-bl-Locate-backlight-node-correctly.patch
diff --git a/patches/linux-3.8.4/0218-arm-Export-cache-flush-management-symbols-when-MULTI.patch b/patches/linux-3.8.13/0244-arm-Export-cache-flush-management-symbols-when-MULTI.patch
index 7dd8b13..7dd8b13 100644
--- a/patches/linux-3.8.4/0218-arm-Export-cache-flush-management-symbols-when-MULTI.patch
+++ b/patches/linux-3.8.13/0244-arm-Export-cache-flush-management-symbols-when-MULTI.patch
diff --git a/patches/linux-3.8.4/0219-am335x-bone-dtsi-Clean-up.patch b/patches/linux-3.8.13/0245-am335x-bone-dtsi-Clean-up.patch
index 7eb4697..7eb4697 100644
--- a/patches/linux-3.8.4/0219-am335x-bone-dtsi-Clean-up.patch
+++ b/patches/linux-3.8.13/0245-am335x-bone-dtsi-Clean-up.patch
diff --git a/patches/linux-3.8.4/0220-am335x-bone-dtsi-Introduce-new-I2C-entries.patch b/patches/linux-3.8.13/0246-am335x-bone-dtsi-Introduce-new-I2C-entries.patch
index df0ad85..df0ad85 100644
--- a/patches/linux-3.8.4/0220-am335x-bone-dtsi-Introduce-new-I2C-entries.patch
+++ b/patches/linux-3.8.13/0246-am335x-bone-dtsi-Introduce-new-I2C-entries.patch
diff --git a/patches/linux-3.8.4/0221-am335x-dt-Add-I2C0-pinctrl-entries.patch b/patches/linux-3.8.13/0247-am335x-dt-Add-I2C0-pinctrl-entries.patch
index 4889713..4889713 100644
--- a/patches/linux-3.8.4/0221-am335x-dt-Add-I2C0-pinctrl-entries.patch
+++ b/patches/linux-3.8.13/0247-am335x-dt-Add-I2C0-pinctrl-entries.patch
diff --git a/patches/linux-3.8.4/0222-Cleanup-am33xx.dtsi.patch b/patches/linux-3.8.13/0248-Cleanup-am33xx.dtsi.patch
index 5308f2e..5308f2e 100644
--- a/patches/linux-3.8.4/0222-Cleanup-am33xx.dtsi.patch
+++ b/patches/linux-3.8.13/0248-Cleanup-am33xx.dtsi.patch
diff --git a/patches/linux-3.8.4/0223-Fix-platform-device-resource-linking.patch b/patches/linux-3.8.13/0249-Fix-platform-device-resource-linking.patch
index e1bcc35..e1bcc35 100644
--- a/patches/linux-3.8.4/0223-Fix-platform-device-resource-linking.patch
+++ b/patches/linux-3.8.13/0249-Fix-platform-device-resource-linking.patch
diff --git a/patches/linux-3.8.4/0224-Link-platform-device-resources-properly.patch b/patches/linux-3.8.13/0250-Link-platform-device-resources-properly.patch
index a503bbb..a503bbb 100644
--- a/patches/linux-3.8.4/0224-Link-platform-device-resources-properly.patch
+++ b/patches/linux-3.8.13/0250-Link-platform-device-resources-properly.patch
diff --git a/patches/linux-3.8.4/0225-Properly-handle-resources-for-omap_devices.patch b/patches/linux-3.8.13/0251-Properly-handle-resources-for-omap_devices.patch
index 92b22e2..92b22e2 100644
--- a/patches/linux-3.8.4/0225-Properly-handle-resources-for-omap_devices.patch
+++ b/patches/linux-3.8.13/0251-Properly-handle-resources-for-omap_devices.patch
diff --git a/patches/linux-3.8.4/0226-omap-Avoid-crashes-in-the-case-of-hwmod-misconfigura.patch b/patches/linux-3.8.13/0252-omap-Avoid-crashes-in-the-case-of-hwmod-misconfigura.patch
index 0527d5f..0527d5f 100644
--- a/patches/linux-3.8.4/0226-omap-Avoid-crashes-in-the-case-of-hwmod-misconfigura.patch
+++ b/patches/linux-3.8.13/0252-omap-Avoid-crashes-in-the-case-of-hwmod-misconfigura.patch
diff --git a/patches/linux-3.8.4/0227-i2c-EEPROM-In-kernel-memory-accessor-interface.patch b/patches/linux-3.8.13/0253-i2c-EEPROM-In-kernel-memory-accessor-interface.patch
index 307ee7d..307ee7d 100644
--- a/patches/linux-3.8.4/0227-i2c-EEPROM-In-kernel-memory-accessor-interface.patch
+++ b/patches/linux-3.8.13/0253-i2c-EEPROM-In-kernel-memory-accessor-interface.patch
diff --git a/patches/linux-3.8.4/0228-Fix-util_is_printable_string.patch b/patches/linux-3.8.13/0254-Fix-util_is_printable_string.patch
index dbbfd6c..dbbfd6c 100644
--- a/patches/linux-3.8.4/0228-Fix-util_is_printable_string.patch
+++ b/patches/linux-3.8.13/0254-Fix-util_is_printable_string.patch
diff --git a/patches/linux-3.8.4/0229-fdtdump-properly-handle-multi-string-properties.patch b/patches/linux-3.8.13/0255-fdtdump-properly-handle-multi-string-properties.patch
index 9060d99..9060d99 100644
--- a/patches/linux-3.8.4/0229-fdtdump-properly-handle-multi-string-properties.patch
+++ b/patches/linux-3.8.13/0255-fdtdump-properly-handle-multi-string-properties.patch
diff --git a/patches/linux-3.8.4/0230-dtc-Dynamic-symbols-fixup-support.patch b/patches/linux-3.8.13/0256-dtc-Dynamic-symbols-fixup-support.patch
index fd446cb..fd446cb 100644
--- a/patches/linux-3.8.4/0230-dtc-Dynamic-symbols-fixup-support.patch
+++ b/patches/linux-3.8.13/0256-dtc-Dynamic-symbols-fixup-support.patch
diff --git a/patches/linux-3.8.4/0231-dtc-Add-DTCO-rule-for-DTB-objects.patch b/patches/linux-3.8.13/0257-dtc-Add-DTCO-rule-for-DTB-objects.patch
index 4b487ce..4b487ce 100644
--- a/patches/linux-3.8.4/0231-dtc-Add-DTCO-rule-for-DTB-objects.patch
+++ b/patches/linux-3.8.13/0257-dtc-Add-DTCO-rule-for-DTB-objects.patch
diff --git a/patches/linux-3.8.4/0232-OF-Compile-Device-Tree-sources-with-resolve-option.patch b/patches/linux-3.8.13/0258-OF-Compile-Device-Tree-sources-with-resolve-option.patch
index 6501e2b..6501e2b 100644
--- a/patches/linux-3.8.4/0232-OF-Compile-Device-Tree-sources-with-resolve-option.patch
+++ b/patches/linux-3.8.13/0258-OF-Compile-Device-Tree-sources-with-resolve-option.patch
diff --git a/patches/linux-3.8.4/0233-firmware-update-.gitignore-with-dtbo-objects.patch b/patches/linux-3.8.13/0259-firmware-update-.gitignore-with-dtbo-objects.patch
index c677b8a..c677b8a 100644
--- a/patches/linux-3.8.4/0233-firmware-update-.gitignore-with-dtbo-objects.patch
+++ b/patches/linux-3.8.13/0259-firmware-update-.gitignore-with-dtbo-objects.patch
diff --git a/patches/linux-3.8.4/0234-OF-Introduce-device-tree-node-flag-helpers.patch b/patches/linux-3.8.13/0260-OF-Introduce-device-tree-node-flag-helpers.patch
index d7da53d..d7da53d 100644
--- a/patches/linux-3.8.4/0234-OF-Introduce-device-tree-node-flag-helpers.patch
+++ b/patches/linux-3.8.13/0260-OF-Introduce-device-tree-node-flag-helpers.patch
diff --git a/patches/linux-3.8.4/0235-OF-export-of_property_notify.patch b/patches/linux-3.8.13/0261-OF-export-of_property_notify.patch
index d50566a..d50566a 100644
--- a/patches/linux-3.8.4/0235-OF-export-of_property_notify.patch
+++ b/patches/linux-3.8.13/0261-OF-export-of_property_notify.patch
diff --git a/patches/linux-3.8.4/0236-OF-Export-all-DT-proc-update-functions.patch b/patches/linux-3.8.13/0262-OF-Export-all-DT-proc-update-functions.patch
index ae1674b..ae1674b 100644
--- a/patches/linux-3.8.4/0236-OF-Export-all-DT-proc-update-functions.patch
+++ b/patches/linux-3.8.13/0262-OF-Export-all-DT-proc-update-functions.patch
diff --git a/patches/linux-3.8.4/0237-OF-Introduce-utility-helper-functions.patch b/patches/linux-3.8.13/0263-OF-Introduce-utility-helper-functions.patch
index ad63055..ad63055 100644
--- a/patches/linux-3.8.4/0237-OF-Introduce-utility-helper-functions.patch
+++ b/patches/linux-3.8.13/0263-OF-Introduce-utility-helper-functions.patch
diff --git a/patches/linux-3.8.4/0238-OF-Introduce-Device-Tree-resolve-support.patch b/patches/linux-3.8.13/0264-OF-Introduce-Device-Tree-resolve-support.patch
index 57949d0..57949d0 100644
--- a/patches/linux-3.8.4/0238-OF-Introduce-Device-Tree-resolve-support.patch
+++ b/patches/linux-3.8.13/0264-OF-Introduce-Device-Tree-resolve-support.patch
diff --git a/patches/linux-3.8.4/0239-OF-Introduce-DT-overlay-support.patch b/patches/linux-3.8.13/0265-OF-Introduce-DT-overlay-support.patch
index d863bb6..d863bb6 100644
--- a/patches/linux-3.8.4/0239-OF-Introduce-DT-overlay-support.patch
+++ b/patches/linux-3.8.13/0265-OF-Introduce-DT-overlay-support.patch
diff --git a/patches/linux-3.8.4/0240-capemgr-Capemgr-makefiles-and-Kconfig-fragments.patch b/patches/linux-3.8.13/0266-capemgr-Capemgr-makefiles-and-Kconfig-fragments.patch
index c4ecff8..c4ecff8 100644
--- a/patches/linux-3.8.4/0240-capemgr-Capemgr-makefiles-and-Kconfig-fragments.patch
+++ b/patches/linux-3.8.13/0266-capemgr-Capemgr-makefiles-and-Kconfig-fragments.patch
diff --git a/patches/linux-3.8.4/0241-capemgr-Beaglebone-capemanager.patch b/patches/linux-3.8.13/0267-capemgr-Beaglebone-capemanager.patch
index 18bdda4..18bdda4 100644
--- a/patches/linux-3.8.4/0241-capemgr-Beaglebone-capemanager.patch
+++ b/patches/linux-3.8.13/0267-capemgr-Beaglebone-capemanager.patch
diff --git a/patches/linux-3.8.4/0242-capemgr-Add-beaglebone-s-cape-driver-bindings.patch b/patches/linux-3.8.13/0268-capemgr-Add-beaglebone-s-cape-driver-bindings.patch
index ad38175..ad38175 100644
--- a/patches/linux-3.8.4/0242-capemgr-Add-beaglebone-s-cape-driver-bindings.patch
+++ b/patches/linux-3.8.13/0268-capemgr-Add-beaglebone-s-cape-driver-bindings.patch
diff --git a/patches/linux-3.8.4/0243-capemgr-am33xx-family-DT-bindings.patch b/patches/linux-3.8.13/0269-capemgr-am33xx-family-DT-bindings.patch
index 1182e83..1182e83 100644
--- a/patches/linux-3.8.4/0243-capemgr-am33xx-family-DT-bindings.patch
+++ b/patches/linux-3.8.13/0269-capemgr-am33xx-family-DT-bindings.patch
diff --git a/patches/linux-3.8.4/0244-bone-geiger-Geiger-bone-driver.patch b/patches/linux-3.8.13/0270-bone-geiger-Geiger-bone-driver.patch
index af2a4ec..af2a4ec 100644
--- a/patches/linux-3.8.4/0244-bone-geiger-Geiger-bone-driver.patch
+++ b/patches/linux-3.8.13/0270-bone-geiger-Geiger-bone-driver.patch
diff --git a/patches/linux-3.8.4/0245-capemgr-firmware-makefiles-for-DT-objects.patch b/patches/linux-3.8.13/0271-capemgr-firmware-makefiles-for-DT-objects.patch
index 9c93d29..9c93d29 100644
--- a/patches/linux-3.8.4/0245-capemgr-firmware-makefiles-for-DT-objects.patch
+++ b/patches/linux-3.8.13/0271-capemgr-firmware-makefiles-for-DT-objects.patch
diff --git a/patches/linux-3.8.4/0246-capemgr-emmc2-cape-definition.patch b/patches/linux-3.8.13/0272-capemgr-emmc2-cape-definition.patch
index e6e8183..e6e8183 100644
--- a/patches/linux-3.8.4/0246-capemgr-emmc2-cape-definition.patch
+++ b/patches/linux-3.8.13/0272-capemgr-emmc2-cape-definition.patch
diff --git a/patches/linux-3.8.4/0247-capemgr-DVI-capes-definitions.patch b/patches/linux-3.8.13/0273-capemgr-DVI-capes-definitions.patch
index 7e40c66..7e40c66 100644
--- a/patches/linux-3.8.4/0247-capemgr-DVI-capes-definitions.patch
+++ b/patches/linux-3.8.13/0273-capemgr-DVI-capes-definitions.patch
diff --git a/patches/linux-3.8.4/0248-capemgr-Geiger-cape-definition.patch b/patches/linux-3.8.13/0274-capemgr-Geiger-cape-definition.patch
index bebe565..e20c3ac 100644
--- a/patches/linux-3.8.4/0248-capemgr-Geiger-cape-definition.patch
+++ b/patches/linux-3.8.13/0274-capemgr-Geiger-cape-definition.patch
@@ -12,7 +12,7 @@ Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
diff --git a/firmware/capes/cape-bone-geiger-00A0.dts b/firmware/capes/cape-bone-geiger-00A0.dts
new file mode 100644
-index 0000000..aded3f5
+index 0000000..4003161
--- /dev/null
+++ b/firmware/capes/cape-bone-geiger-00A0.dts
@@ -0,0 +1,98 @@
@@ -88,7 +88,7 @@ index 0000000..aded3f5
+
+ tscadc-cape-geiger {
+ compatible = "ti-tscadc-dt";
-+ adc-channels = <8>;
++ adc-channels = <0 1 2 3 4 5 6 7>;
+ };
+
+ bone-cape-geiger {
diff --git a/patches/linux-3.8.4/0249-capemgr-LCD3-cape-definition.patch b/patches/linux-3.8.13/0275-capemgr-LCD3-cape-definition.patch
index 0b79e1c..0b79e1c 100644
--- a/patches/linux-3.8.4/0249-capemgr-LCD3-cape-definition.patch
+++ b/patches/linux-3.8.13/0275-capemgr-LCD3-cape-definition.patch
diff --git a/patches/linux-3.8.4/0250-capemgr-Add-weather-cape-definition.patch b/patches/linux-3.8.13/0276-capemgr-Add-weather-cape-definition.patch
index 90204c0..90204c0 100644
--- a/patches/linux-3.8.4/0250-capemgr-Add-weather-cape-definition.patch
+++ b/patches/linux-3.8.13/0276-capemgr-Add-weather-cape-definition.patch
diff --git a/patches/linux-3.8.4/0251-ehrpwm-add-missing-dts-nodes.patch b/patches/linux-3.8.13/0277-ehrpwm-add-missing-dts-nodes.patch
index 05677e3..05677e3 100644
--- a/patches/linux-3.8.4/0251-ehrpwm-add-missing-dts-nodes.patch
+++ b/patches/linux-3.8.13/0277-ehrpwm-add-missing-dts-nodes.patch
diff --git a/patches/linux-3.8.4/0252-am33xx-DT-Update-am33xx.dsi-with-the-new-PWM-DT-bind.patch b/patches/linux-3.8.13/0278-am33xx-DT-Update-am33xx.dsi-with-the-new-PWM-DT-bind.patch
index 240dfee..240dfee 100644
--- a/patches/linux-3.8.4/0252-am33xx-DT-Update-am33xx.dsi-with-the-new-PWM-DT-bind.patch
+++ b/patches/linux-3.8.13/0278-am33xx-DT-Update-am33xx.dsi-with-the-new-PWM-DT-bind.patch
diff --git a/patches/linux-3.8.4/0253-geiger-cape-Update-to-using-the-new-PWM-interface.patch b/patches/linux-3.8.13/0279-geiger-cape-Update-to-using-the-new-PWM-interface.patch
index 6557165..7eb22c7 100644
--- a/patches/linux-3.8.4/0253-geiger-cape-Update-to-using-the-new-PWM-interface.patch
+++ b/patches/linux-3.8.13/0279-geiger-cape-Update-to-using-the-new-PWM-interface.patch
@@ -10,7 +10,7 @@ Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/firmware/capes/cape-bone-geiger-00A0.dts b/firmware/capes/cape-bone-geiger-00A0.dts
-index aded3f5..18bf1f2 100644
+index 4003161..67ec568 100644
--- a/firmware/capes/cape-bone-geiger-00A0.dts
+++ b/firmware/capes/cape-bone-geiger-00A0.dts
@@ -36,6 +36,13 @@
diff --git a/patches/linux-3.8.4/0254-lcd3-cape-Change-into-using-the-lcdc-DRM-driver-inst.patch b/patches/linux-3.8.13/0280-lcd3-cape-Change-into-using-the-lcdc-DRM-driver-inst.patch
index 5fb1f33..5fb1f33 100644
--- a/patches/linux-3.8.4/0254-lcd3-cape-Change-into-using-the-lcdc-DRM-driver-inst.patch
+++ b/patches/linux-3.8.13/0280-lcd3-cape-Change-into-using-the-lcdc-DRM-driver-inst.patch
diff --git a/patches/linux-3.8.4/0255-am33xx-Add-default-config.patch b/patches/linux-3.8.13/0281-am33xx-Add-default-config.patch
index 6fc4763..6fc4763 100644
--- a/patches/linux-3.8.4/0255-am33xx-Add-default-config.patch
+++ b/patches/linux-3.8.13/0281-am33xx-Add-default-config.patch
diff --git a/patches/linux-3.8.4/0256-lcd3-cape-Convert-to-using-the-proper-touchscreen-dr.patch b/patches/linux-3.8.13/0282-lcd3-cape-Convert-to-using-the-proper-touchscreen-dr.patch
index 1c7eef0..f40e259 100644
--- a/patches/linux-3.8.4/0256-lcd3-cape-Convert-to-using-the-proper-touchscreen-dr.patch
+++ b/patches/linux-3.8.13/0282-lcd3-cape-Convert-to-using-the-proper-touchscreen-dr.patch
@@ -10,7 +10,7 @@ Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
1 file changed, 15 insertions(+), 18 deletions(-)
diff --git a/firmware/capes/cape-bone-lcd3-00A0.dts b/firmware/capes/cape-bone-lcd3-00A0.dts
-index 83a6d88..2d806c8 100644
+index 83a6d88..b0784b2 100644
--- a/firmware/capes/cape-bone-lcd3-00A0.dts
+++ b/firmware/capes/cape-bone-lcd3-00A0.dts
@@ -87,13 +87,23 @@
@@ -31,7 +31,7 @@ index 83a6d88..2d806c8 100644
+ tsc {
+ wires = <4>;
+ x-plate-resistance = <200>;
-+ steps-to-configure = <5>;
++ coordinate-readouts = <5>;
+ wire-config = <0x00 0x11 0x22 0x33>;
+ };
diff --git a/patches/linux-3.8.4/0257-geiger-cape-Convert-to-using-the-new-ADC-driver.patch b/patches/linux-3.8.13/0283-geiger-cape-Convert-to-using-the-new-ADC-driver.patch
index 87d863f..e1276a4 100644
--- a/patches/linux-3.8.4/0257-geiger-cape-Convert-to-using-the-new-ADC-driver.patch
+++ b/patches/linux-3.8.13/0283-geiger-cape-Convert-to-using-the-new-ADC-driver.patch
@@ -10,7 +10,7 @@ Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/firmware/capes/cape-bone-geiger-00A0.dts b/firmware/capes/cape-bone-geiger-00A0.dts
-index 18bf1f2..287d75c 100644
+index 67ec568..39e7d38 100644
--- a/firmware/capes/cape-bone-geiger-00A0.dts
+++ b/firmware/capes/cape-bone-geiger-00A0.dts
@@ -54,6 +54,10 @@
@@ -30,7 +30,7 @@ index 18bf1f2..287d75c 100644
- tscadc-cape-geiger {
- compatible = "ti-tscadc-dt";
-- adc-channels = <8>;
+- adc-channels = <0 1 2 3 4 5 6 7>;
+ tscadc {
+ compatible = "ti,ti-tscadc";
+ reg = <0x44e0d000 0x1000>;
@@ -40,7 +40,7 @@ index 18bf1f2..287d75c 100644
+ ti,hwmods = "adc_tsc";
+
+ adc {
-+ adc-channels = <8>;
++ adc-channels = <0 1 2 3 4 5 6 7>;
+ };
};
diff --git a/patches/linux-3.8.4/0258-cape-dvi-Convert-DVI-capes-to-the-new-LCDC-DRM-drive.patch b/patches/linux-3.8.13/0284-cape-dvi-Convert-DVI-capes-to-the-new-LCDC-DRM-drive.patch
index 102be9c..102be9c 100644
--- a/patches/linux-3.8.4/0258-cape-dvi-Convert-DVI-capes-to-the-new-LCDC-DRM-drive.patch
+++ b/patches/linux-3.8.13/0284-cape-dvi-Convert-DVI-capes-to-the-new-LCDC-DRM-drive.patch
diff --git a/patches/linux-3.8.4/0259-boneblack-Add-default-HDMI-cape.patch b/patches/linux-3.8.13/0285-boneblack-Add-default-HDMI-cape.patch
index 657b243..657b243 100644
--- a/patches/linux-3.8.4/0259-boneblack-Add-default-HDMI-cape.patch
+++ b/patches/linux-3.8.13/0285-boneblack-Add-default-HDMI-cape.patch
diff --git a/patches/linux-3.8.4/0260-cape-bone-dvi-Use-720p-mode-as-default.patch b/patches/linux-3.8.13/0286-cape-bone-dvi-Use-720p-mode-as-default.patch
index 9055f57..9055f57 100644
--- a/patches/linux-3.8.4/0260-cape-bone-dvi-Use-720p-mode-as-default.patch
+++ b/patches/linux-3.8.13/0286-cape-bone-dvi-Use-720p-mode-as-default.patch
diff --git a/patches/linux-3.8.4/0261-am33xx.dtsi-Make-the-MUSB-not-crash-on-load.patch b/patches/linux-3.8.13/0287-am33xx.dtsi-Make-the-MUSB-not-crash-on-load.patch
index 28d8122..28d8122 100644
--- a/patches/linux-3.8.4/0261-am33xx.dtsi-Make-the-MUSB-not-crash-on-load.patch
+++ b/patches/linux-3.8.13/0287-am33xx.dtsi-Make-the-MUSB-not-crash-on-load.patch
diff --git a/patches/linux-3.8.4/0262-regulator-DUMMY_REGULATOR-should-work-for-OF-too.patch b/patches/linux-3.8.13/0288-regulator-DUMMY_REGULATOR-should-work-for-OF-too.patch
index 3f18431..86988a7 100644
--- a/patches/linux-3.8.4/0262-regulator-DUMMY_REGULATOR-should-work-for-OF-too.patch
+++ b/patches/linux-3.8.13/0288-regulator-DUMMY_REGULATOR-should-work-for-OF-too.patch
@@ -11,7 +11,7 @@ Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
1 file changed, 2 insertions(+)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
-index 53abc98..9198104 100644
+index 8e7ec07..b160fcc 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -3786,6 +3786,7 @@ static int __init regulator_init_complete(void)
diff --git a/patches/linux-3.8.4/0263-OF-Overlay-Remove-excessive-debugging-crud.patch b/patches/linux-3.8.13/0289-OF-Overlay-Remove-excessive-debugging-crud.patch
index 93bd52b..93bd52b 100644
--- a/patches/linux-3.8.4/0263-OF-Overlay-Remove-excessive-debugging-crud.patch
+++ b/patches/linux-3.8.13/0289-OF-Overlay-Remove-excessive-debugging-crud.patch
diff --git a/patches/linux-3.8.4/0264-of-i2c-Export-single-device-registration-method.patch b/patches/linux-3.8.13/0290-of-i2c-Export-single-device-registration-method.patch
index f0f1f25..f0f1f25 100644
--- a/patches/linux-3.8.4/0264-of-i2c-Export-single-device-registration-method.patch
+++ b/patches/linux-3.8.13/0290-of-i2c-Export-single-device-registration-method.patch
diff --git a/patches/linux-3.8.4/0265-OF-Overlay-I2C-client-devices-special-handling.patch b/patches/linux-3.8.13/0291-OF-Overlay-I2C-client-devices-special-handling.patch
index 2b9fefa..2b9fefa 100644
--- a/patches/linux-3.8.4/0265-OF-Overlay-I2C-client-devices-special-handling.patch
+++ b/patches/linux-3.8.13/0291-OF-Overlay-I2C-client-devices-special-handling.patch
diff --git a/patches/linux-3.8.4/0266-omap-Fix-bug-on-partial-resource-addition.patch b/patches/linux-3.8.13/0292-omap-Fix-bug-on-partial-resource-addition.patch
index ce1c728..ce1c728 100644
--- a/patches/linux-3.8.4/0266-omap-Fix-bug-on-partial-resource-addition.patch
+++ b/patches/linux-3.8.13/0292-omap-Fix-bug-on-partial-resource-addition.patch
diff --git a/patches/linux-3.8.4/0267-ASoC-davinci-mcasp-Add-pinctrl-support.patch b/patches/linux-3.8.13/0293-ASoC-davinci-mcasp-Add-pinctrl-support.patch
index b296f5d..b296f5d 100644
--- a/patches/linux-3.8.4/0267-ASoC-davinci-mcasp-Add-pinctrl-support.patch
+++ b/patches/linux-3.8.13/0293-ASoC-davinci-mcasp-Add-pinctrl-support.patch
diff --git a/patches/linux-3.8.4/0268-ASoC-Davinci-machine-Add-device-tree-binding.patch b/patches/linux-3.8.13/0294-ASoC-Davinci-machine-Add-device-tree-binding.patch
index 3a5144b..3a5144b 100644
--- a/patches/linux-3.8.4/0268-ASoC-Davinci-machine-Add-device-tree-binding.patch
+++ b/patches/linux-3.8.13/0294-ASoC-Davinci-machine-Add-device-tree-binding.patch
diff --git a/patches/linux-3.8.4/0269-am33xx-Add-mcasp0-and-mcasp1-device-tree-entries.patch b/patches/linux-3.8.13/0295-am33xx-Add-mcasp0-and-mcasp1-device-tree-entries.patch
index a4aa777..a4aa777 100644
--- a/patches/linux-3.8.4/0269-am33xx-Add-mcasp0-and-mcasp1-device-tree-entries.patch
+++ b/patches/linux-3.8.13/0295-am33xx-Add-mcasp0-and-mcasp1-device-tree-entries.patch
diff --git a/patches/linux-3.8.4/0270-ASoC-dts-OMAP2-AM33xx-HACK-Add-missing-dma-info.patch b/patches/linux-3.8.13/0296-ASoC-dts-OMAP2-AM33xx-HACK-Add-missing-dma-info.patch
index d80e200..d80e200 100644
--- a/patches/linux-3.8.4/0270-ASoC-dts-OMAP2-AM33xx-HACK-Add-missing-dma-info.patch
+++ b/patches/linux-3.8.13/0296-ASoC-dts-OMAP2-AM33xx-HACK-Add-missing-dma-info.patch
diff --git a/patches/linux-3.8.4/0271-ASoC-Davinci-McASP-remove-unused-header-include.patch b/patches/linux-3.8.13/0297-ASoC-Davinci-McASP-remove-unused-header-include.patch
index 36ac5ff..36ac5ff 100644
--- a/patches/linux-3.8.4/0271-ASoC-Davinci-McASP-remove-unused-header-include.patch
+++ b/patches/linux-3.8.13/0297-ASoC-Davinci-McASP-remove-unused-header-include.patch
diff --git a/patches/linux-3.8.4/0272-ASoC-AM33XX-Add-support-for-AM33xx-SoC-Audio.patch b/patches/linux-3.8.13/0298-ASoC-AM33XX-Add-support-for-AM33xx-SoC-Audio.patch
index beb777d..beb777d 100644
--- a/patches/linux-3.8.4/0272-ASoC-AM33XX-Add-support-for-AM33xx-SoC-Audio.patch
+++ b/patches/linux-3.8.13/0298-ASoC-AM33XX-Add-support-for-AM33xx-SoC-Audio.patch
diff --git a/patches/linux-3.8.4/0273-am33xx-mcasp-Add-dma-channel-definitions.patch b/patches/linux-3.8.13/0299-am33xx-mcasp-Add-dma-channel-definitions.patch
index 389e5fa..389e5fa 100644
--- a/patches/linux-3.8.4/0273-am33xx-mcasp-Add-dma-channel-definitions.patch
+++ b/patches/linux-3.8.13/0299-am33xx-mcasp-Add-dma-channel-definitions.patch
diff --git a/patches/linux-3.8.4/0274-ARM-OMAP2-AM33xx-removed-invalid-McASP-HWMOD-data.patch b/patches/linux-3.8.13/0300-ARM-OMAP2-AM33xx-removed-invalid-McASP-HWMOD-data.patch
index 78b2b26..78b2b26 100644
--- a/patches/linux-3.8.4/0274-ARM-OMAP2-AM33xx-removed-invalid-McASP-HWMOD-data.patch
+++ b/patches/linux-3.8.13/0300-ARM-OMAP2-AM33xx-removed-invalid-McASP-HWMOD-data.patch
diff --git a/patches/linux-3.8.4/0275-davinci-evm-Header-include-move-fix.patch b/patches/linux-3.8.13/0301-davinci-evm-Header-include-move-fix.patch
index 6c25ae4..6c25ae4 100644
--- a/patches/linux-3.8.4/0275-davinci-evm-Header-include-move-fix.patch
+++ b/patches/linux-3.8.13/0301-davinci-evm-Header-include-move-fix.patch
diff --git a/patches/linux-3.8.4/0276-bone-dvi-cape-Add-DT-definition-for-00A2-revision.patch b/patches/linux-3.8.13/0302-bone-dvi-cape-Add-DT-definition-for-00A2-revision.patch
index 5901513..5901513 100644
--- a/patches/linux-3.8.4/0276-bone-dvi-cape-Add-DT-definition-for-00A2-revision.patch
+++ b/patches/linux-3.8.13/0302-bone-dvi-cape-Add-DT-definition-for-00A2-revision.patch
diff --git a/patches/linux-3.8.4/0277-bone-dvi-cape-Update-A1-cape-definition-with-sound.patch b/patches/linux-3.8.13/0303-bone-dvi-cape-Update-A1-cape-definition-with-sound.patch
index 354c65c..354c65c 100644
--- a/patches/linux-3.8.4/0277-bone-dvi-cape-Update-A1-cape-definition-with-sound.patch
+++ b/patches/linux-3.8.13/0303-bone-dvi-cape-Update-A1-cape-definition-with-sound.patch
diff --git a/patches/linux-3.8.4/0278-sndsoc-mcasp-Get-DMA-channels-via-byname.patch b/patches/linux-3.8.13/0304-sndsoc-mcasp-Get-DMA-channels-via-byname.patch
index 5813af4..5813af4 100644
--- a/patches/linux-3.8.4/0278-sndsoc-mcasp-Get-DMA-channels-via-byname.patch
+++ b/patches/linux-3.8.13/0304-sndsoc-mcasp-Get-DMA-channels-via-byname.patch
diff --git a/patches/linux-3.8.4/0279-sound-soc-Davinci-Remove-__devinit-__devexit.patch b/patches/linux-3.8.13/0305-sound-soc-Davinci-Remove-__devinit-__devexit.patch
index 8bceb4f..8bceb4f 100644
--- a/patches/linux-3.8.4/0279-sound-soc-Davinci-Remove-__devinit-__devexit.patch
+++ b/patches/linux-3.8.13/0305-sound-soc-Davinci-Remove-__devinit-__devexit.patch
diff --git a/patches/linux-3.8.4/0280-st7735fb-Remove-__devinit-__devexit.patch b/patches/linux-3.8.13/0306-st7735fb-Remove-__devinit-__devexit.patch
index 8d00aff..8d00aff 100644
--- a/patches/linux-3.8.4/0280-st7735fb-Remove-__devinit-__devexit.patch
+++ b/patches/linux-3.8.13/0306-st7735fb-Remove-__devinit-__devexit.patch
diff --git a/patches/linux-3.8.4/0281-capemgr-Remove-__devinit-__devexit.patch b/patches/linux-3.8.13/0307-capemgr-Remove-__devinit-__devexit.patch
index 35cf436..35cf436 100644
--- a/patches/linux-3.8.4/0281-capemgr-Remove-__devinit-__devexit.patch
+++ b/patches/linux-3.8.13/0307-capemgr-Remove-__devinit-__devexit.patch
diff --git a/patches/linux-3.8.4/0282-capes-fw-target-firmware-directory-change.patch b/patches/linux-3.8.13/0308-capes-fw-target-firmware-directory-change.patch
index 099804e..099804e 100644
--- a/patches/linux-3.8.4/0282-capes-fw-target-firmware-directory-change.patch
+++ b/patches/linux-3.8.13/0308-capes-fw-target-firmware-directory-change.patch
diff --git a/patches/linux-3.8.4/0283-am33xx-edma-Always-update-unused-channel-list.patch b/patches/linux-3.8.13/0309-am33xx-edma-Always-update-unused-channel-list.patch
index 2114a24..2114a24 100644
--- a/patches/linux-3.8.4/0283-am33xx-edma-Always-update-unused-channel-list.patch
+++ b/patches/linux-3.8.13/0309-am33xx-edma-Always-update-unused-channel-list.patch
diff --git a/patches/linux-3.8.4/0284-defconfig-Update-bone-default-config.patch b/patches/linux-3.8.13/0310-defconfig-Update-bone-default-config.patch
index af8189b..af8189b 100644
--- a/patches/linux-3.8.4/0284-defconfig-Update-bone-default-config.patch
+++ b/patches/linux-3.8.13/0310-defconfig-Update-bone-default-config.patch
diff --git a/patches/linux-3.8.4/0285-capes-add-dvi-a2-and-lcd3-a2-dts-files.patch b/patches/linux-3.8.13/0311-capes-add-dvi-a2-and-lcd3-a2-dts-files.patch
index d4a2593..7bf80ce 100644
--- a/patches/linux-3.8.4/0285-capes-add-dvi-a2-and-lcd3-a2-dts-files.patch
+++ b/patches/linux-3.8.13/0311-capes-add-dvi-a2-and-lcd3-a2-dts-files.patch
@@ -328,7 +328,7 @@ index 0000000..84f84c4
+};
diff --git a/firmware/capes/cape-bone-lcd3-00A2.dts b/firmware/capes/cape-bone-lcd3-00A2.dts
new file mode 100644
-index 0000000..2ea1cf4
+index 0000000..3f68434
--- /dev/null
+++ b/firmware/capes/cape-bone-lcd3-00A2.dts
@@ -0,0 +1,226 @@
@@ -437,7 +437,7 @@ index 0000000..2ea1cf4
+ tsc {
+ wires = <4>;
+ x-plate-resistance = <200>;
-+ steps-to-configure = <5>;
++ coordinate-readouts = <5>;
+ wire-config = <0x00 0x11 0x22 0x33>;
+ };
+
diff --git a/patches/linux-3.8.4/0286-capemgr-catch-up-with-lcdc-tilcdc-rename.patch b/patches/linux-3.8.13/0312-capemgr-catch-up-with-lcdc-tilcdc-rename.patch
index d8de794..a10a35e 100644
--- a/patches/linux-3.8.4/0286-capemgr-catch-up-with-lcdc-tilcdc-rename.patch
+++ b/patches/linux-3.8.13/0312-capemgr-catch-up-with-lcdc-tilcdc-rename.patch
@@ -79,7 +79,7 @@ index 84f84c4..54fba3f 100644
interrupt-parent = <&intc>;
interrupts = <36>;
diff --git a/firmware/capes/cape-bone-lcd3-00A0.dts b/firmware/capes/cape-bone-lcd3-00A0.dts
-index 2d806c8..fed53a1 100644
+index b0784b2..8d9482d 100644
--- a/firmware/capes/cape-bone-lcd3-00A0.dts
+++ b/firmware/capes/cape-bone-lcd3-00A0.dts
@@ -178,7 +178,7 @@
@@ -101,7 +101,7 @@ index 2d806c8..fed53a1 100644
interrupt-parent = <&intc>;
interrupts = <36>;
diff --git a/firmware/capes/cape-bone-lcd3-00A2.dts b/firmware/capes/cape-bone-lcd3-00A2.dts
-index 2ea1cf4..18dbe045 100644
+index 3f68434..d78b56b 100644
--- a/firmware/capes/cape-bone-lcd3-00A2.dts
+++ b/firmware/capes/cape-bone-lcd3-00A2.dts
@@ -178,7 +178,7 @@
diff --git a/patches/linux-3.8.4/0287-firmware-fix-dvi-a1-target.patch b/patches/linux-3.8.13/0313-firmware-fix-dvi-a1-target.patch
index 0eb0742..0eb0742 100644
--- a/patches/linux-3.8.4/0287-firmware-fix-dvi-a1-target.patch
+++ b/patches/linux-3.8.13/0313-firmware-fix-dvi-a1-target.patch
diff --git a/patches/linux-3.8.4/0288-capes-remove-tda-from-hdmi-cape-lcdc-handles-it-by-t.patch b/patches/linux-3.8.13/0314-capes-remove-tda-from-hdmi-cape-lcdc-handles-it-by-t.patch
index 01f4200..01f4200 100644
--- a/patches/linux-3.8.4/0288-capes-remove-tda-from-hdmi-cape-lcdc-handles-it-by-t.patch
+++ b/patches/linux-3.8.13/0314-capes-remove-tda-from-hdmi-cape-lcdc-handles-it-by-t.patch
diff --git a/patches/linux-3.8.4/0289-tilcdc-magic-debug-statement-makes-power-gpio-work-o.patch b/patches/linux-3.8.13/0315-tilcdc-magic-debug-statement-makes-power-gpio-work-o.patch
index bbfd769..bbfd769 100644
--- a/patches/linux-3.8.4/0289-tilcdc-magic-debug-statement-makes-power-gpio-work-o.patch
+++ b/patches/linux-3.8.13/0315-tilcdc-magic-debug-statement-makes-power-gpio-work-o.patch
diff --git a/patches/linux-3.8.4/0290-capemgr-add-dts-overlay-for-LCD7-00A2-cape.patch b/patches/linux-3.8.13/0316-capemgr-add-dts-overlay-for-LCD7-00A2-cape.patch
index 37a08a7..ab7f350 100644
--- a/patches/linux-3.8.4/0290-capemgr-add-dts-overlay-for-LCD7-00A2-cape.patch
+++ b/patches/linux-3.8.13/0316-capemgr-add-dts-overlay-for-LCD7-00A2-cape.patch
@@ -25,7 +25,7 @@ index 0bcacba..f8c4a9e 100644
fw-shipped-$(CONFIG_CAPE_BEAGLEBONE_GEIGER) += \
diff --git a/firmware/capes/BB-BONE-LCD7-01-00A2.dts b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
new file mode 100644
-index 0000000..7f9683f
+index 0000000..20f4cc5
--- /dev/null
+++ b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
@@ -0,0 +1,225 @@
@@ -132,7 +132,7 @@ index 0000000..7f9683f
+ tsc {
+ wires = <4>;
+ x-plate-resistance = <200>;
-+ steps-to-configure = <5>;
++ coordinate-readouts = <5>;
+ wire-config = <0x00 0x11 0x22 0x33>;
+ };
+
diff --git a/patches/linux-3.8.4/0291-HACK-am33xx.dtsi-enable-all-PWMs.patch b/patches/linux-3.8.13/0317-HACK-am33xx.dtsi-enable-all-PWMs.patch
index e772a82..e772a82 100644
--- a/patches/linux-3.8.4/0291-HACK-am33xx.dtsi-enable-all-PWMs.patch
+++ b/patches/linux-3.8.13/0317-HACK-am33xx.dtsi-enable-all-PWMs.patch
diff --git a/patches/linux-3.8.4/0292-beaglebone-Add-nixie-cape-prototype-driver.patch b/patches/linux-3.8.13/0318-beaglebone-Add-nixie-cape-prototype-driver.patch
index fdba822..fdba822 100644
--- a/patches/linux-3.8.4/0292-beaglebone-Add-nixie-cape-prototype-driver.patch
+++ b/patches/linux-3.8.13/0318-beaglebone-Add-nixie-cape-prototype-driver.patch
diff --git a/patches/linux-3.8.4/0293-beaglebone-Add-nixie-cape-device-tree-entry.patch b/patches/linux-3.8.13/0319-beaglebone-Add-nixie-cape-device-tree-entry.patch
index 1a4b9aa..1a4b9aa 100644
--- a/patches/linux-3.8.4/0293-beaglebone-Add-nixie-cape-device-tree-entry.patch
+++ b/patches/linux-3.8.13/0319-beaglebone-Add-nixie-cape-device-tree-entry.patch
diff --git a/patches/linux-3.8.4/0294-am335x-bone-common.dtsi-Cleanup-test-remnants.patch b/patches/linux-3.8.13/0320-am335x-bone-common.dtsi-Cleanup-test-remnants.patch
index 83f10f7..83f10f7 100644
--- a/patches/linux-3.8.4/0294-am335x-bone-common.dtsi-Cleanup-test-remnants.patch
+++ b/patches/linux-3.8.13/0320-am335x-bone-common.dtsi-Cleanup-test-remnants.patch
diff --git a/patches/linux-3.8.4/0295-omap_hsmmc-Add-ti-vcc-aux-disable-is-sleep-DT-proper.patch b/patches/linux-3.8.13/0321-omap_hsmmc-Add-ti-vcc-aux-disable-is-sleep-DT-proper.patch
index 71e61f7..71e61f7 100644
--- a/patches/linux-3.8.4/0295-omap_hsmmc-Add-ti-vcc-aux-disable-is-sleep-DT-proper.patch
+++ b/patches/linux-3.8.13/0321-omap_hsmmc-Add-ti-vcc-aux-disable-is-sleep-DT-proper.patch
diff --git a/patches/linux-3.8.4/0296-bone-common-ti-vcc-aux-disable-is-sleep-enable.patch b/patches/linux-3.8.13/0322-bone-common-ti-vcc-aux-disable-is-sleep-enable.patch
index bae5ab7..bae5ab7 100644
--- a/patches/linux-3.8.4/0296-bone-common-ti-vcc-aux-disable-is-sleep-enable.patch
+++ b/patches/linux-3.8.13/0322-bone-common-ti-vcc-aux-disable-is-sleep-enable.patch
diff --git a/patches/linux-3.8.4/0297-am33xx-disable-NAPI.patch b/patches/linux-3.8.13/0323-am33xx-disable-NAPI.patch
index 68b7275..68b7275 100644
--- a/patches/linux-3.8.4/0297-am33xx-disable-NAPI.patch
+++ b/patches/linux-3.8.13/0323-am33xx-disable-NAPI.patch
diff --git a/patches/linux-3.8.4/0298-capemgr-Fixed-AIN-name-display-in-error-message.patch b/patches/linux-3.8.13/0324-capemgr-Fixed-AIN-name-display-in-error-message.patch
index 005660d..005660d 100644
--- a/patches/linux-3.8.4/0298-capemgr-Fixed-AIN-name-display-in-error-message.patch
+++ b/patches/linux-3.8.13/0324-capemgr-Fixed-AIN-name-display-in-error-message.patch
diff --git a/patches/linux-3.8.4/0299-am33xx.dtsi-remove-duplicate-nodes.patch b/patches/linux-3.8.13/0325-am33xx.dtsi-remove-duplicate-nodes.patch
index f69f291..f69f291 100644
--- a/patches/linux-3.8.4/0299-am33xx.dtsi-remove-duplicate-nodes.patch
+++ b/patches/linux-3.8.13/0325-am33xx.dtsi-remove-duplicate-nodes.patch
diff --git a/patches/linux-3.8.4/0300-cape-dtbos-update-to-latest-OF-videomode-bindings.patch b/patches/linux-3.8.13/0326-cape-dtbos-update-to-latest-OF-videomode-bindings.patch
index 8bd3381..0ab6d82 100644
--- a/patches/linux-3.8.4/0300-cape-dtbos-update-to-latest-OF-videomode-bindings.patch
+++ b/patches/linux-3.8.13/0326-cape-dtbos-update-to-latest-OF-videomode-bindings.patch
@@ -10,7 +10,7 @@ Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/firmware/capes/BB-BONE-LCD7-01-00A2.dts b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
-index 7f9683f..09ba0d9 100644
+index 20f4cc5..da0e43f 100644
--- a/firmware/capes/BB-BONE-LCD7-01-00A2.dts
+++ b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
@@ -188,8 +188,6 @@
@@ -32,7 +32,7 @@ index 7f9683f..09ba0d9 100644
};
};
diff --git a/firmware/capes/cape-bone-lcd3-00A0.dts b/firmware/capes/cape-bone-lcd3-00A0.dts
-index fed53a1..4076cf5 100644
+index 8d9482d..899f7c9 100644
--- a/firmware/capes/cape-bone-lcd3-00A0.dts
+++ b/firmware/capes/cape-bone-lcd3-00A0.dts
@@ -190,8 +190,6 @@
@@ -54,7 +54,7 @@ index fed53a1..4076cf5 100644
};
};
diff --git a/firmware/capes/cape-bone-lcd3-00A2.dts b/firmware/capes/cape-bone-lcd3-00A2.dts
-index 18dbe045..d8366b4 100644
+index d78b56b..d4f5ac2 100644
--- a/firmware/capes/cape-bone-lcd3-00A2.dts
+++ b/firmware/capes/cape-bone-lcd3-00A2.dts
@@ -190,8 +190,6 @@
diff --git a/patches/linux-3.8.4/0301-beaglebone-uncomment-eMMC-override.patch b/patches/linux-3.8.13/0327-beaglebone-uncomment-eMMC-override.patch
index 7efc511..7efc511 100644
--- a/patches/linux-3.8.4/0301-beaglebone-uncomment-eMMC-override.patch
+++ b/patches/linux-3.8.13/0327-beaglebone-uncomment-eMMC-override.patch
diff --git a/patches/linux-3.8.4/0302-bone-capes-Update-with-new-tscadc-bindings.patch b/patches/linux-3.8.13/0328-bone-capes-Update-with-new-tscadc-bindings.patch
index ab11f38..c9279d2 100644
--- a/patches/linux-3.8.4/0302-bone-capes-Update-with-new-tscadc-bindings.patch
+++ b/patches/linux-3.8.13/0328-bone-capes-Update-with-new-tscadc-bindings.patch
@@ -13,7 +13,7 @@ Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/firmware/capes/BB-BONE-LCD7-01-00A2.dts b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
-index 09ba0d9..4740fc0 100644
+index da0e43f..5a9a5f9 100644
--- a/firmware/capes/BB-BONE-LCD7-01-00A2.dts
+++ b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
@@ -97,16 +97,17 @@
@@ -25,22 +25,22 @@ index 09ba0d9..4740fc0 100644
tsc {
- wires = <4>;
- x-plate-resistance = <200>;
-- steps-to-configure = <5>;
+- coordinate-readouts = <5>;
- wire-config = <0x00 0x11 0x22 0x33>;
+ ti,wires = <4>;
+ ti,x-plate-resistance = <200>;
-+ ti,steps-to-configure = <5>;
++ ti,coordinate-readouts = <5>;
+ ti,wire-config = <0x00 0x11 0x22 0x33>;
};
adc {
- adc-channels = <4>;
-+ ti,adc-channels = <4>;
++ ti,adc-channels = <4 5 6 7>;
};
};
diff --git a/firmware/capes/cape-bone-geiger-00A0.dts b/firmware/capes/cape-bone-geiger-00A0.dts
-index 287d75c..a37d83f 100644
+index 39e7d38..89417fb 100644
--- a/firmware/capes/cape-bone-geiger-00A0.dts
+++ b/firmware/capes/cape-bone-geiger-00A0.dts
@@ -86,9 +86,10 @@
@@ -50,13 +50,13 @@ index 287d75c..a37d83f 100644
+ status = "okay";
adc {
-- adc-channels = <8>;
-+ ti,adc-channels = <8>;
+- adc-channels = <0 1 2 3 4 5 6 7>;
++ ti,adc-channels = <0 1 2 3 4 5 6 7>;
};
};
diff --git a/firmware/capes/cape-bone-lcd3-00A0.dts b/firmware/capes/cape-bone-lcd3-00A0.dts
-index 4076cf5..c62e4a9 100644
+index 899f7c9..ca31bc3 100644
--- a/firmware/capes/cape-bone-lcd3-00A0.dts
+++ b/firmware/capes/cape-bone-lcd3-00A0.dts
@@ -93,16 +93,17 @@
@@ -68,22 +68,22 @@ index 4076cf5..c62e4a9 100644
tsc {
- wires = <4>;
- x-plate-resistance = <200>;
-- steps-to-configure = <5>;
+- coordinate-readouts = <5>;
- wire-config = <0x00 0x11 0x22 0x33>;
+ ti,wires = <4>;
+ ti,x-plate-resistance = <200>;
-+ ti,steps-to-configure = <5>;
++ ti,coordinate-readouts = <5>;
+ ti,wire-config = <0x00 0x11 0x22 0x33>;
};
adc {
- adc-channels = <4>;
-+ ti,adc-channels = <4>;
++ ti,adc-channels = <4 5 6 7>;
};
};
diff --git a/firmware/capes/cape-bone-lcd3-00A2.dts b/firmware/capes/cape-bone-lcd3-00A2.dts
-index d8366b4..12739a3 100644
+index d4f5ac2..efa2d10 100644
--- a/firmware/capes/cape-bone-lcd3-00A2.dts
+++ b/firmware/capes/cape-bone-lcd3-00A2.dts
@@ -99,16 +99,17 @@
@@ -95,17 +95,17 @@ index d8366b4..12739a3 100644
tsc {
- wires = <4>;
- x-plate-resistance = <200>;
-- steps-to-configure = <5>;
+- coordinate-readouts = <5>;
- wire-config = <0x00 0x11 0x22 0x33>;
+ ti,wires = <4>;
+ ti,x-plate-resistance = <200>;
-+ ti,steps-to-configure = <5>;
++ ti,coordinate-readouts = <5>;
+ ti,wire-config = <0x00 0x11 0x22 0x33>;
};
adc {
- adc-channels = <4>;
-+ ti,adc-channels = <4>;
++ ti,adc-channels = <4 5 6 7>;
};
};
diff --git a/patches/linux-3.8.4/0303-am33xx.dtsi-Update-and-disable-status-of-nodes.patch b/patches/linux-3.8.13/0329-am33xx.dtsi-Update-and-disable-status-of-nodes.patch
index 98b9d5d..98b9d5d 100644
--- a/patches/linux-3.8.4/0303-am33xx.dtsi-Update-and-disable-status-of-nodes.patch
+++ b/patches/linux-3.8.13/0329-am33xx.dtsi-Update-and-disable-status-of-nodes.patch
diff --git a/patches/linux-3.8.4/0304-bone-capes-Adapt-to-new-pwms-setup.patch b/patches/linux-3.8.13/0330-bone-capes-Adapt-to-new-pwms-setup.patch
index 1761d8d..9649235 100644
--- a/patches/linux-3.8.4/0304-bone-capes-Adapt-to-new-pwms-setup.patch
+++ b/patches/linux-3.8.13/0330-bone-capes-Adapt-to-new-pwms-setup.patch
@@ -9,7 +9,7 @@ Subject: [PATCH] bone-capes: Adapt to new pwms setup
3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/firmware/capes/BB-BONE-LCD7-01-00A2.dts b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
-index 4740fc0..05b2e80 100644
+index 5a9a5f9..c13fe80 100644
--- a/firmware/capes/BB-BONE-LCD7-01-00A2.dts
+++ b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
@@ -83,6 +83,7 @@
@@ -21,7 +21,7 @@ index 4740fc0..05b2e80 100644
pwms = <&ehrpwm1 0 500000 0>;
pwm-names = "LCD7";
diff --git a/firmware/capes/cape-bone-geiger-00A0.dts b/firmware/capes/cape-bone-geiger-00A0.dts
-index a37d83f..0ecb67e 100644
+index 89417fb..4757ce7 100644
--- a/firmware/capes/cape-bone-geiger-00A0.dts
+++ b/firmware/capes/cape-bone-geiger-00A0.dts
@@ -36,14 +36,14 @@
@@ -42,7 +42,7 @@ index a37d83f..0ecb67e 100644
__overlay__ {
status = "okay";
diff --git a/firmware/capes/cape-bone-lcd3-00A2.dts b/firmware/capes/cape-bone-lcd3-00A2.dts
-index 12739a3..ef91376 100644
+index efa2d10..ce72c17 100644
--- a/firmware/capes/cape-bone-lcd3-00A2.dts
+++ b/firmware/capes/cape-bone-lcd3-00A2.dts
@@ -69,6 +69,20 @@
diff --git a/patches/linux-3.8.4/0305-tilcdc-introduce-panel-tfp410-power-down-gpio-contro.patch b/patches/linux-3.8.13/0331-tilcdc-introduce-panel-tfp410-power-down-gpio-contro.patch
index e423c23..e423c23 100644
--- a/patches/linux-3.8.4/0305-tilcdc-introduce-panel-tfp410-power-down-gpio-contro.patch
+++ b/patches/linux-3.8.13/0331-tilcdc-introduce-panel-tfp410-power-down-gpio-contro.patch
diff --git a/patches/linux-3.8.4/0306-bone-dvi-Update-to-new-style-tilcdc-bindings.patch b/patches/linux-3.8.13/0332-bone-dvi-Update-to-new-style-tilcdc-bindings.patch
index 1317963..1317963 100644
--- a/patches/linux-3.8.4/0306-bone-dvi-Update-to-new-style-tilcdc-bindings.patch
+++ b/patches/linux-3.8.13/0332-bone-dvi-Update-to-new-style-tilcdc-bindings.patch
diff --git a/patches/linux-3.8.4/0307-tilcdc-tfp410-Rework-power-down-GPIO-logic.patch b/patches/linux-3.8.13/0333-tilcdc-tfp410-Rework-power-down-GPIO-logic.patch
index 179bca7..179bca7 100644
--- a/patches/linux-3.8.4/0307-tilcdc-tfp410-Rework-power-down-GPIO-logic.patch
+++ b/patches/linux-3.8.13/0333-tilcdc-tfp410-Rework-power-down-GPIO-logic.patch
diff --git a/patches/linux-3.8.4/0308-tilcdc-Add-reduced-blanking-mode-checks.patch b/patches/linux-3.8.13/0334-tilcdc-Add-reduced-blanking-mode-checks.patch
index 053503f..3eb1afd 100644
--- a/patches/linux-3.8.4/0308-tilcdc-Add-reduced-blanking-mode-checks.patch
+++ b/patches/linux-3.8.13/0334-tilcdc-Add-reduced-blanking-mode-checks.patch
@@ -14,10 +14,10 @@ Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
-index 5dd3c7d..628d9aa 100644
+index 9f10f05..dcbafad 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
-@@ -422,6 +422,7 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode)
+@@ -426,6 +426,7 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode)
{
struct tilcdc_drm_private *priv = crtc->dev->dev_private;
unsigned int bandwidth;
@@ -25,7 +25,7 @@ index 5dd3c7d..628d9aa 100644
if (mode->hdisplay > tilcdc_crtc_max_width(crtc))
return MODE_VIRTUAL_X;
-@@ -438,6 +439,16 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode)
+@@ -442,6 +443,16 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode)
if (bandwidth > priv->max_bandwidth)
return MODE_BAD;
diff --git a/patches/linux-3.8.4/0309-cape-dvi-Switch-all-DVI-capes-to-using-the-TFTP410-p.patch b/patches/linux-3.8.13/0335-cape-dvi-Switch-all-DVI-capes-to-using-the-TFTP410-p.patch
index 640fd88..640fd88 100644
--- a/patches/linux-3.8.4/0309-cape-dvi-Switch-all-DVI-capes-to-using-the-TFTP410-p.patch
+++ b/patches/linux-3.8.13/0335-cape-dvi-Switch-all-DVI-capes-to-using-the-TFTP410-p.patch
diff --git a/patches/linux-3.8.4/0310-beaglebone-switch-eMMC-to-8bit-mode.patch b/patches/linux-3.8.13/0336-beaglebone-switch-eMMC-to-8bit-mode.patch
index 648637e..648637e 100644
--- a/patches/linux-3.8.4/0310-beaglebone-switch-eMMC-to-8bit-mode.patch
+++ b/patches/linux-3.8.13/0336-beaglebone-switch-eMMC-to-8bit-mode.patch
diff --git a/patches/linux-3.8.4/0311-Pinmux-helper-driver.patch b/patches/linux-3.8.13/0337-Pinmux-helper-driver.patch
index 6094273..6094273 100644
--- a/patches/linux-3.8.4/0311-Pinmux-helper-driver.patch
+++ b/patches/linux-3.8.13/0337-Pinmux-helper-driver.patch
diff --git a/patches/linux-3.8.4/0312-OF-Clear-detach-flag-on-attach.patch b/patches/linux-3.8.13/0338-OF-Clear-detach-flag-on-attach.patch
index e7eed6d..e7eed6d 100644
--- a/patches/linux-3.8.4/0312-OF-Clear-detach-flag-on-attach.patch
+++ b/patches/linux-3.8.13/0338-OF-Clear-detach-flag-on-attach.patch
diff --git a/patches/linux-3.8.4/0313-OF-overlay-Fix-overlay-revert-failure.patch b/patches/linux-3.8.13/0339-OF-overlay-Fix-overlay-revert-failure.patch
index 4a5350e..4a5350e 100644
--- a/patches/linux-3.8.4/0313-OF-overlay-Fix-overlay-revert-failure.patch
+++ b/patches/linux-3.8.13/0339-OF-overlay-Fix-overlay-revert-failure.patch
diff --git a/patches/linux-3.8.4/0314-bone-capemgr-Make-sure-cape-removal-works.patch b/patches/linux-3.8.13/0340-bone-capemgr-Make-sure-cape-removal-works.patch
index 838b423..838b423 100644
--- a/patches/linux-3.8.4/0314-bone-capemgr-Make-sure-cape-removal-works.patch
+++ b/patches/linux-3.8.13/0340-bone-capemgr-Make-sure-cape-removal-works.patch
diff --git a/patches/linux-3.8.4/0315-bone-capemgr-Fix-crash-when-trying-to-remove-non-exi.patch b/patches/linux-3.8.13/0341-bone-capemgr-Fix-crash-when-trying-to-remove-non-exi.patch
index 0e958c5..0e958c5 100644
--- a/patches/linux-3.8.4/0315-bone-capemgr-Fix-crash-when-trying-to-remove-non-exi.patch
+++ b/patches/linux-3.8.13/0341-bone-capemgr-Fix-crash-when-trying-to-remove-non-exi.patch
diff --git a/patches/linux-3.8.4/0316-beaglebone-LCD7-cape-enable-PWM-and-allow-the-specif.patch b/patches/linux-3.8.13/0342-beaglebone-LCD7-cape-enable-PWM-and-allow-the-specif.patch
index 206509d..489b71b 100644
--- a/patches/linux-3.8.4/0316-beaglebone-LCD7-cape-enable-PWM-and-allow-the-specif.patch
+++ b/patches/linux-3.8.13/0342-beaglebone-LCD7-cape-enable-PWM-and-allow-the-specif.patch
@@ -8,7 +8,7 @@ Subject: [PATCH] beaglebone: LCD7 cape: enable PWM and allow the specified
1 file changed, 15 insertions(+)
diff --git a/firmware/capes/BB-BONE-LCD7-01-00A2.dts b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
-index 05b2e80..32d6f9d 100644
+index c13fe80..dc31da7 100644
--- a/firmware/capes/BB-BONE-LCD7-01-00A2.dts
+++ b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
@@ -71,6 +71,20 @@
diff --git a/patches/linux-3.8.4/0317-bone-capemgr-Introduce-pinmux-helper.patch b/patches/linux-3.8.13/0343-bone-capemgr-Introduce-pinmux-helper.patch
index 5620578..5620578 100644
--- a/patches/linux-3.8.4/0317-bone-capemgr-Introduce-pinmux-helper.patch
+++ b/patches/linux-3.8.13/0343-bone-capemgr-Introduce-pinmux-helper.patch
diff --git a/patches/linux-3.8.4/0318-bone-geiger-Fix-comment-to-match-the-contents.patch b/patches/linux-3.8.13/0344-bone-geiger-Fix-comment-to-match-the-contents.patch
index 6adb543..ce22be7 100644
--- a/patches/linux-3.8.4/0318-bone-geiger-Fix-comment-to-match-the-contents.patch
+++ b/patches/linux-3.8.13/0344-bone-geiger-Fix-comment-to-match-the-contents.patch
@@ -7,7 +7,7 @@ Subject: [PATCH] bone-geiger: Fix comment to match the contents
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/firmware/capes/cape-bone-geiger-00A0.dts b/firmware/capes/cape-bone-geiger-00A0.dts
-index 0ecb67e..309dbca 100644
+index 4757ce7..967e03b 100644
--- a/firmware/capes/cape-bone-geiger-00A0.dts
+++ b/firmware/capes/cape-bone-geiger-00A0.dts
@@ -30,7 +30,7 @@
diff --git a/patches/linux-3.8.4/0319-of-overlay-Handle-I2C-devices-already-registered-by-.patch b/patches/linux-3.8.13/0345-of-overlay-Handle-I2C-devices-already-registered-by-.patch
index a5e1ce6..a5e1ce6 100644
--- a/patches/linux-3.8.4/0319-of-overlay-Handle-I2C-devices-already-registered-by-.patch
+++ b/patches/linux-3.8.13/0345-of-overlay-Handle-I2C-devices-already-registered-by-.patch
diff --git a/patches/linux-3.8.4/0320-pinmux-helper-Add-runtime-configuration-capability.patch b/patches/linux-3.8.13/0346-pinmux-helper-Add-runtime-configuration-capability.patch
index 7720da7..7720da7 100644
--- a/patches/linux-3.8.4/0320-pinmux-helper-Add-runtime-configuration-capability.patch
+++ b/patches/linux-3.8.13/0346-pinmux-helper-Add-runtime-configuration-capability.patch
diff --git a/patches/linux-3.8.4/0321-pinmux-helper-Switch-to-using-kmalloc.patch b/patches/linux-3.8.13/0347-pinmux-helper-Switch-to-using-kmalloc.patch
index d0b0bd8..d0b0bd8 100644
--- a/patches/linux-3.8.4/0321-pinmux-helper-Switch-to-using-kmalloc.patch
+++ b/patches/linux-3.8.13/0347-pinmux-helper-Switch-to-using-kmalloc.patch
diff --git a/patches/linux-3.8.4/0322-i2c-DTify-pca954x-driver.patch b/patches/linux-3.8.13/0348-i2c-DTify-pca954x-driver.patch
index 377d395..377d395 100644
--- a/patches/linux-3.8.4/0322-i2c-DTify-pca954x-driver.patch
+++ b/patches/linux-3.8.13/0348-i2c-DTify-pca954x-driver.patch
diff --git a/patches/linux-3.8.4/0323-tty-Add-JHD629-I2C-LCD-Keypad-TTY-driver.patch b/patches/linux-3.8.13/0349-tty-Add-JHD629-I2C-LCD-Keypad-TTY-driver.patch
index 144694b..144694b 100644
--- a/patches/linux-3.8.4/0323-tty-Add-JHD629-I2C-LCD-Keypad-TTY-driver.patch
+++ b/patches/linux-3.8.13/0349-tty-Add-JHD629-I2C-LCD-Keypad-TTY-driver.patch
diff --git a/patches/linux-3.8.4/0324-grove-i2c-Add-rudimentary-grove-i2c-motor-control-dr.patch b/patches/linux-3.8.13/0350-grove-i2c-Add-rudimentary-grove-i2c-motor-control-dr.patch
index c017a34..c017a34 100644
--- a/patches/linux-3.8.4/0324-grove-i2c-Add-rudimentary-grove-i2c-motor-control-dr.patch
+++ b/patches/linux-3.8.13/0350-grove-i2c-Add-rudimentary-grove-i2c-motor-control-dr.patch
diff --git a/patches/linux-3.8.4/0325-tty-jhd629-i2c-Clean-keypad-buffer-when-starting.patch b/patches/linux-3.8.13/0351-tty-jhd629-i2c-Clean-keypad-buffer-when-starting.patch
index 9efd7f3..9efd7f3 100644
--- a/patches/linux-3.8.4/0325-tty-jhd629-i2c-Clean-keypad-buffer-when-starting.patch
+++ b/patches/linux-3.8.13/0351-tty-jhd629-i2c-Clean-keypad-buffer-when-starting.patch
diff --git a/patches/linux-3.8.4/0326-am335x-bone-common-Remove-SPI-unused-pinmux-config.patch b/patches/linux-3.8.13/0352-am335x-bone-common-Remove-SPI-unused-pinmux-config.patch
index a26755d..a26755d 100644
--- a/patches/linux-3.8.4/0326-am335x-bone-common-Remove-SPI-unused-pinmux-config.patch
+++ b/patches/linux-3.8.13/0352-am335x-bone-common-Remove-SPI-unused-pinmux-config.patch
diff --git a/patches/linux-3.8.4/0327-bone-capemgr-Force-a-slot-to-load-unconditionally.patch b/patches/linux-3.8.13/0353-bone-capemgr-Force-a-slot-to-load-unconditionally.patch
index db99338..db99338 100644
--- a/patches/linux-3.8.4/0327-bone-capemgr-Force-a-slot-to-load-unconditionally.patch
+++ b/patches/linux-3.8.13/0353-bone-capemgr-Force-a-slot-to-load-unconditionally.patch
diff --git a/patches/linux-3.8.4/0328-beaglebone-Added-Adafruit-prototype-cape.patch b/patches/linux-3.8.13/0354-beaglebone-Added-Adafruit-prototype-cape.patch
index 445b351..445b351 100644
--- a/patches/linux-3.8.4/0328-beaglebone-Added-Adafruit-prototype-cape.patch
+++ b/patches/linux-3.8.13/0354-beaglebone-Added-Adafruit-prototype-cape.patch
diff --git a/patches/linux-3.8.4/0329-tilcdc-Enable-reduced-blanking-check-only-on-DVI-sla.patch b/patches/linux-3.8.13/0355-tilcdc-Enable-reduced-blanking-check-only-on-DVI-sla.patch
index 60bc920..20bcedc 100644
--- a/patches/linux-3.8.4/0329-tilcdc-Enable-reduced-blanking-check-only-on-DVI-sla.patch
+++ b/patches/linux-3.8.13/0355-tilcdc-Enable-reduced-blanking-check-only-on-DVI-sla.patch
@@ -15,7 +15,7 @@ Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
5 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
-index 628d9aa..4d94daa 100644
+index dcbafad..fe47255 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -241,7 +241,7 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
@@ -27,7 +27,7 @@ index 628d9aa..4d94daa 100644
if (WARN_ON(ret))
return ret;
-@@ -418,7 +418,8 @@ int tilcdc_crtc_max_width(struct drm_crtc *crtc)
+@@ -422,7 +422,8 @@ int tilcdc_crtc_max_width(struct drm_crtc *crtc)
return max_width;
}
@@ -37,7 +37,7 @@ index 628d9aa..4d94daa 100644
{
struct tilcdc_drm_private *priv = crtc->dev->dev_private;
unsigned int bandwidth;
-@@ -439,7 +440,7 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode)
+@@ -443,7 +444,7 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode)
if (bandwidth > priv->max_bandwidth)
return MODE_BAD;
diff --git a/patches/linux-3.8.4/0330-cape-adafruit-Use-the-correct-spi-bus-spi1-no-spi0.patch b/patches/linux-3.8.13/0356-cape-adafruit-Use-the-correct-spi-bus-spi1-no-spi0.patch
index 013f3b3..013f3b3 100644
--- a/patches/linux-3.8.4/0330-cape-adafruit-Use-the-correct-spi-bus-spi1-no-spi0.patch
+++ b/patches/linux-3.8.13/0356-cape-adafruit-Use-the-correct-spi-bus-spi1-no-spi0.patch
diff --git a/patches/linux-3.8.4/0331-BBB-tester-Introduce-board-DTS.patch b/patches/linux-3.8.13/0357-BBB-tester-Introduce-board-DTS.patch
index 7fd3c13..7fd3c13 100644
--- a/patches/linux-3.8.4/0331-BBB-tester-Introduce-board-DTS.patch
+++ b/patches/linux-3.8.13/0357-BBB-tester-Introduce-board-DTS.patch
diff --git a/patches/linux-3.8.4/0332-BBB-tester-Introduce-cape-describing-the-contents-of.patch b/patches/linux-3.8.13/0358-BBB-tester-Introduce-cape-describing-the-contents-of.patch
index 7787996..7787996 100644
--- a/patches/linux-3.8.4/0332-BBB-tester-Introduce-cape-describing-the-contents-of.patch
+++ b/patches/linux-3.8.13/0358-BBB-tester-Introduce-cape-describing-the-contents-of.patch
diff --git a/patches/linux-3.8.4/0333-bone-tester-Add-overrides-for-BB-BONE-TESTER.patch b/patches/linux-3.8.13/0359-bone-tester-Add-overrides-for-BB-BONE-TESTER.patch
index f3d5fe5..f3d5fe5 100644
--- a/patches/linux-3.8.4/0333-bone-tester-Add-overrides-for-BB-BONE-TESTER.patch
+++ b/patches/linux-3.8.13/0359-bone-tester-Add-overrides-for-BB-BONE-TESTER.patch
diff --git a/patches/linux-3.8.4/0334-cape-tester-Add-uart-specific-default-pinmux-state.patch b/patches/linux-3.8.13/0360-cape-tester-Add-uart-specific-default-pinmux-state.patch
index 47d0406..47d0406 100644
--- a/patches/linux-3.8.4/0334-cape-tester-Add-uart-specific-default-pinmux-state.patch
+++ b/patches/linux-3.8.13/0360-cape-tester-Add-uart-specific-default-pinmux-state.patch
diff --git a/patches/linux-3.8.4/0335-cape-tester-Add-pinmux-helper-for-drvvbus-gpio.patch b/patches/linux-3.8.13/0361-cape-tester-Add-pinmux-helper-for-drvvbus-gpio.patch
index 2935ea0..2935ea0 100644
--- a/patches/linux-3.8.4/0335-cape-tester-Add-pinmux-helper-for-drvvbus-gpio.patch
+++ b/patches/linux-3.8.13/0361-cape-tester-Add-pinmux-helper-for-drvvbus-gpio.patch
diff --git a/patches/linux-3.8.4/0336-cape-Added-support-for-IIO-helper-cape.patch b/patches/linux-3.8.13/0362-cape-Added-support-for-IIO-helper-cape.patch
index 088e5f7..088e5f7 100644
--- a/patches/linux-3.8.4/0336-cape-Added-support-for-IIO-helper-cape.patch
+++ b/patches/linux-3.8.13/0362-cape-Added-support-for-IIO-helper-cape.patch
diff --git a/patches/linux-3.8.4/0337-cape-Added-example-IIO-tester-dynamics-overlay.patch b/patches/linux-3.8.13/0363-cape-Added-example-IIO-tester-dynamics-overlay.patch
index 595d1d4..595d1d4 100644
--- a/patches/linux-3.8.4/0337-cape-Added-example-IIO-tester-dynamics-overlay.patch
+++ b/patches/linux-3.8.13/0363-cape-Added-example-IIO-tester-dynamics-overlay.patch
diff --git a/patches/linux-3.8.4/0338-docs-Added-capemanager-extra_override-usage.patch b/patches/linux-3.8.13/0364-docs-Added-capemanager-extra_override-usage.patch
index fc60343..fc60343 100644
--- a/patches/linux-3.8.4/0338-docs-Added-capemanager-extra_override-usage.patch
+++ b/patches/linux-3.8.13/0364-docs-Added-capemanager-extra_override-usage.patch
diff --git a/patches/linux-3.8.4/0339-capemgr-Added-module-param-descriptions.patch b/patches/linux-3.8.13/0365-capemgr-Added-module-param-descriptions.patch
index 4a12adc..4a12adc 100644
--- a/patches/linux-3.8.4/0339-capemgr-Added-module-param-descriptions.patch
+++ b/patches/linux-3.8.13/0365-capemgr-Added-module-param-descriptions.patch
diff --git a/patches/linux-3.8.4/0340-beaglebone-Add-Adafruit-RTC-prototype-cape.patch b/patches/linux-3.8.13/0366-beaglebone-Add-Adafruit-RTC-prototype-cape.patch
index ad0dab0..ad0dab0 100644
--- a/patches/linux-3.8.4/0340-beaglebone-Add-Adafruit-RTC-prototype-cape.patch
+++ b/patches/linux-3.8.13/0366-beaglebone-Add-Adafruit-RTC-prototype-cape.patch
diff --git a/patches/linux-3.8.4/0341-cape-vsense-scale-division-by-zero-check.patch b/patches/linux-3.8.13/0367-cape-vsense-scale-division-by-zero-check.patch
index abeb265..abeb265 100644
--- a/patches/linux-3.8.4/0341-cape-vsense-scale-division-by-zero-check.patch
+++ b/patches/linux-3.8.13/0367-cape-vsense-scale-division-by-zero-check.patch
diff --git a/patches/linux-3.8.4/0342-capes-add-cape-for-beaglebone-based-Hexy-robot.patch b/patches/linux-3.8.13/0368-capes-add-cape-for-beaglebone-based-Hexy-robot.patch
index 922bac0..922bac0 100644
--- a/patches/linux-3.8.4/0342-capes-add-cape-for-beaglebone-based-Hexy-robot.patch
+++ b/patches/linux-3.8.13/0368-capes-add-cape-for-beaglebone-based-Hexy-robot.patch
diff --git a/patches/linux-3.8.4/0343-Extend-bone-iio-helper.patch b/patches/linux-3.8.13/0369-Extend-bone-iio-helper.patch
index 2a2c6ee..2a2c6ee 100644
--- a/patches/linux-3.8.4/0343-Extend-bone-iio-helper.patch
+++ b/patches/linux-3.8.13/0369-Extend-bone-iio-helper.patch
diff --git a/patches/linux-3.8.4/0344-Update-iio-helper-with-more-channels.patch b/patches/linux-3.8.13/0370-Update-iio-helper-with-more-channels.patch
index 1aea044..55e2f15 100644
--- a/patches/linux-3.8.4/0344-Update-iio-helper-with-more-channels.patch
+++ b/patches/linux-3.8.13/0370-Update-iio-helper-with-more-channels.patch
@@ -8,7 +8,7 @@ Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/firmware/capes/cape-bone-iio-00A0.dts b/firmware/capes/cape-bone-iio-00A0.dts
-index 3165702..4fa02ef 100644
+index 3165702..f1cf814 100644
--- a/firmware/capes/cape-bone-iio-00A0.dts
+++ b/firmware/capes/cape-bone-iio-00A0.dts
@@ -21,10 +21,24 @@
@@ -25,7 +25,7 @@ index 3165702..4fa02ef 100644
+ status = "okay";
+
+ adc {
-+ ti,adc-channels = <8>;
++ ti,adc-channels = <0 1 2 3 4 5 6 7>;
+ };
+ };
+
diff --git a/patches/linux-3.8.4/0345-Add-ADC-IIO-helper.patch b/patches/linux-3.8.13/0371-Add-ADC-IIO-helper.patch
index dfeff89..398a28f 100644
--- a/patches/linux-3.8.4/0345-Add-ADC-IIO-helper.patch
+++ b/patches/linux-3.8.13/0371-Add-ADC-IIO-helper.patch
@@ -7,7 +7,7 @@ Subject: [PATCH] Add ADC IIO helper
1 file changed, 30 insertions(+)
diff --git a/firmware/capes/cape-bone-tester-00A0.dts b/firmware/capes/cape-bone-tester-00A0.dts
-index d5b7607..047c30b 100644
+index d5b7607..333849c 100644
--- a/firmware/capes/cape-bone-tester-00A0.dts
+++ b/firmware/capes/cape-bone-tester-00A0.dts
@@ -450,5 +450,35 @@
@@ -30,7 +30,7 @@ index d5b7607..047c30b 100644
+ status = "okay";
+
+ adc {
-+ ti,adc-channels = <8>;
++ ti,adc-channels = <0 1 2 3 4 5 6 7>;
+ };
+ };
+
diff --git a/patches/linux-3.8.4/0346-Changing-DT-data-to-make-selection-of-standard-i.e.-.patch b/patches/linux-3.8.13/0372-Changing-DT-data-to-make-selection-of-standard-i.e.-.patch
index a635a8b..a635a8b 100644
--- a/patches/linux-3.8.4/0346-Changing-DT-data-to-make-selection-of-standard-i.e.-.patch
+++ b/patches/linux-3.8.13/0372-Changing-DT-data-to-make-selection-of-standard-i.e.-.patch
diff --git a/patches/linux-3.8.4/0347-Enhancing-to-support-extra-device-tree-options-for-t.patch b/patches/linux-3.8.13/0373-Enhancing-to-support-extra-device-tree-options-for-t.patch
index f07563b..c5a5d5b 100644
--- a/patches/linux-3.8.4/0347-Enhancing-to-support-extra-device-tree-options-for-t.patch
+++ b/patches/linux-3.8.13/0373-Enhancing-to-support-extra-device-tree-options-for-t.patch
@@ -13,10 +13,10 @@ Subject: [PATCH] Enhancing to support extra device tree options for tilcdc:
3 files changed, 62 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
-index 4d94daa..63aec17 100644
+index fe47255..edafddc 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
-@@ -421,12 +421,15 @@ int tilcdc_crtc_max_width(struct drm_crtc *crtc)
+@@ -425,12 +425,15 @@ int tilcdc_crtc_max_width(struct drm_crtc *crtc)
int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
int rb_check)
{
@@ -34,7 +34,7 @@ index 4d94daa..63aec17 100644
/* width must be multiple of 16 */
if (mode->hdisplay & 0xf)
-@@ -435,10 +438,31 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+@@ -439,10 +442,31 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
if (mode->vdisplay > 2048)
return MODE_VIRTUAL_Y;
@@ -68,7 +68,7 @@ index 4d94daa..63aec17 100644
if (rb_check) {
/* we only support reduced blanking modes */
-@@ -446,8 +470,10 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+@@ -450,8 +474,10 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
(mode->hsync_end - mode->hdisplay == 80) &&
(mode->hsync_end - mode->hsync_start == 32) &&
(mode->vsync_start - mode->vdisplay == 3);
diff --git a/patches/linux-3.8.4/0348-add-WIP-support-LCD4-rev-00A4.patch b/patches/linux-3.8.13/0374-add-WIP-support-LCD4-rev-00A4.patch
index a1714cd..a1714cd 100644
--- a/patches/linux-3.8.4/0348-add-WIP-support-LCD4-rev-00A4.patch
+++ b/patches/linux-3.8.13/0374-add-WIP-support-LCD4-rev-00A4.patch
diff --git a/patches/linux-3.8.4/0349-add-eMMC-cape-support.patch b/patches/linux-3.8.13/0375-add-eMMC-cape-support.patch
index b885685..b885685 100644
--- a/patches/linux-3.8.4/0349-add-eMMC-cape-support.patch
+++ b/patches/linux-3.8.13/0375-add-eMMC-cape-support.patch
diff --git a/patches/linux-3.8.4/0350-Remove-UART-pins-from-the-expansion-set.patch b/patches/linux-3.8.13/0376-Remove-UART-pins-from-the-expansion-set.patch
index 4fb0cb2..1ad389e 100644
--- a/patches/linux-3.8.4/0350-Remove-UART-pins-from-the-expansion-set.patch
+++ b/patches/linux-3.8.13/0376-Remove-UART-pins-from-the-expansion-set.patch
@@ -7,7 +7,7 @@ Subject: [PATCH] Remove UART pins from the expansion set
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/firmware/capes/cape-bone-tester-00A0.dts b/firmware/capes/cape-bone-tester-00A0.dts
-index 047c30b..868e7a8 100644
+index 333849c..cf0b5a8 100644
--- a/firmware/capes/cape-bone-tester-00A0.dts
+++ b/firmware/capes/cape-bone-tester-00A0.dts
@@ -101,8 +101,8 @@
diff --git a/patches/linux-3.8.4/0351-Remove-LCD-pins-from-the-expansion-test-part.patch b/patches/linux-3.8.13/0377-Remove-LCD-pins-from-the-expansion-test-part.patch
index 6db4302..4713ac7 100644
--- a/patches/linux-3.8.4/0351-Remove-LCD-pins-from-the-expansion-test-part.patch
+++ b/patches/linux-3.8.13/0377-Remove-LCD-pins-from-the-expansion-test-part.patch
@@ -7,7 +7,7 @@ Subject: [PATCH] Remove LCD pins from the expansion test part
1 file changed, 40 insertions(+), 40 deletions(-)
diff --git a/firmware/capes/cape-bone-tester-00A0.dts b/firmware/capes/cape-bone-tester-00A0.dts
-index 868e7a8..a32165f 100644
+index cf0b5a8..1f36284 100644
--- a/firmware/capes/cape-bone-tester-00A0.dts
+++ b/firmware/capes/cape-bone-tester-00A0.dts
@@ -54,26 +54,26 @@
diff --git a/patches/linux-3.8.4/0352-Remove-I2C2-pins-from-expansion-test.patch b/patches/linux-3.8.13/0378-Remove-I2C2-pins-from-expansion-test.patch
index 5a9c216..141cd1f 100644
--- a/patches/linux-3.8.4/0352-Remove-I2C2-pins-from-expansion-test.patch
+++ b/patches/linux-3.8.13/0378-Remove-I2C2-pins-from-expansion-test.patch
@@ -9,7 +9,7 @@ Temporarily take it out.
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/firmware/capes/cape-bone-tester-00A0.dts b/firmware/capes/cape-bone-tester-00A0.dts
-index a32165f..46f39bc 100644
+index 1f36284..4d7dc68 100644
--- a/firmware/capes/cape-bone-tester-00A0.dts
+++ b/firmware/capes/cape-bone-tester-00A0.dts
@@ -86,8 +86,8 @@
diff --git a/patches/linux-3.8.4/0353-Add-expansion-test-cape-fragment.patch b/patches/linux-3.8.13/0379-Add-expansion-test-cape-fragment.patch
index 637e15f..637e15f 100644
--- a/patches/linux-3.8.4/0353-Add-expansion-test-cape-fragment.patch
+++ b/patches/linux-3.8.13/0379-Add-expansion-test-cape-fragment.patch
diff --git a/patches/linux-3.8.4/0354-tilcdc-added-some-extra-debug-and-softened-the-wordi.patch b/patches/linux-3.8.13/0380-tilcdc-added-some-extra-debug-and-softened-the-wordi.patch
index 8744185..524c5f9 100644
--- a/patches/linux-3.8.4/0354-tilcdc-added-some-extra-debug-and-softened-the-wordi.patch
+++ b/patches/linux-3.8.13/0380-tilcdc-added-some-extra-debug-and-softened-the-wordi.patch
@@ -9,10 +9,10 @@ Subject: [PATCH] tilcdc added some extra debug, and softened the wording of
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
-index 63aec17..78965d1 100644
+index edafddc..a98b094 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
-@@ -445,13 +445,14 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+@@ -449,13 +449,14 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
/* some devices have a maximum allowed pixel clock */
/* configured from the DT */
if(mode->clock > priv->max_pixelclock) {
@@ -28,7 +28,7 @@ index 63aec17..78965d1 100644
return MODE_BAD;
}
-@@ -459,7 +460,7 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+@@ -463,7 +464,7 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
/* configured from the DT */
bandwidth = mode->hdisplay * mode->vdisplay * drm_mode_vrefresh(mode);
if (bandwidth > priv->max_bandwidth) {
@@ -37,7 +37,7 @@ index 63aec17..78965d1 100644
return MODE_BAD;
}
-@@ -471,7 +472,7 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+@@ -475,7 +476,7 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
(mode->hsync_end - mode->hsync_start == 32) &&
(mode->vsync_start - mode->vdisplay == 3);
if (!rb) {
diff --git a/patches/linux-3.8.4/0355-Make-sure-various-timings-fit-within-the-bits-availa.patch b/patches/linux-3.8.13/0381-Make-sure-various-timings-fit-within-the-bits-availa.patch
index d07aff4..79b661c 100644
--- a/patches/linux-3.8.4/0355-Make-sure-various-timings-fit-within-the-bits-availa.patch
+++ b/patches/linux-3.8.13/0381-Make-sure-various-timings-fit-within-the-bits-availa.patch
@@ -10,7 +10,7 @@ Subject: [PATCH] Make sure various timings fit within the bits available in
1 file changed, 60 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
-index 78965d1..98c3c3c 100644
+index a98b094..69675e6 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -289,31 +289,38 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
@@ -74,7 +74,7 @@ index 78965d1..98c3c3c 100644
/* fallthrough */
case 24:
reg |= LCDC_V2_TFT_24BPP_MODE;
-@@ -423,6 +430,7 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+@@ -427,6 +434,7 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
{
struct tilcdc_drm_private *priv = crtc->dev->dev_private;
unsigned int bandwidth;
@@ -82,7 +82,7 @@ index 78965d1..98c3c3c 100644
int rb;
-@@ -442,6 +450,44 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+@@ -446,6 +454,44 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
DBG("Processing mode %dx%d@%d with pixel clock %d",
mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode), mode->clock);
@@ -127,7 +127,7 @@ index 78965d1..98c3c3c 100644
/* some devices have a maximum allowed pixel clock */
/* configured from the DT */
if(mode->clock > priv->max_pixelclock) {
-@@ -464,7 +510,6 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+@@ -468,7 +514,6 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
return MODE_BAD;
}
diff --git a/patches/linux-3.8.13/0382-fix-cape-bone-hexy.patch b/patches/linux-3.8.13/0382-fix-cape-bone-hexy.patch
new file mode 100644
index 0000000..1a3c23b
--- /dev/null
+++ b/patches/linux-3.8.13/0382-fix-cape-bone-hexy.patch
@@ -0,0 +1,91 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Tue, 26 Mar 2013 17:01:09 +0100
+Subject: [PATCH] fix cape-bone-hexy
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ firmware/capes/cape-bone-hexy-00A0.dts | 64 ++++++++++++++++++--------------
+ 1 file changed, 37 insertions(+), 27 deletions(-)
+
+diff --git a/firmware/capes/cape-bone-hexy-00A0.dts b/firmware/capes/cape-bone-hexy-00A0.dts
+index 4a13484..abc1255 100644
+--- a/firmware/capes/cape-bone-hexy-00A0.dts
++++ b/firmware/capes/cape-bone-hexy-00A0.dts
+@@ -25,13 +25,13 @@
+ */
+
+ / {
+- compatible = "ti,beaglebone", "ti,beaglebone-black";
+- part-number = "BB-BONE-HEXY-01";
+- version = "00A0";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++ part-number = "BB-BONE-HEXY-01";
++ version = "00A0";
+
+- fragment@0 {
+- target = <&am33xx_pinmux>;
+- __overlay__ {
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
+ pwm_backlight_pins: pinmux_pwm_backlight_pins {
+ pinctrl-single,pins = <
+ 0x020 0x4 /* gpmc_ad8.gpio0_22 | MODE4 */
+@@ -125,26 +125,36 @@
+ };
+
+ fragment@5 {
+- target = <&i2c2>;
+-
+- __overlay__ {
+- /* needed to avoid gripping by DTC */
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- lsm303dlhc_magn@1e {
+- compatible = "st,lsm303dlhc_magn";
+- reg = <0x1E>;
+- };
+-
+- lsm303dlh_accel@1e {
+- compatible = "st,lsm303dlhc_accel";
+- reg = <0x19>;
+- };
+- vcnl4000@13 {
+- compatible = "vishay,vcnl4000";
+- reg = <0x13>;
+- };
+- };
++ target = <&i2c2>;
++
++ __overlay__ {
++ /* needed to avoid gripping by DTC */
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ lsm303dlhc_magn@1e {
++ compatible = "st,lsm303dlhc_magn";
++ reg = <0x1E>;
++ };
++
++ lsm303dlh_accel@1e {
++ compatible = "st,lsm303dlhc_accel";
++ reg = <0x19>;
++ };
++
++ vcnl4000@13 {
++ compatible = "vishay,vcnl4000";
++ reg = <0x13>;
++ };
++
++ ssd1306: oled@3c {
++ compatible = "solomon,ssd1306fb-i2c";
++ reg = <0x3c>;
++ reset-gpios = <&gpio4 19 0>;
++ solomon,height = <32>;
++ solomon,width = <128>;
++ solomon,page-offset = <0>;
++ };
++ };
+ };
+ };
diff --git a/patches/linux-3.8.13/0383-firmware-DT-Fragment-for-MRF24J40-BeagleBone-Cape.patch b/patches/linux-3.8.13/0383-firmware-DT-Fragment-for-MRF24J40-BeagleBone-Cape.patch
new file mode 100644
index 0000000..c24f229
--- /dev/null
+++ b/patches/linux-3.8.13/0383-firmware-DT-Fragment-for-MRF24J40-BeagleBone-Cape.patch
@@ -0,0 +1,109 @@
+From: Alan Ott <alan@signal11.us>
+Date: Thu, 14 Mar 2013 09:36:14 -0400
+Subject: [PATCH] firmware: DT Fragment for MRF24J40 BeagleBone Cape
+
+Support for the Signal 11 MRF24J40 BeagleBone Cape.
+---
+ firmware/Makefile | 3 +-
+ firmware/capes/cape-bone-mrf24j40-00A0.dts | 78 ++++++++++++++++++++++++++++
+ 2 files changed, 80 insertions(+), 1 deletion(-)
+ create mode 100644 firmware/capes/cape-bone-mrf24j40-00A0.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index 6d156da..36a0dbb 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -152,7 +152,8 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ BB-BONE-eMMC1-01-00A0.dtbo \
+ cape-bone-iio-00A0.dtbo \
+ cape-bone-pinmux-test-00A0.dtbo \
+- cape-bone-exptest-00A0.dtbo
++ cape-bone-exptest-00A0.dtbo \
++ cape-bone-mrf24j40-00A0.dtbo
+
+ # the geiger cape
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE_GEIGER) += \
+diff --git a/firmware/capes/cape-bone-mrf24j40-00A0.dts b/firmware/capes/cape-bone-mrf24j40-00A0.dts
+new file mode 100644
+index 0000000..cdef7e2
+--- /dev/null
++++ b/firmware/capes/cape-bone-mrf24j40-00A0.dts
+@@ -0,0 +1,78 @@
++/*
++ * Copyright (C) 2013 Alan Ott <alan@signal11.us>
++ *
++ * 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.
++ */
++
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti-beaglebone-black";
++
++ /* Identification */
++ part-number = "BB-BONE-MRF24J40";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ mrf24j40_cape_pins: pinmux_mrf24j40_cape_pins {
++ pinctrl-single,pins = <
++ /* Pinmux comes from TRM section
++ 9.3.1: CONTROL_MODULE Regusters. */
++ //0x44 0x2f /* gpmc_a1.gpio1_17 INPUT,no-pull,mode7 */
++ //0x1A4 0x2f /* mcasp0_fsr.gpio3_19 INPUT,no-pull,mode7 */
++ //0x00 0x2f /* gpmc_ad0.gpio1_0 */
++
++ //so use GPIO1_13 (rst), GPIO1_14 (wake), then SPI1_CS0 (CS), and GPIO1_29 (INT)
++ 0x34 0x37 /* gpmc_ad13.gpio1_13 input, pull up, mode 7 */
++ 0x38 0x2f /* gpmc_ad14.gpio1_14 input, no pull, mode 7 */
++ //0x13c 0x2f /* gpmc_ad15.gpio1_15 input, no pull, mode 7 */
++ 0x7c 0x2f /* gpmc_csn0.gpio1_29 input, no pull, mode 7 */
++ >;
++ };
++ };
++
++ };
++
++
++ fragment@1 {
++ target = <&spi1>;
++
++ __overlay__ {
++ /* needed to avoid DTC warnings */
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi1_pins_s0>;
++
++ mrf24j40@0 {
++ compatible = "mrf24j40ma";
++ reg = <0>; /* CHIPSEL */
++ spi-max-frequency = <20000000>;
++ mode = <0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&mrf24j40_cape_pins>;
++
++ interrupt-parent = <&gpio2>;
++ interrupts = <29>;
++
++ // also working feb 9
++ //interrupt-parent = <&gpio2>;
++ //interrupts = <0>;
++
++ //working configuration
++ //interrupt-parent = <&gpio2>;
++ //interrupts = <17>;
++
++ //mrf24j40-wake = <&gpio4 19>;
++ //mrf24j40-reset = <gpio21 0>;
++ };
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0384-firmware-capes-Update-MRF24J40-cape-to-work-with-lat.patch b/patches/linux-3.8.13/0384-firmware-capes-Update-MRF24J40-cape-to-work-with-lat.patch
new file mode 100644
index 0000000..83c5b85
--- /dev/null
+++ b/patches/linux-3.8.13/0384-firmware-capes-Update-MRF24J40-cape-to-work-with-lat.patch
@@ -0,0 +1,70 @@
+From: Alan Ott <alan@signal11.us>
+Date: Fri, 29 Mar 2013 16:49:27 -0400
+Subject: [PATCH] firmware: capes: Update MRF24J40 cape to work with latest
+ bone dtsi
+
+am335x-bone-common.dtsi has removed the pinmux settings for SPI1.
+Add them to the MRF24J40 cape dts fragment
+
+Signed-off-by: Alan Ott <alan@signal11.us>
+---
+ firmware/capes/cape-bone-mrf24j40-00A0.dts | 25 ++++++++++---------------
+ 1 file changed, 10 insertions(+), 15 deletions(-)
+
+diff --git a/firmware/capes/cape-bone-mrf24j40-00A0.dts b/firmware/capes/cape-bone-mrf24j40-00A0.dts
+index cdef7e2..0fc2aea 100644
+--- a/firmware/capes/cape-bone-mrf24j40-00A0.dts
++++ b/firmware/capes/cape-bone-mrf24j40-00A0.dts
+@@ -23,19 +23,22 @@
+ pinctrl-single,pins = <
+ /* Pinmux comes from TRM section
+ 9.3.1: CONTROL_MODULE Regusters. */
+- //0x44 0x2f /* gpmc_a1.gpio1_17 INPUT,no-pull,mode7 */
+- //0x1A4 0x2f /* mcasp0_fsr.gpio3_19 INPUT,no-pull,mode7 */
+- //0x00 0x2f /* gpmc_ad0.gpio1_0 */
+
+- //so use GPIO1_13 (rst), GPIO1_14 (wake), then SPI1_CS0 (CS), and GPIO1_29 (INT)
++ /* so use GPIO1_13 (rst), GPIO1_14 (wake), then SPI1_CS0 (CS), and GPIO1_29 (INT) */
+ 0x34 0x37 /* gpmc_ad13.gpio1_13 input, pull up, mode 7 */
+ 0x38 0x2f /* gpmc_ad14.gpio1_14 input, no pull, mode 7 */
+- //0x13c 0x2f /* gpmc_ad15.gpio1_15 input, no pull, mode 7 */
+ 0x7c 0x2f /* gpmc_csn0.gpio1_29 input, no pull, mode 7 */
+ >;
+ };
++ bone_mrf24j40_spi1_pins: pinmux_bone_mrf24j40_spi1_pins {
++ pinctrl-single,pins = <
++ 0x190 0x33 /* mcasp0_aclkx.spi1_sclk, RX_ENABLED | PULLUP | MODE3 */
++ 0x194 0x33 /* mcasp0_fsx.spi1_d0, RX_ENABLED | PULLUP | MODE3 */
++ 0x198 0x33 /* mcasp0_axr0.spi1_d1, RX_ENABLED | PULLUP | MODE3 */
++ 0x19c 0x33 /* mcasp0_ahclkr.spi1_cs0, RX_ENABLED | PULLUP | MODE3 */
++ >;
++ };
+ };
+-
+ };
+
+
+@@ -49,7 +52,7 @@
+
+ status = "okay";
+ pinctrl-names = "default";
+- pinctrl-0 = <&spi1_pins_s0>;
++ pinctrl-0 = <&bone_mrf24j40_spi1_pins>;
+
+ mrf24j40@0 {
+ compatible = "mrf24j40ma";
+@@ -62,14 +65,6 @@
+ interrupt-parent = <&gpio2>;
+ interrupts = <29>;
+
+- // also working feb 9
+- //interrupt-parent = <&gpio2>;
+- //interrupts = <0>;
+-
+- //working configuration
+- //interrupt-parent = <&gpio2>;
+- //interrupts = <17>;
+-
+ //mrf24j40-wake = <&gpio4 19>;
+ //mrf24j40-reset = <gpio21 0>;
+ };
diff --git a/patches/linux-3.8.13/0385-am335x-bone-common-DT-Override-for-MRF24J40-Cape.patch b/patches/linux-3.8.13/0385-am335x-bone-common-DT-Override-for-MRF24J40-Cape.patch
new file mode 100644
index 0000000..abdc330
--- /dev/null
+++ b/patches/linux-3.8.13/0385-am335x-bone-common-DT-Override-for-MRF24J40-Cape.patch
@@ -0,0 +1,52 @@
+From: Alan Ott <alan@signal11.us>
+Date: Fri, 29 Mar 2013 16:48:42 -0400
+Subject: [PATCH] am335x-bone-common: DT Override for MRF24J40 Cape
+
+Signed-off-by: Alan Ott <alan@signal11.us>
+---
+ arch/arm/boot/dts/am335x-bone-common.dtsi | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
+index 3dfbb86..29e72a6 100644
+--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
+@@ -196,6 +196,15 @@
+ manufacturer = "Koen Kooi";
+ part-number = "BB-BONE-HEXY-01";
+ };
++ /* MRF24J40 Cape Override */
++ slot@11 {
++ ti,cape-override;
++ compatible = "kernel-command-line", "runtime";
++ board-name = "Bone-MRF24J40";
++ version = "00A0";
++ manufacturer = "Signal 11 Software";
++ part-number = "BB-BONE-MRF24J40";
++ };
+ };
+
+ /* mapping between board names and dtb objects */
+@@ -272,7 +281,6 @@
+ dtbo = "cape-bone-nixie-00A0.dtbo";
+ };
+ };
+-
+ cape@7 {
+ part-number = "BB-BONE-TFT-01";
+ version@00A0 {
+@@ -296,6 +304,14 @@
+ dtbo = "cape-bone-hexy-00A0.dtbo";
+ };
+ };
++ /* mrf24j40 cape */
++ cape@10 {
++ part-number = "BB-BONE-MRF24J40";
++ version@00A0 {
++ version = "00A0";
++ dtbo = "cape-bone-mrf24j40-00A0.dtbo";
++ };
++ };
+ };
+ };
+ };
diff --git a/patches/linux-3.8.13/0386-beaglebone-black-limit-LDO3-to-1.8V.patch b/patches/linux-3.8.13/0386-beaglebone-black-limit-LDO3-to-1.8V.patch
new file mode 100644
index 0000000..1cb4c23
--- /dev/null
+++ b/patches/linux-3.8.13/0386-beaglebone-black-limit-LDO3-to-1.8V.patch
@@ -0,0 +1,26 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Sat, 30 Mar 2013 08:37:26 +0100
+Subject: [PATCH] beaglebone black: limit LDO3 to 1.8V
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/boot/dts/am335x-boneblack.dts | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts
+index e88723c..3274dbd 100644
+--- a/arch/arm/boot/dts/am335x-boneblack.dts
++++ b/arch/arm/boot/dts/am335x-boneblack.dts
+@@ -26,6 +26,12 @@
+ >;
+ };
+
++&ldo3_reg {
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++};
++
+ &mmc2 {
+ vmmc-supply = <&ldo3_reg>;
+ bus-width = <8>;
diff --git a/patches/linux-3.8.13/0387-beaglebone-black-add-new-fixed-regulator-for-uSD-eMM.patch b/patches/linux-3.8.13/0387-beaglebone-black-add-new-fixed-regulator-for-uSD-eMM.patch
new file mode 100644
index 0000000..289a68a
--- /dev/null
+++ b/patches/linux-3.8.13/0387-beaglebone-black-add-new-fixed-regulator-for-uSD-eMM.patch
@@ -0,0 +1,47 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Mon, 1 Apr 2013 09:36:22 +0200
+Subject: [PATCH] beaglebone black: add new fixed regulator for uSD/eMMC
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/boot/dts/am335x-bone-common.dtsi | 8 ++++++++
+ arch/arm/boot/dts/am335x-boneblack.dts | 6 +++++-
+ 2 files changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
+index 29e72a6..6974fcd 100644
+--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
+@@ -314,6 +314,14 @@
+ };
+ };
+ };
++
++ vmmcsd_fixed: fixedregulator@0 {
++ compatible = "regulator-fixed";
++ regulator-name = "vmmcsd_fixed";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
+ };
+
+ &i2c0 {
+diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts
+index 3274dbd..5434bfd 100644
+--- a/arch/arm/boot/dts/am335x-boneblack.dts
++++ b/arch/arm/boot/dts/am335x-boneblack.dts
+@@ -32,8 +32,12 @@
+ regulator-always-on;
+ };
+
++&mmc1 {
++ vmmc-supply = <&vmmcsd_fixed>;
++};
++
+ &mmc2 {
+- vmmc-supply = <&ldo3_reg>;
++ vmmc-supply = <&vmmcsd_fixed>;
+ bus-width = <8>;
+ ti,non-removable;
+ status = "okay";
diff --git a/patches/linux-3.8.13/0388-capemgr-Implement-disable-overrides-on-the-cmd-line.patch b/patches/linux-3.8.13/0388-capemgr-Implement-disable-overrides-on-the-cmd-line.patch
new file mode 100644
index 0000000..bab309d
--- /dev/null
+++ b/patches/linux-3.8.13/0388-capemgr-Implement-disable-overrides-on-the-cmd-line.patch
@@ -0,0 +1,218 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 1 Apr 2013 18:20:35 +0300
+Subject: [PATCH] capemgr: Implement disable overrides on the cmd line
+
+Allow capes to be disabled on the kernel command line.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/misc/cape/beaglebone/capemgr.c | 133 +++++++++++++++++++++-----------
+ 1 file changed, 88 insertions(+), 45 deletions(-)
+
+diff --git a/drivers/misc/cape/beaglebone/capemgr.c b/drivers/misc/cape/beaglebone/capemgr.c
+index 2ee7b11..5d87088 100644
+--- a/drivers/misc/cape/beaglebone/capemgr.c
++++ b/drivers/misc/cape/beaglebone/capemgr.c
+@@ -47,7 +47,14 @@
+ /* extra command line overrides */
+ static char *extra_override = NULL;
+ module_param(extra_override, charp, 0444);
+-MODULE_PARM_DESC(extra_override, "Comma delimited list of PART-NUMBER[:REV] overrides");
++MODULE_PARM_DESC(extra_override,
++ "Comma delimited list of PART-NUMBER[:REV] overrides");
++
++/* disabled capes */
++static char *disable_partno = NULL;
++module_param(disable_partno, charp, 0444);
++MODULE_PARM_DESC(disable_partno,
++ "Comma delimited list of PART-NUMBER[:REV] of disabled capes");
+
+ struct bone_capemgr_info;
+
+@@ -547,51 +554,19 @@ slot_fail_check:
+ return 0;
+ }
+
+-/* check an override slot node if it's compatible */
+-static int bone_is_compatible_override(struct device_node *node,
+- const char *compatible_name)
++/* return 0 if not matched,, 1 if matched */
++static int bone_match_cape(const char *match,
++ const char *part_number, const char *version)
+ {
+- struct property *prop;
+- char *buf, *s, *e, *sn;
+- const char *part_number;
+- const char *version;
+ char *tmp_part_number, *tmp_version;
++ char *buf, *s, *e, *sn;
+ int found;
+
+- /* check if the slot is compatible with the board */
+- prop = of_find_property(node, "compatible", NULL);
+-
+- /* no prop, it's something that's compatible with everything */
+- if (prop == NULL)
+- return 1;
+-
+- /* check if it's directly compatible with the baseboard */
+- if (of_multi_prop_cmp(prop, compatible_name) == 0)
+- return 1;
+-
+- /* forced override? */
+- if (of_multi_prop_cmp(prop, "force") == 0)
+- return 1;
+-
+- /* final try, check if it's specified in the kernel command line */
+- if (extra_override == NULL)
+- return 0;
+-
+- /* the compatible name should have kernel-command-line in it */
+- if (of_multi_prop_cmp(prop, "kernel-command-line") != 0)
+- return 0;
+-
+- /* we must have at least the part-name */
+- if (of_property_read_string(node, "part-number",
+- &part_number) != 0)
++ if (match == NULL || part_number == NULL)
+ return 0;
+
+- /* read the version (if it exists) */
+- if (of_property_read_string(node, "version", &version) != 0)
+- version = NULL;
+-
+ /* copy the argument to work on it */
+- buf = kstrdup(extra_override, GFP_KERNEL);
++ buf = kstrdup(match, GFP_KERNEL);
+
+ /* no memory, too bad... */
+ if (buf == NULL)
+@@ -617,12 +592,6 @@ static int bone_is_compatible_override(struct device_node *node,
+ if (strcmp(tmp_part_number, part_number) != 0)
+ continue;
+
+- pr_info("override: part-number='%s' version='%s' "
+- "tmp_version='%s'\n",
+- part_number,
+- version ? version : "N/A",
+- tmp_version ? tmp_version : "N/A");
+-
+ /* if there's no version, match any */
+ if (version == NULL || tmp_version == NULL ||
+ strcmp(version, tmp_version) == 0) {
+@@ -636,6 +605,50 @@ static int bone_is_compatible_override(struct device_node *node,
+ return found;
+ }
+
++/* check an override slot node if it's compatible */
++static int bone_is_compatible_override(struct device_node *node,
++ const char *compatible_name)
++{
++ struct property *prop;
++ const char *part_number;
++ const char *version;
++
++ /* check if the slot is compatible with the board */
++ prop = of_find_property(node, "compatible", NULL);
++
++ /* no prop, it's something that's compatible with everything */
++ if (prop == NULL)
++ return 1;
++
++ /* check if it's directly compatible with the baseboard */
++ if (of_multi_prop_cmp(prop, compatible_name) == 0)
++ return 1;
++
++ /* forced override? */
++ if (of_multi_prop_cmp(prop, "force") == 0)
++ return 1;
++
++ /* final try, check if it's specified in the kernel command line */
++ if (extra_override == NULL)
++ return 0;
++
++ /* the compatible name should have kernel-command-line in it */
++ if (of_multi_prop_cmp(prop, "kernel-command-line") != 0)
++ return 0;
++
++ /* we must have at least the part-name */
++ if (of_property_read_string(node, "part-number",
++ &part_number) != 0)
++ return 0;
++
++ /* read the version (if it exists) */
++ if (of_property_read_string(node, "version", &version) != 0)
++ version = NULL;
++
++ /* match on the extra override */
++ return bone_match_cape(extra_override, part_number, version);
++}
++
+ static int bone_is_compatible_runtime_override(struct device_node *node,
+ const char *req_part_number, const char *req_version)
+ {
+@@ -1045,6 +1058,15 @@ found:
+ part_number, version))
+ continue;
+
++ /* if matches the disabled ones skip */
++ if (bone_match_cape(disable_partno,
++ part_number, NULL)) {
++ dev_info(&pdev->dev,
++ "Skipping disabled cape with "
++ "part# %s\n", part_number);
++ continue;
++ }
++
+ slot = bone_capemgr_add_slot(info, node,
+ part_number, version);
+ if (IS_ERR(slot)) {
+@@ -1522,6 +1544,7 @@ bone_capemgr_add_slot(struct bone_capemgr_info *info, struct device_node *node,
+ slotno);
+ /* but all is fine */
+ } else {
++
+ dev_info(dev, "slot #%d: '%s'\n",
+ slotno, slot->text_id);
+
+@@ -1701,6 +1724,15 @@ bone_capemgr_probe(struct platform_device *pdev)
+ &part_number) != 0)
+ continue;
+
++ /* if matches the disabled ones skip */
++ if (bone_match_cape(disable_partno,
++ part_number, NULL)) {
++ dev_info(&pdev->dev,
++ "Skipping disabled cape with "
++ "part# %s\n", part_number);
++ continue;
++ }
++
+ len = sizeof(*capemap) + strlen(part_number) + 1;
+ capemap = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
+ if (capemap == NULL) {
+@@ -1741,6 +1773,7 @@ bone_capemgr_probe(struct platform_device *pdev)
+ ret = PTR_ERR(slot);
+ goto err_exit;
+ }
++ /* note that slot may be NULL (means it was disabled) */
+ }
+ of_node_put(slots_node);
+ }
+@@ -1760,6 +1793,16 @@ bone_capemgr_probe(struct platform_device *pdev)
+ /* now load each (take lock to be sure */
+ mutex_lock(&info->slots_list_mutex);
+ list_for_each_entry(slot, &info->slot_list, node) {
++
++ /* if matches the disabled ones skip */
++ if (bone_match_cape(disable_partno,
++ slot->part_number, NULL)) {
++ dev_info(&pdev->dev,
++ "Skipping loading of disabled cape with "
++ "part# %s\n", slot->part_number);
++ continue;
++ }
++
+ if (!slot->probe_failed && !slot->loaded) {
+ slot->loading = 1;
+ slot->loader_thread = kthread_run(bone_capemgr_loader,
diff --git a/patches/linux-3.8.13/0389-tilcdc-Enable-pinmux-states.patch b/patches/linux-3.8.13/0389-tilcdc-Enable-pinmux-states.patch
new file mode 100644
index 0000000..cc480c7
--- /dev/null
+++ b/patches/linux-3.8.13/0389-tilcdc-Enable-pinmux-states.patch
@@ -0,0 +1,492 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Fri, 29 Mar 2013 19:32:29 +0200
+Subject: [PATCH] tilcdc: Enable pinmux states
+
+Things like the boot switch are on the LCD data pins.
+Allows us to change pinmuxing on runtime.
+---
+ drivers/gpu/drm/tilcdc/tilcdc_panel.c | 113 +++++++++++++++++++++++++-
+ drivers/gpu/drm/tilcdc/tilcdc_slave.c | 114 +++++++++++++++++++++++++-
+ drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 115 ++++++++++++++++++++++++++-
+ firmware/capes/cape-boneblack-hdmi-00A0.dts | 8 +-
+ 4 files changed, 337 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+index 2496ee4..361c569 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+@@ -31,6 +31,8 @@ struct panel_module {
+ struct display_timings *timings;
+ struct backlight_device *backlight;
+ int gpio;
++ struct pinctrl *pinctrl;
++ char *selected_state_name;
+ };
+ #define to_panel_module(x) container_of(x, struct panel_module, base)
+
+@@ -355,14 +357,83 @@ static struct tilcdc_panel_info * of_get_panel_info(struct device_node *np)
+
+ static struct of_device_id panel_of_match[];
+
++static ssize_t pinmux_show_state(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct panel_module *panel_mod = platform_get_drvdata(pdev);
++ const char *name;
++
++ name = panel_mod->selected_state_name;
++ if (name == NULL || strlen(name) == 0)
++ name = "none";
++ return sprintf(buf, "%s\n", name);
++}
++
++static ssize_t pinmux_store_state(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t count)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct panel_module *panel_mod = platform_get_drvdata(pdev);
++ struct pinctrl_state *state;
++ char *state_name;
++ char *s;
++ int err;
++
++ /* duplicate (as a null terminated string) */
++ state_name = kmalloc(count + 1, GFP_KERNEL);
++ if (state_name == NULL)
++ return -ENOMEM;
++ memcpy(state_name, buf, count);
++ state_name[count] = '\0';
++
++ /* and chop off newline */
++ s = strchr(state_name, '\n');
++ if (s != NULL)
++ *s = '\0';
++
++ /* try to select default state at first (if it exists) */
++ state = pinctrl_lookup_state(panel_mod->pinctrl, state_name);
++ if (!IS_ERR(state)) {
++ err = pinctrl_select_state(panel_mod->pinctrl, state);
++ if (err != 0)
++ dev_err(dev, "Failed to select state %s\n",
++ state_name);
++ } else {
++ dev_err(dev, "Failed to find state %s\n", state_name);
++ err = PTR_RET(state);
++ }
++
++ if (err == 0) {
++ kfree(panel_mod->selected_state_name);
++ panel_mod->selected_state_name = state_name;
++ }
++
++ return err ? err : count;
++}
++
++static DEVICE_ATTR(pinmux_state, S_IWUSR | S_IRUGO,
++ pinmux_show_state, pinmux_store_state);
++
++static struct attribute *pinmux_attributes[] = {
++ &dev_attr_pinmux_state.attr,
++ NULL
++};
++
++static const struct attribute_group pinmux_attr_group = {
++ .attrs = pinmux_attributes,
++};
++
+ static int panel_probe(struct platform_device *pdev)
+ {
++ struct device *dev = &pdev->dev;
+ struct device_node *node = pdev->dev.of_node;
+ struct panel_module *panel_mod;
+ struct tilcdc_module *mod;
+- struct pinctrl *pinctrl;
++ struct pinctrl_state *state;
+ enum of_gpio_flags ofgpioflags;
+ unsigned long gpioflags;
++ char *state_name;
+ int ret = -EINVAL;
+
+ /* bail out early if no DT data: */
+@@ -375,14 +446,48 @@ static int panel_probe(struct platform_device *pdev)
+ if (!panel_mod)
+ return -ENOMEM;
+
++ platform_set_drvdata(pdev, panel_mod);
++
+ mod = &panel_mod->base;
+
+ tilcdc_module_init(mod, "panel", &panel_module_ops);
+
+- pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+- if (IS_ERR(pinctrl))
+- dev_warn(&pdev->dev, "pins are not configured\n");
++ state_name = kmalloc(strlen(PINCTRL_STATE_DEFAULT) + 1,
++ GFP_KERNEL);
++ if (state_name == NULL) {
++ dev_err(dev, "Failed to allocate state name\n");
++ ret = -ENOMEM;
++ goto fail;
++ }
++ panel_mod->selected_state_name = state_name;
++ strcpy(panel_mod->selected_state_name, PINCTRL_STATE_DEFAULT);
+
++ panel_mod->pinctrl = devm_pinctrl_get(dev);
++ if (IS_ERR(panel_mod->pinctrl)) {
++ dev_err(dev, "Failed to get pinctrl\n");
++ ret = PTR_RET(panel_mod->pinctrl);
++ goto fail;
++ }
++
++ /* try to select default state at first (if it exists) */
++ state = pinctrl_lookup_state(panel_mod->pinctrl,
++ panel_mod->selected_state_name);
++ if (!IS_ERR(state)) {
++ ret = pinctrl_select_state(panel_mod->pinctrl, state);
++ if (ret != 0) {
++ dev_err(dev, "Failed to select default state\n");
++ goto fail;
++ }
++ } else {
++ panel_mod->selected_state_name = '\0';
++ }
++
++ /* Register sysfs hooks */
++ ret = sysfs_create_group(&dev->kobj, &pinmux_attr_group);
++ if (ret) {
++ dev_err(dev, "Failed to create sysfs group\n");
++ goto fail;
++ }
+
+ panel_mod->timings = of_get_display_timings(node);
+ if (!panel_mod->timings) {
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave.c b/drivers/gpu/drm/tilcdc/tilcdc_slave.c
+index a2d86ac..17252ef 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_slave.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_slave.c
+@@ -26,6 +26,8 @@
+ struct slave_module {
+ struct tilcdc_module base;
+ struct i2c_adapter *i2c;
++ struct pinctrl *pinctrl;
++ char *selected_state_name;
+ };
+ #define to_slave_module(x) container_of(x, struct slave_module, base)
+
+@@ -291,14 +293,83 @@ static const struct tilcdc_module_ops slave_module_ops = {
+
+ static struct of_device_id slave_of_match[];
+
++static ssize_t pinmux_show_state(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct slave_module *slave_mod = platform_get_drvdata(pdev);
++ const char *name;
++
++ name = slave_mod->selected_state_name;
++ if (name == NULL || strlen(name) == 0)
++ name = "none";
++ return sprintf(buf, "%s\n", name);
++}
++
++static ssize_t pinmux_store_state(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t count)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct slave_module *slave_mod = platform_get_drvdata(pdev);
++ struct pinctrl_state *state;
++ char *state_name;
++ char *s;
++ int err;
++
++ /* duplicate (as a null terminated string) */
++ state_name = kmalloc(count + 1, GFP_KERNEL);
++ if (state_name == NULL)
++ return -ENOMEM;
++ memcpy(state_name, buf, count);
++ state_name[count] = '\0';
++
++ /* and chop off newline */
++ s = strchr(state_name, '\n');
++ if (s != NULL)
++ *s = '\0';
++
++ /* try to select default state at first (if it exists) */
++ state = pinctrl_lookup_state(slave_mod->pinctrl, state_name);
++ if (!IS_ERR(state)) {
++ err = pinctrl_select_state(slave_mod->pinctrl, state);
++ if (err != 0)
++ dev_err(dev, "Failed to select state %s\n",
++ state_name);
++ } else {
++ dev_err(dev, "Failed to find state %s\n", state_name);
++ err = PTR_RET(state);
++ }
++
++ if (err == 0) {
++ kfree(slave_mod->selected_state_name);
++ slave_mod->selected_state_name = state_name;
++ }
++
++ return err ? err : count;
++}
++
++static DEVICE_ATTR(pinmux_state, S_IWUSR | S_IRUGO,
++ pinmux_show_state, pinmux_store_state);
++
++static struct attribute *pinmux_attributes[] = {
++ &dev_attr_pinmux_state.attr,
++ NULL
++};
++
++static const struct attribute_group pinmux_attr_group = {
++ .attrs = pinmux_attributes,
++};
++
+ static int slave_probe(struct platform_device *pdev)
+ {
++ struct device *dev = &pdev->dev;
+ struct device_node *node = pdev->dev.of_node;
+ struct device_node *i2c_node;
+ struct slave_module *slave_mod;
+ struct tilcdc_module *mod;
+- struct pinctrl *pinctrl;
++ struct pinctrl_state *state;
+ uint32_t i2c_phandle;
++ char *state_name;
+ int ret = -EINVAL;
+
+ /* bail out early if no DT data: */
+@@ -311,13 +382,48 @@ static int slave_probe(struct platform_device *pdev)
+ if (!slave_mod)
+ return -ENOMEM;
+
++ platform_set_drvdata(pdev, slave_mod);
++
+ mod = &slave_mod->base;
+
+ tilcdc_module_init(mod, "slave", &slave_module_ops);
+
+- pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+- if (IS_ERR(pinctrl))
+- dev_warn(&pdev->dev, "pins are not configured\n");
++ state_name = kmalloc(strlen(PINCTRL_STATE_DEFAULT) + 1,
++ GFP_KERNEL);
++ if (state_name == NULL) {
++ dev_err(dev, "Failed to allocate state name\n");
++ ret = -ENOMEM;
++ goto fail;
++ }
++ slave_mod->selected_state_name = state_name;
++ strcpy(slave_mod->selected_state_name, PINCTRL_STATE_DEFAULT);
++
++ slave_mod->pinctrl = devm_pinctrl_get(dev);
++ if (IS_ERR(slave_mod->pinctrl)) {
++ dev_err(dev, "Failed to get pinctrl\n");
++ ret = PTR_RET(slave_mod->pinctrl);
++ goto fail;
++ }
++
++ /* try to select default state at first (if it exists) */
++ state = pinctrl_lookup_state(slave_mod->pinctrl,
++ slave_mod->selected_state_name);
++ if (!IS_ERR(state)) {
++ ret = pinctrl_select_state(slave_mod->pinctrl, state);
++ if (ret != 0) {
++ dev_err(dev, "Failed to select default state\n");
++ goto fail;
++ }
++ } else {
++ slave_mod->selected_state_name = '\0';
++ }
++
++ /* Register sysfs hooks */
++ ret = sysfs_create_group(&dev->kobj, &pinmux_attr_group);
++ if (ret) {
++ dev_err(dev, "Failed to create sysfs group\n");
++ goto fail;
++ }
+
+ if (of_property_read_u32(node, "i2c", &i2c_phandle)) {
+ dev_err(&pdev->dev, "could not get i2c bus phandle\n");
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
+index 6f9d727..9d9796f 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
+@@ -29,6 +29,8 @@ struct tfp410_module {
+ struct i2c_adapter *i2c;
+ enum of_gpio_flags ofgpioflags;
+ int gpio;
++ struct pinctrl *pinctrl;
++ char *selected_state_name;
+ };
+ #define to_tfp410_module(x) container_of(x, struct tfp410_module, base)
+
+@@ -328,15 +330,84 @@ static const struct tilcdc_module_ops tfp410_module_ops = {
+
+ static struct of_device_id tfp410_of_match[];
+
++static ssize_t pinmux_show_state(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct tfp410_module *tfp410_mod = platform_get_drvdata(pdev);
++ const char *name;
++
++ name = tfp410_mod->selected_state_name;
++ if (name == NULL || strlen(name) == 0)
++ name = "none";
++ return sprintf(buf, "%s\n", name);
++}
++
++static ssize_t pinmux_store_state(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t count)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct tfp410_module *tfp410_mod = platform_get_drvdata(pdev);
++ struct pinctrl_state *state;
++ char *state_name;
++ char *s;
++ int err;
++
++ /* duplicate (as a null terminated string) */
++ state_name = kmalloc(count + 1, GFP_KERNEL);
++ if (state_name == NULL)
++ return -ENOMEM;
++ memcpy(state_name, buf, count);
++ state_name[count] = '\0';
++
++ /* and chop off newline */
++ s = strchr(state_name, '\n');
++ if (s != NULL)
++ *s = '\0';
++
++ /* try to select default state at first (if it exists) */
++ state = pinctrl_lookup_state(tfp410_mod->pinctrl, state_name);
++ if (!IS_ERR(state)) {
++ err = pinctrl_select_state(tfp410_mod->pinctrl, state);
++ if (err != 0)
++ dev_err(dev, "Failed to select state %s\n",
++ state_name);
++ } else {
++ dev_err(dev, "Failed to find state %s\n", state_name);
++ err = PTR_RET(state);
++ }
++
++ if (err == 0) {
++ kfree(tfp410_mod->selected_state_name);
++ tfp410_mod->selected_state_name = state_name;
++ }
++
++ return err ? err : count;
++}
++
++static DEVICE_ATTR(pinmux_state, S_IWUSR | S_IRUGO,
++ pinmux_show_state, pinmux_store_state);
++
++static struct attribute *pinmux_attributes[] = {
++ &dev_attr_pinmux_state.attr,
++ NULL
++};
++
++static const struct attribute_group pinmux_attr_group = {
++ .attrs = pinmux_attributes,
++};
++
+ static int tfp410_probe(struct platform_device *pdev)
+ {
++ struct device *dev = &pdev->dev;
+ struct device_node *node = pdev->dev.of_node;
+ struct device_node *i2c_node;
+ struct tfp410_module *tfp410_mod;
+ struct tilcdc_module *mod;
+- struct pinctrl *pinctrl;
++ struct pinctrl_state *state;
+ uint32_t i2c_phandle;
+ unsigned long gpioflags;
++ char *state_name;
+ int ret = -EINVAL;
+
+ /* bail out early if no DT data: */
+@@ -349,13 +420,49 @@ static int tfp410_probe(struct platform_device *pdev)
+ if (!tfp410_mod)
+ return -ENOMEM;
+
++ platform_set_drvdata(pdev, tfp410_mod);
++
+ mod = &tfp410_mod->base;
+
+ tilcdc_module_init(mod, "tfp410", &tfp410_module_ops);
+
+- pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+- if (IS_ERR(pinctrl))
+- dev_warn(&pdev->dev, "pins are not configured\n");
++ state_name = kmalloc(strlen(PINCTRL_STATE_DEFAULT) + 1,
++ GFP_KERNEL);
++ if (state_name == NULL) {
++ dev_err(dev, "Failed to allocate state name\n");
++ ret = -ENOMEM;
++ goto fail;
++ }
++ tfp410_mod->selected_state_name = state_name;
++ strcpy(tfp410_mod->selected_state_name, PINCTRL_STATE_DEFAULT);
++
++ tfp410_mod->pinctrl = devm_pinctrl_get(dev);
++ if (IS_ERR(tfp410_mod->pinctrl)) {
++ dev_err(dev, "Failed to get pinctrl\n");
++ ret = PTR_RET(tfp410_mod->pinctrl);
++ goto fail;
++ }
++
++ /* try to select default state at first (if it exists) */
++ state = pinctrl_lookup_state(tfp410_mod->pinctrl,
++ tfp410_mod->selected_state_name);
++ if (!IS_ERR(state)) {
++ ret = pinctrl_select_state(tfp410_mod->pinctrl, state);
++ if (ret != 0) {
++ dev_err(dev, "Failed to select default state\n");
++ goto fail;
++ }
++ } else {
++ tfp410_mod->selected_state_name = '\0';
++ }
++
++ /* Register sysfs hooks */
++ ret = sysfs_create_group(&dev->kobj, &pinmux_attr_group);
++ if (ret) {
++ dev_err(dev, "Failed to create sysfs group\n");
++ goto fail;
++ }
++
+
+ if (of_property_read_u32(node, "i2c", &i2c_phandle)) {
+ dev_err(&pdev->dev, "could not get i2c bus phandle\n");
+diff --git a/firmware/capes/cape-boneblack-hdmi-00A0.dts b/firmware/capes/cape-boneblack-hdmi-00A0.dts
+index 02bcb93..ee36d0e 100644
+--- a/firmware/capes/cape-boneblack-hdmi-00A0.dts
++++ b/firmware/capes/cape-boneblack-hdmi-00A0.dts
+@@ -41,6 +41,11 @@
+ 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+ >;
+ };
++ nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins {
++ pinctrl-single,pins = <
++ 0x1b0 0x03 /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */
++ >;
++ };
+ };
+ };
+
+@@ -55,8 +60,9 @@
+ hdmi {
+ compatible = "tilcdc,slave";
+ i2c = <&i2c0>;
+- pinctrl-names = "default";
++ pinctrl-names = "default", "off";
+ pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
++ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
+ };
+
+ fb {
diff --git a/patches/linux-3.8.13/0390-cape-Add-a-simple-cape-for-handling-the-uSD-button.patch b/patches/linux-3.8.13/0390-cape-Add-a-simple-cape-for-handling-the-uSD-button.patch
new file mode 100644
index 0000000..f7cd84c
--- /dev/null
+++ b/patches/linux-3.8.13/0390-cape-Add-a-simple-cape-for-handling-the-uSD-button.patch
@@ -0,0 +1,84 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Fri, 29 Mar 2013 17:44:02 +0200
+Subject: [PATCH] cape: Add a simple cape for handling the uSD button.
+
+Doesn't work ofcourse due to conflict with the HDMI.
+
+Conflicts:
+ firmware/Makefile
+---
+ firmware/Makefile | 3 +-
+ firmware/capes/BB-BONELT-BT-00A0.dts | 50 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 52 insertions(+), 1 deletion(-)
+ create mode 100644 firmware/capes/BB-BONELT-BT-00A0.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index 36a0dbb..f9f0294 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -153,7 +153,8 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ cape-bone-iio-00A0.dtbo \
+ cape-bone-pinmux-test-00A0.dtbo \
+ cape-bone-exptest-00A0.dtbo \
+- cape-bone-mrf24j40-00A0.dtbo
++ cape-bone-mrf24j40-00A0.dtbo \
++ BB-BONELT-BT-00A0.dtbo
+
+ # the geiger cape
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE_GEIGER) += \
+diff --git a/firmware/capes/BB-BONELT-BT-00A0.dts b/firmware/capes/BB-BONELT-BT-00A0.dts
+new file mode 100644
+index 0000000..f32d6f5
+--- /dev/null
++++ b/firmware/capes/BB-BONELT-BT-00A0.dts
+@@ -0,0 +1,50 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-BONELT-BT";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ bone_bt_cape_key_pins: pinmux_bone_bt_cape_key_pins {
++ pinctrl-single,pins = <
++ 0x0a8 0x27 /* P8.43 lcd_data2.gpio2[8] */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ bt_gpio_key {
++ compatible = "gpio-keys";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bone_bt_cape_key_pins>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ button@1 {
++ debounce_interval = <1>;
++ linux,code = <28>;
++ label = "enter";
++ gpios = <&gpio3 8 0x0>;
++ };
++ };
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0391-beaglebone-add-support-for-DVI-00A3.patch b/patches/linux-3.8.13/0391-beaglebone-add-support-for-DVI-00A3.patch
new file mode 100644
index 0000000..82d55d9
--- /dev/null
+++ b/patches/linux-3.8.13/0391-beaglebone-add-support-for-DVI-00A3.patch
@@ -0,0 +1,42 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Wed, 3 Apr 2013 15:39:38 +0200
+Subject: [PATCH] beaglebone: add support for DVI 00A3
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/boot/dts/am335x-bone-common.dtsi | 8 ++++++++
+ firmware/capes/cape-bone-dvi-00A2.dts | 2 +-
+ 2 files changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
+index 6974fcd..524bf03 100644
+--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
+@@ -221,6 +221,14 @@
+ version = "00A1", "01";
+ dtbo = "cape-bone-dvi-00A1.dtbo";
+ };
++ version@00A2 {
++ version = "00A2", "A2";
++ dtbo = "cape-bone-dvi-00A2.dtbo";
++ };
++ version@00A3 {
++ version = "00A3";
++ dtbo = "cape-bone-dvi-00A2.dtbo";
++ };
+ };
+
+ /* beaglebone black emmc on board */
+diff --git a/firmware/capes/cape-bone-dvi-00A2.dts b/firmware/capes/cape-bone-dvi-00A2.dts
+index fb2dcf0..34ced98 100644
+--- a/firmware/capes/cape-bone-dvi-00A2.dts
++++ b/firmware/capes/cape-bone-dvi-00A2.dts
+@@ -13,7 +13,7 @@
+
+ /* identification */
+ part-number = "BB-BONE-DVID-01";
+- version = "00A2", "A2";
++ version = "00A3", "00A2", "A2";
+
+ fragment@0 {
+ target = <&am33xx_pinmux>;
diff --git a/patches/linux-3.8.13/0392-beaglebone-remove-audio-section-from-DVID-rev-2-and-.patch b/patches/linux-3.8.13/0392-beaglebone-remove-audio-section-from-DVID-rev-2-and-.patch
new file mode 100644
index 0000000..faf35ed
--- /dev/null
+++ b/patches/linux-3.8.13/0392-beaglebone-remove-audio-section-from-DVID-rev-2-and-.patch
@@ -0,0 +1,90 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Wed, 3 Apr 2013 15:59:07 +0200
+Subject: [PATCH] beaglebone: remove audio section from DVID rev 2 and 3 capes
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ firmware/capes/cape-bone-dvi-00A2.dts | 65 ---------------------------------
+ 1 file changed, 65 deletions(-)
+
+diff --git a/firmware/capes/cape-bone-dvi-00A2.dts b/firmware/capes/cape-bone-dvi-00A2.dts
+index 34ced98..a3cd39d 100644
+--- a/firmware/capes/cape-bone-dvi-00A2.dts
++++ b/firmware/capes/cape-bone-dvi-00A2.dts
+@@ -52,16 +52,6 @@
+ 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+ >;
+ };
+-
+- bone_dvi_cape_audio_pins: pinmux_bone_dvi_cape_audio_pins {
+- pinctrl-single,pins = <
+- 0x190 0x20 /* mcasp0_aclkx.mcasp0_aclkx, INPUT | MODE0 */
+- 0x194 0x20 /* mcasp0_fsx.mcasp0_fsx, INPUT | MODE0 */
+- 0x19c 0x22 /* mcasp0_ahclkr.mcasp0_axr2, INPUT | MODE2 */
+- 0x1ac 0x22 /* mcasp0_ahclkx.mcasp0_axr3, INPUT | MODE2 */
+-
+- >;
+- };
+ };
+ };
+
+@@ -112,59 +102,4 @@
+
+ };
+ };
+-
+- fragment@2 {
+- target = <&i2c2>;
+- __overlay__ {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- tlv320aic3x: tlv320aic3x@1b {
+- compatible = "ti,tlv320aic3x";
+- reg = <0x1b>;
+- status = "okay";
+- };
+- };
+- };
+-
+- fragment@3 {
+- target = <&mcasp0>;
+- __overlay__ {
+- pinctrl-names = "default";
+- pinctrl-0 = <&bone_dvi_cape_audio_pins>;
+-
+- status = "okay";
+-
+- op-mode = <0>; /* MCASP_IIS_MODE */
+- tdm-slots = <2>;
+- num-serializer = <16>;
+- serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+- 0 0 2 1
+- 0 0 0 0
+- 0 0 0 0
+- 0 0 0 0
+- >;
+- tx-num-evt = <1>;
+- rx-num-evt = <1>;
+- };
+- };
+-
+- fragment@4 {
+- target = <&ocp>;
+- __overlay__ {
+- sound {
+- compatible = "ti,da830-evm-audio";
+- ti,model = "DA830 EVM";
+- ti,audio-codec = <&tlv320aic3x>;
+- ti,mcasp-controller = <&mcasp0>;
+- ti,codec-clock-rate = <12000000>;
+- ti,audio-routing =
+- "Headphone Jack", "HPLOUT",
+- "Headphone Jack", "HPROUT",
+- "LINE1L", "Line In",
+- "LINE1R", "Line In";
+- };
+- };
+-
+- };
+ };
diff --git a/patches/linux-3.8.13/0393-beaglebone-add-dts-for-audio-cape.patch b/patches/linux-3.8.13/0393-beaglebone-add-dts-for-audio-cape.patch
new file mode 100644
index 0000000..a5d1324
--- /dev/null
+++ b/patches/linux-3.8.13/0393-beaglebone-add-dts-for-audio-cape.patch
@@ -0,0 +1,154 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Thu, 4 Apr 2013 10:24:06 +0200
+Subject: [PATCH] beaglebone: add dts for audio cape
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ firmware/Makefile | 1 +
+ firmware/capes/BB-BONE-AUDI-01-00A0.dts | 125 +++++++++++++++++++++++++++++++
+ 2 files changed, 126 insertions(+)
+ create mode 100644 firmware/capes/BB-BONE-AUDI-01-00A0.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index f9f0294..d4403b5 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -147,6 +147,7 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ cape-bone-hexy-00A0.dtbo \
+ cape-bone-lcd3-00A0.dtbo \
+ cape-bone-lcd3-00A2.dtbo \
++ BB-BONE-AUDI-01-00A0.dtbo \
+ BB-BONE-LCD7-01-00A2.dtbo \
+ BB-BONE-LCD7-01-00A4.dtbo \
+ BB-BONE-eMMC1-01-00A0.dtbo \
+diff --git a/firmware/capes/BB-BONE-AUDI-01-00A0.dts b/firmware/capes/BB-BONE-AUDI-01-00A0.dts
+new file mode 100644
+index 0000000..8e1256e
+--- /dev/null
++++ b/firmware/capes/BB-BONE-AUDI-01-00A0.dts
+@@ -0,0 +1,125 @@
++/*
++ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "BB-BONE-AUDI-01";
++ version = "00A0", "A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ bone_audio_cape_led_pins: pinmux_bone_audio_cape_led_pins {
++ pinctrl-single,pins = <
++ 0x48 0x07 /* gpmc_a2.gpio1_18, OUTPUT | MODE7 */
++ 0x4c 0x07 /* gpmc_a3.gpio1_19, OUTPUT | MODE7 */
++ >;
++ };
++
++ bone_audio_cape_audio_pins: pinmux_bone_audio_cape_audio_pins {
++ pinctrl-single,pins = <
++ 0x190 0x20 /* mcasp0_aclkx.mcasp0_aclkx, INPUT | MODE0 */
++ 0x194 0x20 /* mcasp0_fsx.mcasp0_fsx, INPUT | MODE0 */
++ 0x19c 0x22 /* mcasp0_ahclkr.mcasp0_axr2, INPUT | MODE2 */
++ 0x1ac 0x22 /* mcasp0_ahclkx.mcasp0_axr3, INPUT | MODE2 */
++
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++
++ /* avoid stupid warning */
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ gpio-leds-cape-audio {
++ compatible = "gpio-leds";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bone_audio_cape_led_pins>;
++
++ audio-led0 {
++ label = "audio:green:usr0";
++ gpios = <&gpio2 18 0>;
++ linux,default-trigger = "heartbeat";
++ default-state = "off";
++ };
++
++ audio-led1 {
++ label = "audio:green:usr1";
++ gpios = <&gpio2 19 0>;
++ linux,default-trigger = "mmc0";
++ default-state = "off";
++ };
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&i2c2>;
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ tlv320aic3x: tlv320aic3x@1b {
++ compatible = "ti,tlv320aic3x";
++ reg = <0x1b>;
++ status = "okay";
++ };
++ };
++ };
++
++ fragment@3 {
++ target = <&mcasp0>;
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&bone_audio_cape_audio_pins>;
++
++ status = "okay";
++
++ op-mode = <0>; /* MCASP_IIS_MODE */
++ tdm-slots = <2>;
++ num-serializer = <16>;
++ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
++ 0 0 2 1
++ 0 0 0 0
++ 0 0 0 0
++ 0 0 0 0
++ >;
++ tx-num-evt = <1>;
++ rx-num-evt = <1>;
++ };
++ };
++
++ fragment@4 {
++ target = <&ocp>;
++ __overlay__ {
++ sound {
++ compatible = "ti,da830-evm-audio";
++ ti,model = "DA830 EVM";
++ ti,audio-codec = <&tlv320aic3x>;
++ ti,mcasp-controller = <&mcasp0>;
++ ti,codec-clock-rate = <12000000>;
++ ti,audio-routing =
++ "Headphone Jack", "HPLOUT",
++ "Headphone Jack", "HPROUT",
++ "LINE1L", "Line In",
++ "LINE1R", "Line In";
++ };
++ };
++
++ };
++};
diff --git a/patches/linux-3.8.13/0394-cape-bone-hexy-add-iio-helper.patch b/patches/linux-3.8.13/0394-cape-bone-hexy-add-iio-helper.patch
new file mode 100644
index 0000000..1f66241
--- /dev/null
+++ b/patches/linux-3.8.13/0394-cape-bone-hexy-add-iio-helper.patch
@@ -0,0 +1,48 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Fri, 5 Apr 2013 12:07:30 +0200
+Subject: [PATCH] cape-bone-hexy: add iio helper
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ firmware/capes/cape-bone-hexy-00A0.dts | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/firmware/capes/cape-bone-hexy-00A0.dts b/firmware/capes/cape-bone-hexy-00A0.dts
+index abc1255..0e90904 100644
+--- a/firmware/capes/cape-bone-hexy-00A0.dts
++++ b/firmware/capes/cape-bone-hexy-00A0.dts
+@@ -157,4 +157,34 @@
+ };
+ };
+ };
++
++ fragment@6 {
++ target = <&ocp>;
++ __overlay__ {
++ /* avoid stupid warning */
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ tscadc {
++ compatible = "ti,ti-tscadc";
++ reg = <0x44e0d000 0x1000>;
++
++ interrupt-parent = <&intc>;
++ interrupts = <16>;
++ ti,hwmods = "adc_tsc";
++ status = "okay";
++
++ adc {
++ ti,adc-channels = <0 1 2 3 4 5 6 7>;
++ };
++ };
++
++ test_helper: helper {
++ compatible = "bone-iio-helper";
++ vsense-name = "AIN0", "AIN1", "AIN2", "AIN3", "AIN4", "AIN5", "AIN6", "AIN7";
++ vsense-scale = <100 100 100 100 100 100 100 100>;
++ status = "okay";
++ };
++ };
++ };
+ };
diff --git a/patches/linux-3.8.13/0395-cape-Add-CAPE-BONE-EXPTEST-to-capemaps.patch b/patches/linux-3.8.13/0395-cape-Add-CAPE-BONE-EXPTEST-to-capemaps.patch
new file mode 100644
index 0000000..77e9d86
--- /dev/null
+++ b/patches/linux-3.8.13/0395-cape-Add-CAPE-BONE-EXPTEST-to-capemaps.patch
@@ -0,0 +1,27 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Fri, 5 Apr 2013 14:34:31 +0300
+Subject: [PATCH] cape: Add CAPE-BONE-EXPTEST to capemaps
+
+---
+ arch/arm/boot/dts/am335x-bone-common.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
+index 524bf03..1c91d7d 100644
+--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
+@@ -320,6 +320,14 @@
+ dtbo = "cape-bone-mrf24j40-00A0.dtbo";
+ };
+ };
++ /* expansion test */
++ cape@11 {
++ part-number = "BB-BONE-EXPTEST";
++ version@00A0 {
++ version = "00A0";
++ dtbo = "cape-bone-exptest-00A0.dtbo";
++ };
++ };
+ };
+ };
+
diff --git a/patches/linux-3.8.13/0396-tester-button-cape.patch b/patches/linux-3.8.13/0396-tester-button-cape.patch
new file mode 100644
index 0000000..1b381d9
--- /dev/null
+++ b/patches/linux-3.8.13/0396-tester-button-cape.patch
@@ -0,0 +1,31 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 8 Apr 2013 22:35:55 +0300
+Subject: [PATCH] tester: button cape
+
+Disable pull up on the pinmux.
+---
+ firmware/capes/BB-BONELT-BT-00A0.dts | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/firmware/capes/BB-BONELT-BT-00A0.dts b/firmware/capes/BB-BONELT-BT-00A0.dts
+index f32d6f5..94b9a12 100644
+--- a/firmware/capes/BB-BONELT-BT-00A0.dts
++++ b/firmware/capes/BB-BONELT-BT-00A0.dts
+@@ -21,7 +21,7 @@
+
+ bone_bt_cape_key_pins: pinmux_bone_bt_cape_key_pins {
+ pinctrl-single,pins = <
+- 0x0a8 0x27 /* P8.43 lcd_data2.gpio2[8] */
++ 0x0a8 0x2f /* P8.43 lcd_data2.gpio2[8] DISABLE internal pullup */
+ >;
+ };
+ };
+@@ -39,7 +39,7 @@
+ #size-cells = <0>;
+
+ button@1 {
+- debounce_interval = <1>;
++ debounce_interval = <0>;
+ linux,code = <28>;
+ label = "enter";
+ gpios = <&gpio3 8 0x0>;
diff --git a/patches/linux-3.8.13/0397-pwm_test-fix-some-issues.patch b/patches/linux-3.8.13/0397-pwm_test-fix-some-issues.patch
new file mode 100644
index 0000000..3ffb8ae
--- /dev/null
+++ b/patches/linux-3.8.13/0397-pwm_test-fix-some-issues.patch
@@ -0,0 +1,89 @@
+From: Jack Mitchell <jack@embed.me.uk>
+Date: Tue, 9 Apr 2013 16:47:31 +0200
+Subject: [PATCH] pwm_test: fix some issues
+
+---
+ drivers/pwm/pwm_test.c | 39 ++++++++++++++++++++++++++++++---------
+ 1 file changed, 30 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/pwm/pwm_test.c b/drivers/pwm/pwm_test.c
+index d9948db..3da1890 100644
+--- a/drivers/pwm/pwm_test.c
++++ b/drivers/pwm/pwm_test.c
+@@ -91,6 +91,11 @@ static ssize_t pwm_test_store_config(struct device *dev,
+ struct pwm_test *pwm_test = dev_get_drvdata(dev);
+ int ret;
+
++ if (pwm_test->pwm == NULL) {
++ pr_err("PWM Device has not been requested\n");
++ return -ENODEV;
++ }
++
+ if (pwm_test->duty_s == 0) {
+ ret = pwm_config(pwm_test->pwm, 0, pwm_test->period_s);
+ if (ret) {
+@@ -199,6 +204,12 @@ static ssize_t pwm_test_store_request(struct device *dev,
+ return rc;
+
+ if (pwm_test->requested_s) {
++
++ if (pwm_test->pwm) {
++ pr_info("PWM already requested!\n");
++ return count;
++ }
++
+ pwm_test->pwm = pwm_get(dev, NULL);
+
+ if (IS_ERR(pwm_test->pwm)) {
+@@ -206,9 +217,9 @@ static ssize_t pwm_test_store_request(struct device *dev,
+ PTR_ERR(pwm_test->pwm));
+ rc = -EINVAL;
+ }
+- } else {
+- pwm_free(pwm_test->pwm);
+- pwm_test->polarity = 0;
++ } else if (pwm_test->pwm != NULL) {
++
++ pwm_test->polarity = 0;
+ pwm_test->run = 0;
+ pwm_test->duty = 0;
+ pwm_test->period = 0;
+@@ -218,8 +229,18 @@ static ssize_t pwm_test_store_request(struct device *dev,
+ pwm_test->duty_s = 0;
+ pwm_test->period_s = 0;
+ pwm_test->config_s = 0;
++
++ pwm_config(pwm_test->pwm, pwm_test->duty_s,
++ pwm_test->period_s);
++
++ pwm_disable(pwm_test->pwm);
++
+ rc = 0;
+ }
++ else {
++ pr_info("PWM was already unrequested\n");
++ }
++
+
+ if (rc) {
+ pr_err("operation failed %d\n", rc);
+@@ -231,13 +252,13 @@ static ssize_t pwm_test_store_request(struct device *dev,
+ return count;
+ }
+
+-static DEVICE_ATTR(duty, 0644, pwm_test_show_duty, pwm_test_store_duty);
+-static DEVICE_ATTR(period, 0644, pwm_test_show_period, pwm_test_store_period);
+-static DEVICE_ATTR(polarity, 0644, pwm_test_show_polarity,
++static DEVICE_ATTR(duty, S_IRUSR | S_IWUSR, pwm_test_show_duty, pwm_test_store_duty);
++static DEVICE_ATTR(period, S_IRUSR | S_IWUSR, pwm_test_show_period, pwm_test_store_period);
++static DEVICE_ATTR(polarity, S_IRUSR | S_IWUSR, pwm_test_show_polarity,
+ pwm_test_store_polarity);
+-static DEVICE_ATTR(config, 0644 , pwm_test_show_config, pwm_test_store_config);
+-static DEVICE_ATTR(run, 0644 , pwm_test_show_run, pwm_test_store_run);
+-static DEVICE_ATTR(request, 0644 , pwm_test_show_request, pwm_test_store_request);
++static DEVICE_ATTR(config, S_IRUSR | S_IWUSR , pwm_test_show_config, pwm_test_store_config);
++static DEVICE_ATTR(run, S_IRUSR | S_IWUSR , pwm_test_show_run, pwm_test_store_run);
++static DEVICE_ATTR(request, S_IRUSR | S_IWUSR , pwm_test_show_request, pwm_test_store_request);
+
+ static const struct attribute *pwm_attrs[] = {
+ &dev_attr_duty.attr,
diff --git a/patches/linux-3.8.13/0398-pwm_test-Clean-up-and-make-it-work-on-DT-correctly.patch b/patches/linux-3.8.13/0398-pwm_test-Clean-up-and-make-it-work-on-DT-correctly.patch
new file mode 100644
index 0000000..336826c
--- /dev/null
+++ b/patches/linux-3.8.13/0398-pwm_test-Clean-up-and-make-it-work-on-DT-correctly.patch
@@ -0,0 +1,467 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Tue, 9 Apr 2013 22:14:29 +0300
+Subject: [PATCH] pwm_test: Clean-up and make it work on DT correctly
+
+Clean up and DTify the pwm_test driver into something that's reasonably
+useful.
+Based on work done by Elias & Jack Mitchel.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/pwm/pwm_test.c | 312 ++++++++++++++++++++++++------------------------
+ 1 file changed, 155 insertions(+), 157 deletions(-)
+
+diff --git a/drivers/pwm/pwm_test.c b/drivers/pwm/pwm_test.c
+index 3da1890..9c07880 100644
+--- a/drivers/pwm/pwm_test.c
++++ b/drivers/pwm/pwm_test.c
+@@ -26,21 +26,23 @@
+ #include <linux/err.h>
+ #include <linux/clk.h>
+ #include <linux/pm_runtime.h>
++#include <linux/pinctrl/consumer.h>
+
+ struct pwm_test {
+ struct pwm_device *pwm;
+- int ret;
+ struct class *pwm_test_class;
+- unsigned long period, duty, run, polarity, config, requested;
+- unsigned long period_s, duty_s, run_s, polarity_s, config_s, requested_s;
+- struct device *dev;
++ int period;
++ int duty;
++ enum pwm_polarity polarity;
++ int run;
+ };
+
+ static ssize_t pwm_test_show_duty(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+ struct pwm_test *pwm_test = dev_get_drvdata(dev);
+- return sprintf(buf, "%lu\n", pwm_test->duty);
++
++ return sprintf(buf, "%d\n", pwm_test->duty);
+ }
+
+ static ssize_t pwm_test_store_duty(struct device *dev,
+@@ -48,10 +50,23 @@ static ssize_t pwm_test_store_duty(struct device *dev,
+ {
+ int rc;
+ struct pwm_test *pwm_test = dev_get_drvdata(dev);
++ int duty;
+
+- rc = kstrtoul(buf, 0, &pwm_test->duty_s);
++ rc = kstrtoint(buf, 0, &duty);
+ if (rc)
+ return rc;
++
++ if (duty < 0)
++ return -EINVAL;
++
++ rc = pwm_config(pwm_test->pwm, duty, pwm_test->period);
++ if (rc) {
++ dev_err(dev, "pwm_config() failed\n");
++ return rc;
++ }
++
++ pwm_test->duty = duty;
++
+ return count;
+ }
+
+@@ -60,7 +75,7 @@ static ssize_t pwm_test_show_period(struct device *dev,
+ {
+ struct pwm_test *pwm_test = dev_get_drvdata(dev);
+
+- return sprintf(buf, "%lu\n", pwm_test->period);
++ return sprintf(buf, "%d\n", pwm_test->period);
+ }
+
+ static ssize_t pwm_test_store_period(struct device *dev,
+@@ -68,60 +83,27 @@ static ssize_t pwm_test_store_period(struct device *dev,
+ {
+ int rc;
+ struct pwm_test *pwm_test = dev_get_drvdata(dev);
++ int period;
+
+- rc = kstrtoul(buf, 0, &pwm_test->period_s);
++ rc = kstrtoint(buf, 0, &period);
+ if (rc)
+ return rc;
+
+- return count;
+-}
++ if (period < 0)
++ return -EINVAL;
+
+-static ssize_t pwm_test_show_config(struct device *dev,
+- struct device_attribute *attr, char *buf)
+-{
+- struct pwm_test *pwm_test = dev_get_drvdata(dev);
+- if (pwm_test->config)
+- return sprintf(buf, "config Done\n");
+- else
+- return sprintf(buf, "config Failed\n");
+-}
+-static ssize_t pwm_test_store_config(struct device *dev,
+- struct device_attribute *attr, const char *buf, size_t count)
+-{
+- struct pwm_test *pwm_test = dev_get_drvdata(dev);
+- int ret;
+-
+- if (pwm_test->pwm == NULL) {
+- pr_err("PWM Device has not been requested\n");
+- return -ENODEV;
+- }
+-
+- if (pwm_test->duty_s == 0) {
+- ret = pwm_config(pwm_test->pwm, 0, pwm_test->period_s);
+- if (ret) {
+- pwm_test->config = 0;
+- pr_err("operation failed %d\n", ret);
+- pwm_test->duty_s = pwm_test->duty;
+- pwm_test->period_s = pwm_test->period;
+- return ret;
+- }
+- pwm_test->duty = pwm_test->duty_s;
+- pwm_test->period = pwm_test->period_s;
+- pwm_test->config = 1;
+- } else {
+- ret = pwm_config(pwm_test->pwm, pwm_test->duty_s,
+- pwm_test->period_s);
+- if (ret) {
+- pwm_test->config = 0;
+- pr_err("operation failed %d\n", ret);
+- pwm_test->duty_s = pwm_test->duty;
+- pwm_test->period_s = pwm_test->period;
+- return ret;
+- }
+- pwm_test->duty = pwm_test->duty_s;
+- pwm_test->period = pwm_test->period_s;
+- pwm_test->config = 1;
++ /* same period? just return */
++ if (pwm_test->period == period)
++ return count;
++
++ rc = pwm_config(pwm_test->pwm, pwm_test->duty, period);
++ if (rc) {
++ dev_err(dev, "pwm_config() failed\n");
++ return rc;
+ }
++
++ pwm_test->period = period;
++
+ return count;
+ }
+
+@@ -129,7 +111,8 @@ static ssize_t pwm_test_show_run(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+ struct pwm_test *pwm_test = dev_get_drvdata(dev);
+- return sprintf(buf, "%s\n", pwm_test->run ? "Enabled" : "Disabled");
++
++ return sprintf(buf, "%d\n", pwm_test->run);
+ }
+
+ static ssize_t pwm_test_store_run(struct device *dev,
+@@ -137,23 +120,31 @@ static ssize_t pwm_test_store_run(struct device *dev,
+ {
+ int rc;
+ struct pwm_test *pwm_test = dev_get_drvdata(dev);
++ int run;
+
+- rc = kstrtoul(buf, 0, &pwm_test->run_s);
++ rc = kstrtoint(buf, 0, &run);
+ if (rc)
+ return rc;
+
+- if (pwm_test->run_s)
++ /* only 0 & 1 allowed */
++ if (run != 0 && run != 1)
++ return -EINVAL;
++
++ /* same state, don't bother */
++ if (run == pwm_test->run)
++ return count;
++
++ if (run) {
+ rc = pwm_enable(pwm_test->pwm);
+- else
++ if (rc != 0) {
++ dev_err(dev, "pwm_enable failed\n");
++ return rc;
++ }
++ } else
+ pwm_disable(pwm_test->pwm);
+
+- if (rc) {
+- pr_err("operation failed %d\n", rc);
+- pwm_test->run_s = pwm_test->run;
+- return rc;
+- }
++ pwm_test->run = run;
+
+- pwm_test->run = pwm_test->run_s;
+ return count;
+ }
+
+@@ -161,9 +152,8 @@ static ssize_t pwm_test_show_polarity(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+ struct pwm_test *pwm_test = dev_get_drvdata(dev);
+- return sprintf(buf, "%s\n",
+- pwm_test->polarity ? "Polarity Inversed" :
+- "Polarity Normal");
++
++ return sprintf(buf, "%u\n", pwm_test->polarity);
+ }
+
+ static ssize_t pwm_test_store_polarity(struct device *dev,
+@@ -171,84 +161,40 @@ static ssize_t pwm_test_store_polarity(struct device *dev,
+ {
+ int rc;
+ struct pwm_test *pwm_test = dev_get_drvdata(dev);
++ int val;
++ enum pwm_polarity polarity;
+
+- rc = kstrtoul(buf, 0, &pwm_test->polarity_s);
++ rc = kstrtoint(buf, 0, &val);
+ if (rc)
+ return rc;
+
+- rc = pwm_set_polarity(pwm_test->pwm, pwm_test->polarity_s);
+- if (rc) {
+- pr_err("operation failed %d\n", rc);
+- return rc;
+- }
++ /* only zero and one allowed */
++ if (val != 0 && val != 1)
++ return -EINVAL;
+
+- pwm_test->polarity = pwm_test->polarity_s;
+- return count;
+-}
++ polarity = val ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL;
+
+-static ssize_t pwm_test_show_request(struct device *dev,
+- struct device_attribute *attr, char *buf)
+-{
+- struct pwm_test *pwm_test = dev_get_drvdata(dev);
+- return sprintf(buf, "%s\n", pwm_test->requested ? "Requested" : "Freed");
+-}
++ /* same? don't do anything */
++ if (polarity == pwm_test->polarity)
++ return count;
+
+-static ssize_t pwm_test_store_request(struct device *dev,
+- struct device_attribute *attr, const char *buf, size_t count)
+-{
+- int rc;
+- struct pwm_test *pwm_test = dev_get_drvdata(dev);
++ /* polarity can only change when we stop the pwm */
++ if (pwm_test->run)
++ pwm_disable(pwm_test->pwm);
+
+- rc = kstrtoul(buf, 0, &pwm_test->requested_s);
+- if (rc)
++ rc = pwm_set_polarity(pwm_test->pwm, polarity);
++ if (rc) {
++ dev_err(dev, "pwm_set_polarity failed\n");
++ if (pwm_test->run)
++ pwm_enable(pwm_test->pwm);
+ return rc;
+-
+- if (pwm_test->requested_s) {
+-
+- if (pwm_test->pwm) {
+- pr_info("PWM already requested!\n");
+- return count;
+- }
+-
+- pwm_test->pwm = pwm_get(dev, NULL);
+-
+- if (IS_ERR(pwm_test->pwm)) {
+- dev_err(dev, "%s() %d %ld\n", __func__, __LINE__,
+- PTR_ERR(pwm_test->pwm));
+- rc = -EINVAL;
+- }
+- } else if (pwm_test->pwm != NULL) {
+-
+- pwm_test->polarity = 0;
+- pwm_test->run = 0;
+- pwm_test->duty = 0;
+- pwm_test->period = 0;
+- pwm_test->config = 0;
+- pwm_test->polarity_s = 0;
+- pwm_test->run_s = 0;
+- pwm_test->duty_s = 0;
+- pwm_test->period_s = 0;
+- pwm_test->config_s = 0;
+-
+- pwm_config(pwm_test->pwm, pwm_test->duty_s,
+- pwm_test->period_s);
+-
+- pwm_disable(pwm_test->pwm);
+-
+- rc = 0;
+ }
+- else {
+- pr_info("PWM was already unrequested\n");
+- }
+
++ if (pwm_test->run)
++ pwm_enable(pwm_test->pwm);
+
+- if (rc) {
+- pr_err("operation failed %d\n", rc);
+- pwm_test->requested_s = pwm_test->requested;
+- return rc;
+- }
++ pwm_test->polarity = polarity;
+
+- pwm_test->requested = pwm_test->requested_s;
+ return count;
+ }
+
+@@ -256,16 +202,12 @@ static DEVICE_ATTR(duty, S_IRUSR | S_IWUSR, pwm_test_show_duty, pwm_test_store_d
+ static DEVICE_ATTR(period, S_IRUSR | S_IWUSR, pwm_test_show_period, pwm_test_store_period);
+ static DEVICE_ATTR(polarity, S_IRUSR | S_IWUSR, pwm_test_show_polarity,
+ pwm_test_store_polarity);
+-static DEVICE_ATTR(config, S_IRUSR | S_IWUSR , pwm_test_show_config, pwm_test_store_config);
+ static DEVICE_ATTR(run, S_IRUSR | S_IWUSR , pwm_test_show_run, pwm_test_store_run);
+-static DEVICE_ATTR(request, S_IRUSR | S_IWUSR , pwm_test_show_request, pwm_test_store_request);
+
+ static const struct attribute *pwm_attrs[] = {
+ &dev_attr_duty.attr,
+ &dev_attr_period.attr,
+- &dev_attr_config.attr,
+ &dev_attr_run.attr,
+- &dev_attr_request.attr,
+ &dev_attr_polarity.attr,
+ NULL,
+ };
+@@ -274,30 +216,89 @@ static const struct attribute_group pwm_device_attr_group = {
+ .attrs = (struct attribute **) pwm_attrs,
+ };
+
+-static int __init pwm_test_class_init(struct device *dev)
+-{
+- if (sysfs_create_group(&dev->kobj, &pwm_device_attr_group))
+- return 1;
+- return 0;
+-}
+-
+ static int pwm_test_probe(struct platform_device *pdev)
+ {
++ struct device *dev = &pdev->dev;
++ struct device_node *node = dev->of_node;
+ struct pwm_test *pwm_test;
++ struct of_phandle_args args;
++ struct pinctrl *pinctrl;
++ u32 val;
++ int rc;
+
+- pwm_test = devm_kzalloc(&pdev->dev, sizeof(*pwm_test), GFP_KERNEL);
++ if (node == NULL) {
++ dev_err(dev, "Non DT platforms not supported\n");
++ return -EINVAL;
++ }
++
++ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
++ if (IS_ERR(pinctrl))
++ dev_warn(&pdev->dev, "Unable to select pin group\n");
+
++ pwm_test = devm_kzalloc(&pdev->dev, sizeof(*pwm_test), GFP_KERNEL);
+ if (!pwm_test) {
+ dev_err(&pdev->dev, "memory error\n");
+ return -ENOMEM;
+ }
++ platform_set_drvdata(pdev, pwm_test);
+
+- if (pwm_test_class_init(&pdev->dev)) {
+- dev_err(&pdev->dev, "sysfs creation failed\n");
+- return -EINVAL;
++ /* now do the probe time config */
++ pwm_test->pwm = devm_pwm_get(&pdev->dev, NULL);
++ if (IS_ERR(pwm_test->pwm)) {
++ dev_err(dev, "unable to request PWM\n");
++ return PTR_ERR(pwm_test->pwm);
+ }
+- dev_set_drvdata(&pdev->dev, pwm_test);
+- platform_set_drvdata(pdev, pwm_test);
++
++ rc = of_parse_phandle_with_args(node, "pwms", "#pwm-cells", 0, &args);
++ if (rc != 0) {
++ dev_err(dev, "of_parse_phandle_with_args() failed\n");
++ return rc;
++ }
++
++ /* read the period */
++ pwm_test->period = args.args[1];
++
++ /* should be at least 2, but 3 is possible to store polarity */
++ pwm_test->polarity = PWM_POLARITY_NORMAL;
++ /* PWM_SPEC_POLARITY is (1 << 0) */
++ if (args.args_count >= 3 && (args.args[2] & (1 << 0)) != 0)
++ pwm_test->polarity = PWM_POLARITY_INVERSED;
++
++ /* Determine the duty from the device tree */
++ rc = of_property_read_u32(node, "duty", &val);
++ if (rc != 0)
++ val = 0; /* default is 0 */
++ pwm_test->duty = val;
++
++ /* polarity is already set */
++ rc = pwm_config(pwm_test->pwm, pwm_test->duty, pwm_test->period);
++ if (rc) {
++ dev_err(dev, "pwm_config() failed\n");
++ return rc;
++ }
++
++ /* Determine running or not from the device tree */
++ rc = of_property_read_u32(node, "enabled", &val);
++ if (rc < 0)
++ val = 0; /* default is disabled */
++
++ /* single bit */
++ pwm_test->run = !!val;
++
++ if (pwm_test->run) {
++ rc = pwm_enable(pwm_test->pwm);
++ if (rc < 0) {
++ dev_err(dev, "pwm_enable failed\n");
++ return rc;
++ }
++ }
++
++ rc = sysfs_create_group(&dev->kobj, &pwm_device_attr_group);
++ if (rc != 0) {
++ dev_err(dev, "Unable to create sysfs entries\n");
++ return rc;
++ }
++
+ return 0;
+ }
+
+@@ -305,17 +306,14 @@ static int pwm_test_remove(struct platform_device *pdev)
+ {
+ struct pwm_test *pwm_test = platform_get_drvdata(pdev);
+
+- if (!pwm_test->ret) {
++ sysfs_remove_group(&pdev->dev.kobj, &pwm_device_attr_group);
++
++ if (pwm_test->run) {
+ pwm_config(pwm_test->pwm, 0, 0x1000);
+ pwm_disable(pwm_test->pwm);
+- pr_emerg("PWM Device Disabled %s\n", dev_name(&pdev->dev));
+ }
+- if (pwm_test->requested)
+- pwm_free(pwm_test->pwm);
+
+- pr_emerg("PWM Device Freed %s\n", dev_name(&pdev->dev));
+- pwm_test->run = 0;
+- sysfs_remove_group(&pdev->dev.kobj, &pwm_device_attr_group);
++ devm_pwm_put(&pdev->dev, pwm_test->pwm);
+ return 0;
+ }
+
diff --git a/patches/linux-3.8.13/0399-capes-Add-PWM-test-example-cape.patch b/patches/linux-3.8.13/0399-capes-Add-PWM-test-example-cape.patch
new file mode 100644
index 0000000..e23dbae
--- /dev/null
+++ b/patches/linux-3.8.13/0399-capes-Add-PWM-test-example-cape.patch
@@ -0,0 +1,89 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Tue, 9 Apr 2013 22:52:14 +0300
+Subject: [PATCH] capes: Add PWM test example cape
+
+A simple example of a PWM test based cape.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ firmware/Makefile | 3 +-
+ firmware/capes/BB-BONE-PWMT-00A0.dts | 56 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 58 insertions(+), 1 deletion(-)
+ create mode 100644 firmware/capes/BB-BONE-PWMT-00A0.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index d4403b5..098b4b4 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -155,7 +155,8 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ cape-bone-pinmux-test-00A0.dtbo \
+ cape-bone-exptest-00A0.dtbo \
+ cape-bone-mrf24j40-00A0.dtbo \
+- BB-BONELT-BT-00A0.dtbo
++ BB-BONELT-BT-00A0.dtbo \
++ BB-BONE-PWMT-00A0.dtbo
+
+ # the geiger cape
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE_GEIGER) += \
+diff --git a/firmware/capes/BB-BONE-PWMT-00A0.dts b/firmware/capes/BB-BONE-PWMT-00A0.dts
+new file mode 100644
+index 0000000..fb2b8b1
+--- /dev/null
++++ b/firmware/capes/BB-BONE-PWMT-00A0.dts
+@@ -0,0 +1,56 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "BB-BONE-PWMT";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pwm_test_pins: pinmux_pwm_test_pins {
++ pinctrl-single,pins = <0x150 0x3>; /* spi0_sclk = ehrpwm0A = P9_14 = Heater_HBP | MODE 3 */
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&epwmss0>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@2 {
++ target = <&ehrpwm0>;
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_test_pins>;
++ status = "okay";
++ };
++ };
++
++ fragment@3 {
++ target = <&ocp>;
++ __overlay__ {
++ pwm_test {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm0 0 500000 1>;
++ pwm-names = "PWM0";
++ enabled = <1>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0400-Sync-tester-DTS-with-am335x-common.patch b/patches/linux-3.8.13/0400-Sync-tester-DTS-with-am335x-common.patch
new file mode 100644
index 0000000..5aad332
--- /dev/null
+++ b/patches/linux-3.8.13/0400-Sync-tester-DTS-with-am335x-common.patch
@@ -0,0 +1,134 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 11 Apr 2013 19:37:08 +0300
+Subject: [PATCH] Sync tester DTS with am335x-common
+
+---
+ arch/arm/boot/dts/am335x-tester.dts | 87 ++++++++++++++++++++++++++++++++---
+ 1 file changed, 80 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/boot/dts/am335x-tester.dts b/arch/arm/boot/dts/am335x-tester.dts
+index 1fdba03..5059988 100644
+--- a/arch/arm/boot/dts/am335x-tester.dts
++++ b/arch/arm/boot/dts/am335x-tester.dts
+@@ -177,15 +177,43 @@
+ part-number = "BB-BONE-NIXIE";
+ };
+
+- /* geiger cape version A0 without an EEPROM */
++ /* adafruit 1.8" TFT prototype cape */
+ slot@8 {
+ ti,cape-override;
+ compatible = "kernel-command-line", "runtime";
+- board-name = "Bone-Tester";
++ board-name = "Bone-TFT";
++ version = "00A0";
++ manufacturer = "Adafruit";
++ part-number = "BB-BONE-TFT-01";
++ };
++
++ /* adafruit RTC DS1307 prototype cape */
++ slot@9 {
++ ti,cape-override;
++ compatible = "kernel-command-line", "runtime";
++ board-name = "Bone-RTC";
+ version = "00A0";
+- part-number = "BB-BONE-TESTER";
++ manufacturer = "Adafruit";
++ part-number = "BB-BONE-RTC-01";
+ };
+
++ slot@10 {
++ ti,cape-override;
++ compatible = "kernel-command-line", "runtime";
++ board-name = "Bone-Hexy";
++ version = "00A0";
++ manufacturer = "Koen Kooi";
++ part-number = "BB-BONE-HEXY-01";
++ };
++ /* MRF24J40 Cape Override */
++ slot@11 {
++ ti,cape-override;
++ compatible = "kernel-command-line", "runtime";
++ board-name = "Bone-MRF24J40";
++ version = "00A0";
++ manufacturer = "Signal 11 Software";
++ part-number = "BB-BONE-MRF24J40";
++ };
+ };
+
+ /* mapping between board names and dtb objects */
+@@ -202,6 +230,14 @@
+ version = "00A1", "01";
+ dtbo = "cape-bone-dvi-00A1.dtbo";
+ };
++ version@00A2 {
++ version = "00A2", "A2";
++ dtbo = "cape-bone-dvi-00A2.dtbo";
++ };
++ version@00A3 {
++ version = "00A3";
++ dtbo = "cape-bone-dvi-00A2.dtbo";
++ };
+ };
+
+ /* beaglebone black emmc on board */
+@@ -262,18 +298,55 @@
+ dtbo = "cape-bone-nixie-00A0.dtbo";
+ };
+ };
+-
+- /* tester */
+ cape@7 {
+- part-number = "BB-BONE-TESTER";
++ part-number = "BB-BONE-TFT-01";
++ version@00A0 {
++ version = "00A0";
++ dtbo = "cape-bone-adafruit-lcd-00A0.dtbo";
++ };
++ };
++
++ cape@8 {
++ part-number = "BB-BONE-RTC-01";
+ version@00A0 {
+ version = "00A0";
+- dtbo = "cape-bone-tester-00A0.dtbo";
++ dtbo = "cape-bone-adafruit-rtc-00A0.dtbo";
+ };
+ };
+
++ cape@9 {
++ part-number = "BB-BONE-HEXY-01";
++ version@00A0 {
++ version = "00A0";
++ dtbo = "cape-bone-hexy-00A0.dtbo";
++ };
++ };
++ /* mrf24j40 cape */
++ cape@10 {
++ part-number = "BB-BONE-MRF24J40";
++ version@00A0 {
++ version = "00A0";
++ dtbo = "cape-bone-mrf24j40-00A0.dtbo";
++ };
++ };
++ /* expansion test */
++ cape@11 {
++ part-number = "BB-BONE-EXPTEST";
++ version@00A0 {
++ version = "00A0";
++ dtbo = "cape-bone-exptest-00A0.dtbo";
++ };
++ };
+ };
+ };
++
++ vmmcsd_fixed: fixedregulator@0 {
++ compatible = "regulator-fixed";
++ regulator-name = "vmmcsd_fixed";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ };
++
+ };
+
+ &i2c0 {
diff --git a/patches/linux-3.8.13/0401-Add-in-missing-cape-bone-tester-back-in.patch b/patches/linux-3.8.13/0401-Add-in-missing-cape-bone-tester-back-in.patch
new file mode 100644
index 0000000..10a33dc
--- /dev/null
+++ b/patches/linux-3.8.13/0401-Add-in-missing-cape-bone-tester-back-in.patch
@@ -0,0 +1,28 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 11 Apr 2013 21:19:13 +0300
+Subject: [PATCH] Add in missing cape-bone-tester back in.
+
+---
+ arch/arm/boot/dts/am335x-tester.dts | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/arch/arm/boot/dts/am335x-tester.dts b/arch/arm/boot/dts/am335x-tester.dts
+index 5059988..4a5ae294 100644
+--- a/arch/arm/boot/dts/am335x-tester.dts
++++ b/arch/arm/boot/dts/am335x-tester.dts
+@@ -240,6 +240,15 @@
+ };
+ };
+
++ /* tester */
++ cape@100 {
++ part-number = "BB-BONE-TESTER";
++ version@00A0 {
++ version = "00A0";
++ dtbo = "cape-bone-tester-00A0.dtbo";
++ };
++ };
++
+ /* beaglebone black emmc on board */
+ cape@1 {
+ /* board-name = "BeagleBone 2G eMMC1 CAPE"; */
diff --git a/patches/linux-3.8.13/0402-cape-bone-hexy-move-OLED-to-different-reset-gpio.patch b/patches/linux-3.8.13/0402-cape-bone-hexy-move-OLED-to-different-reset-gpio.patch
new file mode 100644
index 0000000..d8a21c1
--- /dev/null
+++ b/patches/linux-3.8.13/0402-cape-bone-hexy-move-OLED-to-different-reset-gpio.patch
@@ -0,0 +1,22 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Fri, 12 Apr 2013 14:22:04 +0200
+Subject: [PATCH] cape-bone-hexy: move OLED to different reset gpio
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ firmware/capes/cape-bone-hexy-00A0.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/firmware/capes/cape-bone-hexy-00A0.dts b/firmware/capes/cape-bone-hexy-00A0.dts
+index 0e90904..f02abd7 100644
+--- a/firmware/capes/cape-bone-hexy-00A0.dts
++++ b/firmware/capes/cape-bone-hexy-00A0.dts
+@@ -150,7 +150,7 @@
+ ssd1306: oled@3c {
+ compatible = "solomon,ssd1306fb-i2c";
+ reg = <0x3c>;
+- reset-gpios = <&gpio4 19 0>;
++ reset-gpios = <&gpio2 17 0>;
+ solomon,height = <32>;
+ solomon,width = <128>;
+ solomon,page-offset = <0>;
diff --git a/patches/linux-3.8.13/0403-firmware-capes-added-dts-file-for-every-PWM-pin.patch b/patches/linux-3.8.13/0403-firmware-capes-added-dts-file-for-every-PWM-pin.patch
new file mode 100644
index 0000000..0ebeb04
--- /dev/null
+++ b/patches/linux-3.8.13/0403-firmware-capes-added-dts-file-for-every-PWM-pin.patch
@@ -0,0 +1,830 @@
+From: Jason Kridner <jdk@ti.com>
+Date: Fri, 12 Apr 2013 13:38:27 +0000
+Subject: [PATCH] firmware/capes: added dts file for every PWM pin
+
+---
+ firmware/Makefile | 15 +++++++
+ firmware/capes/am33xx_pwm-00A0.dts | 74 ++++++++++++++++++++++++++++++++
+ firmware/capes/bone_pwm_P8_13-00A0.dts | 43 +++++++++++++++++++
+ firmware/capes/bone_pwm_P8_19-00A0.dts | 43 +++++++++++++++++++
+ firmware/capes/bone_pwm_P8_34-00A0.dts | 43 +++++++++++++++++++
+ firmware/capes/bone_pwm_P8_36-00A0.dts | 43 +++++++++++++++++++
+ firmware/capes/bone_pwm_P8_45-00A0.dts | 43 +++++++++++++++++++
+ firmware/capes/bone_pwm_P8_46-00A0.dts | 43 +++++++++++++++++++
+ firmware/capes/bone_pwm_P9_14-00A0.dts | 43 +++++++++++++++++++
+ firmware/capes/bone_pwm_P9_16-00A0.dts | 43 +++++++++++++++++++
+ firmware/capes/bone_pwm_P9_21-00A0.dts | 43 +++++++++++++++++++
+ firmware/capes/bone_pwm_P9_22-00A0.dts | 43 +++++++++++++++++++
+ firmware/capes/bone_pwm_P9_28-00A0.dts | 43 +++++++++++++++++++
+ firmware/capes/bone_pwm_P9_29-00A0.dts | 43 +++++++++++++++++++
+ firmware/capes/bone_pwm_P9_31-00A0.dts | 43 +++++++++++++++++++
+ firmware/capes/bone_pwm_P9_42-00A0.dts | 43 +++++++++++++++++++
+ 16 files changed, 691 insertions(+)
+ create mode 100644 firmware/capes/am33xx_pwm-00A0.dts
+ create mode 100644 firmware/capes/bone_pwm_P8_13-00A0.dts
+ create mode 100644 firmware/capes/bone_pwm_P8_19-00A0.dts
+ create mode 100644 firmware/capes/bone_pwm_P8_34-00A0.dts
+ create mode 100644 firmware/capes/bone_pwm_P8_36-00A0.dts
+ create mode 100644 firmware/capes/bone_pwm_P8_45-00A0.dts
+ create mode 100644 firmware/capes/bone_pwm_P8_46-00A0.dts
+ create mode 100644 firmware/capes/bone_pwm_P9_14-00A0.dts
+ create mode 100644 firmware/capes/bone_pwm_P9_16-00A0.dts
+ create mode 100644 firmware/capes/bone_pwm_P9_21-00A0.dts
+ create mode 100644 firmware/capes/bone_pwm_P9_22-00A0.dts
+ create mode 100644 firmware/capes/bone_pwm_P9_28-00A0.dts
+ create mode 100644 firmware/capes/bone_pwm_P9_29-00A0.dts
+ create mode 100644 firmware/capes/bone_pwm_P9_31-00A0.dts
+ create mode 100644 firmware/capes/bone_pwm_P9_42-00A0.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index 098b4b4..88a4e82 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -156,6 +156,21 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ cape-bone-exptest-00A0.dtbo \
+ cape-bone-mrf24j40-00A0.dtbo \
+ BB-BONELT-BT-00A0.dtbo \
++ am33xx_pwm-00A0.dtbo \
++ bone_pwm_P8_13-00A0.dtbo \
++ bone_pwm_P8_19-00A0.dtbo \
++ bone_pwm_P8_34-00A0.dtbo \
++ bone_pwm_P8_36-00A0.dtbo \
++ bone_pwm_P8_45-00A0.dtbo \
++ bone_pwm_P8_46-00A0.dtbo \
++ bone_pwm_P9_14-00A0.dtbo \
++ bone_pwm_P9_16-00A0.dtbo \
++ bone_pwm_P9_21-00A0.dtbo \
++ bone_pwm_P9_22-00A0.dtbo \
++ bone_pwm_P9_28-00A0.dtbo \
++ bone_pwm_P9_29-00A0.dtbo \
++ bone_pwm_P9_31-00A0.dtbo \
++ bone_pwm_P9_42-00A0.dtbo \
+ BB-BONE-PWMT-00A0.dtbo
+
+ # the geiger cape
+diff --git a/firmware/capes/am33xx_pwm-00A0.dts b/firmware/capes/am33xx_pwm-00A0.dts
+new file mode 100644
+index 0000000..609c1db
+--- /dev/null
++++ b/firmware/capes/am33xx_pwm-00A0.dts
+@@ -0,0 +1,74 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "test1";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&epwmss0>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@1 {
++ target = <&ehrpwm0>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@2 {
++ target = <&ecap0>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@3 {
++ target = <&epwmss1>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@4 {
++ target = <&ehrpwm1>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@5 {
++ target = <&epwmss2>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@6 {
++ target = <&ehrpwm2>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@7 {
++ target = <&ecap2>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++};
+diff --git a/firmware/capes/bone_pwm_P8_13-00A0.dts b/firmware/capes/bone_pwm_P8_13-00A0.dts
+new file mode 100644
+index 0000000..6c2168a
+--- /dev/null
++++ b/firmware/capes/bone_pwm_P8_13-00A0.dts
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "bone_pwm_P8_13";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pwm_P8_13: pinmux_pwm_P8_13_pins {
++ pinctrl-single,pins = <0x024 0x4>; /* P8_13 (ZCZ ball T10) | MODE 4 */
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ pwm_test_P8_13 {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm2 1 500000 1>;
++ pwm-names = "PWM_P8_13";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P8_13>;
++ enabled = <1>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/bone_pwm_P8_19-00A0.dts b/firmware/capes/bone_pwm_P8_19-00A0.dts
+new file mode 100644
+index 0000000..f5f7454
+--- /dev/null
++++ b/firmware/capes/bone_pwm_P8_19-00A0.dts
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "bone_pwm_P8_19";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pwm_P8_19: pinmux_pwm_P8_19_pins {
++ pinctrl-single,pins = <0x020 0x4>; /* P8_19 (ZCZ ball U10) | MODE 4 */
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ pwm_test_P8_19 {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm2 0 500000 1>;
++ pwm-names = "PWM_P8_19";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P8_19>;
++ enabled = <1>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/bone_pwm_P8_34-00A0.dts b/firmware/capes/bone_pwm_P8_34-00A0.dts
+new file mode 100644
+index 0000000..be227bf
+--- /dev/null
++++ b/firmware/capes/bone_pwm_P8_34-00A0.dts
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "bone_pwm_P8_34";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pwm_P8_34: pinmux_pwm_P8_34_pins {
++ pinctrl-single,pins = <0x0cc 0x2>; /* P8_34 (ZCZ ball U4) | MODE 2 */
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ pwm_test_P8_34 {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm1 1 500000 1>;
++ pwm-names = "PWM_P8_34";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P8_34>;
++ enabled = <1>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/bone_pwm_P8_36-00A0.dts b/firmware/capes/bone_pwm_P8_36-00A0.dts
+new file mode 100644
+index 0000000..7ca8694c
+--- /dev/null
++++ b/firmware/capes/bone_pwm_P8_36-00A0.dts
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "bone_pwm_P8_36";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pwm_P8_36: pinmux_pwm_P8_36_pins {
++ pinctrl-single,pins = <0x0c8 0x2>; /* P8_36 (ZCZ ball U3) | MODE 2 */
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ pwm_test_P8_36 {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm1 0 500000 1>;
++ pwm-names = "PWM_P8_36";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P8_36>;
++ enabled = <1>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/bone_pwm_P8_45-00A0.dts b/firmware/capes/bone_pwm_P8_45-00A0.dts
+new file mode 100644
+index 0000000..3bc8103
+--- /dev/null
++++ b/firmware/capes/bone_pwm_P8_45-00A0.dts
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "bone_pwm_P8_45";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pwm_P8_45: pinmux_pwm_P8_45_pins {
++ pinctrl-single,pins = <0x0a0 0x3>; /* P8_45 (ZCZ ball R1) | MODE 3 */
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ pwm_test_P8_45 {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm2 0 500000 1>;
++ pwm-names = "PWM_P8_45";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P8_45>;
++ enabled = <1>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/bone_pwm_P8_46-00A0.dts b/firmware/capes/bone_pwm_P8_46-00A0.dts
+new file mode 100644
+index 0000000..4cc6170
+--- /dev/null
++++ b/firmware/capes/bone_pwm_P8_46-00A0.dts
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "bone_pwm_P8_46";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pwm_P8_46: pinmux_pwm_P8_46_pins {
++ pinctrl-single,pins = <0x0a4 0x3>; /* P8_46 (ZCZ ball R2) | MODE 3 */
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ pwm_test_P8_46 {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm2 1 500000 1>;
++ pwm-names = "PWM_P8_46";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P8_46>;
++ enabled = <1>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/bone_pwm_P9_14-00A0.dts b/firmware/capes/bone_pwm_P9_14-00A0.dts
+new file mode 100644
+index 0000000..6a6c01a
+--- /dev/null
++++ b/firmware/capes/bone_pwm_P9_14-00A0.dts
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "bone_pwm_P9_14";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pwm_P9_14: pinmux_pwm_P9_14_pins {
++ pinctrl-single,pins = <0x048 0x6>; /* P9_14 (ZCZ ball U14) | MODE 6 */
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ pwm_test_P9_14 {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm1 0 500000 1>;
++ pwm-names = "PWM_P9_14";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P9_14>;
++ enabled = <1>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/bone_pwm_P9_16-00A0.dts b/firmware/capes/bone_pwm_P9_16-00A0.dts
+new file mode 100644
+index 0000000..a1ee9d8
+--- /dev/null
++++ b/firmware/capes/bone_pwm_P9_16-00A0.dts
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "bone_pwm_P9_16";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pwm_P9_16: pinmux_pwm_P9_16_pins {
++ pinctrl-single,pins = <0x04c 0x6>; /* P9_16 (ZCZ ball T14) | MODE 6 */
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ pwm_test_P9_16 {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm1 1 500000 1>;
++ pwm-names = "PWM_P9_16";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P9_16>;
++ enabled = <1>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/bone_pwm_P9_21-00A0.dts b/firmware/capes/bone_pwm_P9_21-00A0.dts
+new file mode 100644
+index 0000000..e667f81
+--- /dev/null
++++ b/firmware/capes/bone_pwm_P9_21-00A0.dts
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "bone_pwm_P9_21";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pwm_P9_21: pinmux_pwm_P9_21_pins {
++ pinctrl-single,pins = <0x154 0x3>; /* P9_21 (ZCZ ball B17) | MODE 3 */
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ pwm_test_P9_21 {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm0 1 500000 1>;
++ pwm-names = "PWM_P9_21";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P9_21>;
++ enabled = <1>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/bone_pwm_P9_22-00A0.dts b/firmware/capes/bone_pwm_P9_22-00A0.dts
+new file mode 100644
+index 0000000..f7c5ed2
+--- /dev/null
++++ b/firmware/capes/bone_pwm_P9_22-00A0.dts
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "bone_pwm_P9_22";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pwm_P9_22: pinmux_pwm_P9_22_pins {
++ pinctrl-single,pins = <0x150 0x3>; /* P9_22 (ZCZ ball A17) | MODE 3 */
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ pwm_test_P9_22 {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm0 0 500000 1>;
++ pwm-names = "PWM_P9_22";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P9_22>;
++ enabled = <1>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/bone_pwm_P9_28-00A0.dts b/firmware/capes/bone_pwm_P9_28-00A0.dts
+new file mode 100644
+index 0000000..96df33d
+--- /dev/null
++++ b/firmware/capes/bone_pwm_P9_28-00A0.dts
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "bone_pwm_P9_28";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pwm_P9_28: pinmux_pwm_P9_28_pins {
++ pinctrl-single,pins = <0x19c 0x4>; /* P9_28 (ZCZ ball C12) | MODE 4 */
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ pwm_test_P9_28 {
++ compatible = "pwm_test";
++ pwms = <&ecap2 0 500000 1>;
++ pwm-names = "PWM_P9_28";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P9_28>;
++ enabled = <1>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/bone_pwm_P9_29-00A0.dts b/firmware/capes/bone_pwm_P9_29-00A0.dts
+new file mode 100644
+index 0000000..5cff5a8
+--- /dev/null
++++ b/firmware/capes/bone_pwm_P9_29-00A0.dts
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "bone_pwm_P9_29";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pwm_P9_29: pinmux_pwm_P9_29_pins {
++ pinctrl-single,pins = <0x194 0x1>; /* P9_29 (ZCZ ball B13) | MODE 1 */
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ pwm_test_P9_29 {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm0 1 500000 1>;
++ pwm-names = "PWM_P9_29";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P9_29>;
++ enabled = <1>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/bone_pwm_P9_31-00A0.dts b/firmware/capes/bone_pwm_P9_31-00A0.dts
+new file mode 100644
+index 0000000..8126597
+--- /dev/null
++++ b/firmware/capes/bone_pwm_P9_31-00A0.dts
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "bone_pwm_P9_31";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pwm_P9_31: pinmux_pwm_P9_31_pins {
++ pinctrl-single,pins = <0x190 0x1>; /* P9_31 (ZCZ ball A13) | MODE 1 */
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ pwm_test_P9_31 {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm0 0 500000 1>;
++ pwm-names = "PWM_P9_31";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P9_31>;
++ enabled = <1>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/bone_pwm_P9_42-00A0.dts b/firmware/capes/bone_pwm_P9_42-00A0.dts
+new file mode 100644
+index 0000000..7ffcb9b
+--- /dev/null
++++ b/firmware/capes/bone_pwm_P9_42-00A0.dts
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ * Copyright (C) 2013 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "bone_pwm_P9_42";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pwm_P9_42: pinmux_pwm_P9_42_pins {
++ pinctrl-single,pins = <0x164 0x0>; /* P9_42 (ZCZ ball C18) | MODE 0 */
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ pwm_test_P9_42 {
++ compatible = "pwm_test";
++ pwms = <&ecap0 0 500000 1>;
++ pwm-names = "PWM_P9_42";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P9_42>;
++ enabled = <1>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0404-capes-add-LCD7-A3.patch b/patches/linux-3.8.13/0404-capes-add-LCD7-A3.patch
new file mode 100644
index 0000000..8e47e8c
--- /dev/null
+++ b/patches/linux-3.8.13/0404-capes-add-LCD7-A3.patch
@@ -0,0 +1,271 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Tue, 23 Apr 2013 15:12:00 +0200
+Subject: [PATCH] capes: add LCD7 A3
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ firmware/Makefile | 1 +
+ firmware/capes/BB-BONE-LCD7-01-00A3.dts | 242 +++++++++++++++++++++++++++++++
+ 2 files changed, 243 insertions(+)
+ create mode 100644 firmware/capes/BB-BONE-LCD7-01-00A3.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index 88a4e82..0ba37c6 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -149,6 +149,7 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ cape-bone-lcd3-00A2.dtbo \
+ BB-BONE-AUDI-01-00A0.dtbo \
+ BB-BONE-LCD7-01-00A2.dtbo \
++ BB-BONE-LCD7-01-00A3.dtbo \
+ BB-BONE-LCD7-01-00A4.dtbo \
+ BB-BONE-eMMC1-01-00A0.dtbo \
+ cape-bone-iio-00A0.dtbo \
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A3.dts b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+new file mode 100644
+index 0000000..805a6c0
+--- /dev/null
++++ b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+@@ -0,0 +1,242 @@
++/*
++ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-BONE-LCD7-01";
++ version = "00A3";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ bone_lcd7_cape_led_00A3_pins: pinmux_bone_lcd7_cape_led_00A3_pins {
++ pinctrl-single,pins = <
++ 0x078 0x2f /* gpmc_ben1.gpio1_28, INPUT | PULLDIS | MODE7 */
++ >;
++ };
++
++ pwm_bl_pins: pinmux_pwm_bl_pins {
++ pinctrl-single,pins = <
++ 0x48 0x06 /* gpmc_a2.ehrpwm1a, OMAP_MUX_MODE6 | AM33XX_PIN_OUTPUT */
++ >;
++ };
++
++ bone_lcd7_cape_lcd_pins: pinmux_bone_lcd7_cape_lcd_pins {
++ pinctrl-single,pins = <
++ //0x84 0x07 /* gpmc_csn2.gpio1_31, OUTPUT | MODE7 - AVDD_EN */
++ 0xa0 0x08 /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xa3 0x08 /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xa8 0x08 /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xac 0x08 /* lcd_data3.lcd_data3, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xb0 0x08 /* lcd_data3.lcd_data3, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xb4 0x08 /* lcd_data5.lcd_data5, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xb8 0x08 /* lcd_data6.lcd_data6, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xbc 0x08 /* lcd_data7.lcd_data7, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xc0 0x08 /* lcd_data8.lcd_data8, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xc4 0x08 /* lcd_data9.lcd_data9, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xc8 0x08 /* lcd_data10.lcd_data10, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xcc 0x08 /* lcd_data11.lcd_data11, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xd0 0x08 /* lcd_data12.lcd_data12, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xd4 0x08 /* lcd_data13.lcd_data13, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xd8 0x08 /* lcd_data14.lcd_data14, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xdc 0x08 /* lcd_data15.lcd_data15, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xe0 0x00 /* lcd_vsync.lcd_vsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0xe4 0x00 /* lcd_hsync.lcd_hsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0xe8 0x00 /* lcd_pclk.lcd_pclk, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ >;
++ };
++
++ bone_lcd7_cape_keys_00A3_pins: pinmux_bone_lcd7_cape_keys_00A3_pins {
++ pinctrl-single,pins = <
++ 0x040 0x2f /* KEY_LEFT gpmc_a0.gpio1_16, INPUT | PULLDIS | MODE7 */
++ 0x044 0x2f /* KEY_RIGHT gpmc_a1.gpio1_17, INPUT | PULLDIS | MODE7 */
++ 0x04c 0x2f /* KEY_UP gpmc_a3.gpio1_19, INPUT | PULLDIS | MODE7 */
++ 0x1a3 0x2f /* TSC_INTn mcasp0_fsr.gpio3_19, INPUT | PULLDIS | MODE7 */
++ // gpio3_16 KEY_DOWN
++ >;
++ };
++
++ };
++ };
++
++ fragment@1 {
++ target = <&epwmss1>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@2 {
++ target = <&ehrpwm1>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@3 {
++ target = <&ocp>;
++
++ __overlay__ {
++
++ /* avoid stupid warning */
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ backlight {
++ compatible = "pwm-backlight";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_bl_pins>;
++ status = "okay";
++
++ pwms = <&ehrpwm1 0 500000 0>;
++ pwm-names = "LCD7";
++ brightness-levels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100>;
++ default-brightness-level = <50>; /* index to the array above */
++ };
++
++ tscadc {
++ compatible = "ti,ti-tscadc";
++ reg = <0x44e0d000 0x1000>;
++
++ interrupt-parent = <&intc>;
++ interrupts = <16>;
++ ti,hwmods = "adc_tsc";
++ status = "okay";
++
++ tsc {
++ ti,wires = <4>;
++ ti,x-plate-resistance = <200>;
++ ti,coordinate-readouts = <5>;
++ ti,wire-config = <0x00 0x11 0x22 0x33>;
++ };
++
++ adc {
++ ti,adc-channels = <4>;
++ };
++ };
++
++ gpio-leds-cape-lcd7 {
++ compatible = "gpio-leds";
++ pinctrl-names = "default";
++
++ pinctrl-0 = <&bone_lcd7_cape_led_00A3_pins>;
++
++ lcd7-led0 {
++ label = "lcd7:green:usr0";
++ gpios = <&gpio2 28 0>;
++ linux,default-trigger = "heartbeat";
++ default-state = "off";
++ };
++
++ };
++
++ gpio_keys {
++ compatible = "gpio-keys";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bone_lcd7_cape_keys_00A3_pins>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ button@1 {
++ debounce_interval = <50>;
++ linux,code = <105>;
++ label = "left";
++ gpios = <&gpio2 16 0x0>;
++ gpio-key,wakeup;
++ autorepeat;
++ };
++ button@2 {
++ debounce_interval = <50>;
++ linux,code = <106>;
++ label = "right";
++ gpios = <&gpio2 17 0x0>;
++ gpio-key,wakeup;
++ autorepeat;
++ };
++ button@3 {
++ debounce_interval = <50>;
++ linux,code = <103>;
++ label = "up";
++ gpios = <&gpio2 19 0x0>;
++ gpio-key,wakeup;
++ autorepeat;
++ };
++ button@4 {
++ debounce_interval = <50>;
++ linux,code = <108>;
++ label = "down";
++ gpios = <&gpio4 16 0x0>;
++ gpio-key,wakeup;
++ autorepeat;
++ };
++ button@5 {
++ debounce_interval = <50>;
++ linux,code = <28>;
++ label = "enter";
++ gpios = <&gpio1 3 0x0>;
++ gpio-key,wakeup;
++ };
++ };
++
++ /* Settings for ThreeFive S9700RTWV35TR / LCD7 cape: */
++ panel {
++ compatible = "tilcdc,panel";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bone_lcd7_cape_lcd_pins>;
++ panel-info {
++ ac-bias = <255>;
++ ac-bias-intrpt = <0>;
++ dma-burst-sz = <16>;
++ bpp = <16>;
++ fdd = <0x80>;
++ tft-alt-mode = <0>;
++ stn-565-mode = <0>;
++ mono-8bit-mode = <0>;
++ sync-edge = <0>;
++ sync-ctrl = <1>;
++ raster-order = <0>;
++ fifo-th = <0>;
++ };
++ display-timings {
++ native-mode = <&timing0>;
++ timing0: 800x480 {
++ hactive = <800>;
++ vactive = <480>;
++ hback-porch = <39>;
++ hfront-porch = <39>;
++ hsync-len = <47>;
++ vback-porch = <29>;
++ vfront-porch = <13>;
++ vsync-len = <2>;
++ clock-frequency = <30000000>;
++ hsync-active = <0>;
++ vsync-active = <0>;
++ };
++ };
++ };
++
++ fb {
++ compatible = "ti,am33xx-tilcdc";
++ reg = <0x4830e000 0x1000>;
++ interrupt-parent = <&intc>;
++ interrupts = <36>;
++ ti,hwmods = "lcdc";
++ ti,power-gpio = <&gpio2 31 0x0>;
++ ti,allow-non-reduced-blanking-modes;
++ };
++
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0405-capes-add-basic-support-for-LCD4-capes.patch b/patches/linux-3.8.13/0405-capes-add-basic-support-for-LCD4-capes.patch
new file mode 100644
index 0000000..5dc4436
--- /dev/null
+++ b/patches/linux-3.8.13/0405-capes-add-basic-support-for-LCD4-capes.patch
@@ -0,0 +1,440 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Thu, 25 Apr 2013 09:28:32 +0200
+Subject: [PATCH] capes: add basic support for LCD4 capes
+
+Picture only, TS is broken
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ firmware/Makefile | 2 +
+ firmware/capes/BB-BONE-LCD4-01-00A0.dts | 161 +++++++++++++++++++++
+ firmware/capes/BB-BONE-LCD4-01-00A1.dts | 239 +++++++++++++++++++++++++++++++
+ 3 files changed, 402 insertions(+)
+ create mode 100644 firmware/capes/BB-BONE-LCD4-01-00A0.dts
+ create mode 100644 firmware/capes/BB-BONE-LCD4-01-00A1.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index 0ba37c6..1c8c844 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -148,6 +148,8 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ cape-bone-lcd3-00A0.dtbo \
+ cape-bone-lcd3-00A2.dtbo \
+ BB-BONE-AUDI-01-00A0.dtbo \
++ BB-BONE-LCD4-01-00A0.dtbo \
++ BB-BONE-LCD4-01-00A1.dtbo \
+ BB-BONE-LCD7-01-00A2.dtbo \
+ BB-BONE-LCD7-01-00A3.dtbo \
+ BB-BONE-LCD7-01-00A4.dtbo \
+diff --git a/firmware/capes/BB-BONE-LCD4-01-00A0.dts b/firmware/capes/BB-BONE-LCD4-01-00A0.dts
+new file mode 100644
+index 0000000..b1c7e00
+--- /dev/null
++++ b/firmware/capes/BB-BONE-LCD4-01-00A0.dts
+@@ -0,0 +1,161 @@
++/*
++ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-BONE-LCD4-01";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ bone_lcd4_cape_led_00A0_pins: pinmux_bone_lcd4_cape_led_00A0_pins {
++ pinctrl-single,pins = <
++ 0x48 0x07 /* gpmc_a2.gpio1_18, OUTPUT | MODE7 */
++ >;
++ };
++
++ bone_lcd4_cape_lcd_pins: pinmux_bone_lcd4_cape_lcd_pins {
++ pinctrl-single,pins = <
++ 0xa0 0x08 /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xa4 0x08 /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xa8 0x08 /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xac 0x08 /* lcd_data3.lcd_data3, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xb0 0x08 /* lcd_data4.lcd_data4, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xb4 0x08 /* lcd_data5.lcd_data5, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xb8 0x08 /* lcd_data6.lcd_data6, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xbc 0x08 /* lcd_data7.lcd_data7, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xc0 0x08 /* lcd_data8.lcd_data8, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xc4 0x08 /* lcd_data9.lcd_data9, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xc8 0x08 /* lcd_data10.lcd_data10, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xcc 0x08 /* lcd_data11.lcd_data11, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xd0 0x08 /* lcd_data12.lcd_data12, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xd4 0x08 /* lcd_data13.lcd_data13, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xd8 0x08 /* lcd_data14.lcd_data14, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xdc 0x08 /* lcd_data15.lcd_data15, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xe0 0x00 /* lcd_vsync.lcd_vsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0xe4 0x00 /* lcd_hsync.lcd_hsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0xe8 0x00 /* lcd_pclk.lcd_pclk, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0x4c 0x27 /* TSC_INT gpmc_a3.gpio1_19, INPUT | MODE7 */
++ >;
++ };
++
++ };
++ };
++
++ fragment@1 {
++ target = <&tps>;
++ __overlay__ {
++ backlight {
++ compatible = "not-tps65217-backlight";
++ isel = <1>;
++ fdim = <200>;
++ brightness = <100>;
++ tps = <&tps>;
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&ocp>;
++
++ __overlay__ {
++
++ /* avoid stupid warning */
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ tscadc {
++ compatible = "ti,ti-tscadc";
++ reg = <0x44e0d000 0x1000>;
++
++ interrupt-parent = <&intc>;
++ interrupts = <16>;
++ ti,hwmods = "adc_tsc";
++ status = "okay";
++
++ tsc {
++ ti,wires = <4>;
++ ti,x-plate-resistance = <200>;
++ ti,coordinate-readouts = <5>;
++ ti,wire-config = <0x00 0x11 0x22 0x33>;
++ };
++
++ adc {
++ ti,adc-channels = <4>;
++ };
++ };
++
++ gpio-leds-cape-lcd4 {
++ compatible = "gpio-leds";
++ pinctrl-names = "default";
++
++ pinctrl-0 = <&bone_lcd4_cape_led_00A0_pins>;
++
++ lcd4-led0 {
++ label = "lcd4:green:usr0";
++ gpios = <&gpio2 18 0>;
++ linux,default-trigger = "heartbeat";
++ default-state = "off";
++ };
++ };
++
++ /* Settings for NHD-4.3-ATXI#-T-1 / LCD4 cape: */
++ panel {
++ compatible = "tilcdc,panel";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bone_lcd4_cape_lcd_pins>;
++ panel-info {
++ ac-bias = <255>;
++ ac-bias-intrpt = <0>;
++ dma-burst-sz = <16>;
++ bpp = <24>;
++ fdd = <0x80>;
++ tft-alt-mode = <0>;
++ stn-565-mode = <0>;
++ mono-8bit-mode = <0>;
++ sync-edge = <0>;
++ sync-ctrl = <1>;
++ raster-order = <0>;
++ fifo-th = <0>;
++ };
++ display-timings {
++ native-mode = <&timing0>;
++ timing0: 480x272 {
++ hactive = <480>;
++ vactive = <272>;
++ hback-porch = <43>;
++ hfront-porch = <8>;
++ hsync-len = <4>;
++ vback-porch = <12>;
++ vfront-porch = <4>;
++ vsync-len = <10>;
++ clock-frequency = <9000000>;
++ hsync-active = <0>;
++ vsync-active = <0>;
++ };
++ };
++ };
++
++ fb {
++ compatible = "ti,am33xx-tilcdc";
++ reg = <0x4830e000 0x1000>;
++ interrupt-parent = <&intc>;
++ interrupts = <36>;
++ ti,hwmods = "lcdc";
++ };
++
++ };
++ };
++};
+diff --git a/firmware/capes/BB-BONE-LCD4-01-00A1.dts b/firmware/capes/BB-BONE-LCD4-01-00A1.dts
+new file mode 100644
+index 0000000..2744c27
+--- /dev/null
++++ b/firmware/capes/BB-BONE-LCD4-01-00A1.dts
+@@ -0,0 +1,239 @@
++/*
++ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-BONE-LCD4-01";
++ version = "00A1";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ bone_lcd4_cape_led_00A2_pins: pinmux_bone_lcd4_cape_led_00A2_pins {
++ pinctrl-single,pins = <
++ 0x078 0x2f /* gpmc_ben1.gpio1_28, INPUT | PULLDIS | MODE7 */
++ >;
++ };
++
++ pwm_bl_pins: pinmux_pwm_bl_pins {
++ pinctrl-single,pins = <
++ 0x48 0x06 /* gpmc_a2.ehrpwm1a, OMAP_MUX_MODE6 | AM33XX_PIN_OUTPUT */
++ >;
++ };
++
++ bone_lcd4_cape_lcd_pins: pinmux_bone_lcd4_cape_lcd_pins {
++ pinctrl-single,pins = <
++ 0xa0 0x08 /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xa4 0x08 /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xa8 0x08 /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xac 0x08 /* lcd_data3.lcd_data3, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xb0 0x08 /* lcd_data4.lcd_data4, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xb4 0x08 /* lcd_data5.lcd_data5, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xb8 0x08 /* lcd_data6.lcd_data6, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xbc 0x08 /* lcd_data7.lcd_data7, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xc0 0x08 /* lcd_data8.lcd_data8, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xc4 0x08 /* lcd_data9.lcd_data9, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xc8 0x08 /* lcd_data10.lcd_data10, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xcc 0x08 /* lcd_data11.lcd_data11, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xd0 0x08 /* lcd_data12.lcd_data12, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xd4 0x08 /* lcd_data13.lcd_data13, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xd8 0x08 /* lcd_data14.lcd_data14, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xdc 0x08 /* lcd_data15.lcd_data15, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xe0 0x00 /* lcd_vsync.lcd_vsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0xe4 0x00 /* lcd_hsync.lcd_hsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0xe8 0x00 /* lcd_pclk.lcd_pclk, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0x1a4 0x17 /* mcasp0_fsr.gpio3_19, OUTPUT | MODE7 LCD DISEN */
++ >;
++ };
++
++ bone_lcd4_cape_keys_00A2_pins: pinmux_bone_lcd4_cape_keys_00A2_pins {
++ pinctrl-single,pins = <
++ 0x040 0x2f /* gpmc_a0.gpio1_16, INPUT | PULLDIS | MODE7 */
++ 0x044 0x2f /* gpmc_a1.gpio1_17, INPUT | PULLDIS | MODE7 */
++ 0x04c 0x2f /* gpmc_a3.gpio1_19, INPUT | PULLDIS | MODE7 */
++ 0x154 0x2f /* P9_21 spi0_d0.gpio0_3 INPUT | PULLDIS | MODE7 */
++ >;
++ };
++
++ };
++ };
++
++ fragment@1 {
++ target = <&epwmss1>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@2 {
++ target = <&ehrpwm1>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@3 {
++ target = <&ocp>;
++
++ __overlay__ {
++
++ /* avoid stupid warning */
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ backlight {
++ compatible = "pwm-backlight";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_bl_pins>;
++
++ pwms = <&ehrpwm1 0 500000 0>;
++ pwm-names = "LCD4";
++ brightness-levels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100>;
++ default-brightness-level = <50>; /* index to the array above */
++ status = "okay";
++ };
++
++ tscadc {
++ compatible = "ti,ti-tscadc";
++ reg = <0x44e0d000 0x1000>;
++
++ interrupt-parent = <&intc>;
++ interrupts = <16>;
++ ti,hwmods = "adc_tsc";
++ status = "okay";
++
++ tsc {
++ ti,wires = <4>;
++ ti,x-plate-resistance = <200>;
++ ti,coordinate-readouts = <5>;
++ ti,wire-config = <0x00 0x11 0x22 0x33>;
++ };
++
++ adc {
++ ti,adc-channels = <4>;
++ };
++ };
++
++ gpio-leds-cape-lcd4 {
++ compatible = "gpio-leds";
++ pinctrl-names = "default";
++
++ pinctrl-0 = <&bone_lcd4_cape_led_00A2_pins>;
++
++ lcd4-led0 {
++ label = "lcd4:green:usr0";
++ gpios = <&gpio2 28 0>;
++ linux,default-trigger = "heartbeat";
++ default-state = "off";
++ };
++
++ };
++
++ gpio_keys {
++ compatible = "gpio-keys";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bone_lcd4_cape_keys_00A2_pins>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ button@1 {
++ debounce_interval = <50>;
++ linux,code = <105>;
++ label = "left";
++ gpios = <&gpio2 16 0x0>;
++ gpio-key,wakeup;
++ autorepeat;
++ };
++ button@2 {
++ debounce_interval = <50>;
++ linux,code = <106>;
++ label = "right";
++ gpios = <&gpio2 17 0x0>;
++ gpio-key,wakeup;
++ autorepeat;
++ };
++ button@3 {
++ debounce_interval = <50>;
++ linux,code = <103>;
++ label = "up";
++ gpios = <&gpio2 19 0x0>;
++ gpio-key,wakeup;
++ autorepeat;
++ };
++ button@4 {
++ debounce_interval = <50>;
++ linux,code = <108>;
++ label = "down";
++ gpios = <&gpio4 16 0x0>;
++ gpio-key,wakeup;
++ autorepeat;
++ };
++ button@5 {
++ debounce_interval = <50>;
++ linux,code = <28>;
++ label = "enter";
++ gpios = <&gpio1 15 0x0>;
++ gpio-key,wakeup;
++ };
++ };
++
++ /* Settings for NHD-4.3-ATXI#-T-1 / LCD4 cape: */
++ panel {
++ compatible = "tilcdc,panel";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bone_lcd4_cape_lcd_pins>;
++ panel-info {
++ ac-bias = <255>;
++ ac-bias-intrpt = <0>;
++ dma-burst-sz = <16>;
++ bpp = <24>;
++ fdd = <0x80>;
++ tft-alt-mode = <0>;
++ stn-565-mode = <0>;
++ mono-8bit-mode = <0>;
++ sync-edge = <0>;
++ sync-ctrl = <1>;
++ raster-order = <0>;
++ fifo-th = <0>;
++ };
++ display-timings {
++ native-mode = <&timing0>;
++ timing0: 480x272 {
++ hactive = <480>;
++ vactive = <272>;
++ hback-porch = <43>;
++ hfront-porch = <8>;
++ hsync-len = <4>;
++ vback-porch = <12>;
++ vfront-porch = <4>;
++ vsync-len = <10>;
++ clock-frequency = <9000000>;
++ hsync-active = <0>;
++ vsync-active = <0>;
++ };
++ };
++ };
++
++ fb {
++ compatible = "ti,am33xx-tilcdc";
++ reg = <0x4830e000 0x1000>;
++ interrupt-parent = <&intc>;
++ interrupts = <36>;
++ ti,hwmods = "lcdc";
++ };
++
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0406-OF-overlay-Add-depth-option-for-device-creation.patch b/patches/linux-3.8.13/0406-OF-overlay-Add-depth-option-for-device-creation.patch
new file mode 100644
index 0000000..924f5a2
--- /dev/null
+++ b/patches/linux-3.8.13/0406-OF-overlay-Add-depth-option-for-device-creation.patch
@@ -0,0 +1,83 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 1 May 2013 16:43:05 +0300
+Subject: [PATCH] OF-overlay: Add depth option for device creation.
+
+Add a depth option for device creation. Normally all nodes that
+represent devices are created, but some devices like gpmc for instance,
+perform their own device creation.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/of/overlay.c | 25 +++++++++++++++++++++++++
+ include/linux/of.h | 1 +
+ 2 files changed, 26 insertions(+)
+
+diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
+index 29078c7..f09fe56 100644
+--- a/drivers/of/overlay.c
++++ b/drivers/of/overlay.c
+@@ -271,6 +271,8 @@ static int of_overlay_notify(struct notifier_block *nb,
+ struct of_prop_reconfig *pr;
+ struct platform_device *pdev;
+ struct i2c_client *client;
++ struct device_node *tnode;
++ int depth;
+ int prevstate, state;
+ int err = 0;
+
+@@ -359,6 +361,21 @@ static int of_overlay_notify(struct notifier_block *nb,
+ return notifier_from_errno(0);
+ }
+
++ /* find depth */
++ depth = 1;
++ tnode = node;
++ while (tnode != NULL && tnode != ovinfo->target) {
++ tnode = tnode->parent;
++ depth++;
++ }
++
++ /* respect overlay's maximum depth */
++ if (ovinfo->device_depth != 0 && depth > ovinfo->device_depth) {
++ pr_debug("OF: skipping device creation for node=%s depth=%d\n",
++ node->name, depth);
++ goto out;
++ }
++
+ if (state == 0) {
+ pdev = of_find_device_by_node(node);
+ client = of_find_i2c_device_by_node(node);
+@@ -366,6 +383,7 @@ static int of_overlay_notify(struct notifier_block *nb,
+
+ of_overlay_device_entry_entry_add(ovinfo, node, pdev, client,
+ prevstate, state);
++out:
+
+ return notifier_from_errno(err);
+ }
+@@ -749,6 +767,13 @@ int of_fill_overlay_info(struct device_node *info_node,
+ if (ovinfo->overlay == NULL)
+ goto err_fail;
+
++ ret = of_property_read_u32(info_node, "depth", &val);
++ if (ret == 0)
++ ovinfo->device_depth = val;
++ else
++ ovinfo->device_depth = 0;
++
++
+ return 0;
+
+ err_fail:
+diff --git a/include/linux/of.h b/include/linux/of.h
+index 73cfde5..6c72d94 100644
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -735,6 +735,7 @@ struct of_overlay_info {
+ struct list_head le_list;
+ struct list_head de_list;
+ struct notifier_block notifier;
++ int device_depth;
+ };
+
+ #ifdef CONFIG_OF_OVERLAY
diff --git a/patches/linux-3.8.13/0407-capes-Add-BB-BONE-GPEVT-cape.patch b/patches/linux-3.8.13/0407-capes-Add-BB-BONE-GPEVT-cape.patch
new file mode 100644
index 0000000..b496ddb
--- /dev/null
+++ b/patches/linux-3.8.13/0407-capes-Add-BB-BONE-GPEVT-cape.patch
@@ -0,0 +1,72 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 1 May 2013 16:52:20 +0300
+Subject: [PATCH] capes: Add BB-BONE-GPEVT cape
+
+Add a virtual cape for the GPEVT dma test driver.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ firmware/Makefile | 1 +
+ firmware/capes/BB-BONE-GPEVT-00A0.dts | 41 +++++++++++++++++++++++++++++++++
+ 2 files changed, 42 insertions(+)
+ create mode 100644 firmware/capes/BB-BONE-GPEVT-00A0.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index 1c8c844..d122aa1 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -154,6 +154,7 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ BB-BONE-LCD7-01-00A3.dtbo \
+ BB-BONE-LCD7-01-00A4.dtbo \
+ BB-BONE-eMMC1-01-00A0.dtbo \
++ BB-BONE-GPEVT-00A0.dtbo \
+ cape-bone-iio-00A0.dtbo \
+ cape-bone-pinmux-test-00A0.dtbo \
+ cape-bone-exptest-00A0.dtbo \
+diff --git a/firmware/capes/BB-BONE-GPEVT-00A0.dts b/firmware/capes/BB-BONE-GPEVT-00A0.dts
+new file mode 100644
+index 0000000..80f9016
+--- /dev/null
++++ b/firmware/capes/BB-BONE-GPEVT-00A0.dts
+@@ -0,0 +1,41 @@
++/*
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "BB-BONE-GPEVT";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ gpevt_pins_s0: pinmux_gpevt_pins_s0 {
++ pinctrl-single,pins = <
++ 0x090 0x37 /* gpmc_advn_ale.gpio2_2, INPUT_PULLUP | MODE7 */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ gpevt {
++ compatible = "gpevt";
++ pinctrl-names = "default";
++ pinctrl-0 = <&gpevt_pins_s0>;
++
++ dmas = <&edma 12>;
++ dma-names = "gpioevt";
++ gpio-evt = <&gpio3 2 0>;
++ };
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0408-clock-Export-__clock_set_parent.patch b/patches/linux-3.8.13/0408-clock-Export-__clock_set_parent.patch
new file mode 100644
index 0000000..872fc98
--- /dev/null
+++ b/patches/linux-3.8.13/0408-clock-Export-__clock_set_parent.patch
@@ -0,0 +1,47 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 1 May 2013 18:19:26 +0300
+Subject: [PATCH] clock: Export __clock_set_parent
+
+We need this exported for the manipulation of the clkout2 external
+clock. As part of clock rate selection, the parent must change.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/clk/clk.c | 3 ++-
+ include/linux/clk-provider.h | 2 ++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 251e45d..8cb8b08 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -1077,7 +1077,7 @@ out:
+ __clk_recalc_rates(clk, POST_RATE_CHANGE);
+ }
+
+-static int __clk_set_parent(struct clk *clk, struct clk *parent)
++int __clk_set_parent(struct clk *clk, struct clk *parent)
+ {
+ struct clk *old_parent;
+ unsigned long flags;
+@@ -1136,6 +1136,7 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent)
+ out:
+ return ret;
+ }
++EXPORT_SYMBOL_GPL(__clk_set_parent);
+
+ /**
+ * clk_set_parent - switch the parent of a mux clk
+diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
+index 1c09481..8c6dadc 100644
+--- a/include/linux/clk-provider.h
++++ b/include/linux/clk-provider.h
+@@ -369,6 +369,8 @@ void __clk_unprepare(struct clk *clk);
+ void __clk_reparent(struct clk *clk, struct clk *new_parent);
+ unsigned long __clk_round_rate(struct clk *clk, unsigned long rate);
+
++int __clk_set_parent(struct clk *clk, struct clk *parent);
++
+ struct of_device_id;
+
+ typedef void (*of_clk_init_cb_t)(struct device_node *);
diff --git a/patches/linux-3.8.13/0409-omap-clk-Add-adjustable-clkout2.patch b/patches/linux-3.8.13/0409-omap-clk-Add-adjustable-clkout2.patch
new file mode 100644
index 0000000..fb19d10
--- /dev/null
+++ b/patches/linux-3.8.13/0409-omap-clk-Add-adjustable-clkout2.patch
@@ -0,0 +1,276 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 1 May 2013 18:32:29 +0300
+Subject: [PATCH] omap-clk: Add adjustable clkout2
+
+The way clkout2 work is no good for external devices needing the clock.
+A way to select rate, that translates to selecting a parent clock is
+required for drivers to work.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ arch/arm/mach-omap2/cclock33xx_data.c | 239 +++++++++++++++++++++++++++++++++
+ 1 file changed, 239 insertions(+)
+
+diff --git a/arch/arm/mach-omap2/cclock33xx_data.c b/arch/arm/mach-omap2/cclock33xx_data.c
+index 7e29317..c028220 100644
+--- a/arch/arm/mach-omap2/cclock33xx_data.c
++++ b/arch/arm/mach-omap2/cclock33xx_data.c
+@@ -818,6 +818,242 @@ DEFINE_CLK_DIVIDER_TABLE(clkout2_div_ck, "sysclkout_pre_ck", &sysclkout_pre_ck,
+ DEFINE_CLK_GATE(clkout2_ck, "clkout2_div_ck", &clkout2_div_ck, 0x0,
+ AM33XX_CM_CLKOUT_CTRL, AM33XX_CLKOUT2EN_SHIFT, 0x0, NULL);
+
++/********************************************/
++
++static const char *adjustable_sysclkout_ck_parents[] = {
++ "clk_32768_ck", "l3_gclk", "dpll_ddr_m2_ck", "dpll_per_m2_ck",
++ "lcd_gclk",
++};
++
++static const struct clksel foo_sysclkout_pre_sel[] = {
++ { .parent = &clk_32768_ck, .rates = div_1_0_rates },
++ { .parent = &l3_gclk, .rates = div_1_1_rates },
++ { .parent = &dpll_ddr_m2_ck, .rates = div_1_2_rates },
++ { .parent = &dpll_per_m2_ck, .rates = div_1_3_rates },
++ { .parent = &lcd_gclk, .rates = div_1_4_rates },
++ { .parent = NULL },
++};
++
++struct clkout_match {
++ unsigned long best_rate;
++ unsigned long parent_rate;
++ const struct clksel *best_clks;
++ const struct clksel_rate *best_clkr;
++ const struct clk_div_table *best_clkd;
++};
++
++struct clk_hw_clkout {
++ struct clk_hw_omap omap_hw;
++ void __iomem *div_reg;
++ u32 div_mask;
++ const struct clk_div_table *div_table;
++ struct clkout_match match;
++};
++
++#define to_clk_hw_clkout(_hw) container_of(_hw, struct clk_hw_clkout, omap_hw.hw)
++
++static int clkout_clk_enable(struct clk_hw *hw)
++{
++ return omap2_dflt_clk_enable(hw);
++}
++
++static void clkout_clk_disable(struct clk_hw *hw)
++{
++ omap2_dflt_clk_enable(hw);
++}
++
++static int clkout_clk_is_enabled(struct clk_hw *hw)
++{
++ return omap2_dflt_clk_is_enabled(hw);
++}
++
++static int clkout_find_match(struct clk_hw *hw, unsigned long target_rate,
++ struct clkout_match *m)
++{
++ struct clk_hw_clkout *clkout_clk = to_clk_hw_clkout(hw);
++ struct clk_hw_omap *omap_clk = to_clk_hw_omap(hw);
++ struct clk *pclk;
++ unsigned long prate, test_rate;
++ const struct clksel *clks;
++ const struct clksel_rate *clkr;
++ const struct clk_div_table *clkd;
++
++ memset(m, 0, sizeof(*m));
++
++ /* iterate over all the clksel */
++ for (clks = omap_clk->clksel; (pclk = clks->parent) != NULL; clks++) {
++ prate = __clk_get_rate(pclk);
++ for (clkr = clks->rates; clkr->div; clkr++) {
++ if (!(clkr->flags & cpu_mask))
++ continue;
++ for (clkd = clkout_clk->div_table; clkd->div; clkd++) {
++ test_rate = (prate / clkr->div) / clkd->div;
++
++ if (abs(test_rate - target_rate) < abs(m->best_rate - target_rate)) {
++ m->parent_rate = prate / clkr->div;
++ m->best_rate = test_rate;
++ m->best_clks = clks;
++ m->best_clkr = clkr;
++ m->best_clkd = clkd;
++ }
++ }
++ }
++ }
++
++ if (!m->best_clks || !m->best_clkr || !m->best_clkd) {
++ pr_err("%s: Failed to find a best match\n", __func__);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int clkout_clksel_set_rate(struct clk_hw *hw, unsigned long rate,
++ unsigned long parent_rate)
++{
++ struct clk_hw_clkout *clkout_clk = to_clk_hw_clkout(hw);
++ struct clk_hw_omap *omap_clk = to_clk_hw_omap(hw);
++ struct clkout_match *m = &clkout_clk->match;
++ struct clk *clk = hw->clk;
++ int ret;
++ u32 v;
++
++ ret = clkout_find_match(hw, rate, m);
++ if (ret != 0)
++ return ret;
++
++ /* have to be exact now */
++ if (rate != m->best_rate) {
++ pr_err("%s: Failed to find exact rate %lu (was %lu)\n",
++ __func__, rate, m->best_rate);
++ return -EINVAL;
++ }
++
++ /* switch parent */
++ if (m->best_clks->parent != __clk_get_parent(clk)) {
++ __clk_set_parent(clk, m->best_clks->parent);
++ __clk_reparent(clk, m->best_clks->parent);
++ parent_rate = __clk_get_rate(__clk_get_parent(clk));
++ }
++
++ /* we need to write the new value */
++ if (omap_clk->clksel_reg != clkout_clk->div_reg) {
++ v = __raw_readl(omap_clk->clksel_reg);
++ v &= ~omap_clk->clksel_mask;
++ v |= m->best_clkr->val << __ffs(omap_clk->clksel_mask);
++ __raw_writel(v, omap_clk->clksel_reg);
++ v = __raw_readl(omap_clk->clksel_reg); /* OCP barrier */
++
++ v = __raw_readl(clkout_clk->div_reg);
++ v &= ~clkout_clk->div_mask;
++ v |= m->best_clkd->val << __ffs(clkout_clk->div_mask);
++ __raw_writel(v, clkout_clk->div_reg);
++ v = __raw_readl(clkout_clk->div_reg); /* OCP barrier */
++ } else {
++ v = __raw_readl(omap_clk->clksel_reg);
++ v &= ~(omap_clk->clksel_mask | clkout_clk->div_mask);
++ v |= (m->best_clkr->val << __ffs(omap_clk->clksel_mask)) |
++ (m->best_clkd->val << __ffs(clkout_clk->div_mask));
++ __raw_writel(v, omap_clk->clksel_reg);
++ v = __raw_readl(omap_clk->clksel_reg); /* OCP barrier */
++ }
++
++ return ret;
++}
++
++static long clkout_clksel_round_rate(struct clk_hw *hw, unsigned long target_rate,
++ unsigned long *parent_rate)
++{
++ struct clkout_match m;
++ long ret;
++
++ ret = clkout_find_match(hw, target_rate, &m);
++ if (ret != 0) {
++ pr_err("%s: Failed to find a best match\n", __func__);
++ return (unsigned long)-1;
++ }
++
++ *parent_rate = __clk_get_rate(m.best_clks->parent);
++
++ return m.best_rate;
++}
++
++static unsigned long clkout_clksel_recalc(struct clk_hw *hw, unsigned long parent_rate)
++{
++ struct clk_hw_clkout *clkout_clk = to_clk_hw_clkout(hw);
++ struct clk_hw_omap *omap_clk = to_clk_hw_omap(hw);
++ u32 v;
++ unsigned int divr, divd;
++
++ v = __raw_readl(omap_clk->clksel_reg);
++ v &= omap_clk->clksel_mask;
++ v >>= __ffs(omap_clk->clksel_mask);
++ divr = v;
++
++ v = __raw_readl(clkout_clk->div_reg);
++ v &= clkout_clk->div_mask;
++ v >>= __ffs(clkout_clk->div_mask);
++ divd = v;
++
++ return clkout_clk->match.best_rate;
++}
++
++static u8 clkout_clksel_find_parent_index(struct clk_hw *hw)
++{
++ return omap2_clksel_find_parent_index(hw);
++}
++
++static int clkout_clksel_set_parent(struct clk_hw *hw, u8 field_val)
++{
++ return omap2_clksel_set_parent(hw, field_val);
++}
++
++static void clkout_init_clk_clkdm(struct clk_hw *hw)
++{
++ omap2_init_clk_clkdm(hw);
++}
++
++static const struct clk_ops adjustable_sysclkout_ck_clk_ops = {
++ .enable = &clkout_clk_enable,
++ .disable = &clkout_clk_disable,
++ .is_enabled = &clkout_clk_is_enabled,
++ .set_rate = &clkout_clksel_set_rate,
++ .round_rate = &clkout_clksel_round_rate,
++ .recalc_rate = &clkout_clksel_recalc,
++ .get_parent = &clkout_clksel_find_parent_index,
++ .set_parent = &clkout_clksel_set_parent,
++ .init = &clkout_init_clk_clkdm,
++};
++
++static struct clk adjustable_clkout2_ck;
++static struct clk_hw_clkout adjustable_clkout2_ck_hw = {
++ .omap_hw = {
++ .hw = {
++ .clk = &adjustable_clkout2_ck,
++ },
++ .ops = NULL,
++ .enable_reg = AM33XX_CM_CLKOUT_CTRL,
++ .enable_bit = AM33XX_CLKOUT2EN_SHIFT,
++ .clksel = foo_sysclkout_pre_sel,
++ .clksel_reg = AM33XX_CM_CLKOUT_CTRL,
++ .clksel_mask = AM33XX_CLKOUT2SOURCE_MASK,
++ .clkdm_name = NULL,
++ },
++ .div_reg = AM33XX_CM_CLKOUT_CTRL,
++ .div_mask = AM33XX_CLKOUT2DIV_MASK,
++ .div_table = div8_rates,
++};
++static struct clk adjustable_clkout2_ck = {
++ .name = "adjustable_clkout2_ck",
++ .hw = &adjustable_clkout2_ck_hw.omap_hw.hw,
++ .parent_names = adjustable_sysclkout_ck_parents,
++ .num_parents = ARRAY_SIZE(adjustable_sysclkout_ck_parents),
++ .ops = &adjustable_sysclkout_ck_clk_ops,
++ .flags = CLK_GET_RATE_NOCACHE | CLK_SET_PARENT_GATE | CLK_SET_RATE_GATE
++};
++
++/********************************************/
++
+ static const char *wdt_ck_parents[] = {
+ "clk_rc32k_ck", "clkdiv32k_ick",
+ };
+@@ -947,12 +1183,15 @@ static struct omap_clk am33xx_clks[] = {
+ CLK(NULL, "gfx_fck_div_ck", &gfx_fck_div_ck, CK_AM33XX),
+ CLK(NULL, "sysclkout_pre_ck", &sysclkout_pre_ck, CK_AM33XX),
+ CLK(NULL, "clkout2_div_ck", &clkout2_div_ck, CK_AM33XX),
++ CLK(NULL, "clkout2_ck", &clkout2_ck, CK_AM33XX),
+ CLK(NULL, "timer_32k_ck", &clkdiv32k_ick, CK_AM33XX),
+ CLK(NULL, "timer_sys_ck", &sys_clkin_ck, CK_AM33XX),
+ CLK("48300200.ehrpwm", "tbclk", &ehrpwm0_tbclk, CK_AM33XX),
+ CLK("48302200.ehrpwm", "tbclk", &ehrpwm1_tbclk, CK_AM33XX),
+ CLK("48304200.ehrpwm", "tbclk", &ehrpwm2_tbclk, CK_AM33XX),
+ CLK("4830e000.fb", "fck", &lcd_gclk, CK_AM33XX),
++ /* magical adjustable clkout2 without mult/div */
++ CLK(NULL, "adjustable_clkout2_ck", &adjustable_clkout2_ck,CK_AM33XX),
+ };
+
+
diff --git a/patches/linux-3.8.13/0410-am33xx-Update-DTS-EDMA.patch b/patches/linux-3.8.13/0410-am33xx-Update-DTS-EDMA.patch
new file mode 100644
index 0000000..485679c
--- /dev/null
+++ b/patches/linux-3.8.13/0410-am33xx-Update-DTS-EDMA.patch
@@ -0,0 +1,48 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 1 May 2013 18:36:32 +0300
+Subject: [PATCH] am33xx: Update DTS EDMA
+
+Update EDMA bindings to work the same way as on the 3.2 kernel
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ arch/arm/boot/dts/am335x-bone-common.dtsi | 3 ++-
+ arch/arm/boot/dts/am33xx.dtsi | 4 ++--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
+index 1c91d7d..92e3fb6 100644
+--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
+@@ -447,7 +447,8 @@
+ };
+
+ &edma {
+- ti,edma-xbar-event-map = <32 12>;
++ ti,edma-xbar-event-map = <32 12>, /* gpevt2 -> 12 */
++ <30 20>; /* xdma_event_intr2 -> 20 */
+ };
+
+ &sham {
+diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
+index 797f421..9bf0d2c 100644
+--- a/arch/arm/boot/dts/am33xx.dtsi
++++ b/arch/arm/boot/dts/am33xx.dtsi
+@@ -95,7 +95,7 @@
+ compatible = "ti,edma3";
+ ti,hwmods = "tpcc", "tptc0", "tptc1", "tptc2";
+ reg = <0x49000000 0x10000>,
+- <0x44e10f90 0x10>;
++ <0x44e10f90 0x40>;
+ interrupt-parent = <&intc>;
+ interrupts = <12 13 14>;
+ #dma-cells = <1>;
+@@ -108,7 +108,7 @@
+ ti,edma-queue-priority-map = <0 0
+ 1 1
+ 2 2>;
+- ti,edma-default-queue = <0>;
++ ti,edma-default-queue = <1>;
+ };
+
+ gpio1: gpio@44e07000 {
diff --git a/patches/linux-3.8.13/0411-bone-Added-RS232-prototype-cape-DT-object.patch b/patches/linux-3.8.13/0411-bone-Added-RS232-prototype-cape-DT-object.patch
new file mode 100644
index 0000000..4f6b581
--- /dev/null
+++ b/patches/linux-3.8.13/0411-bone-Added-RS232-prototype-cape-DT-object.patch
@@ -0,0 +1,110 @@
+From: Matt Ranostay <mranostay@gmail.com>
+Date: Tue, 23 Apr 2013 17:18:34 +0000
+Subject: [PATCH] bone: Added RS232 prototype cape DT object
+
+Added UART device tree object to setup UART3 and pinmux.
+This should work with the RS232 cape that currently exists.
+
+Signed-off-by: Matt Ranostay <mranostay@gmail.com>
+---
+ arch/arm/boot/dts/am335x-bone-common.dtsi | 19 +++++++++++++-
+ firmware/Makefile | 1 +
+ firmware/capes/BB-BONE-RS232-00A0.dts | 39 +++++++++++++++++++++++++++++
+ 3 files changed, 58 insertions(+), 1 deletion(-)
+ create mode 100644 firmware/capes/BB-BONE-RS232-00A0.dts
+
+diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
+index 92e3fb6..d525195 100644
+--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
+@@ -205,8 +205,18 @@
+ manufacturer = "Signal 11 Software";
+ part-number = "BB-BONE-MRF24J40";
+ };
+- };
+
++ /* RS232 cape */
++ slot@12 {
++ ti,cape-override;
++ compatible = "kernel-command-line", "runtime";
++ board-name = "BB-BONE-RS232";
++ version = "00A0";
++ manufacturer = "Adafruit";
++ part-number = "BB-BONE-RS232-01";
++ };
++ };
++
+ /* mapping between board names and dtb objects */
+ capemaps {
+ /* DVI cape */
+@@ -328,6 +338,13 @@
+ dtbo = "cape-bone-exptest-00A0.dtbo";
+ };
+ };
++ cape@12 {
++ part-number = "BB-BONE-RS232-01";
++ version@00A0 {
++ version = "00A0";
++ dtbo = "BB-BONE-RS232-00A0.dtbo";
++ };
++ };
+ };
+ };
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index d122aa1..3a4f126 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -155,6 +155,7 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ BB-BONE-LCD7-01-00A4.dtbo \
+ BB-BONE-eMMC1-01-00A0.dtbo \
+ BB-BONE-GPEVT-00A0.dtbo \
++ BB-BONE-RS232-00A0.dtbo \
+ cape-bone-iio-00A0.dtbo \
+ cape-bone-pinmux-test-00A0.dtbo \
+ cape-bone-exptest-00A0.dtbo \
+diff --git a/firmware/capes/BB-BONE-RS232-00A0.dts b/firmware/capes/BB-BONE-RS232-00A0.dts
+new file mode 100644
+index 0000000..220c85d
+--- /dev/null
++++ b/firmware/capes/BB-BONE-RS232-00A0.dts
+@@ -0,0 +1,39 @@
++/*
++ * Copyright (C) 2013 Matt Ranostay <mranostay@gmail.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-BONE-RS232";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ uart_pins: pinmux_uart_pins {
++ pinctrl-single,pins = <
++ 0x150 0x21 /* spi0_sclk.uart2_rxd | MODE1 | PULL_UP */
++ 0x154 0x01 /* spi0_d0.uart2_txd | MODE1 */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&uart3>;
++ __overlay__ {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart_pins>;
++ };
++ };
++
++};
diff --git a/patches/linux-3.8.13/0412-Add-support-for-BB-BONE_SERL-01-00A1-CanBus-cape.patch b/patches/linux-3.8.13/0412-Add-support-for-BB-BONE_SERL-01-00A1-CanBus-cape.patch
new file mode 100644
index 0000000..eabeb8f
--- /dev/null
+++ b/patches/linux-3.8.13/0412-Add-support-for-BB-BONE_SERL-01-00A1-CanBus-cape.patch
@@ -0,0 +1,66 @@
+From: Martin Gysel <me@bearsh.org>
+Date: Wed, 15 May 2013 16:48:34 +0200
+Subject: [PATCH] Add support for BB-BONE_SERL-01-00A1 CanBus cape
+
+Signed-off-by: Martin Gysel <me@bearsh.org>
+---
+ firmware/Makefile | 1 +
+ firmware/capes/BB-BONE-SERL-01-00A1.dts | 37 +++++++++++++++++++++++++++++++
+ 2 files changed, 38 insertions(+)
+ create mode 100644 firmware/capes/BB-BONE-SERL-01-00A1.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index 3a4f126..3497631 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -156,6 +156,7 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ BB-BONE-eMMC1-01-00A0.dtbo \
+ BB-BONE-GPEVT-00A0.dtbo \
+ BB-BONE-RS232-00A0.dtbo \
++ BB-BONE-SERL-01-00A1.dtbo \
+ cape-bone-iio-00A0.dtbo \
+ cape-bone-pinmux-test-00A0.dtbo \
+ cape-bone-exptest-00A0.dtbo \
+diff --git a/firmware/capes/BB-BONE-SERL-01-00A1.dts b/firmware/capes/BB-BONE-SERL-01-00A1.dts
+new file mode 100644
+index 0000000..b0459c8
+--- /dev/null
++++ b/firmware/capes/BB-BONE-SERL-01-00A1.dts
+@@ -0,0 +1,37 @@
++/*
++* Copyright (C) 2013 Martin Gysel <me@bearsh.org>
++*
++* 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.
++*/
++/dts-v1/;
++/plugin/;
++
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++ part-number = "BB-BONE-SERL-01";
++ version = "00A1";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ bone_serl_01_dcan1_pins: bone_serl_01_dcan1_pins {
++ pinctrl-single,pins = <
++ 0x180 0x02 /* uart1_rxd.d_can1_tx", OUTPUT | MODE2 */
++ 0x184 0x32 /* uart1_txd.d_can1_rx", INPUT_PULLUP | MODE2 */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&dcan1>;
++ __overlay__ {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bone_serl_01_dcan1_pins>;
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0413-capes-Add-virtual-capes-serving-as-examples.patch b/patches/linux-3.8.13/0413-capes-Add-virtual-capes-serving-as-examples.patch
new file mode 100644
index 0000000..3c06b53
--- /dev/null
+++ b/patches/linux-3.8.13/0413-capes-Add-virtual-capes-serving-as-examples.patch
@@ -0,0 +1,676 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 30 May 2013 15:44:07 +0300
+Subject: [PATCH] capes: Add virtual capes serving as examples
+
+Example capes for UART/I2C/SPI.
+
+Conflicts:
+ firmware/Makefile
+---
+ firmware/Makefile | 19 +++++++++
+ firmware/capes/BB-I2C1-00A0.dts | 65 +++++++++++++++++++++++++++++
+ firmware/capes/BB-I2C1A1-00A0.dts | 65 +++++++++++++++++++++++++++++
+ firmware/capes/BB-SPI0-00A0.dts | 79 ++++++++++++++++++++++++++++++++++++
+ firmware/capes/BB-SPI1-00A0.dts | 79 ++++++++++++++++++++++++++++++++++++
+ firmware/capes/BB-SPI1A1-00A0.dts | 81 +++++++++++++++++++++++++++++++++++++
+ firmware/capes/BB-UART1-00A0.dts | 48 ++++++++++++++++++++++
+ firmware/capes/BB-UART2-00A0.dts | 48 ++++++++++++++++++++++
+ firmware/capes/BB-UART4-00A0.dts | 48 ++++++++++++++++++++++
+ firmware/capes/BB-UART5-00A0.dts | 49 ++++++++++++++++++++++
+ 10 files changed, 581 insertions(+)
+ create mode 100644 firmware/capes/BB-I2C1-00A0.dts
+ create mode 100644 firmware/capes/BB-I2C1A1-00A0.dts
+ create mode 100644 firmware/capes/BB-SPI0-00A0.dts
+ create mode 100644 firmware/capes/BB-SPI1-00A0.dts
+ create mode 100644 firmware/capes/BB-SPI1A1-00A0.dts
+ create mode 100644 firmware/capes/BB-UART1-00A0.dts
+ create mode 100644 firmware/capes/BB-UART2-00A0.dts
+ create mode 100644 firmware/capes/BB-UART4-00A0.dts
+ create mode 100644 firmware/capes/BB-UART5-00A0.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index 3497631..b039188 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -196,6 +196,25 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += cape-boneblack-hdmi-00A0.dtbo
+ # the Tester cape (tester-side)
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += cape-bone-tester-00A0.dtbo
+
++# the virtual peripheral capes for the UARTs
++# UART3 is not routed to the connectors, no cape for it
++fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
++ BB-UART1-00A0.dtbo BB-UART2-00A0.dtbo \
++ BB-UART4-00A0.dtbo BB-UART5-00A0.dtbo
++
++# the virtual peripheral capes for the I2Cs
++# I2C0 & I2C2 are enabled by default, no capes for them
++fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
++ BB-I2C1-00A0.dtbo BB-I2C1A1-00A0.dtbo
++
++# the virtual peripheral capes for the SPIs
++fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
++ BB-SPI0-00A0.dtbo BB-SPI1-00A0.dtbo BB-SPI1A1-00A0.dtbo
++
++# PRU firmware
++#fw-shipped-$(CONFIG_PRU_RPROC) += \
++# prutest.bin
++
+ fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-)
+
+ # Directories which we _might_ need to create, so we have a rule for them.
+diff --git a/firmware/capes/BB-I2C1-00A0.dts b/firmware/capes/BB-I2C1-00A0.dts
+new file mode 100644
+index 0000000..9e74f26
+--- /dev/null
++++ b/firmware/capes/BB-I2C1-00A0.dts
+@@ -0,0 +1,65 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ *
++ * Virtual cape for I2C1 on connector pins P9.17 P9.18
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-I2C1";
++ version = "00A0";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.18", /* i2c1_sda */
++ "P9.17", /* i2c1_scl */
++ /* the hardware ip uses */
++ "i2c1";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ bb_i2c1_pins: pinmux_bb_i2c1_pins {
++ pinctrl-single,pins = <
++ 0x158 0x72 /* spi0_d1.i2c1_sda, SLEWCTRL_SLOW | INPUT_PULLUP | MODE2 */
++ 0x15c 0x72 /* spi0_cs0.i2c1_scl, SLEWCTRL_SLOW | INPUT_PULLUP | MODE2 */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&i2c1>; /* i2c1 is numbered correctly */
++ __overlay__ {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bb_i2c1_pins>;
++
++ /* this is the configuration part */
++ clock-frequency = <100000>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* add any i2c devices on the bus here */
++
++ // commented out example of a touchscreen (taken from BB-BONE-LCD7-01-00A4) */
++ // maxtouch@4a {
++ // compatible = "mXT224";
++ // reg = <0x4a>;
++ // interrupt-parent = <&gpio4>;
++ // interrupts = <19 0x0>;
++ // atmel,irq-gpio = <&gpio4 19 0>;
++ // };
++ };
++ };
++};
+diff --git a/firmware/capes/BB-I2C1A1-00A0.dts b/firmware/capes/BB-I2C1A1-00A0.dts
+new file mode 100644
+index 0000000..4a2b1bd
+--- /dev/null
++++ b/firmware/capes/BB-I2C1A1-00A0.dts
+@@ -0,0 +1,65 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ *
++ * Virtual cape for I2C1 on connector pins P9.26 P9.24 (ALT config #1)
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-I2C1A1";
++ version = "00A0";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.26", /* i2c1_sda */
++ "P9.24", /* i2c1_scl */
++ /* the hardware ip uses */
++ "i2c1";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ bb_i2c1a1_pins: pinmux_bb_i2c1a1_pins {
++ pinctrl-single,pins = <
++ 0x180 0x73 /* uart1_rxd.i2c1_sda, SLEWCTRL_SLOW | INPUT_PULLUP | MODE3 */
++ 0x184 0x73 /* uart1_txdi2c1_scl, SLEWCTRL_SLOW | INPUT_PULLUP | MODE3 */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&i2c1>; /* i2c1 is numbered correctly */
++ __overlay__ {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bb_i2c1a1_pins>;
++
++ /* this is the configuration part */
++ clock-frequency = <100000>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* add any i2c devices on the bus here */
++
++ // commented out example of a touchscreen (taken from BB-BONE-LCD7-01-00A4) */
++ // maxtouch@4a {
++ // compatible = "mXT224";
++ // reg = <0x4a>;
++ // interrupt-parent = <&gpio4>;
++ // interrupts = <19 0x0>;
++ // atmel,irq-gpio = <&gpio4 19 0>;
++ // };
++ };
++ };
++};
+diff --git a/firmware/capes/BB-SPI0-00A0.dts b/firmware/capes/BB-SPI0-00A0.dts
+new file mode 100644
+index 0000000..547efce
+--- /dev/null
++++ b/firmware/capes/BB-SPI0-00A0.dts
+@@ -0,0 +1,79 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ *
++ * Virtual cape for SPI0 on connector pins P9.22 P9.21 P9.18 P9.17
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-SPI0";
++ version = "00A0";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.17", /* spi0_cs0 */
++ "P9.18", /* spi0_d1 */
++ "P9.21", /* spi0_d0 */
++ "P9.22", /* spi0_sclk */
++ /* the hardware ip uses */
++ "spi0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ /* default state has all gpios released and mode set to uart1 */
++ bb_spi0_pins: pinmux_bb_spi0_pins {
++ pinctrl-single,pins = <
++ 0x150 0x30 /* spi0_sclk.spi0_sclk, INPUT_PULLUP | MODE0 */
++ 0x154 0x30 /* spi0_d0.spi0_d0, INPUT_PULLUP | MODE0 */
++ 0x158 0x10 /* spi0_d1.spi0_d1, OUTPUT_PULLUP | MODE0 */
++ 0x15c 0x10 /* spi0_cs0.spi0_cs0, OUTPUT_PULLUP | MODE0 */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&spi0>; /* spi0 is numbered correctly */
++ __overlay__ {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bb_spi0_pins>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* add any spi devices connected here */
++ /* note that you can do direct SPI via spidev now */
++
++ // commented out example of an adafruit 1.8" TFT display
++ // from firmare/capes/cape-bone-adafruit-lcd-00A0.dts
++ // lcd@0 {
++ // #address-cells = <1>;
++ // #size-cells = <0>;
++ //
++ // compatible = "adafruit,tft-lcd-1.8-red", "sitronix,st7735";
++ // reg = <0>;
++ //
++ // spi-max-frequency = <8000000>;
++ // spi-cpol;
++ // spi-cpha;
++ //
++ // pinctrl-names = "default";
++ // pinctrl-0 = <&bone_adafruit_lcd_pins>;
++ //
++ // st7735-rst = <&gpio4 19 0>;
++ // st7735-dc = <&gpio4 21 0>;
++ // };
++ };
++ };
++};
+diff --git a/firmware/capes/BB-SPI1-00A0.dts b/firmware/capes/BB-SPI1-00A0.dts
+new file mode 100644
+index 0000000..e26f346
+--- /dev/null
++++ b/firmware/capes/BB-SPI1-00A0.dts
+@@ -0,0 +1,79 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ *
++ * Virtual cape for SPI1 on connector pins P9.29 P9.31 P9.30 P9.28
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-SPI1";
++ version = "00A0";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.31", /* spi1_sclk */
++ "P9.29", /* spi1_d0 */
++ "P9.30", /* spi1_d1 */
++ "P9.28", /* spi1_cs0 */
++ /* the hardware ip uses */
++ "spi1";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ /* default state has all gpios released and mode set to uart1 */
++ bb_spi1_pins: pinmux_bb_spi1_pins {
++ pinctrl-single,pins = <
++ 0x190 0x33 /* mcasp0_aclkx.spi1_sclk, INPUT_PULLUP | MODE3 */
++ 0x194 0x33 /* mcasp0_fsx.spi1_d0, INPUT_PULLUP | MODE3 */
++ 0x198 0x13 /* mcasp0_axr0.spi1_d1, OUTPUT_PULLUP | MODE3 */
++ 0x19c 0x13 /* mcasp0_ahclkr.spi1_cs0, OUTPUT_PULLUP | MODE3 */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&spi1>; /* spi1 is numbered correctly */
++ __overlay__ {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bb_spi1_pins>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* add any spi devices connected here */
++ /* note that you can do direct SPI via spidev now */
++
++ // commented out example of an adafruit 1.8" TFT display
++ // from firmare/capes/cape-bone-adafruit-lcd-00A0.dts
++ // lcd@0 {
++ // #address-cells = <1>;
++ // #size-cells = <0>;
++ //
++ // compatible = "adafruit,tft-lcd-1.8-red", "sitronix,st7735";
++ // reg = <0>;
++ //
++ // spi-max-frequency = <8000000>;
++ // spi-cpol;
++ // spi-cpha;
++ //
++ // pinctrl-names = "default";
++ // pinctrl-0 = <&bone_adafruit_lcd_pins>;
++ //
++ // st7735-rst = <&gpio4 19 0>;
++ // st7735-dc = <&gpio4 21 0>;
++ // };
++ };
++ };
++};
+diff --git a/firmware/capes/BB-SPI1A1-00A0.dts b/firmware/capes/BB-SPI1A1-00A0.dts
+new file mode 100644
+index 0000000..ba98e73
+--- /dev/null
++++ b/firmware/capes/BB-SPI1A1-00A0.dts
+@@ -0,0 +1,81 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ *
++ * Virtual cape for SPI1 (ALT #1) on connector pins
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-SPI1";
++ version = "00A0";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.42", /* spi1_sclk */
++ "P9.29", /* spi1_d0 */
++ "P9.30", /* spi1_d1 */
++ "P9.20", /* spi1_cs0 */
++ /* the hardware ip uses */
++ "spi1";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ /* default state has all gpios released and mode set to uart1 */
++ bb_spi1_pins: pinmux_bb_spi1_pins {
++ pinctrl-single,pins = <
++ 0x164 0x34 /* eCAP0_in_PWM0_out.spi1_sclk, INPUT_PULLUP | MODE4 */
++ /* NOTE: P9.42 is connected to two pads */
++ // 0x1A0 0x27 /* set the other pad to gpio input */
++ 0x194 0x33 /* mcasp0_fsx.spi1_d0, INPUT_PULLUP | MODE3 */
++ 0x198 0x13 /* mcasp0_axr0.spi1_d1, OUTPUT_PULLUP | MODE3 */
++ 0x178 0x14 /* uart1_ctsn.spi1_cs0, OUTPUT_PULLUP | MODE4 */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&spi1>; /* spi1 is numbered correctly */
++ __overlay__ {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bb_spi1_pins>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* add any spi devices connected here */
++ /* note that you can do direct SPI via spidev now */
++
++ // commented out example of an adafruit 1.8" TFT display
++ // from firmare/capes/cape-bone-adafruit-lcd-00A0.dts
++ // lcd@0 {
++ // #address-cells = <1>;
++ // #size-cells = <0>;
++ //
++ // compatible = "adafruit,tft-lcd-1.8-red", "sitronix,st7735";
++ // reg = <0>;
++ //
++ // spi-max-frequency = <8000000>;
++ // spi-cpol;
++ // spi-cpha;
++ //
++ // pinctrl-names = "default";
++ // pinctrl-0 = <&bone_adafruit_lcd_pins>;
++ //
++ // st7735-rst = <&gpio4 19 0>;
++ // st7735-dc = <&gpio4 21 0>;
++ // };
++ };
++ };
++};
+diff --git a/firmware/capes/BB-UART1-00A0.dts b/firmware/capes/BB-UART1-00A0.dts
+new file mode 100644
+index 0000000..ce2b3d1
+--- /dev/null
++++ b/firmware/capes/BB-UART1-00A0.dts
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ *
++ * Virtual cape for UART1 on connector pins P9.24 P9.26
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-UART1";
++ version = "00A0";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.24", /* uart1_txd */
++ "P9.26", /* uart1_rxd */
++ /* the hardware ip uses */
++ "uart1";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ bb_uart1_pins: pinmux_bb_uart1_pins {
++ pinctrl-single,pins = <
++ 0x184 0x20 /* P9.24 uart1_txd.uart1_txd OUTPUT */
++ 0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd INPUT */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&uart2>; /* really uart1 */
++ __overlay__ {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bb_uart1_pins>;
++ };
++ };
++};
+diff --git a/firmware/capes/BB-UART2-00A0.dts b/firmware/capes/BB-UART2-00A0.dts
+new file mode 100644
+index 0000000..7534495
+--- /dev/null
++++ b/firmware/capes/BB-UART2-00A0.dts
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ *
++ * Virtual cape for UART2 on connector pins P9.21 P9.22
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-UART2";
++ version = "00A0";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.21", /* uart2_txd */
++ "P9.22", /* uart2_rxd */
++ /* the hardware ip uses */
++ "uart2";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ bb_uart2_pins: pinmux_bb_uart2_pins {
++ pinctrl-single,pins = <
++ 0x150 0x21 /* spi0_sclk.uart2_rxd | MODE1 */
++ 0x154 0x01 /* spi0_d0.uart2_txd | MODE1 */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&uart3>; /* really uart2 */
++ __overlay__ {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bb_uart2_pins>;
++ };
++ };
++};
+diff --git a/firmware/capes/BB-UART4-00A0.dts b/firmware/capes/BB-UART4-00A0.dts
+new file mode 100644
+index 0000000..cfd7947
+--- /dev/null
++++ b/firmware/capes/BB-UART4-00A0.dts
+@@ -0,0 +1,48 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ *
++ * Virtual cape for UART4 on connector pins P9.13 P9.11
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-UART4";
++ version = "00A0";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.13", /* uart4_txd */
++ "P9.11", /* uart4_rxd */
++ /* the hardware ip uses */
++ "uart4";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ bb_uart4_pins: pinmux_bb_uart4_pins {
++ pinctrl-single,pins = <
++ 0x070 0x26 /* gpmc_wait0.uart4_rxd | MODE6 */
++ 0x074 0x06 /* gpmc_wpn.uart4_txd | MODE6 */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&uart5>; /* really uart4 */
++ __overlay__ {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bb_uart4_pins>;
++ };
++ };
++};
+diff --git a/firmware/capes/BB-UART5-00A0.dts b/firmware/capes/BB-UART5-00A0.dts
+new file mode 100644
+index 0000000..e067068
+--- /dev/null
++++ b/firmware/capes/BB-UART5-00A0.dts
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ *
++ * Virtual cape for UART5 on connector pins P9.37 P8.38
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-UART5";
++ version = "00A0";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.37", /* uart5_txd */
++ "P8.38", /* uart5_rxd */
++ /* the hardware ip uses */
++ "uart5";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ bb_uart5_pins: pinmux_bb_uart5_pins {
++ pinctrl-single,pins = <
++ /* the uart pins */
++ 0x0C4 0x24 /* lcd_data9.uart5_rxd | MODE4 */
++ 0x0C0 0x04 /* lcd_data8.uart5_txd | MODE4 */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&uart6>; /* really uart5 */
++ __overlay__ {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bb_uart5_pins>;
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0414-capes-Add-TowerTech-TT3201-CAN-Bus-Cape-TT3201-001-3.patch b/patches/linux-3.8.13/0414-capes-Add-TowerTech-TT3201-CAN-Bus-Cape-TT3201-001-3.patch
new file mode 100644
index 0000000..df4b6f0
--- /dev/null
+++ b/patches/linux-3.8.13/0414-capes-Add-TowerTech-TT3201-CAN-Bus-Cape-TT3201-001-3.patch
@@ -0,0 +1,175 @@
+From: Alessandro Zummo <a.zummo@towertech.it>
+Date: Sat, 25 May 2013 19:18:07 +0200
+Subject: [PATCH] capes: Add TowerTech TT3201 CAN Bus Cape (TT3201-001, 3
+ channels) Rev 01 and 02
+
+--
+
+firmware/Makefile | 3 +-
+ firmware/capes/TT3201-001-01.dts | 134 ++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 136 insertions(+), 1 deletion(-)
+---
+ firmware/Makefile | 8 ++-
+ firmware/capes/TT3201-001-01.dts | 134 ++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 141 insertions(+), 1 deletion(-)
+ create mode 100644 firmware/capes/TT3201-001-01.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index b039188..6d896d2 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -177,7 +177,13 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ bone_pwm_P9_29-00A0.dtbo \
+ bone_pwm_P9_31-00A0.dtbo \
+ bone_pwm_P9_42-00A0.dtbo \
+- BB-BONE-PWMT-00A0.dtbo
++ BB-BONE-PWMT-00A0.dtbo \
++ BB-BONE-PRU-01-00A0.dtbo \
++ BB-BONE-PRU-02-00A0.dtbo \
++ BB-BONE-RST-00A0.dtbo \
++ BB-BONE-RST2-00A0.dtbo \
++ BB-BONE-CAM3-01-00A2.dtbo \
++ TT3201-001-01.dtbo
+
+ # the geiger cape
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE_GEIGER) += \
+diff --git a/firmware/capes/TT3201-001-01.dts b/firmware/capes/TT3201-001-01.dts
+new file mode 100644
+index 0000000..d1f950c
+--- /dev/null
++++ b/firmware/capes/TT3201-001-01.dts
+@@ -0,0 +1,134 @@
++/*
++* Copyright (C) 2013 Tower Technologies
++* Written by Alessandro Zummo <a.zummo@towertech.it>
++*
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License version 2 as
++* published by the Free Software Foundation.
++*/
++/dts-v1/;
++/plugin/;
++
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++ part-number = "TT3201-001";
++ version = "01";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.27", /* spi irq: gpio3_19 */
++ "P9.25", /* spi irq: gpio3_21 */
++ "P9.31", /* spi: spi1_sclk */
++ "P9.29", /* spi: spi1_d0 */
++ "P9.30", /* spi: spi1_d1 */
++ "P9.28", /* spi: spi1_cs0 */
++ "P9.42", /* spi: spi1_cs1 */
++ "P9.26", /* dcan1: dcan1_tx */
++ "P9.24", /* dcan1: dcan1_rx */
++ /* the hardware IP uses */
++ "gpio3_19",
++ "gpio3_21",
++ "spi1",
++ "dcan1";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ bone_tt3201_dcan1_pins: bone_tt3201_dcan1_pins {
++ pinctrl-single,pins = <
++ 0x180 0x02 /* uart1_rxd.d_can1_tx", OUTPUT | MODE2 */
++ 0x184 0x32 /* uart1_txd.d_can1_rx", INPUT_PULLUP | MODE2 */
++ >;
++ };
++
++ bone_tt3201_spi1_pins: pinmux_bone_tt3201_spi1_pins {
++ pinctrl-single,pins = <
++ 0x190 0x33 /* mcasp0_aclkx.spi1_sclk, RX_ENABLED | PULLUP | MODE3 */
++ 0x194 0x33 /* mcasp0_fsx.spi1_d0, RX_ENABLED | PULLUP | MODE3 */
++ 0x198 0x13 /* mcasp0_axr0.spi1_d1, OUTPUT_PULLUP | MODE3 */
++ 0x19c 0x13 /* mcasp0_ahclkr.spi1_cs0, OUTPUT_PULLUP | MODE3 */
++ 0x164 0x12 /* ecap0_in_pwm0_out.spi1_cs1, OUTPUT_PULLUP | MODE2 */
++ >;
++ };
++
++ bone_tt3201_mcp2515_0_pins: pinmux_bone_tt3201_0_mcp2515_pins {
++ pinctrl-single,pins = <
++ 0x1a4 0x37 /* mcasp0_fsr.gpio3_19, RX_ENABLED | PULLUP | MODE7 */
++ >;
++ };
++
++ bone_tt3201_mcp2515_1_pins: pinmux_bone_tt3201_1_mcp2515_pins {
++ pinctrl-single,pins = <
++ 0x1ac 0x37 /* mcasp0_ahclkx.gpio3_21, RX_ENABLED | PULLUP | MODE7 */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&spi1>;
++
++ __overlay__ {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bone_tt3201_spi1_pins>;
++
++ cs-gpios = <&gpio4 17 0>, <&gpio1 7 0>;
++
++ mcp2515@0 {
++
++ compatible = "microchip,mcp2515";
++ reg = <1>; /* cs1 */
++ mode = <0>;
++
++ spi-max-frequency = <10000000>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&bone_tt3201_mcp2515_1_pins>;
++
++ interrupt-parent = <&gpio4>;
++ interrupts = <21>;
++
++ mcp251x,oscillator-frequency = <16000000>;
++ mcp251x,irq-gpios = <&gpio4 21 0>;
++ mcp251x,stay-awake = <1>;
++ };
++
++ mcp2515@1 {
++
++ compatible = "microchip,mcp2515";
++ reg = <0>; /* cs0 */
++ mode = <0>;
++
++ spi-max-frequency = <10000000>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&bone_tt3201_mcp2515_0_pins>;
++
++ interrupt-parent = <&gpio4>;
++ interrupts = <19>;
++
++ mcp251x,oscillator-frequency = <16000000>;
++ mcp251x,irq-gpios = <&gpio4 19 0>;
++ mcp251x,stay-awake = <1>;
++ mcp251x,enable-clkout = <1>;
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&dcan1>;
++ __overlay__ {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bone_tt3201_dcan1_pins>;
++ };
++ };
++};
++
diff --git a/patches/linux-3.8.13/0415-capes-Add-commented-out-example-of-use-of-spi1_cs1.patch b/patches/linux-3.8.13/0415-capes-Add-commented-out-example-of-use-of-spi1_cs1.patch
new file mode 100644
index 0000000..5774cce
--- /dev/null
+++ b/patches/linux-3.8.13/0415-capes-Add-commented-out-example-of-use-of-spi1_cs1.patch
@@ -0,0 +1,28 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 30 May 2013 16:38:42 +0300
+Subject: [PATCH] capes: Add commented out example of use of spi1_cs1
+
+---
+ firmware/capes/BB-SPI1-00A0.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/firmware/capes/BB-SPI1-00A0.dts b/firmware/capes/BB-SPI1-00A0.dts
+index e26f346..1ead983 100644
+--- a/firmware/capes/BB-SPI1-00A0.dts
++++ b/firmware/capes/BB-SPI1-00A0.dts
+@@ -24,6 +24,7 @@
+ "P9.29", /* spi1_d0 */
+ "P9.30", /* spi1_d1 */
+ "P9.28", /* spi1_cs0 */
++ // "P9.42", /* spi1_cs1 */
+ /* the hardware ip uses */
+ "spi1";
+
+@@ -37,6 +38,7 @@
+ 0x194 0x33 /* mcasp0_fsx.spi1_d0, INPUT_PULLUP | MODE3 */
+ 0x198 0x13 /* mcasp0_axr0.spi1_d1, OUTPUT_PULLUP | MODE3 */
+ 0x19c 0x13 /* mcasp0_ahclkr.spi1_cs0, OUTPUT_PULLUP | MODE3 */
++ // 0x164 0x12 /* eCAP0_in_PWM0_out.spi1_cs1 OUTPUT_PULLUP | MODE2 */
+ >;
+ };
+ };
diff --git a/patches/linux-3.8.13/0416-cape-LCD4-Correct-key-active-polarity.patch b/patches/linux-3.8.13/0416-cape-LCD4-Correct-key-active-polarity.patch
new file mode 100644
index 0000000..f06193c
--- /dev/null
+++ b/patches/linux-3.8.13/0416-cape-LCD4-Correct-key-active-polarity.patch
@@ -0,0 +1,57 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 3 Jun 2013 15:59:04 +0300
+Subject: [PATCH] cape: LCD4: Correct key active polarity
+
+---
+ firmware/capes/BB-BONE-LCD4-01-00A1.dts | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/firmware/capes/BB-BONE-LCD4-01-00A1.dts b/firmware/capes/BB-BONE-LCD4-01-00A1.dts
+index 2744c27..bd3c2a8 100644
+--- a/firmware/capes/BB-BONE-LCD4-01-00A1.dts
++++ b/firmware/capes/BB-BONE-LCD4-01-00A1.dts
+@@ -152,7 +152,7 @@
+ debounce_interval = <50>;
+ linux,code = <105>;
+ label = "left";
+- gpios = <&gpio2 16 0x0>;
++ gpios = <&gpio2 16 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -160,7 +160,7 @@
+ debounce_interval = <50>;
+ linux,code = <106>;
+ label = "right";
+- gpios = <&gpio2 17 0x0>;
++ gpios = <&gpio2 17 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -168,7 +168,7 @@
+ debounce_interval = <50>;
+ linux,code = <103>;
+ label = "up";
+- gpios = <&gpio2 19 0x0>;
++ gpios = <&gpio2 19 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -176,7 +176,7 @@
+ debounce_interval = <50>;
+ linux,code = <108>;
+ label = "down";
+- gpios = <&gpio4 16 0x0>;
++ gpios = <&gpio4 16 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -184,7 +184,7 @@
+ debounce_interval = <50>;
+ linux,code = <28>;
+ label = "enter";
+- gpios = <&gpio1 15 0x0>;
++ gpios = <&gpio1 15 0x1>;
+ gpio-key,wakeup;
+ };
+ };
diff --git a/patches/linux-3.8.13/0417-capes-lcd3-Correct-button-polarity.patch b/patches/linux-3.8.13/0417-capes-lcd3-Correct-button-polarity.patch
new file mode 100644
index 0000000..c0a8091
--- /dev/null
+++ b/patches/linux-3.8.13/0417-capes-lcd3-Correct-button-polarity.patch
@@ -0,0 +1,107 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 3 Jun 2013 16:42:22 +0300
+Subject: [PATCH] capes: lcd3: Correct button polarity
+
+---
+ firmware/capes/cape-bone-lcd3-00A0.dts | 10 +++++-----
+ firmware/capes/cape-bone-lcd3-00A2.dts | 10 +++++-----
+ 2 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/firmware/capes/cape-bone-lcd3-00A0.dts b/firmware/capes/cape-bone-lcd3-00A0.dts
+index ca31bc3..1ac8462 100644
+--- a/firmware/capes/cape-bone-lcd3-00A0.dts
++++ b/firmware/capes/cape-bone-lcd3-00A0.dts
+@@ -140,7 +140,7 @@
+ debounce_interval = <50>;
+ linux,code = <105>;
+ label = "left";
+- gpios = <&gpio2 16 0x0>;
++ gpios = <&gpio2 16 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -148,7 +148,7 @@
+ debounce_interval = <50>;
+ linux,code = <106>;
+ label = "right";
+- gpios = <&gpio2 17 0x0>;
++ gpios = <&gpio2 17 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -156,7 +156,7 @@
+ debounce_interval = <50>;
+ linux,code = <103>;
+ label = "up";
+- gpios = <&gpio4 19 0x0>;
++ gpios = <&gpio4 19 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -164,7 +164,7 @@
+ debounce_interval = <50>;
+ linux,code = <108>;
+ label = "down";
+- gpios = <&gpio2 28 0x0>;
++ gpios = <&gpio2 28 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -172,7 +172,7 @@
+ debounce_interval = <50>;
+ linux,code = <28>;
+ label = "enter";
+- gpios = <&gpio1 7 0x0>;
++ gpios = <&gpio1 7 0x1>;
+ gpio-key,wakeup;
+ };
+ };
+diff --git a/firmware/capes/cape-bone-lcd3-00A2.dts b/firmware/capes/cape-bone-lcd3-00A2.dts
+index ce72c17..9c7bb17 100644
+--- a/firmware/capes/cape-bone-lcd3-00A2.dts
++++ b/firmware/capes/cape-bone-lcd3-00A2.dts
+@@ -151,7 +151,7 @@
+ debounce_interval = <50>;
+ linux,code = <105>;
+ label = "left";
+- gpios = <&gpio2 16 0x0>;
++ gpios = <&gpio2 16 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -159,7 +159,7 @@
+ debounce_interval = <50>;
+ linux,code = <106>;
+ label = "right";
+- gpios = <&gpio2 17 0x0>;
++ gpios = <&gpio2 17 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -167,7 +167,7 @@
+ debounce_interval = <50>;
+ linux,code = <103>;
+ label = "up";
+- gpios = <&gpio2 19 0x0>;
++ gpios = <&gpio2 19 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -175,7 +175,7 @@
+ debounce_interval = <50>;
+ linux,code = <108>;
+ label = "down";
+- gpios = <&gpio4 16 0x0>;
++ gpios = <&gpio4 16 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -183,7 +183,7 @@
+ debounce_interval = <50>;
+ linux,code = <28>;
+ label = "enter";
+- gpios = <&gpio1 3 0x0>;
++ gpios = <&gpio1 3 0x1>;
+ gpio-key,wakeup;
+ };
+ };
diff --git a/patches/linux-3.8.13/0418-cape-Fix-LCD7-keys-polarity.patch b/patches/linux-3.8.13/0418-cape-Fix-LCD7-keys-polarity.patch
new file mode 100644
index 0000000..24638eb
--- /dev/null
+++ b/patches/linux-3.8.13/0418-cape-Fix-LCD7-keys-polarity.patch
@@ -0,0 +1,157 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 3 Jun 2013 18:19:12 +0300
+Subject: [PATCH] cape: Fix LCD7 keys polarity
+
+---
+ firmware/capes/BB-BONE-LCD7-01-00A2.dts | 10 +++++-----
+ firmware/capes/BB-BONE-LCD7-01-00A3.dts | 10 +++++-----
+ firmware/capes/BB-BONE-LCD7-01-00A4.dts | 10 +++++-----
+ 3 files changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A2.dts b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
+index dc31da7..d1eac3b 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A2.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
+@@ -153,7 +153,7 @@
+ debounce_interval = <50>;
+ linux,code = <105>;
+ label = "left";
+- gpios = <&gpio2 16 0x0>;
++ gpios = <&gpio2 16 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -161,7 +161,7 @@
+ debounce_interval = <50>;
+ linux,code = <106>;
+ label = "right";
+- gpios = <&gpio2 17 0x0>;
++ gpios = <&gpio2 17 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -169,7 +169,7 @@
+ debounce_interval = <50>;
+ linux,code = <103>;
+ label = "up";
+- gpios = <&gpio2 19 0x0>;
++ gpios = <&gpio2 19 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -177,7 +177,7 @@
+ debounce_interval = <50>;
+ linux,code = <108>;
+ label = "down";
+- gpios = <&gpio4 16 0x0>;
++ gpios = <&gpio4 16 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -185,7 +185,7 @@
+ debounce_interval = <50>;
+ linux,code = <28>;
+ label = "enter";
+- gpios = <&gpio4 19 0x0>;
++ gpios = <&gpio4 19 0x1>;
+ gpio-key,wakeup;
+ };
+ };
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A3.dts b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+index 805a6c0..979fd73 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A3.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+@@ -153,7 +153,7 @@
+ debounce_interval = <50>;
+ linux,code = <105>;
+ label = "left";
+- gpios = <&gpio2 16 0x0>;
++ gpios = <&gpio2 16 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -161,7 +161,7 @@
+ debounce_interval = <50>;
+ linux,code = <106>;
+ label = "right";
+- gpios = <&gpio2 17 0x0>;
++ gpios = <&gpio2 17 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -169,7 +169,7 @@
+ debounce_interval = <50>;
+ linux,code = <103>;
+ label = "up";
+- gpios = <&gpio2 19 0x0>;
++ gpios = <&gpio2 19 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -177,7 +177,7 @@
+ debounce_interval = <50>;
+ linux,code = <108>;
+ label = "down";
+- gpios = <&gpio4 16 0x0>;
++ gpios = <&gpio4 16 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -185,7 +185,7 @@
+ debounce_interval = <50>;
+ linux,code = <28>;
+ label = "enter";
+- gpios = <&gpio1 3 0x0>;
++ gpios = <&gpio1 3 0x1>;
+ gpio-key,wakeup;
+ };
+ };
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A4.dts b/firmware/capes/BB-BONE-LCD7-01-00A4.dts
+index e0a0677..6f34b79 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A4.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A4.dts
+@@ -132,7 +132,7 @@
+ debounce_interval = <50>;
+ linux,code = <105>;
+ label = "left";
+- gpios = <&gpio2 16 0x0>;
++ gpios = <&gpio2 16 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -140,7 +140,7 @@
+ debounce_interval = <50>;
+ linux,code = <106>;
+ label = "right";
+- gpios = <&gpio2 17 0x0>;
++ gpios = <&gpio2 17 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -148,7 +148,7 @@
+ debounce_interval = <50>;
+ linux,code = <103>;
+ label = "up";
+- gpios = <&gpio2 19 0x0>;
++ gpios = <&gpio2 19 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -156,7 +156,7 @@
+ debounce_interval = <50>;
+ linux,code = <108>;
+ label = "down";
+- gpios = <&gpio4 16 0x0>;
++ gpios = <&gpio4 16 0x1>;
+ gpio-key,wakeup;
+ autorepeat;
+ };
+@@ -164,7 +164,7 @@
+ debounce_interval = <50>;
+ linux,code = <28>;
+ label = "enter";
+- gpios = <&gpio1 3 0x0>;
++ gpios = <&gpio1 3 0x1>;
+ gpio-key,wakeup;
+ };
+ };
diff --git a/patches/linux-3.8.13/0419-gpio-Introduce-GPIO-OF-helper.patch b/patches/linux-3.8.13/0419-gpio-Introduce-GPIO-OF-helper.patch
new file mode 100644
index 0000000..049064a
--- /dev/null
+++ b/patches/linux-3.8.13/0419-gpio-Introduce-GPIO-OF-helper.patch
@@ -0,0 +1,470 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Tue, 4 Jun 2013 16:23:59 +0300
+Subject: [PATCH] gpio: Introduce GPIO OF helper
+
+A gpio OF helper driver that allows configuration to be done via
+DT.
+---
+ drivers/gpio/Kconfig | 14 ++
+ drivers/gpio/Makefile | 1 +
+ drivers/gpio/gpio-of-helper.c | 414 +++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 429 insertions(+)
+ create mode 100644 drivers/gpio/gpio-of-helper.c
+
+diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
+index 682de75..6b5fc42 100644
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -79,6 +79,20 @@ config GPIO_SYSFS
+ Kernel drivers may also request that a particular GPIO be
+ exported to userspace; this can be useful when debugging.
+
++config GPIO_OF_HELPER
++ bool "GPIO OF helper device"
++ depends on OF_GPIO && EXPERIMENTAL
++ help
++ Say Y here to add an GPIO OF helper driver
++
++ Allows you specify a GPIO helper based on OF
++ which allows simple export of GPIO functionality
++ in user-space.
++
++ Features include, value set/get, direction control,
++ interrupt/value change poll support, event counting
++ and others.
++
+ config GPIO_GENERIC
+ tristate
+
+diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
+index c5aebd0..126e2cb 100644
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -5,6 +5,7 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
+ obj-$(CONFIG_GPIOLIB) += gpiolib.o devres.o
+ obj-$(CONFIG_OF_GPIO) += gpiolib-of.o
+ obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o
++obj-$(CONFIG_GPIO_OF_HELPER) += gpio-of-helper.o
+
+ # Device drivers. Generally keep list sorted alphabetically
+ obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
+diff --git a/drivers/gpio/gpio-of-helper.c b/drivers/gpio/gpio-of-helper.c
+new file mode 100644
+index 0000000..16a607f
+--- /dev/null
++++ b/drivers/gpio/gpio-of-helper.c
+@@ -0,0 +1,414 @@
++/*
++ * GPIO OF based helper
++ *
++ * A simple DT based driver to provide access to GPIO functionality
++ * to user-space via sysfs.
++ *
++ * Copyright (C) 2013 Pantelis Antoniou <panto@antoniou-consulting.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., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/timer.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/bitops.h>
++#include <linux/err.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_gpio.h>
++#include <linux/pinctrl/pinctrl.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/atomic.h>
++#include <linux/clk.h>
++#include <linux/interrupt.h>
++#include <linux/math64.h>
++#include <linux/atomic.h>
++#include <linux/idr.h>
++
++/* fwd decl. */
++struct gpio_of_helper_info;
++
++enum gpio_type {
++ GPIO_TYPE_INPUT = 0,
++ GPIO_TYPE_OUTPUT = 1,
++};
++
++struct gpio_of_entry {
++ int id;
++ struct gpio_of_helper_info *info;
++ struct device_node *node;
++ enum gpio_type type;
++ int gpio;
++ enum of_gpio_flags gpio_flags;
++ int irq;
++ const char *name;
++ atomic64_t counter;
++ unsigned int count_flags;
++#define COUNT_RISING_EDGE (1 << 0)
++#define COUNT_FALLING_EDGE (1 << 1)
++};
++
++struct gpio_of_helper_info {
++ struct platform_device *pdev;
++ struct idr idr;
++};
++
++static const struct of_device_id gpio_of_helper_of_match[] = {
++ {
++ .compatible = "gpio-of-helper",
++ },
++ { },
++};
++MODULE_DEVICE_TABLE(of, gpio_of_helper_of_match);
++
++static ssize_t gpio_of_helper_show_status(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct gpio_of_helper_info *info = platform_get_drvdata(pdev);
++ struct gpio_of_entry *entry;
++ char *p, *e;
++ int id, n;
++
++ p = buf;
++ e = p + PAGE_SIZE;
++ n = 0;
++ idr_for_each_entry(&info->idr, entry, id) {
++ switch (entry->type) {
++ case GPIO_TYPE_INPUT:
++ n = snprintf(p, e - p, "%2d %-24s %3d %-3s %llu\n",
++ entry->id, entry->name, entry->gpio, "IN",
++ (unsigned long long)
++ atomic64_read(&entry->counter));
++ break;
++ case GPIO_TYPE_OUTPUT:
++ n = snprintf(p, e - p, "%2d %-24s %3d %-3s\n",
++ entry->id, entry->name, entry->gpio, "OUT");
++ break;
++ }
++ p += n;
++ }
++
++ return p - buf;
++}
++
++static DEVICE_ATTR(status, S_IRUGO,
++ gpio_of_helper_show_status, NULL);
++
++static irqreturn_t gpio_of_helper_handler(int irq, void *ptr)
++{
++ struct gpio_of_entry *entry = ptr;
++
++ /* caution - low speed interfaces only! */
++ atomic64_inc(&entry->counter);
++
++ return IRQ_HANDLED;
++}
++
++static struct gpio_of_entry *
++gpio_of_entry_create(struct gpio_of_helper_info *info,
++ struct device_node *node)
++{
++ struct platform_device *pdev = info->pdev;
++ struct device *dev = &pdev->dev;
++ struct gpio_of_entry *entry;
++ int err, gpio, irq;
++ unsigned int req_flags, count_flags, irq_flags;
++ enum gpio_type type;
++ enum of_gpio_flags gpio_flags;
++ const char *name;
++
++ /* get the type of the node first */
++ if (of_property_read_bool(node, "input"))
++ type = GPIO_TYPE_INPUT;
++ else if (of_property_read_bool(node, "output"))
++ type = GPIO_TYPE_OUTPUT;
++ else {
++ dev_err(dev, "Not valid gpio node type\n");
++ err = -EINVAL;
++ goto err_bad_node;
++ }
++
++ /* get the name */
++ err = of_property_read_string(node, "gpio-name", &name);
++ if (err != 0) {
++ dev_err(dev, "Failed to get name property\n");
++ goto err_bad_node;
++ }
++
++ err = of_get_named_gpio_flags(node, "gpio", 0, &gpio_flags);
++ if (IS_ERR_VALUE(err)) {
++ dev_err(dev, "Failed to get gpio property of '%s'\n", name);
++ goto err_bad_node;
++ }
++ gpio = err;
++
++ req_flags = 0;
++ count_flags = 0;
++
++ /* set the request flags */
++ switch (type) {
++ case GPIO_TYPE_INPUT:
++ req_flags = GPIOF_DIR_IN | GPIOF_EXPORT;
++ if (of_property_read_bool(node, "count-falling-edge"))
++ count_flags |= COUNT_FALLING_EDGE;
++ if (of_property_read_bool(node, "count-rising-edge"))
++ count_flags |= COUNT_RISING_EDGE;
++ break;
++ case GPIO_TYPE_OUTPUT:
++ req_flags = GPIOF_DIR_OUT | GPIOF_EXPORT;
++ if (of_property_read_bool(node, "init-high"))
++ req_flags |= GPIOF_OUT_INIT_HIGH;
++ else if (of_property_read_bool(node, "init-low"))
++ req_flags |= GPIOF_OUT_INIT_LOW;
++ break;
++ }
++
++ /* request the gpio */
++ err = devm_gpio_request_one(dev, gpio, req_flags, name);
++ if (err != 0) {
++ dev_err(dev, "Failed to request gpio '%s'\n", name);
++ goto err_bad_node;
++ }
++
++ irq = -1;
++ irq_flags = 0;
++
++ /* counter mode requested - need an interrupt */
++ if (count_flags != 0) {
++ irq = gpio_to_irq(gpio);
++ if (IS_ERR_VALUE(irq)) {
++ dev_err(dev, "Failed to request gpio '%s'\n", name);
++ goto err_bad_node;
++ }
++
++ if (count_flags & COUNT_RISING_EDGE)
++ irq_flags |= IRQF_TRIGGER_RISING;
++ if (count_flags & COUNT_FALLING_EDGE)
++ irq_flags |= IRQF_TRIGGER_FALLING;
++ }
++
++ if (!idr_pre_get(&info->idr, GFP_KERNEL)) {
++ dev_err(dev, "Failed on idr_pre_get of '%s'\n", name);
++ err = -ENOMEM;
++ goto err_no_mem;
++ }
++
++ entry = devm_kzalloc(dev, sizeof(*entry), GFP_KERNEL);
++ if (entry == NULL) {
++ dev_err(dev, "Failed to allocate gpio entry of '%s'\n", name);
++ err = -ENOMEM;
++ goto err_no_mem;
++ }
++
++ entry->id = -1;
++ entry->info = info;
++ entry->node = of_node_get(node); /* get node reference */
++ entry->type = type;
++ entry->gpio = gpio;
++ entry->gpio_flags = gpio_flags;
++ entry->irq = irq;
++ entry->name = name;
++
++ /* interrupt enable is last thing done */
++ if (irq >= 0) {
++ atomic64_set(&entry->counter, 0);
++ entry->count_flags = count_flags;
++ err = devm_request_irq(dev, irq, gpio_of_helper_handler,
++ irq_flags, name, entry);
++ if (err != 0) {
++ dev_err(dev, "Failed to request irq of '%s'\n", name);
++ goto err_no_irq;
++ }
++ }
++
++ /* all done; insert */
++ err = idr_get_new(&info->idr, entry, &entry->id);
++ if (IS_ERR_VALUE(err)) {
++ dev_err(dev, "Failed to idr_get_new of '%s'\n", name);
++ goto err_fail_idr;
++ }
++
++ dev_info(dev, "Allocated GPIO id=%d\n", entry->id);
++
++ return entry;
++
++err_fail_idr:
++ /* nothing to do */
++err_no_irq:
++ /* release node ref */
++ of_node_put(node);
++ /* nothing else needs to be done, devres handles it */
++err_no_mem:
++err_bad_node:
++ return ERR_PTR(err);
++}
++
++static int gpio_of_entry_destroy(struct gpio_of_entry *entry)
++{
++ struct gpio_of_helper_info *info = entry->info;
++ struct platform_device *pdev = info->pdev;
++ struct device *dev = &pdev->dev;
++
++ dev_info(dev, "Destroying GPIO id=%d\n", entry->id);
++
++ /* remove from the IDR */
++ idr_remove(&info->idr, entry->id);
++
++ /* remove node ref */
++ of_node_put(entry->node);
++
++ /* free gpio */
++ devm_gpio_free(dev, entry->gpio);
++
++ /* gree irq */
++ if (entry->irq >= 0)
++ devm_free_irq(dev, entry->irq, entry);
++
++ /* and free */
++ devm_kfree(dev, entry);
++
++ return 0;
++}
++
++static int gpio_of_helper_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct gpio_of_helper_info *info;
++ struct gpio_of_entry *entry;
++ struct device_node *pnode = pdev->dev.of_node;
++ struct device_node *cnode;
++ struct pinctrl *pinctrl;
++ int err;
++
++ /* we only support OF */
++ if (pnode == NULL) {
++ dev_err(&pdev->dev, "No platform of_node!\n");
++ return -ENODEV;
++ }
++
++ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
++ if (IS_ERR(pinctrl)) {
++ /* special handling for probe defer */
++ if (PTR_ERR(pinctrl) == -EPROBE_DEFER)
++ return -EPROBE_DEFER;
++
++ dev_warn(&pdev->dev,
++ "pins are not configured from the driver\n");
++ }
++
++ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
++ if (info == NULL) {
++ dev_err(&pdev->dev, "Failed to allocate info\n");
++ err = -ENOMEM;
++ goto err_no_mem;
++ }
++ platform_set_drvdata(pdev, info);
++ info->pdev = pdev;
++
++ idr_init(&info->idr);
++
++ err = device_create_file(dev, &dev_attr_status);
++ if (err != 0) {
++ dev_err(dev, "Failed to create status sysfs attribute\n");
++ goto err_no_sysfs;
++ }
++
++ for_each_child_of_node(pnode, cnode) {
++
++ entry = gpio_of_entry_create(info, cnode);
++ if (IS_ERR_OR_NULL(entry)) {
++ dev_err(dev, "Failed to create gpio entry\n");
++ err = PTR_ERR(entry);
++ goto err_fail_entry;
++ }
++ }
++
++ dev_info(&pdev->dev, "ready\n");
++
++ return 0;
++err_fail_entry:
++ device_remove_file(&pdev->dev, &dev_attr_status);
++err_no_sysfs:
++err_no_mem:
++ return err;
++}
++
++static int gpio_of_helper_remove(struct platform_device *pdev)
++{
++ struct gpio_of_helper_info *info = platform_get_drvdata(pdev);
++ struct gpio_of_entry *entry;
++ int id;
++
++ dev_info(&pdev->dev, "removing\n");
++
++ device_remove_file(&pdev->dev, &dev_attr_status);
++
++ id = 0;
++ idr_for_each_entry(&info->idr, entry, id) {
++ /* destroy each and every one */
++ gpio_of_entry_destroy(entry);
++ }
++
++ return 0;
++}
++
++#ifdef CONFIG_PM
++#ifdef CONFIG_PM_RUNTIME
++static int gpio_of_helper_runtime_suspend(struct device *dev)
++{
++ /* place holder */
++ return 0;
++}
++
++static int gpio_of_helper_runtime_resume(struct device *dev)
++{
++ /* place holder */
++ return 0;
++}
++#endif /* CONFIG_PM_RUNTIME */
++
++static struct dev_pm_ops gpio_of_helper_pm_ops = {
++ SET_RUNTIME_PM_OPS(gpio_of_helper_runtime_suspend,
++ gpio_of_helper_runtime_resume, NULL)
++};
++#define GPIO_OF_HELPER_PM_OPS (&gpio_of_helper_pm_ops)
++#else
++#define GPIO_OF_HELPER_PM_OPS NULL
++#endif /* CONFIG_PM */
++
++struct platform_driver gpio_of_helper_driver = {
++ .probe = gpio_of_helper_probe,
++ .remove = gpio_of_helper_remove,
++ .driver = {
++ .name = "gpio-of-helper",
++ .owner = THIS_MODULE,
++ .pm = GPIO_OF_HELPER_PM_OPS,
++ .of_match_table = gpio_of_helper_of_match,
++ },
++};
++
++module_platform_driver(gpio_of_helper_driver);
++
++MODULE_AUTHOR("Pantelis Antoniou <panto@antoniou-consulting.com>");
++MODULE_DESCRIPTION("GPIO OF Helper driver");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:gpio-of-helper");
diff --git a/patches/linux-3.8.13/0420-capes-ADC-GPIO-helper-capes.patch b/patches/linux-3.8.13/0420-capes-ADC-GPIO-helper-capes.patch
new file mode 100644
index 0000000..538b89b
--- /dev/null
+++ b/patches/linux-3.8.13/0420-capes-ADC-GPIO-helper-capes.patch
@@ -0,0 +1,168 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Tue, 4 Jun 2013 16:25:24 +0300
+Subject: [PATCH] capes: ADC & GPIO helper capes
+
+---
+ firmware/Makefile | 8 +++++
+ firmware/capes/BB-ADC-00A0.dts | 59 +++++++++++++++++++++++++++++++
+ firmware/capes/BB-GPIOHELP-00A0.dts | 66 +++++++++++++++++++++++++++++++++++
+ 3 files changed, 133 insertions(+)
+ create mode 100644 firmware/capes/BB-ADC-00A0.dts
+ create mode 100644 firmware/capes/BB-GPIOHELP-00A0.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index 6d896d2..d82fb9b 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -217,6 +217,14 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ BB-SPI0-00A0.dtbo BB-SPI1-00A0.dtbo BB-SPI1A1-00A0.dtbo
+
++# the virtual peripheral capes for ADC
++fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
++ BB-ADC-00A0.dtbo
++
++# the virtual peripheral capes for GPIO
++fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
++ BB-GPIOHELP-00A0.dtbo
++
+ # PRU firmware
+ #fw-shipped-$(CONFIG_PRU_RPROC) += \
+ # prutest.bin
+diff --git a/firmware/capes/BB-ADC-00A0.dts b/firmware/capes/BB-ADC-00A0.dts
+new file mode 100644
+index 0000000..88f6fc6
+--- /dev/null
++++ b/firmware/capes/BB-ADC-00A0.dts
+@@ -0,0 +1,59 @@
++/*
++ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-ADC";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.39", /* AIN0 */
++ "P9.40", /* AIN1 */
++ "P9.37", /* AIN2 */
++ "P9.38", /* AIN3 */
++ "P9.33", /* AIN4 */
++ "P9.36", /* AIN5 */
++ "P9.35", /* AIN6 */
++ /* the hardware IP uses */
++ "tscadc";
++
++ fragment@0 {
++ target = <&ocp>;
++ __overlay__ {
++ /* avoid stupid warning */
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ tscadc {
++ compatible = "ti,ti-tscadc";
++ reg = <0x44e0d000 0x1000>;
++
++ interrupt-parent = <&intc>;
++ interrupts = <16>;
++ ti,hwmods = "adc_tsc";
++ status = "okay";
++
++ adc {
++ ti,adc-channels = <0 1 2 3 4 5 6 7>;
++ };
++ };
++
++ test_helper: helper {
++ compatible = "bone-iio-helper";
++ vsense-name = "AIN0", "AIN1", "AIN2", "AIN3", "AIN4", "AIN5", "AIN6", "AIN7";
++ vsense-scale = <100 100 100 100 100 100 100 100>;
++ status = "okay";
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/BB-GPIOHELP-00A0.dts b/firmware/capes/BB-GPIOHELP-00A0.dts
+new file mode 100644
+index 0000000..d7e0b4b
+--- /dev/null
++++ b/firmware/capes/BB-GPIOHELP-00A0.dts
+@@ -0,0 +1,66 @@
++/*
++* Copyright (C) 2013 Pantelis Antoniou <panto@antoniou-consulting.com>
++*
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License version 2 as
++* published by the Free Software Foundation.
++*/
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-BONE-PRU-01";
++ version = "00A0";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.27", /* gpio */
++ "P9.28", /* gpio */
++ /* the hardware IP uses */
++ "gpio3_19", "gpio3_17";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ gpio_helper_pins: pinmux_gpio_helper_pins {
++ pinctrl-single,pins = <
++ 0x1a4 0x0f /* P9 27 GPIO3_19: mcasp0_fsr.gpio3_19 | MODE7 | OUTPUT */
++ 0x19c 0x2f /* P9 28 SPI1_CS0: mcasp0_ahclkr.gpio3_17 | MODE7 | INPUT */
++ >;
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&ocp>;
++ __overlay__ {
++
++ gpio_helper {
++ compatible = "gpio-of-helper";
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&gpio_helper_pins>;
++
++ /* declare your gpios */
++ test_led {
++ gpio-name = "test_led";
++ gpio = <&gpio4 19 0x00>; /* gpio4 is gpio3 */
++ output;
++ init-high;
++ };
++
++ test_input {
++ gpio-name = "test_input";
++ gpio = <&gpio4 17 0x00>; /* gpio4 is gpio3 */
++ input;
++ count-rising-edge;
++ count-falling-edge;
++ };
++ };
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0421-capes-RS232-Cape-support-added.patch b/patches/linux-3.8.13/0421-capes-RS232-Cape-support-added.patch
new file mode 100644
index 0000000..d075339
--- /dev/null
+++ b/patches/linux-3.8.13/0421-capes-RS232-Cape-support-added.patch
@@ -0,0 +1,81 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Fri, 14 Jun 2013 19:06:09 +0300
+Subject: [PATCH] capes: RS232 Cape support added
+
+Add support for the default configuration of the cape at UART2.
+---
+ firmware/Makefile | 3 +-
+ firmware/capes/BB-BONE-SERL-03-00A1.dts | 50 +++++++++++++++++++++++++++++++
+ 2 files changed, 52 insertions(+), 1 deletion(-)
+ create mode 100644 firmware/capes/BB-BONE-SERL-03-00A1.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index d82fb9b..0727ec9 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -183,7 +183,8 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ BB-BONE-RST-00A0.dtbo \
+ BB-BONE-RST2-00A0.dtbo \
+ BB-BONE-CAM3-01-00A2.dtbo \
+- TT3201-001-01.dtbo
++ TT3201-001-01.dtbo \
++ BB-BONE-SERL-03-00A1.dtbo
+
+ # the geiger cape
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE_GEIGER) += \
+diff --git a/firmware/capes/BB-BONE-SERL-03-00A1.dts b/firmware/capes/BB-BONE-SERL-03-00A1.dts
+new file mode 100644
+index 0000000..47d9890
+--- /dev/null
++++ b/firmware/capes/BB-BONE-SERL-03-00A1.dts
+@@ -0,0 +1,50 @@
++/*
++ * Copyright (C) 2013 CircuitCo
++ *
++ * RS232 cape for the default configuration on UART2
++ * Use one of the BB-UART* examples if you modify the default
++ * configuration.
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-BONE-SERL-03";
++ version = "00A1";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.21", /* uart2_txd */
++ "P9.22", /* uart2_rxd */
++ /* the hardware ip uses */
++ "uart2";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ bb_uart2_pins: pinmux_bb_uart2_pins {
++ pinctrl-single,pins = <
++ 0x150 0x21 /* spi0_sclk.uart2_rxd | MODE1 */
++ 0x154 0x01 /* spi0_d0.uart2_txd | MODE1 */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&uart3>; /* really uart2 */
++ __overlay__ {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bb_uart2_pins>;
++ };
++ };
++};
diff --git a/patches/linux-3.8.4/0356-uio-uio_pruss-port-to-AM33xx.patch b/patches/linux-3.8.13/0422-uio-uio_pruss-port-to-AM33xx.patch
index aa081fc..aa081fc 100644
--- a/patches/linux-3.8.4/0356-uio-uio_pruss-port-to-AM33xx.patch
+++ b/patches/linux-3.8.13/0422-uio-uio_pruss-port-to-AM33xx.patch
diff --git a/patches/linux-3.8.4/0357-ARM-omap-add-DT-support-for-deasserting-hardware-res.patch b/patches/linux-3.8.13/0423-ARM-omap-add-DT-support-for-deasserting-hardware-res.patch
index 700d47a..700d47a 100644
--- a/patches/linux-3.8.4/0357-ARM-omap-add-DT-support-for-deasserting-hardware-res.patch
+++ b/patches/linux-3.8.13/0423-ARM-omap-add-DT-support-for-deasserting-hardware-res.patch
diff --git a/patches/linux-3.8.4/0358-ARM-dts-AM33xx-PRUSS-support.patch b/patches/linux-3.8.13/0424-ARM-dts-AM33xx-PRUSS-support.patch
index bdb7e7d..144f5d8 100644
--- a/patches/linux-3.8.4/0358-ARM-dts-AM33xx-PRUSS-support.patch
+++ b/patches/linux-3.8.13/0424-ARM-dts-AM33xx-PRUSS-support.patch
@@ -11,7 +11,7 @@ Signed-off-by: Matt Ranostay <mranostay@gmail.com>
1 file changed, 11 insertions(+)
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
-index 797f421..29ab2fd 100644
+index 9bf0d2c..5d4f913 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -347,6 +347,17 @@
diff --git a/patches/linux-3.8.13/0425-uio_pruss-add-dt-support-replicape-00A1.patch b/patches/linux-3.8.13/0425-uio_pruss-add-dt-support-replicape-00A1.patch
new file mode 100644
index 0000000..7cdb706
--- /dev/null
+++ b/patches/linux-3.8.13/0425-uio_pruss-add-dt-support-replicape-00A1.patch
@@ -0,0 +1,75 @@
+From: Elias Bakken <elias.bakken@gmail.com>
+Date: Thu, 4 Apr 2013 11:38:53 -0500
+Subject: [PATCH] uio_pruss: add dt support (replicape-00A1)
+
+Signed-off-by: Elias Bakken <elias.bakken@gmail.com>
+Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
+---
+ drivers/uio/uio_pruss.c | 40 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c
+index 563a337..6f49ea1 100644
+--- a/drivers/uio/uio_pruss.c
++++ b/drivers/uio/uio_pruss.c
+@@ -19,6 +19,7 @@
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/platform_device.h>
++#include <linux/of_gpio.h>
+ #include <linux/uio_driver.h>
+ #include <linux/platform_data/uio_pruss.h>
+ #include <linux/io.h>
+@@ -132,6 +133,10 @@ static int pruss_probe(struct platform_device *dev)
+ struct uio_pruss_pdata *pdata = dev->dev.platform_data;
+ struct pinctrl *pinctrl;
+
++ int count;
++ struct device_node *child;
++ const char *pin_name;
++
+ gdev = kzalloc(sizeof(struct uio_pruss_dev), GFP_KERNEL);
+ if (!gdev)
+ return -ENOMEM;
+@@ -175,6 +180,41 @@ static int pruss_probe(struct platform_device *dev)
+ if (IS_ERR(pinctrl))
+ dev_warn(&dev->dev,
+ "pins are not configured from the driver\n");
++ else{
++ count = of_get_child_count(dev->dev.of_node);
++ if (!count){
++ dev_info(&dev->dev, "No children\n");
++ return -ENODEV;
++ }
++ // Run through all children. They have lables for easy reference.
++ for_each_child_of_node(dev->dev.of_node, child){
++ enum of_gpio_flags flags;
++ unsigned gpio;
++
++ count = of_gpio_count(child);
++
++ ret = of_property_count_strings(child, "pin-names");
++ if (ret < 0) {
++ dev_err(&dev->dev, "Failed to get pin-names\n");
++ continue;
++ }
++ if(count != ret){
++ dev_err(&dev->dev, "The number of gpios (%d) does not match"\
++ " the number of pin names (%d)\n", count, ret);
++ continue;
++ }
++
++ dev_dbg(&dev->dev, "Child has %u gpios\n", count);
++ for(cnt=0; cnt<count; cnt++){
++ ret = of_property_read_string_index(child,
++ "pin-names", cnt, &pin_name);
++ if (ret != 0)
++ dev_err(&dev->dev, "Error on pin-name #%d\n", cnt);
++ gpio = of_get_gpio_flags(child, cnt, &flags);
++ ret = devm_gpio_request_one(&dev->dev, gpio, flags, pin_name);
++ }
++ }
++ }
+
+ regs_prussio = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!regs_prussio) {
diff --git a/patches/linux-3.8.13/0426-pruss-Make-sure-it-works-when-no-child-nodes-are-pre.patch b/patches/linux-3.8.13/0426-pruss-Make-sure-it-works-when-no-child-nodes-are-pre.patch
new file mode 100644
index 0000000..55e1baa
--- /dev/null
+++ b/patches/linux-3.8.13/0426-pruss-Make-sure-it-works-when-no-child-nodes-are-pre.patch
@@ -0,0 +1,79 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 15 May 2013 20:44:34 +0300
+Subject: [PATCH] pruss: Make sure it works when no child nodes are present
+
+Pruss shouldn't fail when no child nodes are present.
+---
+ drivers/uio/uio_pruss.c | 58 +++++++++++++++++++++--------------------------
+ 1 file changed, 26 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c
+index 6f49ea1..5de4f11 100644
+--- a/drivers/uio/uio_pruss.c
++++ b/drivers/uio/uio_pruss.c
+@@ -180,39 +180,33 @@ static int pruss_probe(struct platform_device *dev)
+ if (IS_ERR(pinctrl))
+ dev_warn(&dev->dev,
+ "pins are not configured from the driver\n");
+- else{
+- count = of_get_child_count(dev->dev.of_node);
+- if (!count){
+- dev_info(&dev->dev, "No children\n");
+- return -ENODEV;
++
++ // Run through all children. They have lables for easy reference.
++ for_each_child_of_node(dev->dev.of_node, child) {
++ enum of_gpio_flags flags;
++ unsigned gpio;
++
++ count = of_gpio_count(child);
++
++ ret = of_property_count_strings(child, "pin-names");
++ if (ret < 0) {
++ dev_err(&dev->dev, "Failed to get pin-names\n");
++ continue;
++ }
++ if(count != ret){
++ dev_err(&dev->dev, "The number of gpios (%d) does not match"\
++ " the number of pin names (%d)\n", count, ret);
++ continue;
+ }
+- // Run through all children. They have lables for easy reference.
+- for_each_child_of_node(dev->dev.of_node, child){
+- enum of_gpio_flags flags;
+- unsigned gpio;
+-
+- count = of_gpio_count(child);
+-
+- ret = of_property_count_strings(child, "pin-names");
+- if (ret < 0) {
+- dev_err(&dev->dev, "Failed to get pin-names\n");
+- continue;
+- }
+- if(count != ret){
+- dev_err(&dev->dev, "The number of gpios (%d) does not match"\
+- " the number of pin names (%d)\n", count, ret);
+- continue;
+- }
+-
+- dev_dbg(&dev->dev, "Child has %u gpios\n", count);
+- for(cnt=0; cnt<count; cnt++){
+- ret = of_property_read_string_index(child,
+- "pin-names", cnt, &pin_name);
+- if (ret != 0)
+- dev_err(&dev->dev, "Error on pin-name #%d\n", cnt);
+- gpio = of_get_gpio_flags(child, cnt, &flags);
+- ret = devm_gpio_request_one(&dev->dev, gpio, flags, pin_name);
+- }
++
++ dev_dbg(&dev->dev, "Child has %u gpios\n", count);
++ for(cnt=0; cnt<count; cnt++){
++ ret = of_property_read_string_index(child,
++ "pin-names", cnt, &pin_name);
++ if (ret != 0)
++ dev_err(&dev->dev, "Error on pin-name #%d\n", cnt);
++ gpio = of_get_gpio_flags(child, cnt, &flags);
++ ret = devm_gpio_request_one(&dev->dev, gpio, flags, pin_name);
+ }
+ }
+
diff --git a/patches/linux-3.8.13/0427-am33xx-pru-Very-simple-led-cape-via-GPO-of-the-PRU.patch b/patches/linux-3.8.13/0427-am33xx-pru-Very-simple-led-cape-via-GPO-of-the-PRU.patch
new file mode 100644
index 0000000..53091f3
--- /dev/null
+++ b/patches/linux-3.8.13/0427-am33xx-pru-Very-simple-led-cape-via-GPO-of-the-PRU.patch
@@ -0,0 +1,76 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Tue, 14 May 2013 14:18:47 +0300
+Subject: [PATCH] am33xx: pru: Very simple led cape via GPO of the PRU
+
+Simple cape definition for a cape that works on all beaglebones
+---
+ firmware/Makefile | 3 ++-
+ firmware/capes/BB-BONE-PRU-01-00A0.dts | 45 ++++++++++++++++++++++++++++++++
+ 2 files changed, 47 insertions(+), 1 deletion(-)
+ create mode 100644 firmware/capes/BB-BONE-PRU-01-00A0.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index 0727ec9..1a353ce 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -184,7 +184,8 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ BB-BONE-RST2-00A0.dtbo \
+ BB-BONE-CAM3-01-00A2.dtbo \
+ TT3201-001-01.dtbo \
+- BB-BONE-SERL-03-00A1.dtbo
++ BB-BONE-SERL-03-00A1.dtbo \
++ BB-BONE-PRU-01-00A0.dtbo
+
+ # the geiger cape
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE_GEIGER) += \
+diff --git a/firmware/capes/BB-BONE-PRU-01-00A0.dts b/firmware/capes/BB-BONE-PRU-01-00A0.dts
+new file mode 100644
+index 0000000..29ab671
+--- /dev/null
++++ b/firmware/capes/BB-BONE-PRU-01-00A0.dts
+@@ -0,0 +1,45 @@
++/*
++* Copyright (C) 2013 Matt Ranostay <mranostay@gmail.com>
++*
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License version 2 as
++* published by the Free Software Foundation.
++*/
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-BONE-PRU-01";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ pru_gpio_pins: pinmux_pru_gpio_pins {
++ pinctrl-single,pins = <
++ 0x1a4 0x0f /* P9 27 GPIO3_19: mcasp0_fsr.gpio3[19] | MODE7 | OUTPUT */
++ >;
++ };
++
++ pru_pru_pins: pinmux_pru_pru_pins {
++ pinctrl-single,pins = <
++ 0x1a4 0x25 /* mcasp0_fsr.pr1_pru0_pru_r30_5, MODE5 | OUTPUT | PRU */
++ >;
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&pruss>;
++ __overlay__ {
++ status = "okay";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&pru_pru_pins>;
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0428-PRU-remote-proc-wip.patch b/patches/linux-3.8.13/0428-PRU-remote-proc-wip.patch
new file mode 100644
index 0000000..45f00be
--- /dev/null
+++ b/patches/linux-3.8.13/0428-PRU-remote-proc-wip.patch
@@ -0,0 +1,355 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 16 May 2013 10:37:39 +0300
+Subject: [PATCH] PRU remote proc wip
+
+---
+ drivers/remoteproc/Kconfig | 11 ++
+ drivers/remoteproc/Makefile | 1 +
+ drivers/remoteproc/pru_rproc.c | 240 ++++++++++++++++++++++++++++++++
+ firmware/capes/BB-BONE-PRU-02-00A0.dts | 61 ++++++++
+ 4 files changed, 313 insertions(+)
+ create mode 100644 drivers/remoteproc/pru_rproc.c
+ create mode 100644 firmware/capes/BB-BONE-PRU-02-00A0.dts
+
+diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
+index a936efb..690097b 100644
+--- a/drivers/remoteproc/Kconfig
++++ b/drivers/remoteproc/Kconfig
+@@ -41,4 +41,15 @@ config STE_MODEM_RPROC
+ This can be either built-in or a loadable module.
+ If unsure say N.
+
++config PRU_RPROC
++ tristate "AM33xx PRU remoteproc support"
++ depends on EXPERIMENTAL
++ depends on HAS_DMA && SOC_AM33XX
++ select REMOTEPROC
++ default n
++ help
++ Say y or m here to support AM33xx PRU
++ This can be either built-in or a loadable module.
++ If unsure say N.
++
+ endmenu
+diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
+index 391b651..9042660 100644
+--- a/drivers/remoteproc/Makefile
++++ b/drivers/remoteproc/Makefile
+@@ -9,3 +9,4 @@ remoteproc-y += remoteproc_virtio.o
+ remoteproc-y += remoteproc_elf_loader.o
+ obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o
+ obj-$(CONFIG_STE_MODEM_RPROC) += ste_modem_rproc.o
++obj-$(CONFIG_PRU_RPROC) += pru_rproc.o
+diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c
+new file mode 100644
+index 0000000..113ad80
+--- /dev/null
++++ b/drivers/remoteproc/pru_rproc.c
+@@ -0,0 +1,240 @@
++/*
++ * PRU driver for TI's AM33xx series of SoCs
++ *
++ * Copyright (C) 2013 Pantelis Antoniou <panto@antoniou-consulting.com>
++ *
++ * This file is licensed under the terms of the GNU General Public License
++ * version 2. This program is licensed "as is" without any warranty of any
++ * kind, whether express or implied.
++ */
++
++#include <linux/module.h>
++#include <linux/err.h>
++#include <linux/dma-mapping.h>
++#include <linux/remoteproc.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/genalloc.h>
++#include <linux/of.h>
++#include <linux/of_platform.h>
++#include <linux/of_address.h>
++#include <linux/of_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/io.h>
++
++#include "remoteproc_internal.h"
++
++/* PRU control structure */
++struct pruproc {
++ struct rproc *rproc;
++ struct platform_device *pdev;
++ struct resource_table *table;
++ void __iomem *vaddr;
++ dma_addr_t paddr;
++};
++
++/* Loads the firmware to shared memory. */
++static int pruproc_load_segments(struct rproc *rproc, const struct firmware *fw)
++{
++ struct pruproc *pruproc = rproc->priv;
++
++ dev_dbg(&pruproc->pdev->dev, "%s\n", __func__);
++
++ return 0;
++}
++
++/* Find the resource table inside the remote processor's firmware. */
++static struct resource_table *
++pruproc_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
++ int *tablesz)
++{
++ struct pruproc *pruproc = rproc->priv;
++ struct resource_table *table;
++
++ table = devm_kzalloc(&pruproc->pdev->dev, sizeof(*table), GFP_KERNEL);
++
++ dev_dbg(&pruproc->pdev->dev, "%s\n", __func__);
++
++ return table;
++}
++
++static int pruproc_sanity_check(struct rproc *rproc, const struct firmware *fw)
++{
++ return 0;
++}
++
++/* PRU firmware handler operations */
++const struct rproc_fw_ops pruproc_fw_ops = {
++ .find_rsc_table = pruproc_find_rsc_table,
++ .load = pruproc_load_segments,
++ .sanity_check = pruproc_sanity_check,
++};
++
++/* Kick the modem with specified notification id */
++static void pruproc_kick(struct rproc *rproc, int vqid)
++{
++ struct pruproc *pruproc = rproc->priv;
++
++ dev_dbg(&pruproc->pdev->dev, "kick vqid:%d\n", vqid);
++}
++
++/* Start the PRU modem */
++static int pruproc_start(struct rproc *rproc)
++{
++ struct pruproc *pruproc = rproc->priv;
++
++ dev_dbg(&pruproc->pdev->dev, "start pru\n");
++
++ return 0;
++}
++
++/* Stop the PRU modem */
++static int pruproc_stop(struct rproc *rproc)
++{
++ struct pruproc *pruproc = rproc->priv;
++
++ dev_dbg(&pruproc->pdev->dev, "stop PRU\n");
++
++ return 0;
++}
++
++static struct rproc_ops pruproc_ops = {
++ .start = pruproc_start,
++ .stop = pruproc_stop,
++ .kick = pruproc_kick,
++};
++
++/* PRU is unregistered */
++static int pruproc_remove(struct platform_device *pdev)
++{
++ struct pruproc *pruproc = platform_get_drvdata(pdev);
++
++ dev_dbg(&pdev->dev, "remove pru\n");
++
++ /* Unregister as remoteproc device */
++ rproc_del(pruproc->rproc);
++ rproc_put(pruproc->rproc);
++
++ platform_set_drvdata(pdev, NULL);
++
++ return 0;
++}
++
++/* Handle probe of a modem device */
++static int pruproc_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct pruproc *pruproc;
++ struct rproc *rproc;
++ struct resource *res;
++ struct pinctrl *pinctrl;
++ int err;
++
++ dev_dbg(dev, "probe pru\n");
++
++ /* get pinctrl */
++ pinctrl = devm_pinctrl_get_select_default(dev);
++ if (IS_ERR(pinctrl)) {
++ err = PTR_ERR(pinctrl);
++ /* deferring probe */
++ if (err == -EPROBE_DEFER) {
++ dev_warn(dev, "deferring proble\n");
++ return err;
++ }
++ dev_warn(dev, "pins are not configured from the driver\n");
++ }
++
++ /* we only work on OF */
++ if (dev->of_node == NULL) {
++ dev_err(dev, "Only OF configuration supported\n");
++ err = -ENODEV;
++ goto fail_of_node;
++ }
++
++ pm_runtime_enable(dev);
++ err = pm_runtime_get_sync(dev);
++ if (err != 0) {
++ dev_err(dev, "pm_runtime_get_sync failed\n");
++ goto fail_pm_runtime_get_sync;
++ }
++
++ err = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
++ if (err) {
++ dev_err(dev, "dma_set_coherent_mask: %d\n", err);
++ goto fail_dma_set_coherent_mask;
++ }
++
++ rproc = rproc_alloc(dev, pdev->name, &pruproc_ops,
++ "prutest.bin", sizeof(*pruproc));
++ if (!rproc) {
++ dev_err(dev, "rproc_alloc failed\n");
++ err = -ENOMEM;
++ goto fail_rproc_alloc;
++ }
++
++ pruproc = rproc->priv;
++ pruproc->pdev = pdev;
++ pruproc->rproc = rproc;
++
++ platform_set_drvdata(pdev, pruproc);
++
++ /* Set the PRU specific firmware handler */
++ rproc->fw_ops = &pruproc_fw_ops;
++
++ /* Register as a remoteproc device */
++ err = rproc_add(rproc);
++ if (err) {
++ dev_err(dev, "rproc_add failed\n");
++ goto fail_rproc_add;
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (res == NULL) {
++ dev_err(dev, "failed to parse MEM resource\n");
++ goto fail_platform_get_resource;
++ }
++
++ pruproc->vaddr = devm_ioremap(dev, res->start, resource_size(res));
++ if (pruproc->vaddr == NULL) {
++ dev_err(dev, "failed to parse MEM resource\n");
++ goto fail_devm_ioremap;
++ }
++
++ dev_info(dev, "Loaded OK\n");
++
++ return 0;
++fail_devm_ioremap:
++fail_platform_get_resource:
++ rproc_del(rproc);
++fail_rproc_add:
++ platform_set_drvdata(pdev, NULL);
++ rproc_put(rproc);
++fail_rproc_alloc:
++fail_dma_set_coherent_mask:
++fail_of_node:
++ pm_runtime_disable(dev);
++fail_pm_runtime_get_sync:
++ return err;
++}
++
++static const struct of_device_id pru_rproc_dt_ids[] = {
++ { .compatible = "ti,pru-rproc", .data = NULL, },
++ {},
++};
++MODULE_DEVICE_TABLE(of, pruss_dt_ids);
++
++static struct platform_driver pruproc_driver = {
++ .driver = {
++ .name = "pru-rproc",
++ .owner = THIS_MODULE,
++ .of_match_table = pru_rproc_dt_ids,
++ },
++ .probe = pruproc_probe,
++ .remove = pruproc_remove,
++};
++
++module_platform_driver(pruproc_driver);
++MODULE_LICENSE("GPL v2");
++MODULE_DESCRIPTION("PRU Remote Processor control driver");
++MODULE_AUTHOR("Pantelis Antoniou <panto@antoniou-consulting.com>");
+diff --git a/firmware/capes/BB-BONE-PRU-02-00A0.dts b/firmware/capes/BB-BONE-PRU-02-00A0.dts
+new file mode 100644
+index 0000000..ddb63f7
+--- /dev/null
++++ b/firmware/capes/BB-BONE-PRU-02-00A0.dts
+@@ -0,0 +1,61 @@
++/*
++* Copyright (C) 2013 Matt Ranostay <mranostay@gmail.com>
++*
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License version 2 as
++* published by the Free Software Foundation.
++*/
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-BONE-PRU-01";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ pru_gpio_pins: pinmux_pru_gpio_pins {
++ pinctrl-single,pins = <
++ 0x1a4 0x0f /* P9 27 GPIO3_19: mcasp0_fsr.gpio3[19] | MODE7 | OUTPUT */
++ >;
++ };
++
++ pru_pru_pins: pinmux_pru_pru_pins {
++ pinctrl-single,pins = <
++ 0x1a4 0x25 /* mcasp0_fsr.pr1_pru0_pru_r30_5, MODE5 | OUTPUT | PRU */
++ >;
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&ocp>;
++
++ __overlay__ {
++
++ /* avoid stupid warning */
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ prurproc {
++ compatible = "ti,pru-rproc";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&pru_pru_pins>;
++
++ ti,hwmods = "pruss";
++ ti,deassert-hard-reset = "pruss", "pruss";
++ reg = <0x4a300000 0x080000>;
++ ti,pintc-offset = <0x20000>;
++ interrupt-parent = <&intc>;
++ status = "okay";
++ interrupts = <20 21 22 23 24 25 26 27>;
++ };
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0429-Add-sysfs-entry-for-DDR-sync.patch b/patches/linux-3.8.13/0429-Add-sysfs-entry-for-DDR-sync.patch
new file mode 100644
index 0000000..1e32fa1
--- /dev/null
+++ b/patches/linux-3.8.13/0429-Add-sysfs-entry-for-DDR-sync.patch
@@ -0,0 +1,64 @@
+From: Chris Micali <chrismicali@gmail.com>
+Date: Mon, 20 May 2013 13:10:58 -0400
+Subject: [PATCH] Add sysfs entry for DDR sync
+
+---
+ drivers/uio/uio_pruss.c | 31 +++++++++++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c
+index 5de4f11..54f4781 100644
+--- a/drivers/uio/uio_pruss.c
++++ b/drivers/uio/uio_pruss.c
+@@ -78,6 +78,32 @@ struct uio_pruss_dev {
+ struct gen_pool *sram_pool;
+ };
+
++static ssize_t store_sync_ddr(struct device *dev, struct device_attribute *attr, char *buf, size_t count) {
++ struct uio_pruss_dev *gdev;
++ gdev = dev_get_drvdata(dev);
++ dma_sync_single_for_cpu(dev, gdev->ddr_paddr, extram_pool_sz, DMA_FROM_DEVICE);
++ return count;
++}
++static DEVICE_ATTR(sync_ddr, S_IWUSR, NULL, store_sync_ddr);
++
++static const struct attribute *uio_sysfs_attrs[] = {
++ &dev_attr_sync_ddr.attr,
++ NULL
++};
++
++static int uio_sysfs_init(struct platform_device *pdev) {
++ int error;
++ error = sysfs_create_files(&pdev->dev.kobj, uio_sysfs_attrs);
++ if (error) {
++ dev_err(&pdev->dev, "Failed to create sysfs entries");
++ }
++ return error;
++}
++
++static void uio_sysfs_cleanup(struct platform_device *pdev) {
++ sysfs_remove_files(&pdev->dev.kobj, uio_sysfs_attrs);
++}
++
+ static irqreturn_t pruss_handler(int irq, struct uio_info *info)
+ {
+ struct uio_pruss_dev *gdev = info->priv;
+@@ -103,6 +129,8 @@ static void pruss_cleanup(struct platform_device *dev,
+ int cnt;
+ struct uio_info *p = gdev->info;
+
++ uio_sysfs_cleanup(dev);
++
+ for (cnt = 0; cnt < MAX_PRUSS_EVT; cnt++, p++) {
+ uio_unregister_device(p);
+ kfree(p->name);
+@@ -295,6 +323,9 @@ static int pruss_probe(struct platform_device *dev)
+ goto out_free;
+ }
+
++ if (uio_sysfs_init(dev))
++ goto out_free;
++
+ platform_set_drvdata(dev, gdev);
+ return 0;
+
diff --git a/patches/linux-3.8.13/0430-virtio-ring-Introduce-dma-mapping-for-real-devices.patch b/patches/linux-3.8.13/0430-virtio-ring-Introduce-dma-mapping-for-real-devices.patch
new file mode 100644
index 0000000..5799e7c
--- /dev/null
+++ b/patches/linux-3.8.13/0430-virtio-ring-Introduce-dma-mapping-for-real-devices.patch
@@ -0,0 +1,227 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Tue, 2 Jul 2013 22:13:27 +0300
+Subject: [PATCH] virtio: ring: Introduce dma mapping for real devices
+
+Real hardware devices need to use the dma mapping functions to work.
+Blindly calling sg_phys and expecting it to work on any address
+is a fool's errand.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/virtio/virtio_ring.c | 120 +++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 112 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
+index ffd7e7d..1c7ad01 100644
+--- a/drivers/virtio/virtio_ring.c
++++ b/drivers/virtio/virtio_ring.c
+@@ -19,6 +19,8 @@
+ #include <linux/virtio.h>
+ #include <linux/virtio_ring.h>
+ #include <linux/virtio_config.h>
++#include <linux/virtio_ids.h>
++#include <linux/dma-mapping.h>
+ #include <linux/device.h>
+ #include <linux/slab.h>
+ #include <linux/module.h>
+@@ -74,6 +76,13 @@
+ #define END_USE(vq)
+ #endif
+
++struct vring_sg {
++ struct scatterlist sg;
++ void *va;
++ dma_addr_t dma;
++ enum dma_data_direction dir;
++};
++
+ struct vring_virtqueue
+ {
+ struct virtqueue vq;
+@@ -113,12 +122,83 @@ struct vring_virtqueue
+ ktime_t last_add_time;
+ #endif
+
++ /* copy of the scatter list */
++ struct vring_sg *vsg;
++
+ /* Tokens for callbacks. */
+ void *data[];
+ };
+
+ #define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq)
+
++/* gross hack */
++#define is_rproc_enabled IS_ENABLED(CONFIG_REMOTEPROC)
++
++static inline bool vdev_needs_mapping(const struct virtio_device *vdev)
++{
++ return is_rproc_enabled && vdev->id.device == VIRTIO_ID_RPROC_SERIAL;
++}
++
++static inline bool vring_needs_mapping(const struct virtqueue *vq)
++{
++ return vdev_needs_mapping(vq->vdev);
++}
++
++dma_addr_t vring_map_single(struct virtqueue *vq, int pos,
++ struct scatterlist *sg, enum dma_data_direction dir)
++{
++ struct device *dev;
++ struct vring_sg *vsg;
++ struct vring_virtqueue *vvq;
++
++ if (!vring_needs_mapping(vq))
++ return sg_phys(sg);
++
++ /* grab the ancestor (this is vdev->rproc->pdev) */
++ if (!vq->vdev->dev.parent || !vq->vdev->dev.parent->parent)
++ return DMA_ERROR_CODE;
++ dev = vq->vdev->dev.parent->parent;
++
++ vvq = to_vvq(vq);
++
++ vsg = &vvq->vsg[pos];
++
++ /* copy the whole structure */
++ vsg->sg = *sg;
++ vsg->va = sg_virt(sg);
++ vsg->dir = dir;
++ vsg->dma = dma_map_single(dev, vsg->va, vsg->sg.length, dir);
++
++ /* could be dma_mapping_error */
++ return vsg->dma;
++}
++
++int vring_unmap_single(struct virtqueue *vq, int pos)
++{
++ struct device *dev;
++ struct vring_sg *vsg;
++ struct vring_virtqueue *vvq;
++
++ if (!vring_needs_mapping(vq))
++ return 0;
++
++ /* grab the ancestor (this is vdev->rproc->pdev) */
++ if (!vq->vdev->dev.parent || !vq->vdev->dev.parent->parent)
++ return -EINVAL;
++
++ dev = vq->vdev->dev.parent->parent;
++
++ vvq = to_vvq(vq);
++
++ vsg = &vvq->vsg[pos];
++
++ dma_unmap_single(dev, vsg->dma, vsg->sg.length, vsg->dir);
++
++ memset(vsg, 0, sizeof(*vsg));
++
++ return 0;
++}
++
+ /* Set up an indirect table of descriptors and add it to the queue. */
+ static int vring_add_indirect(struct vring_virtqueue *vq,
+ struct scatterlist sg[],
+@@ -219,8 +299,10 @@ int virtqueue_add_buf(struct virtqueue *_vq,
+ #endif
+
+ /* If the host supports indirect descriptor tables, and we have multiple
+- * buffers, then go indirect. FIXME: tune this threshold */
+- if (vq->indirect && (out + in) > 1 && vq->vq.num_free) {
++ * buffers, then go indirect; but only if we don't need dma mapping.
++ * FIXME: tune this threshold */
++ if (vq->indirect && (out + in) > 1 && vq->vq.num_free &&
++ !vring_needs_mapping(_vq)) {
+ head = vring_add_indirect(vq, sg, out, in, gfp);
+ if (likely(head >= 0))
+ goto add_head;
+@@ -247,14 +329,14 @@ int virtqueue_add_buf(struct virtqueue *_vq,
+ head = vq->free_head;
+ for (i = vq->free_head; out; i = vq->vring.desc[i].next, out--) {
+ vq->vring.desc[i].flags = VRING_DESC_F_NEXT;
+- vq->vring.desc[i].addr = sg_phys(sg);
++ vq->vring.desc[i].addr = vring_map_single(_vq, i, sg, DMA_TO_DEVICE);
+ vq->vring.desc[i].len = sg->length;
+ prev = i;
+ sg++;
+ }
+ for (; in; i = vq->vring.desc[i].next, in--) {
+ vq->vring.desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE;
+- vq->vring.desc[i].addr = sg_phys(sg);
++ vq->vring.desc[i].addr = vring_map_single(_vq, i, sg, DMA_FROM_DEVICE);
+ vq->vring.desc[i].len = sg->length;
+ prev = i;
+ sg++;
+@@ -371,7 +453,8 @@ EXPORT_SYMBOL_GPL(virtqueue_kick);
+
+ static void detach_buf(struct vring_virtqueue *vq, unsigned int head)
+ {
+- unsigned int i;
++ unsigned int i, out, in;
++ u16 flags;
+
+ /* Clear data ptr. */
+ vq->data[head] = NULL;
+@@ -383,15 +466,21 @@ static void detach_buf(struct vring_virtqueue *vq, unsigned int head)
+ if (vq->vring.desc[i].flags & VRING_DESC_F_INDIRECT)
+ kfree(phys_to_virt(vq->vring.desc[i].addr));
+
+- while (vq->vring.desc[i].flags & VRING_DESC_F_NEXT) {
++ out = 0;
++ in = 0;
++ while ((flags = vq->vring.desc[i].flags) & VRING_DESC_F_NEXT) {
+ i = vq->vring.desc[i].next;
+ vq->vq.num_free++;
++
++ vring_unmap_single(&vq->vq, i);
+ }
+
+ vq->vring.desc[i].next = vq->free_head;
+ vq->free_head = head;
+ /* Plus final descriptor */
+ vq->vq.num_free++;
++
++ vring_unmap_single(&vq->vq, i);
+ }
+
+ static inline bool more_used(const struct vring_virtqueue *vq)
+@@ -629,7 +718,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
+ const char *name)
+ {
+ struct vring_virtqueue *vq;
+- unsigned int i;
++ unsigned int i, size, size_vsg;
+
+ /* We assume num is a power of 2. */
+ if (num & (num - 1)) {
+@@ -637,7 +726,16 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
+ return NULL;
+ }
+
+- vq = kmalloc(sizeof(*vq) + sizeof(void *)*num, GFP_KERNEL);
++ size = sizeof(*vq) + sizeof(void *)*num;
++ /* align size to dma_addr_t */
++ size = ALIGN(size, sizeof(struct vring_sg));
++
++ /* add the size of the sg array (if needed) */
++ if (vdev_needs_mapping(vdev))
++ size_vsg = sizeof(struct vring_sg) * num;
++ else
++ size_vsg = 0;
++ vq = kmalloc(size + size_vsg, GFP_KERNEL);
+ if (!vq)
+ return NULL;
+
+@@ -673,6 +771,12 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
+ }
+ vq->data[i] = NULL;
+
++ /* initialize everything to zero */
++ if (size_vsg > 0) {
++ vq->vsg = (void *)vq + size;
++ memset(vq->vsg, 0, size_vsg);
++ }
++
+ return &vq->vq;
+ }
+ EXPORT_SYMBOL_GPL(vring_new_virtqueue);
diff --git a/patches/linux-3.8.13/0431-virtio_console-Simplify-virtio_console-for-h-w-devic.patch b/patches/linux-3.8.13/0431-virtio_console-Simplify-virtio_console-for-h-w-devic.patch
new file mode 100644
index 0000000..46c3899
--- /dev/null
+++ b/patches/linux-3.8.13/0431-virtio_console-Simplify-virtio_console-for-h-w-devic.patch
@@ -0,0 +1,81 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Tue, 2 Jul 2013 22:15:02 +0300
+Subject: [PATCH] virtio_console: Simplify virtio_console for h/w devices.
+
+Now that virtio_ring properly maps the buffers there is no need
+for special handling of rproc_serial, nor any need to use
+dma_alloc_coherent for the buffers; the standard mapping works,
+plus sg_phys() on a piece of dma_alloc_coherent memory is bogus.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/char/virtio_console.c | 49 +++++++----------------------------------
+ 1 file changed, 8 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
+index a4b7aa0..2e9808b 100644
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -375,25 +375,7 @@ static void free_buf(struct port_buffer *buf, bool can_sleep)
+ put_page(page);
+ }
+
+- if (!buf->dev) {
+- kfree(buf->buf);
+- } else if (is_rproc_enabled) {
+- unsigned long flags;
+-
+- /* dma_free_coherent requires interrupts to be enabled. */
+- if (!can_sleep) {
+- /* queue up dma-buffers to be freed later */
+- spin_lock_irqsave(&dma_bufs_lock, flags);
+- list_add_tail(&buf->list, &pending_free_dma_bufs);
+- spin_unlock_irqrestore(&dma_bufs_lock, flags);
+- return;
+- }
+- dma_free_coherent(buf->dev, buf->size, buf->buf, buf->dma);
+-
+- /* Release device refcnt and allow it to be freed */
+- put_device(buf->dev);
+- }
+-
++ kfree(buf->buf);
+ kfree(buf);
+ }
+
+@@ -442,28 +424,13 @@ static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size,
+ return buf;
+ }
+
+- if (is_rproc_serial(vq->vdev)) {
+- /*
+- * Allocate DMA memory from ancestor. When a virtio
+- * device is created by remoteproc, the DMA memory is
+- * associated with the grandparent device:
+- * vdev => rproc => platform-dev.
+- * The code here would have been less quirky if
+- * DMA_MEMORY_INCLUDES_CHILDREN had been supported
+- * in dma-coherent.c
+- */
+- if (!vq->vdev->dev.parent || !vq->vdev->dev.parent->parent)
+- goto free_buf;
+- buf->dev = vq->vdev->dev.parent->parent;
+-
+- /* Increase device refcnt to avoid freeing it */
+- get_device(buf->dev);
+- buf->buf = dma_alloc_coherent(buf->dev, buf_size, &buf->dma,
+- GFP_KERNEL);
+- } else {
+- buf->dev = NULL;
+- buf->buf = kmalloc(buf_size, GFP_KERNEL);
+- }
++ /* NOTE: No more dma_alloc_coherent for rproc_serial
++ * It was bogus anyway, since you ended up calling sg_phys()
++ * on a dma_alloc_coherent address. With vring supporting
++ * dma mapping regular kmalloc memory is fine.
++ */
++ buf->dev = NULL; /* FIXME: Perhaps revisit? */
++ buf->buf = kmalloc(buf_size, GFP_KERNEL);
+
+ if (!buf->buf)
+ goto free_buf;
diff --git a/patches/linux-3.8.13/0432-rpmsg-Make-the-buffers-number-and-size-configurable.patch b/patches/linux-3.8.13/0432-rpmsg-Make-the-buffers-number-and-size-configurable.patch
new file mode 100644
index 0000000..acc6952
--- /dev/null
+++ b/patches/linux-3.8.13/0432-rpmsg-Make-the-buffers-number-and-size-configurable.patch
@@ -0,0 +1,59 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 23 May 2013 20:22:52 +0300
+Subject: [PATCH] rpmsg: Make the buffers number and size configurable
+
+The defaults are just too much for small devices. Make them
+configurable (by a kernel config option for now).
+---
+ drivers/rpmsg/Kconfig | 14 ++++++++++++++
+ drivers/rpmsg/virtio_rpmsg_bus.c | 14 ++++++++++++--
+ 2 files changed, 26 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
+index 2bd911f..e3d09d2 100644
+--- a/drivers/rpmsg/Kconfig
++++ b/drivers/rpmsg/Kconfig
+@@ -6,4 +6,18 @@ config RPMSG
+ select VIRTIO
+ depends on EXPERIMENTAL
+
++config RPMSG_NUM_BUFS
++ int "RPMSG number of buffers"
++ depends on RPMSG
++ default 512
++ help
++ Configure rpmsg number of bufs (default is 512)
++
++config RPMSG_BUF_SIZE
++ int "RPMSG size of buffers"
++ depends on RPMSG
++ default 512
++ help
++ Configure rpmsg buffer size (default is 512)
++
+ endmenu
+diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
+index f1e3239..1ca8700 100644
+--- a/drivers/rpmsg/virtio_rpmsg_bus.c
++++ b/drivers/rpmsg/virtio_rpmsg_bus.c
+@@ -102,8 +102,18 @@ struct rpmsg_channel_info {
+ * can change this without changing anything in the firmware of the remote
+ * processor.
+ */
+-#define RPMSG_NUM_BUFS (512)
+-#define RPMSG_BUF_SIZE (512)
++#ifndef CONFIG_RPMSG_NUM_BUFS
++#define RPMSG_NUM_BUFS 512
++#else
++#define RPMSG_NUM_BUFS CONFIG_RPMSG_NUM_BUFS
++#endif
++
++#ifndef CONFIG_RPMSG_BUF_SIZE
++#define RPMSG_BUF_SIZE 512
++#else
++#define RPMSG_BUF_SIZE CONFIG_RPMSG_BUF_SIZE
++#endif
++
+ #define RPMSG_TOTAL_BUF_SPACE (RPMSG_NUM_BUFS * RPMSG_BUF_SIZE)
+
+ /*
diff --git a/patches/linux-3.8.13/0433-remoteproc-Use-driver-ops-for-allocation-of-virtqueu.patch b/patches/linux-3.8.13/0433-remoteproc-Use-driver-ops-for-allocation-of-virtqueu.patch
new file mode 100644
index 0000000..31aeaf8
--- /dev/null
+++ b/patches/linux-3.8.13/0433-remoteproc-Use-driver-ops-for-allocation-of-virtqueu.patch
@@ -0,0 +1,167 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Fri, 24 May 2013 15:01:19 +0300
+Subject: [PATCH] remoteproc: Use driver ops for allocation of virtqueus
+
+Virtqueues can not always be dynamically allocated.
+In many cases they should be placed in driver controlled areas.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/remoteproc/remoteproc_core.c | 64 ++++++++++++++++++++++++++--------
+ include/linux/remoteproc.h | 9 +++++
+ 2 files changed, 59 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
+index 752b507..7c56d0a 100644
+--- a/drivers/remoteproc/remoteproc_core.c
++++ b/drivers/remoteproc/remoteproc_core.c
+@@ -187,31 +187,59 @@ void *rproc_da_to_va(struct rproc *rproc, u64 da, int len)
+ }
+ EXPORT_SYMBOL(rproc_da_to_va);
+
++static inline void *rproc_alloc_vring_internal(struct rproc *rproc,
++ const struct fw_rsc_vdev_vring *vring,
++ int size, dma_addr_t *dma)
++{
++ struct device *dev = &rproc->dev;
++
++ /* Custom vring allocator */
++ if (rproc->ops->alloc_vring != NULL)
++ return rproc->ops->alloc_vring(rproc, vring, size, dma);
++
++ /*
++ * Allocate non-cacheable memory for the vring. In the future
++ * this call will also configure the IOMMU for us
++ * TODO: let the rproc know the da of this vring
++ */
++ return dma_alloc_coherent(dev->parent, PAGE_ALIGN(size),
++ dma, GFP_KERNEL);
++}
++
++static inline void rproc_free_vring_internal(struct rproc *rproc,
++ const struct fw_rsc_vdev_vring *vring,
++ int size, void *va, dma_addr_t dma)
++{
++ struct device *dev = &rproc->dev;
++
++ /* Custom vring allocator */
++ if (rproc->ops->free_vring != NULL)
++ rproc->ops->free_vring(rproc, vring, size, va, dma);
++ else
++ dma_free_coherent(dev->parent,
++ PAGE_ALIGN(size), va, dma);
++}
++
+ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
+ {
+ struct rproc *rproc = rvdev->rproc;
+ struct device *dev = &rproc->dev;
+ struct rproc_vring *rvring = &rvdev->vring[i];
++ struct fw_rsc_vdev_vring *vring = rvring->rsc_vring;
+ dma_addr_t dma;
+ void *va;
+ int ret, size, notifyid;
+
+- /* actual size of vring (in bytes) */
+- size = PAGE_ALIGN(vring_size(rvring->len, rvring->align));
+-
+ if (!idr_pre_get(&rproc->notifyids, GFP_KERNEL)) {
+ dev_err(dev, "idr_pre_get failed\n");
+ return -ENOMEM;
+ }
+
+- /*
+- * Allocate non-cacheable memory for the vring. In the future
+- * this call will also configure the IOMMU for us
+- * TODO: let the rproc know the da of this vring
+- */
+- va = dma_alloc_coherent(dev->parent, size, &dma, GFP_KERNEL);
++ size = vring_size(rvring->len, rvring->align);
++
++ va = rproc_alloc_vring_internal(rproc, vring, size, &dma);
+ if (!va) {
+- dev_err(dev->parent, "dma_alloc_coherent failed\n");
++ dev_err(dev->parent, "rproc alloc of vring #%d failed\n", i);
+ return -EINVAL;
+ }
+
+@@ -224,7 +252,7 @@ int rproc_alloc_vring(struct rproc_vdev *rvdev, int i)
+ ret = idr_get_new(&rproc->notifyids, rvring, &notifyid);
+ if (ret) {
+ dev_err(dev, "idr_get_new failed: %d\n", ret);
+- dma_free_coherent(dev->parent, size, va, dma);
++ rproc_free_vring_internal(rproc, vring, size, va, dma);
+ return ret;
+ }
+
+@@ -269,6 +297,9 @@ rproc_parse_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, int i)
+ rvring->align = vring->align;
+ rvring->rvdev = rvdev;
+
++ /* point to the resource */
++ rvring->rsc_vring = vring;
++
+ return 0;
+ }
+
+@@ -281,11 +312,13 @@ static int rproc_max_notifyid(int id, void *p, void *data)
+
+ void rproc_free_vring(struct rproc_vring *rvring)
+ {
+- int size = PAGE_ALIGN(vring_size(rvring->len, rvring->align));
+- struct rproc *rproc = rvring->rvdev->rproc;
++ int size = vring_size(rvring->len, rvring->align);
++ struct rproc_vdev *rvdev = rvring->rvdev;
++ struct rproc *rproc = rvdev->rproc;
+ int maxid = 0;
+
+- dma_free_coherent(rproc->dev.parent, size, rvring->va, rvring->dma);
++ rproc_free_vring_internal(rproc, rvring->rsc_vring,
++ size, rvring->va, rvring->dma);
+ idr_remove(&rproc->notifyids, rvring->notifyid);
+
+ /* Find the largest remaining notifyid */
+@@ -355,6 +388,9 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
+
+ rvdev->rproc = rproc;
+
++ /* point to the resource */
++ rvdev->rsc_vdev = rsc;
++
+ /* parse the vrings */
+ for (i = 0; i < rsc->num_of_vrings; i++) {
+ ret = rproc_parse_vring(rvdev, rsc, i);
+diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
+index faf3332..c8573fd 100644
+--- a/include/linux/remoteproc.h
++++ b/include/linux/remoteproc.h
+@@ -335,6 +335,13 @@ struct rproc_ops {
+ int (*start)(struct rproc *rproc);
+ int (*stop)(struct rproc *rproc);
+ void (*kick)(struct rproc *rproc, int vqid);
++
++ void *(*alloc_vring)(struct rproc *rproc,
++ const struct fw_rsc_vdev_vring *vring,
++ int size, dma_addr_t *dma);
++ void (*free_vring)(struct rproc *rproc,
++ const struct fw_rsc_vdev_vring *vring,
++ int size, void *va, dma_addr_t dma);
+ };
+
+ /**
+@@ -454,6 +461,7 @@ struct rproc_vring {
+ int notifyid;
+ struct rproc_vdev *rvdev;
+ struct virtqueue *vq;
++ struct fw_rsc_vdev_vring *rsc_vring;
+ };
+
+ /**
+@@ -472,6 +480,7 @@ struct rproc_vdev {
+ struct rproc_vring vring[RVDEV_NUM_VRINGS];
+ unsigned long dfeatures;
+ unsigned long gfeatures;
++ struct fw_rsc_vdev *rsc_vdev;
+ };
+
+ struct rproc *rproc_alloc(struct device *dev, const char *name,
diff --git a/patches/linux-3.8.13/0434-rproc-core-Allow-bootup-without-resources.patch b/patches/linux-3.8.13/0434-rproc-core-Allow-bootup-without-resources.patch
new file mode 100644
index 0000000..75fe5c5
--- /dev/null
+++ b/patches/linux-3.8.13/0434-rproc-core-Allow-bootup-without-resources.patch
@@ -0,0 +1,40 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 10 Jul 2013 00:13:03 +0300
+Subject: [PATCH] rproc: core: Allow bootup without resources
+
+Not every core has a need to communicate with the host via VDEVS.
+Allow booting without a resource table.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/remoteproc/remoteproc_core.c | 17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
+index 7c56d0a..76ca36a 100644
+--- a/drivers/remoteproc/remoteproc_core.c
++++ b/drivers/remoteproc/remoteproc_core.c
+@@ -868,16 +868,13 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
+
+ /* look for the resource table */
+ table = rproc_find_rsc_table(rproc, fw, &tablesz);
+- if (!table) {
+- ret = -EINVAL;
+- goto clean_up;
+- }
+-
+- /* handle fw resources which are required to boot rproc */
+- ret = rproc_handle_boot_rsc(rproc, table, tablesz);
+- if (ret) {
+- dev_err(dev, "Failed to process resources: %d\n", ret);
+- goto clean_up;
++ if (table != NULL) {
++ /* handle fw resources which are required to boot rproc */
++ ret = rproc_handle_boot_rsc(rproc, table, tablesz);
++ if (ret) {
++ dev_err(dev, "Failed to process resources: %d\n", ret);
++ goto clean_up;
++ }
+ }
+
+ /* load the ELF segments to memory */
diff --git a/patches/linux-3.8.13/0435-tools-virtio-fix-build-for-3.8.patch b/patches/linux-3.8.13/0435-tools-virtio-fix-build-for-3.8.patch
new file mode 100644
index 0000000..36aedd5
--- /dev/null
+++ b/patches/linux-3.8.13/0435-tools-virtio-fix-build-for-3.8.patch
@@ -0,0 +1,87 @@
+From: "Michael S. Tsirkin" <mst@redhat.com>
+Date: Mon, 18 Mar 2013 13:22:18 +1030
+Subject: [PATCH] tools/virtio: fix build for 3.8
+
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+---
+ drivers/vhost/test.c | 4 +++-
+ tools/virtio/Makefile | 2 +-
+ tools/virtio/linux/virtio.h | 7 ++++++-
+ tools/virtio/virtio_test.c | 3 ++-
+ 4 files changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
+index 91d6f06..329d302 100644
+--- a/drivers/vhost/test.c
++++ b/drivers/vhost/test.c
+@@ -275,7 +275,9 @@ static long vhost_test_ioctl(struct file *f, unsigned int ioctl,
+ return vhost_test_reset_owner(n);
+ default:
+ mutex_lock(&n->dev.mutex);
+- r = vhost_dev_ioctl(&n->dev, ioctl, arg);
++ r = vhost_dev_ioctl(&n->dev, ioctl, argp);
++ if (r == -ENOIOCTLCMD)
++ r = vhost_vring_ioctl(&n->dev, ioctl, argp);
+ vhost_test_flush(n);
+ mutex_unlock(&n->dev.mutex);
+ return r;
+diff --git a/tools/virtio/Makefile b/tools/virtio/Makefile
+index d1d442e..b48c432 100644
+--- a/tools/virtio/Makefile
++++ b/tools/virtio/Makefile
+@@ -1,7 +1,7 @@
+ all: test mod
+ test: virtio_test
+ virtio_test: virtio_ring.o virtio_test.o
+-CFLAGS += -g -O2 -Wall -I. -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -MMD
++CFLAGS += -g -O2 -Wall -I. -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD
+ vpath %.c ../../drivers/virtio
+ mod:
+ ${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test
+diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h
+index 81847dd..390c4cb 100644
+--- a/tools/virtio/linux/virtio.h
++++ b/tools/virtio/linux/virtio.h
+@@ -85,6 +85,8 @@ typedef __u16 u16;
+ typedef enum {
+ GFP_KERNEL,
+ GFP_ATOMIC,
++ __GFP_HIGHMEM,
++ __GFP_HIGH
+ } gfp_t;
+ typedef enum {
+ IRQ_NONE,
+@@ -163,6 +165,8 @@ struct virtqueue {
+ void (*callback)(struct virtqueue *vq);
+ const char *name;
+ struct virtio_device *vdev;
++ unsigned int index;
++ unsigned int num_free;
+ void *priv;
+ };
+
+@@ -206,7 +210,8 @@ bool virtqueue_enable_cb(struct virtqueue *vq);
+ bool virtqueue_enable_cb_delayed(struct virtqueue *vq);
+
+ void *virtqueue_detach_unused_buf(struct virtqueue *vq);
+-struct virtqueue *vring_new_virtqueue(unsigned int num,
++struct virtqueue *vring_new_virtqueue(unsigned int index,
++ unsigned int num,
+ unsigned int vring_align,
+ struct virtio_device *vdev,
+ bool weak_barriers,
+diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c
+index fcc9aa2..faf3f0c 100644
+--- a/tools/virtio/virtio_test.c
++++ b/tools/virtio/virtio_test.c
+@@ -92,7 +92,8 @@ static void vq_info_add(struct vdev_info *dev, int num)
+ assert(r >= 0);
+ memset(info->ring, 0, vring_size(num, 4096));
+ vring_init(&info->vring, num, info->ring, 4096);
+- info->vq = vring_new_virtqueue(info->vring.num, 4096, &dev->vdev,
++ info->vq = vring_new_virtqueue(info->idx,
++ info->vring.num, 4096, &dev->vdev,
+ true, info->ring,
+ vq_notify, vq_callback, "test");
+ assert(info->vq);
diff --git a/patches/linux-3.8.13/0436-rproc-pru-PRU-remoteproc-updated-to-work-with-virtio.patch b/patches/linux-3.8.13/0436-rproc-pru-PRU-remoteproc-updated-to-work-with-virtio.patch
new file mode 100644
index 0000000..974ae66
--- /dev/null
+++ b/patches/linux-3.8.13/0436-rproc-pru-PRU-remoteproc-updated-to-work-with-virtio.patch
@@ -0,0 +1,2487 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 11 Jul 2013 19:38:54 +0300
+Subject: [PATCH] rproc: pru: PRU remoteproc updated to work with virtio +
+ complex h/w setup
+
+Major update for the PRU rproc driver. Implemented logic for interrupt event
+routing, virtio support, dual PRU support, system calls and many more.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/remoteproc/Kconfig | 1 +
+ drivers/remoteproc/pru_rproc.c | 2370 ++++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 2251 insertions(+), 120 deletions(-)
+
+diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
+index 690097b..13cb3ca 100644
+--- a/drivers/remoteproc/Kconfig
++++ b/drivers/remoteproc/Kconfig
+@@ -46,6 +46,7 @@ config PRU_RPROC
+ depends on EXPERIMENTAL
+ depends on HAS_DMA && SOC_AM33XX
+ select REMOTEPROC
++ select RPMSG
+ default n
+ help
+ Say y or m here to support AM33xx PRU
+diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c
+index 113ad80..e3ec63b 100644
+--- a/drivers/remoteproc/pru_rproc.c
++++ b/drivers/remoteproc/pru_rproc.c
+@@ -1,6 +1,6 @@
+ /*
+ * PRU driver for TI's AM33xx series of SoCs
+- *
++ *
+ * Copyright (C) 2013 Pantelis Antoniou <panto@antoniou-consulting.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+@@ -22,199 +22,2329 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/io.h>
++#include <plat/mailbox.h>
++#include <linux/virtio_ids.h>
++#include <linux/elf.h>
++#include <linux/byteorder/generic.h>
++#include <linux/virtio.h>
++#include <linux/virtio_ring.h>
++#include <asm/atomic.h>
+
+ #include "remoteproc_internal.h"
+
++/* PRU_EVTOUT0 is halt (system call) */
++
++/* maximum PRUs */
++#define MAX_PRUS 2
++
++/* sysevent targets (ARM + PRU) */
++#define MAX_TARGETS (1 + MAX_PRUS)
++
++/* sysevent target ids */
++#define TARGET_ARM 0
++#define TARGET_PRU(x) (1 + (x))
++#define TARGET_PRU_TO_PRU_IDX(x) ({ \
++ unsigned int _x = (x) - TARGET_PRU(0); \
++ _x < MAX_PRUS ? _x : -1; \
++ })
++#define TARGET_FROM_TO_IDX(_from, _to) \
++ ((_from) * MAX_TARGETS + (_to))
++#define TARGET_ARM_TO_PRU_IDX(x) \
++ TARGET_FROM_TO_IDX(TARGET_ARM, TARGET_PRU(x))
++#define TARGET_PRU_TO_ARM_IDX(x) \
++ TARGET_FROM_TO_IDX(TARGET_PRU(x), TARGET_ARM)
++
++/* maximum interrupts routed to host */
++#define MAX_ARM_PRU_INTS 8
++
++/* maximum number of sys events */
++#define MAX_PRU_SYS_EVENTS 64
++
++/* maximum number of interrupt channels */
++#define MAX_PRU_CHANNELS 10
++
++/* maximum number of host interrupts (ARM + 1 for each PRU) */
++#define MIN_PRU_HOST_INT 2
++#define MAX_PRU_HOST_INT 10
++
++struct pruproc;
++struct pruproc_core;
++
++/* maximum 4 vdevs per PRU */
++#define PRU_VDEV_MAX 4
++#define PRU_VRING_MAX (RVDEV_NUM_VRINGS * PRU_VDEV_MAX)
++
++struct pru_vring_info {
++ struct fw_rsc_vdev_vring *rsc;
++ struct vring vr;
++ void __iomem *va;
++ dma_addr_t pa;
++ u32 da;
++ struct rproc_vring *rvring;
++};
++
++/* per PRU core control structure */
++struct pruproc_core {
++ int idx;
++ struct pruproc *pruproc;
++ struct rproc *rproc;
++
++ u32 pctrl;
++ u32 pdbg;
++
++ u32 iram, iram_sz, iram_da; /* global, size, own */
++ u32 dram, dram_sz, dram_da, dram_oda; /* global, size, own, other */
++
++ const char *fw_name;
++ unsigned int is_elf : 1;
++ u32 entry_point;
++
++ struct resource_table *table;
++ int table_size;
++ /* copy of the resource table in device accessible area */
++ void * __iomem dev_table_va;
++ dma_addr_t dev_table_pa;
++
++ int num_vdevs;
++ struct fw_rsc_vdev *rsc_vdev[PRU_VDEV_MAX];
++ int vdev_vring_start[PRU_VDEV_MAX];
++ int vdev_vring_count[PRU_VDEV_MAX];
++
++ /* total for all the vdevs */
++ int num_vrings;
++ struct pru_vring_info vring_info[PRU_VRING_MAX];
++
++ /* sysevent the host generates when kicking any vring */
++ int host_vring_sysev;
++
++ /* sysevent the pru generates when kicking any vring */
++ int pru_vring_sysev;
++
++ /* boots */
++ atomic_t bootcnt;
++};
++
++struct pru_sysev_target {
++ unsigned int valid : 1; /* sysevent is valid */
++ unsigned int vring : 1; /* sysevent is vring related */
++ int source; /* 0=ARM, 1=PRU0, 2=PRU1 */
++ int target; /* 0=ARM, 1=PRU0, 2=PRU1 */
++};
++
+ /* PRU control structure */
+ struct pruproc {
+- struct rproc *rproc;
+ struct platform_device *pdev;
+- struct resource_table *table;
+ void __iomem *vaddr;
+ dma_addr_t paddr;
++ struct omap_mbox *mbox;
++ struct notifier_block nb;
++ u32 pintc;
++ u32 pdram, pdram_sz, pdram_da;
++
++ int num_irqs;
++ int irqs[MAX_ARM_PRU_INTS];
++ int events[MAX_ARM_PRU_INTS];
++ int sysev_to_ch[MAX_PRU_SYS_EVENTS];
++ int ch_to_host[MAX_PRU_CHANNELS];
++ int target_to_sysev[MAX_TARGETS * MAX_TARGETS];
++
++ /* map an incoming sysevent to kind and handler */
++ struct pru_sysev_target sysev_to_target[MAX_PRU_SYS_EVENTS];
++
++ /* number of prus */
++ u32 num_prus;
++ struct pruproc_core **pruc;
++ struct pruproc_core *pru_to_pruc[MAX_PRUS];
+ };
+
+-/* Loads the firmware to shared memory. */
+-static int pruproc_load_segments(struct rproc *rproc, const struct firmware *fw)
++/* global memory map (for am33xx) (almost the same as local) */
++#define PRU_DATA_RAM0 0x00000
++#define PRU_DATA_RAM1 0x02000
++#define PRU_SHARED_DATA_RAM 0x10000
++#define PRU_INTC 0x20000
++#define PRU_PRU0_CONTROL 0x22000
++#define PRU_PRU0_DEBUG 0x22400
++#define PRU_PRU1_CONTROL 0x24000
++#define PRU_PRU1_DEBUG 0x24400
++#define PRU_CFG 0x26000
++#define PRU_UART0 0x28000
++#define PRU_IEP 0x2E000
++#define PRU_ECAP0 0x30000
++#define PRU_MII_RT_CFG 0x32000
++#define PRU_MII_MDIO 0x32400
++#define PRU_INSN_RAM0 0x34000
++#define PRU_INSN_RAM1 0x38000
++
++/* PRU CONTROL */
++#define PCTRL_CONTROL 0x0000
++#define CONTROL_SOFT_RST_N 0x0001
++#define CONTROL_ENABLE 0x0002
++#define CONTROL_SLEEPING 0x0004
++#define CONTROL_COUNTER_ENABLE 0x0008
++#define CONTROL_SINGLE_STEP 0x0100
++#define CONTROL_RUNSTATE 0x4000
++
++#define PCTRL_STATUS 0x0004
++#define PCTRL_WAKEUP_EN 0x0008
++#define PCTRL_CYCLE 0x000C
++#define PCTRL_STALL 0x0010
++#define PCTRL_CTBIR0 0x0020
++#define PCTRL_CTBIR1 0x0024
++#define PCTRL_CTPPR0 0x0028
++#define PCTRL_CTPPR1 0x002C
++
++/* PRU DEBUG */
++#define PDBG_GPREG(x) (0x0000 + (x) * 4)
++#define PDBG_CT_REG(x) (0x0080 + (x) * 4)
++
++/* PRU INTC */
++#define PINTC_REVID 0x0000
++#define PINTC_CR 0x0004
++#define PINTC_GER 0x0010
++#define PINTC_GNLR 0x001C
++#define PINTC_SISR 0x0020
++#define PINTC_SICR 0x0024
++#define PINTC_EISR 0x0028
++#define PINTC_EICR 0x002C
++#define PINTC_HIEISR 0x0034
++#define PINTC_HIDISR 0x0038
++#define PINTC_GPIR 0x0080
++#define PINTC_SRSR0 0x0200
++#define PINTC_SRSR1 0x0204
++#define PINTC_SECR0 0x0280
++#define PINTC_SECR1 0x0284
++#define PINTC_ESR0 0x0300
++#define PINTC_ESR1 0x0304
++#define PINTC_ECR0 0x0380
++#define PINTC_ECR1 0x0384
++#define PINTC_CMR0 0x0400
++#define PINTC_CMR1 0x0404
++#define PINTC_CMR2 0x0408
++#define PINTC_CMR3 0x040C
++#define PINTC_CMR4 0x0410
++#define PINTC_CMR5 0x0414
++#define PINTC_CMR6 0x0418
++#define PINTC_CMR7 0x041C
++#define PINTC_CMR8 0x0420
++#define PINTC_CMR9 0x0424
++#define PINTC_CMR10 0x0428
++#define PINTC_CMR11 0x042C
++#define PINTC_CMR12 0x0430
++#define PINTC_CMR13 0x0434
++#define PINTC_CMR14 0x0438
++#define PINTC_CMR15 0x043C
++#define PINTC_HMR0 0x0800
++#define PINTC_HMR1 0x0804
++#define PINTC_HMR2 0x0808
++#define PINTC_HIPIR0 0x0900
++#define PINTC_HIPIR1 0x0904
++#define PINTC_HIPIR2 0x0908
++#define PINTC_HIPIR3 0x090C
++#define PINTC_HIPIR4 0x0910
++#define PINTC_HIPIR5 0x0914
++#define PINTC_HIPIR6 0x0918
++#define PINTC_HIPIR7 0x091C
++#define PINTC_HIPIR8 0x0920
++#define PINTC_HIPIR9 0x0924
++#define PINTC_SIPR0 0x0D00
++#define PINTC_SIPR1 0x0D04
++#define PINTC_SITR0 0x0D80
++#define PINTC_SITR1 0x0D84
++#define PINTC_HINLR0 0x1100
++#define PINTC_HINLR1 0x1104
++#define PINTC_HINLR2 0x1108
++#define PINTC_HINLR3 0x110C
++#define PINTC_HINLR4 0x1110
++#define PINTC_HINLR5 0x1114
++#define PINTC_HINLR6 0x1118
++#define PINTC_HINLR7 0x111C
++#define PINTC_HINLR8 0x1120
++#define PINTC_HINLR9 0x1124
++#define PINTC_HIER 0x1500
++
++#define HIPIR_NOPEND 0x80000000
++
++static inline u32 pru_read_reg(struct pruproc *pp, unsigned int reg)
+ {
+- struct pruproc *pruproc = rproc->priv;
++ return __raw_readl(pp->vaddr + reg);
++}
+
+- dev_dbg(&pruproc->pdev->dev, "%s\n", __func__);
++static inline void pru_write_reg(struct pruproc *pp, unsigned int reg,
++ u32 val)
++{
++ __raw_writel(val, pp->vaddr + reg);
++}
+
+- return 0;
++static inline u32 pintc_read_reg(struct pruproc *pp, unsigned int reg)
++{
++ return pru_read_reg(pp, reg + pp->pintc);
+ }
+
+-/* Find the resource table inside the remote processor's firmware. */
+-static struct resource_table *
+-pruproc_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
+- int *tablesz)
++static inline void pintc_write_reg(struct pruproc *pp, unsigned int reg,
++ u32 val)
+ {
+- struct pruproc *pruproc = rproc->priv;
+- struct resource_table *table;
++ return pru_write_reg(pp, reg + pp->pintc, val);
++}
+
+- table = devm_kzalloc(&pruproc->pdev->dev, sizeof(*table), GFP_KERNEL);
++static inline u32 pcntrl_read_reg(struct pruproc_core *ppc, unsigned int reg)
++{
++ return pru_read_reg(ppc->pruproc, reg + ppc->pctrl);
++}
+
+- dev_dbg(&pruproc->pdev->dev, "%s\n", __func__);
++static inline void pcntrl_write_reg(struct pruproc_core *ppc, unsigned int reg,
++ u32 val)
++{
++ return pru_write_reg(ppc->pruproc, reg + ppc->pctrl, val);
++}
+
+- return table;
++static inline u32 pdbg_read_reg(struct pruproc_core *ppc, unsigned int reg)
++{
++ return pru_read_reg(ppc->pruproc, reg + ppc->pdbg);
+ }
+
+-static int pruproc_sanity_check(struct rproc *rproc, const struct firmware *fw)
++static inline void pdbg_write_reg(struct pruproc_core *ppc, unsigned int reg,
++ u32 val)
+ {
+- return 0;
++ return pru_write_reg(ppc->pruproc, reg + ppc->pdbg, val);
+ }
+
+-/* PRU firmware handler operations */
+-const struct rproc_fw_ops pruproc_fw_ops = {
+- .find_rsc_table = pruproc_find_rsc_table,
+- .load = pruproc_load_segments,
+- .sanity_check = pruproc_sanity_check,
+-};
++/* convert 32 bit Data device address to a virtual (and physical) host addr */
++static void * __iomem pru_d_da_to_va(struct pruproc_core *ppc, u32 da,
++ dma_addr_t *pa)
++{
++ struct pruproc *pp = ppc->pruproc;
++ u32 offset;
+
+-/* Kick the modem with specified notification id */
+-static void pruproc_kick(struct rproc *rproc, int vqid)
++ /* check own data ram first */
++ if (da >= ppc->dram_da && da < ppc->dram_da + ppc->dram_sz)
++ offset = ppc->dram + da - ppc->dram_da;
++ /* check other's data ram */
++ else if (da >= ppc->dram_oda && da < ppc->dram_oda + ppc->dram_sz)
++ offset = ppc->dram + da - ppc->dram_oda;
++ /* shared data */
++ else if (da >= pp->pdram_da && da < pp->pdram_da + pp->pdram_sz)
++ offset = pp->pdram + da - pp->pdram_da;
++ else
++ return NULL;
++
++ if (pa)
++ *pa = pp->paddr + offset;
++ return pp->vaddr + offset;
++}
++
++/* convert physical address to device address */
++static u32 pru_d_pa_to_da(struct pruproc_core *ppc, dma_addr_t pa)
+ {
+- struct pruproc *pruproc = rproc->priv;
++ /* we don't support mapping in the GPMC space */
++ if (pa < 0x00080000)
++ return 0xffffffff;
++
++ /* we also don't map internal memories */
+
+- dev_dbg(&pruproc->pdev->dev, "kick vqid:%d\n", vqid);
++ return (u32)pa;
+ }
+
+-/* Start the PRU modem */
+-static int pruproc_start(struct rproc *rproc)
++static void * __iomem pru_i_da_to_va(struct pruproc_core *ppc, u32 da,
++ dma_addr_t *pa)
++{
++ struct pruproc *pp = ppc->pruproc;
++ u32 offset;
++
++ /* check whether is within the iram space */
++ if (da >= ppc->iram_da && da < ppc->iram-da + ppc->iram_sz)
++ offset = ppc->iram + da - ppc->iram_da;
++ else
++ return NULL;
++
++ if (pa)
++ *pa = pp->paddr + offset;
++ return pp->vaddr + offset;
++}
++
++static void * __iomem pru_d_da_to_va_block(struct pruproc_core *ppc, u32 da,
++ dma_addr_t *pa, int size)
++{
++ void * __iomem va_start;
++ void * __iomem va_end;
++
++ /* make sure size is not bogus */
++ if (size <= 0)
++ return NULL;
++
++ /* get start vaddr of device address (D) */
++ va_start = pru_d_da_to_va(ppc, da, pa);
++ if (va_start == NULL)
++ return NULL;
++
++ /* get end vaddr of device address (D) */
++ va_end = pru_d_da_to_va(ppc, da + size - 1, NULL);
++ if (va_end == NULL)
++ return NULL;
++
++ /* for the block to be valid the VAs must be consecutive */
++ if ((va_end - va_start) != (size - 1))
++ return NULL;
++
++ /* all good */
++ return va_start;
++}
++
++static void * __iomem pru_i_da_to_va_block(struct pruproc_core *ppc, u32 da,
++ dma_addr_t *pa, int size)
++{
++ void * __iomem va_start;
++ void * __iomem va_end;
++
++ /* make sure size is not bogus */
++ if (size <= 0)
++ return NULL;
++
++ /* get start vaddr of device address (I) */
++ va_start = pru_i_da_to_va(ppc, da, pa);
++ if (va_start == NULL)
++ return NULL;
++
++ /* get end vaddr of device address (I) */
++ va_end = pru_i_da_to_va(ppc, da + size - 1, NULL);
++ if (va_end == NULL)
++ return NULL;
++
++ /* for the block to be valid the VAs must be consecutive */
++ if ((va_end - va_start) != (size - 1))
++ return NULL;
++
++ /* all good */
++ return va_start;
++}
++
++static int pru_i_read_u32(struct pruproc_core *ppc, u32 da, u32 *val)
+ {
+- struct pruproc *pruproc = rproc->priv;
++ void * __iomem va;
++
++ /* verify it's a word address */
++ if (da & 3)
++ return -EINVAL;
+
+- dev_dbg(&pruproc->pdev->dev, "start pru\n");
++ /* get vaddr of device address (I) */
++ va = pru_i_da_to_va_block(ppc, da, NULL, sizeof(u32));
++ if (va == NULL)
++ return -EFAULT;
++
++ if (val)
++ *val = le32_to_cpu(*(u32 *)va);
+
+ return 0;
+ }
+
+-/* Stop the PRU modem */
+-static int pruproc_stop(struct rproc *rproc)
++static int pru_d_read_u32(struct pruproc_core *ppc, u32 da, u32 *val)
+ {
+- struct pruproc *pruproc = rproc->priv;
++ void * __iomem va;
++
++ /* verify it's a word address */
++ if (da & 3)
++ return -EINVAL;
+
+- dev_dbg(&pruproc->pdev->dev, "stop PRU\n");
++ /* get vaddr of device address (I) */
++ va = pru_d_da_to_va_block(ppc, da, NULL, sizeof(u32));
++ if (va == NULL)
++ return -EINVAL;
++
++ if (val)
++ *val = le32_to_cpu(*(u32 *)va);
+
+ return 0;
+ }
+
+-static struct rproc_ops pruproc_ops = {
+- .start = pruproc_start,
+- .stop = pruproc_stop,
+- .kick = pruproc_kick,
+-};
++static int pru_i_write_u32(struct pruproc_core *ppc, u32 da, u32 val)
++{
++ void * __iomem va;
+
+-/* PRU is unregistered */
+-static int pruproc_remove(struct platform_device *pdev)
++ /* verify it's a word address */
++ if (da & 3)
++ return -EINVAL;
++
++ /* get vaddr of device address (I) */
++ va = pru_i_da_to_va_block(ppc, da, NULL, sizeof(u32));
++ if (va == NULL)
++ return -EINVAL;
++
++ *(u32 *)va = cpu_to_le32(val);
++
++ return 0;
++}
++
++static int pru_d_write_u32(struct pruproc_core *ppc, u32 da, u32 val)
+ {
+- struct pruproc *pruproc = platform_get_drvdata(pdev);
++ void * __iomem va;
+
+- dev_dbg(&pdev->dev, "remove pru\n");
++ /* verify it's a word address */
++ if (da & 3)
++ return -EINVAL;
+
+- /* Unregister as remoteproc device */
+- rproc_del(pruproc->rproc);
+- rproc_put(pruproc->rproc);
++ /* get vaddr of device address (I) */
++ va = pru_d_da_to_va_block(ppc, da, NULL, sizeof(u32));
++ if (va == NULL)
++ return -EINVAL;
+
+- platform_set_drvdata(pdev, NULL);
++ *(u32 *)va = cpu_to_le32(val);
++ return 0;
++}
+
++static int pruproc_bin_sanity_check(struct rproc *rproc, const struct firmware *fw)
++{
+ return 0;
+ }
+
+-/* Handle probe of a modem device */
+-static int pruproc_probe(struct platform_device *pdev)
++/* Loads the firmware to shared memory. */
++static int pruproc_bin_load_segments(struct rproc *rproc, const struct firmware *fw)
+ {
+- struct device *dev = &pdev->dev;
+- struct pruproc *pruproc;
+- struct rproc *rproc;
+- struct resource *res;
+- struct pinctrl *pinctrl;
+- int err;
++ struct pruproc_core *ppc = rproc->priv;
++ struct device *dev = &rproc->dev;
++ void __iomem *va;
+
+- dev_dbg(dev, "probe pru\n");
++ pcntrl_write_reg(ppc, PCTRL_CONTROL, CONTROL_SOFT_RST_N);
+
+- /* get pinctrl */
+- pinctrl = devm_pinctrl_get_select_default(dev);
+- if (IS_ERR(pinctrl)) {
+- err = PTR_ERR(pinctrl);
+- /* deferring probe */
+- if (err == -EPROBE_DEFER) {
+- dev_warn(dev, "deferring proble\n");
+- return err;
+- }
+- dev_warn(dev, "pins are not configured from the driver\n");
++ /* binary starts from 0 */
++ ppc->entry_point = 0;
++
++ va = pru_i_da_to_va_block(ppc, ppc->entry_point, NULL, fw->size);
++ if (va == NULL) {
++ dev_err(dev, "FW is larger than available space (%u)\n",
++ fw->size);
++ return -ENOMEM;
+ }
+
+- /* we only work on OF */
+- if (dev->of_node == NULL) {
+- dev_err(dev, "Only OF configuration supported\n");
+- err = -ENODEV;
+- goto fail_of_node;
++ /* just copy */
++ memcpy(va, fw->data, fw->size);
++
++ return 0;
++}
++
++static int
++pruproc_elf_sanity_check(struct rproc *rproc, const struct firmware *fw)
++{
++ const char *name = rproc->firmware;
++ struct device *dev = &rproc->dev;
++ struct elf32_hdr *ehdr;
++ char class;
++
++ if (!fw) {
++ dev_err(dev, "failed to load %s\n", name);
++ return -EINVAL;
+ }
+
+- pm_runtime_enable(dev);
+- err = pm_runtime_get_sync(dev);
+- if (err != 0) {
+- dev_err(dev, "pm_runtime_get_sync failed\n");
+- goto fail_pm_runtime_get_sync;
++ if (fw->size < sizeof(struct elf32_hdr)) {
++ dev_err(dev, "Image is too small\n");
++ return -EINVAL;
+ }
+
+- err = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
+- if (err) {
+- dev_err(dev, "dma_set_coherent_mask: %d\n", err);
+- goto fail_dma_set_coherent_mask;
++ ehdr = (struct elf32_hdr *)fw->data;
++
++ /* We only support ELF32 at this point */
++ class = ehdr->e_ident[EI_CLASS];
++ if (class != ELFCLASS32) {
++ dev_err(dev, "Unsupported class: %d\n", class);
++ return -EINVAL;
+ }
+
+- rproc = rproc_alloc(dev, pdev->name, &pruproc_ops,
+- "prutest.bin", sizeof(*pruproc));
+- if (!rproc) {
+- dev_err(dev, "rproc_alloc failed\n");
+- err = -ENOMEM;
+- goto fail_rproc_alloc;
++ /* PRU is little endian */
++ if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {
++ dev_err(dev, "Unsupported firmware endianness\n");
++ return -EINVAL;
+ }
+
+- pruproc = rproc->priv;
+- pruproc->pdev = pdev;
+- pruproc->rproc = rproc;
++ if (fw->size < le32_to_cpu(ehdr->e_shoff) +
++ sizeof(struct elf32_shdr)) {
++ dev_err(dev, "Image is too small\n");
++ return -EINVAL;
++ }
+
+- platform_set_drvdata(pdev, pruproc);
++ if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
++ dev_err(dev, "Image is corrupted (bad magic)\n");
++ return -EINVAL;
++ }
+
+- /* Set the PRU specific firmware handler */
+- rproc->fw_ops = &pruproc_fw_ops;
++ if (le16_to_cpu(ehdr->e_phnum) == 0) {
++ dev_err(dev, "No loadable segments\n");
++ return -EINVAL;
++ }
+
+- /* Register as a remoteproc device */
+- err = rproc_add(rproc);
+- if (err) {
+- dev_err(dev, "rproc_add failed\n");
+- goto fail_rproc_add;
++ if (le32_to_cpu(ehdr->e_phoff) > fw->size) {
++ dev_err(dev, "Firmware size is too small\n");
++ return -EINVAL;
+ }
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- if (res == NULL) {
+- dev_err(dev, "failed to parse MEM resource\n");
+- goto fail_platform_get_resource;
++ return 0;
++}
++
++static int
++pruproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
++{
++ struct device *dev = &rproc->dev;
++ struct pruproc_core *ppc = rproc->priv;
++ struct elf32_hdr *ehdr;
++ struct elf32_phdr *phdr;
++ int i, ret = 0;
++ const u8 *elf_data = fw->data;
++ u32 da, memsz, filesz, offset, flags;
++ void * __iomem va;
++
++ pcntrl_write_reg(ppc, PCTRL_CONTROL, CONTROL_SOFT_RST_N);
++
++ ehdr = (struct elf32_hdr *)elf_data;
++ phdr = (struct elf32_phdr *)(elf_data + le32_to_cpu(ehdr->e_phoff));
++
++ /* go through the available ELF segments */
++ for (i = 0; i < le16_to_cpu(ehdr->e_phnum); i++, phdr++) {
++
++ da = le32_to_cpu(phdr->p_paddr);
++ memsz = le32_to_cpu(phdr->p_memsz);
++ filesz = le32_to_cpu(phdr->p_filesz);
++ offset = le32_to_cpu(phdr->p_offset);
++ flags = le32_to_cpu(phdr->p_flags);
++
++ if (le32_to_cpu(phdr->p_type) != PT_LOAD)
++ continue;
++
++ dev_dbg(dev, "phdr: type %d da 0x%x memsz 0x%x filesz 0x%x"
++ " flags %c%c%c\n",
++ le32_to_cpu(phdr->p_type),
++ da, memsz, filesz,
++ (flags & PF_R) ? 'R' : '-',
++ (flags & PF_W) ? 'W' : '-',
++ (flags & PF_X) ? 'E' : '-');
++
++ /* PRU is not a unified address space architecture */
++ /* we need to map differently executable & data segments */
++
++ if (filesz > memsz) {
++ dev_err(dev, "bad phdr filesz 0x%x memsz 0x%x\n",
++ filesz, memsz);
++ ret = -EINVAL;
++ break;
++ }
++
++ if (offset + filesz > fw->size) {
++ dev_err(dev, "truncated fw: need 0x%x avail 0x%zx\n",
++ offset + filesz, fw->size);
++ ret = -EINVAL;
++ break;
++ }
++
++ /* we can't use rproc_da_to_va (it relies on carveouts) */
++
++ /* text? to code area */
++ if (flags & PF_X)
++ va = pru_i_da_to_va_block(ppc, da, NULL, memsz);
++ else
++ va = pru_d_da_to_va_block(ppc, da, NULL, memsz);
++
++ /* check if valid section */
++ if (va == NULL) {
++ dev_err(dev, "fw: #%d @0x%x sz 0x%x bad\n",
++ i, da, memsz);
++ ret = -EINVAL;
++ break;
++ }
++
++ /* put the segment where the remote processor expects it */
++ if (filesz > 0)
++ memcpy(va, elf_data + offset, filesz);
++ else
++ memset(va, 0, memsz);
+ }
+
+- pruproc->vaddr = devm_ioremap(dev, res->start, resource_size(res));
+- if (pruproc->vaddr == NULL) {
+- dev_err(dev, "failed to parse MEM resource\n");
+- goto fail_devm_ioremap;
++ ppc->entry_point = le32_to_cpu(ehdr->e_entry);
++
++ return ret;
++}
++
++static
++u32 pruproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw)
++{
++ struct elf32_hdr *ehdr = (struct elf32_hdr *)fw->data;
++
++ return le32_to_cpu(ehdr->e_entry);
++}
++
++/* just return the built-firmware resources */
++static struct resource_table *
++pruproc_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
++ int *tablesz)
++{
++ struct pruproc_core *ppc = rproc->priv;
++
++ /* no resource table for this PRU */
++ if (ppc->table == NULL) {
++ *tablesz = 0;
++ return NULL;
+ }
+
+- dev_info(dev, "Loaded OK\n");
++ *tablesz = ppc->table_size;
++ return ppc->table;
++}
++
++void *get_resource_type(struct resource_table *res,
++ int type, int idx)
++{
++ struct fw_rsc_hdr *rsc_hdr;
++ int i, j;
++
++ j = 0;
++ for (i = 0; i < res->num; i++) {
++ rsc_hdr = (void *)res + res->offset[i];
++ if (type >= 0 && rsc_hdr->type != type)
++ continue;
++ if (j == idx)
++ return &rsc_hdr->data[0];
++ j++;
++ }
++
++ return NULL;
++}
++
++/* update the device's firmware resource with the allocated values */
++static int update_dev_rsc_table(struct pruproc_core *ppc)
++{
++ struct rproc *rproc = ppc->rproc;
++ struct device *dev = &rproc->dev;
++ struct rproc_vdev *rvdev;
++ struct rproc_vring *rvring;
++ struct pru_vring_info *vri;
++ struct fw_rsc_vdev *rsc_vdev;
++ int vdev_idx, i, cnt, err, j, vring_start, num_vrings;
++
++ /* no table; do nothing */
++ if (ppc->table == NULL)
++ return 0;
++
++ /* copy the resource table here */
++ memcpy(ppc->dev_table_va, ppc->table, ppc->table_size);
++
++ /* everything is initialized; fill in the real da & notify ids */
++ for (vdev_idx = 0; vdev_idx < ppc->num_vdevs; vdev_idx++) {
++ vring_start = ppc->vdev_vring_start[vdev_idx];
++ num_vrings = ppc->vdev_vring_count[vdev_idx];
++
++ /* find rvdev */
++ cnt = 0;
++ list_for_each_entry(rvdev, &rproc->rvdevs, node) {
++ if (cnt == vdev_idx)
++ break;
++ cnt++;
++ }
++ if (cnt != vdev_idx) {
++ dev_warn(dev, "rsc_vdev not found (continuing anyway)\n");
++ rvdev = NULL;
++ }
++
++ /* locate the vdev resource in the device memory */
++ rsc_vdev = get_resource_type(ppc->dev_table_va, RSC_VDEV,
++ vdev_idx);
++ if (rsc_vdev == NULL) {
++ dev_err(dev, "PRU#%d Failed to get RSV_VDEV #%d\n",
++ ppc->idx, vdev_idx);
++ err = -EINVAL;
++ goto err_fail;
++ }
++
++ for (i = 0; i < num_vrings; i++) {
++ j = vring_start + i;
++
++ vri = &ppc->vring_info[j];
++
++ if (rvdev != NULL)
++ rvring = &rvdev->vring[i];
++ else
++ rvring = NULL;
++
++ /* keep track of rproc's rvring */
++ vri->rvring = rvring;
++
++ rsc_vdev->vring[i].da = vri->da;
++ if (rvring != NULL)
++ rsc_vdev->vring[i].notifyid = rvring->notifyid;
++ else
++ rsc_vdev->vring[i].notifyid = -1; /* mark that it's not ready yet */
++
++ dev_info(dev, "VDEV#%d VR#%d da=0x%08x notifyid=0x%08x\n",
++ vdev_idx, i, vri->da, rvring->notifyid);
++ }
++ }
++
++#if 0
++ j = 0;
++ list_for_each_entry(rvdev, &rproc->rvdevs, node) {
++
++ /* get copied resource's VDEV */
++ rsc_vdev = get_resource_type(ppc->dev_table_va, RSC_VDEV,
++ vdev_idx);
++ if (rsc_vdev == NULL) {
++ dev_err(dev, "Failed to get RSV_VDEV #%d\n", vdev_idx);
++ err = -EINVAL;
++ goto err_fail;
++ }
++
++ for (i = 0; i < ARRAY_SIZE(rvdev->vring); i++) {
++ rvring = &rvdev->vring[i];
++
++ if (j >= ARRAY_SIZE(ppc->vring_info)) {
++ dev_err(dev, "Too many vrings\n");
++ err = -ENOENT;
++ goto err_fail;
++ }
++
++ vri = &ppc->vring_info[j];
++
++ /* keep track of rproc's rvring */
++ vri->rvring = rvring;
++
++ rsc_vdev->vring[i].da = vri->da;
++ rsc_vdev->vring[i].notifyid = rvring->notifyid;
++
++ dev_info(dev, "VDEV#%d VR#%d da=0x%08x notifyid=0x%08x\n",
++ vdev_idx, i, vri->da, rvring->notifyid);
++
++ j++;
++ }
++
++ vdev_idx++;
++ }
++#endif
+
+ return 0;
+-fail_devm_ioremap:
+-fail_platform_get_resource:
+- rproc_del(rproc);
+-fail_rproc_add:
+- platform_set_drvdata(pdev, NULL);
+- rproc_put(rproc);
+-fail_rproc_alloc:
+-fail_dma_set_coherent_mask:
+-fail_of_node:
+- pm_runtime_disable(dev);
+-fail_pm_runtime_get_sync:
++err_fail:
++ return err;
++
++}
++
++/* PRU binary firmware handler operations */
++const struct rproc_fw_ops pruproc_bin_fw_ops = {
++ .find_rsc_table = pruproc_find_rsc_table,
++ .load = pruproc_bin_load_segments,
++ .sanity_check = pruproc_bin_sanity_check,
++};
++
++/* PRU elf handler operations */
++const struct rproc_fw_ops pruproc_elf_fw_ops = {
++ .find_rsc_table = pruproc_find_rsc_table,
++ .load = pruproc_elf_load_segments,
++ .sanity_check = pruproc_elf_sanity_check,
++ .get_boot_addr = pruproc_elf_get_boot_addr,
++};
++
++void dump_vring(struct vring *vring)
++{
++ int i;
++ struct vring_desc *vd;
++
++ pr_info("vring: num=%u desc @%p\n", vring->num, vring->desc);
++
++ for (i = 0; i < vring->num; i++) {
++ vd = &vring->desc[i];
++ pr_info(" d#%2d: a 0x%016llx l 0x%08x f 0x%04x n 0x%04x\n",
++ i, vd->addr, vd->len, vd->flags, vd->next);
++ }
++ pr_info(" avail: flags 0x%04x idx 0x%04x\n",
++ vring->avail->flags, vring->avail->idx);
++ for (i = 0; i < vring->num; i++) {
++ pr_info(" a#%2d: ring 0x%04x\n", i,
++ vring->avail->ring[i]);
++ }
++ pr_info(" avail: used_event_idx 0x%04x\n",
++ vring->avail->ring[vring->num]);
++
++ pr_info(" used: flags 0x%04x idx 0x%04x\n",
++ vring->used->flags, vring->used->idx);
++ for (i = 0; i < vring->num; i++) {
++ pr_info(" u#%2d: id 0x%08x len 0x%08x\n", i,
++ vring->used->ring[i].id,
++ vring->used->ring[i].len);
++ }
++}
++
++void dump_all_vrings(struct pruproc_core *ppc)
++{
++ struct device *dev = &ppc->rproc->dev;
++ struct vring *vr;
++ struct fw_rsc_vdev_vring *rsc_vr;
++ struct pru_vring_info *vri;
++ int i;
++
++ for (i = 0; i < ppc->num_vrings; i++) {
++ vri = &ppc->vring_info[i];
++
++ vr = &vri->vr;
++ rsc_vr = vri->rsc;
++
++ dev_dbg(dev, "VRING #%d (size %d)\n", i,
++ vring_size(vr->num, rsc_vr->align));
++ dump_vring(vr);
++ dev_dbg(dev, "\n");
++ print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,
++ 16, 4, vr->desc,
++ vring_size(vr->num, rsc_vr->align),
++ false);
++ }
++}
++
++/* Kick the modem with specified notification id */
++static void pruproc_kick(struct rproc *rproc, int vqid)
++{
++ struct device *dev = &rproc->dev;
++ struct pruproc_core *ppc = rproc->priv;
++ struct pruproc *pp = ppc->pruproc;
++ int sysint;
++
++ dev_dbg(dev, "kick #%d vqid:%d\n", ppc->idx, vqid);
++
++ /* ARM to PRUx system event */
++ sysint = pp->target_to_sysev[TARGET_ARM_TO_PRU_IDX(ppc->idx)];
++
++ /* signal event */
++ if (sysint < 32)
++ pintc_write_reg(pp, PINTC_SRSR0, 1 << sysint);
++ else
++ pintc_write_reg(pp, PINTC_SRSR1, 1 << (sysint - 32));
++
++ // dump_all_vrings(ppc);
++}
++
++void dump_resource_table(const struct resource_table *res)
++{
++ const struct fw_rsc_hdr *rsc_hdr;
++ const struct fw_rsc_vdev *rsc_vdev;
++ const struct fw_rsc_vdev_vring *rsc_vring;
++ int i, j;
++
++ /* do nothing if given nothing */
++ if (res == NULL)
++ return;
++
++ pr_info("resource_table @%p\n", res);
++ pr_info(" .ver = 0x%08x\n", res->ver);
++ pr_info(" .num = 0x%08x\n", res->num);
++ for (i = 0; i < res->num; i++) {
++ rsc_hdr = (void *)res + res->offset[i];
++ pr_info(" rsc_hdr#%d: .type = 0x%08x\n", i,
++ rsc_hdr->type);
++ switch (rsc_hdr->type) {
++ case RSC_CARVEOUT:
++ pr_info(" CARVEOUT:\n");
++ break;
++ case RSC_DEVMEM:
++ pr_info(" DEVMEM:\n");
++ break;
++ case RSC_TRACE:
++ pr_info(" TRACE:\n");
++ break;
++ case RSC_VDEV:
++ pr_info(" VDEV:\n");
++ rsc_vdev = (void *)&rsc_hdr->data[0];
++ pr_info(" .id = 0x%08x\n", rsc_vdev->id);
++ pr_info(" .notifyid = 0x%08x\n", rsc_vdev->notifyid);
++ pr_info(" .dfeatures = 0x%08x\n", rsc_vdev->dfeatures);
++ pr_info(" .gfeatures = 0x%08x\n", rsc_vdev->gfeatures);
++ pr_info(" .config_len = 0x%08x\n", rsc_vdev->config_len);
++ pr_info(" .status = 0x%02x\n", rsc_vdev->status);
++ pr_info(" .num_of_vrings = 0x%02x\n", rsc_vdev->num_of_vrings);
++ for (j = 0; j < rsc_vdev->num_of_vrings; j++) {
++ rsc_vring = &rsc_vdev->vring[j];
++ pr_info(" VRING #%d:\n", j);
++ pr_info(" .da = 0x%08x\n",
++ rsc_vring->da);
++ pr_info(" .align = 0x%08x\n",
++ rsc_vring->align);
++ pr_info(" .num = 0x%08x\n",
++ rsc_vring->num);
++ pr_info(" .notifyid = 0x%08x\n",
++ rsc_vring->notifyid);
++ }
++ break;
++ }
++ }
++}
++
++/* Start the PRU modem */
++static int pruproc_start(struct rproc *rproc)
++{
++ struct device *dev = &rproc->dev;
++ struct pruproc_core *ppc = rproc->priv;
++ u32 val;
++ int err;
++
++ /* start the processors only when all devices have booted */
++ if (ppc->num_vdevs == 0 || atomic_inc_return(&ppc->bootcnt) == 1) {
++
++ dev_info(dev, "start PRU #%d entry-point 0x%x\n",
++ ppc->idx, ppc->entry_point);
++
++#if 1
++ if (ppc->table)
++ dump_resource_table(ppc->table);
++
++ err = update_dev_rsc_table(ppc);
++ if (err != 0) {
++ dev_err(dev, "failed to update resource table\n");
++ return err;
++ }
++
++ if (ppc->dev_table_va)
++ dump_resource_table(ppc->dev_table_va);
++
++#endif
++
++
++ val = CONTROL_ENABLE | ((ppc->entry_point >> 2) << 16);
++ pcntrl_write_reg(ppc, PCTRL_CONTROL, val);
++ }
++
++ return 0;
++}
++
++/* Stop the PRU modem */
++static int pruproc_stop(struct rproc *rproc)
++{
++ struct device *dev = &rproc->dev;
++ struct pruproc_core *ppc = rproc->priv;
++ u32 val;
++
++ /* we have to copy the resource table and update the device addresses */
++ if (1 || ppc->num_vdevs == 0 || atomic_dec_return(&ppc->bootcnt) == 0) {
++
++ dev_info(dev, "PRU#%d stop\n", ppc->idx);
++
++ val = pcntrl_read_reg(ppc, PCTRL_CONTROL);
++ val &= ~CONTROL_ENABLE;
++ pcntrl_write_reg(ppc, PCTRL_CONTROL, val);
++ }
++
++ return 0;
++}
++
++static void *pruproc_alloc_vring(struct rproc *rproc,
++ const struct fw_rsc_vdev_vring *rsc_vring,
++ int size, dma_addr_t *dma)
++{
++ struct device *dev = &rproc->dev;
++ struct pruproc_core *ppc = rproc->priv;
++ struct pru_vring_info *vri;
++ struct vring *vring;
++ void * __iomem va;
++ dma_addr_t dma_tmp;
++ int i;
++
++ dev_dbg(dev, "PRU#%d alloc rsc_vring %p\n",
++ ppc->idx, rsc_vring);
++
++ /* find vring index */
++ for (i = 0; i < ppc->num_vrings; i++) {
++ if (rsc_vring == ppc->vring_info[i].rsc)
++ break;
++ }
++
++ if (i >= ppc->num_vrings) {
++ dev_err(dev, "PRU #%d could not find rsc_vring at %p\n",
++ ppc->idx, rsc_vring);
++ return NULL;
++ }
++
++ if (dma == NULL)
++ dma = &dma_tmp;
++
++ if (rsc_vring->da != 0) {
++ dev_dbg(dev, "PRU #%d alloc vring #%d from internal memory\n",
++ ppc->idx, i);
++ va = pru_d_da_to_va_block(ppc, rsc_vring->da, dma, size);
++ } else {
++ dev_dbg(dev, "PRU #%d alloc vring #%d dma_alloc_coherent\n",
++ ppc->idx, i);
++ va = dma_alloc_coherent(dev->parent, PAGE_ALIGN(size),
++ dma, GFP_KERNEL);
++ }
++
++ if (va == NULL) {
++ dev_err(dev, "PRU #%d could not allocate vring %p\n",
++ ppc->idx, rsc_vring);
++ return NULL;
++ }
++
++ /* setup vring for use */
++ vri = &ppc->vring_info[i];
++ vring = &vri->vr;
++ vring_init(vring, rsc_vring->num, va, rsc_vring->align);
++
++ /* save VA & PA */
++ vri->va = va;
++ vri->pa = *dma;
++ vri->da = pru_d_pa_to_da(ppc, *dma);
++
++ dev_dbg(dev, "PRU #%d vring #%d da=0x%x, va=%p, dma=0x%llx size=%u\n",
++ ppc->idx, i, rsc_vring->da, va, (unsigned long long)*dma, size);
++
++ return va;
++}
++
++static void pruproc_free_vring(struct rproc *rproc,
++ const struct fw_rsc_vdev_vring *rsc_vring,
++ int size, void *va, dma_addr_t dma)
++{
++ struct device *dev = &rproc->dev;
++
++ /* if DA is NULL, means we allocated via dma_alloc_coherent */
++ if (rsc_vring->da == 0)
++ dma_free_coherent(dev->parent, PAGE_ALIGN(size), va, dma);
++}
++
++static struct rproc_ops pruproc_ops = {
++ .start = pruproc_start,
++ .stop = pruproc_stop,
++ .kick = pruproc_kick,
++
++ .alloc_vring = pruproc_alloc_vring,
++ .free_vring = pruproc_free_vring,
++};
++
++static ssize_t pruproc_store_load(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct pruproc *pp = platform_get_drvdata(pdev);
++ struct pruproc_core *ppc;
++ char *fw_name[MAX_PRUS];
++ const char *s, *e, *t;
++ int i, pru_idx, sz, err;
++ const struct firmware *fw;
++ u32 val;
++
++ memset(fw_name, 0, sizeof(fw_name));
++
++ s = buf;
++ while (*s != '\0' && *s != '\n') {
++ e = strchr(s, ',');
++ if (e == NULL) {
++ e = s + strlen(s);
++ while (e > buf && e[-1] == '\n')
++ e--;
++ }
++ t = strchr(s, ':');
++ if (t == NULL) {
++ t = s;
++ pru_idx = 0;
++ } else {
++ t++;
++ pru_idx = simple_strtoul(s, NULL, 10);
++ }
++
++ for (i = 0; i < pp->num_prus; i++) {
++ ppc = pp->pruc[i];
++ if (pru_idx == ppc->idx)
++ break;
++ }
++ if (i >= pp->num_prus) {
++ dev_err(dev, "Can not find PRU#%d\n", pru_idx);
++ return -EINVAL;
++ }
++
++ sz = e - t;
++ fw_name[pru_idx] = kzalloc(sz + 1, GFP_KERNEL);
++ if (fw_name[pru_idx] == NULL)
++ return -ENOMEM;
++ memcpy(fw_name[pru_idx], t, sz);
++ fw_name[pru_idx][sz] = '\0';
++
++ s = e;
++ if (*s == ',')
++ s++;
++ }
++
++ /* first halt every PRU affected */
++ for (i = 0; i < pp->num_prus; i++) {
++ ppc = pp->pruc[i];
++
++ if (fw_name[ppc->idx] == NULL)
++ continue;
++
++ /* keep it in reset */
++ pcntrl_write_reg(ppc, PCTRL_CONTROL, CONTROL_SOFT_RST_N);
++
++ dev_info(dev, "PRU#%d halted\n", ppc->idx);
++
++ }
++
++ /* load every PRU */
++ for (i = 0; i < pp->num_prus; i++) {
++ ppc = pp->pruc[i];
++ if (fw_name[ppc->idx] == NULL)
++ continue;
++
++ dev_info(dev, "PRU#%d loading %s\n", ppc->idx, fw_name[ppc->idx]);
++
++ /* note this is not the rproc device */
++ err = request_firmware(&fw, fw_name[ppc->idx], dev);
++ if (err != 0) {
++ dev_err(dev, "PRU#%d Failed to load firmware %s\n",
++ ppc->idx, fw_name[ppc->idx]);
++ return err;
++ }
++
++ err = pruproc_elf_load_segments(ppc->rproc, fw);
++ if (err != 0) {
++ dev_err(dev, "PRU#%d Failed to update firmware %s\n",
++ ppc->idx, fw_name[ppc->idx]);
++ return err;
++ }
++
++ release_firmware(fw);
++ }
++
++ /* start every PRU affected */
++ for (i = 0; i < pp->num_prus; i++) {
++ ppc = pp->pruc[i];
++ if (fw_name[ppc->idx] == NULL)
++ continue;
++
++ dev_info(dev, "PRU#%d starting %s\n", ppc->idx, fw_name[ppc->idx]);
++
++ val = CONTROL_ENABLE | ((ppc->entry_point >> 2) << 16);
++ pcntrl_write_reg(ppc, PCTRL_CONTROL, val);
++
++ /* and free */
++ kfree(fw_name[ppc->idx]);
++ fw_name[ppc->idx] = NULL;
++ };
++
++ return strlen(buf);
++}
++
++static ssize_t pruproc_store_reset(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct pruproc *pp = platform_get_drvdata(pdev);
++ struct pruproc_core *ppc;
++ int i;
++ u32 val;
++
++ /* first halt every PRU affected */
++ for (i = 0; i < pp->num_prus; i++) {
++ ppc = pp->pruc[i];
++ /* keep it in reset */
++ pcntrl_write_reg(ppc, PCTRL_CONTROL, CONTROL_SOFT_RST_N);
++ }
++
++ /* start every PRU affected */
++ for (i = 0; i < pp->num_prus; i++) {
++ ppc = pp->pruc[i];
++ val = CONTROL_ENABLE | ((ppc->entry_point >> 2) << 16);
++ pcntrl_write_reg(ppc, PCTRL_CONTROL, val);
++
++ };
++
++ return strlen(buf);
++}
++
++static DEVICE_ATTR(load, S_IWUSR, NULL, pruproc_store_load);
++static DEVICE_ATTR(reset, S_IWUSR, NULL, pruproc_store_reset);
++
++/* PRU is unregistered */
++static int pruproc_remove(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct pruproc *pp = platform_get_drvdata(pdev);
++ struct pruproc_core *ppc;
++ int i;
++
++ dev_dbg(dev, "remove pru\n");
++
++ device_remove_file(dev, &dev_attr_reset);
++ device_remove_file(dev, &dev_attr_load);
++
++ /* Unregister as remoteproc device */
++ for (i = pp->num_prus - 1; i >= 0; i--) {
++ ppc = pp->pruc[i];
++ rproc_del(ppc->rproc);
++ rproc_put(ppc->rproc);
++
++ if (ppc->dev_table_va != NULL)
++ dma_free_coherent(dev, PAGE_ALIGN(ppc->table_size),
++ ppc->dev_table_va, ppc->dev_table_pa);
++ }
++
++ platform_set_drvdata(pdev, NULL);
++
++ return 0;
++}
++
++#define PRU_HALT_INSN 0x2a000000
++
++#define PRU_SC_HALT 0
++#define PRU_SC_PUTC 1
++#define PRU_SC_EXIT 2
++#define PRU_SC_PUTS 3
++#define PRU_SC_GET_CFG 4
++#define PRU_SC_GET_CFG_VRING_NR 0
++#define PRU_SC_GET_CFG_VRING_INFO 1
++#define PRU_SC_GET_CFG_RESOURCE_TABLE 2
++
++struct pru_dev_vring_info {
++ u32 paddr;
++ u32 num;
++ u32 align;
++ u32 pad;
++};
++
++static int pru_handle_syscall(struct pruproc_core *ppc)
++{
++ struct pruproc *pp = ppc->pruproc;
++ struct device *dev = &pp->pdev->dev;
++ u32 val, addr, scno, arg0, arg1, arg2, ret;
++ int err, valid_sc;
++ void * __iomem va;
++ struct pru_vring_info *vri;
++ struct pru_dev_vring_info *dvri;
++
++ /* check whether it's halted */
++ val = pcntrl_read_reg(ppc, PCTRL_CONTROL);
++ if ((val & CONTROL_RUNSTATE) != 0) {
++ dev_dbg(dev, "PRU #%d not halted\n",
++ ppc->idx);
++ return -EINVAL;
++ }
++
++ /* read the instruction */
++ addr = pcntrl_read_reg(ppc, PCTRL_STATUS) * 4;
++ err = pru_i_read_u32(ppc, addr, &val);
++ if (err != 0) {
++ dev_err(dev, "PRU #%d halted PC 0x%x bad\n", ppc->idx, addr);
++ return err;
++ }
++
++ /* check whether it's a halt instruction */
++ if (val != PRU_HALT_INSN) {
++ dev_err(dev, "PRU #%d not in halt insn (addr=0x%x val 0x%08x)\n",
++ ppc->idx, addr, val);
++ return -EFAULT;
++ }
++
++ valid_sc = 0;
++ scno = pdbg_read_reg(ppc, PDBG_GPREG(14));
++ arg0 = pdbg_read_reg(ppc, PDBG_GPREG(15));
++ arg1 = pdbg_read_reg(ppc, PDBG_GPREG(16));
++ arg2 = pdbg_read_reg(ppc, PDBG_GPREG(17));
++ ret = 0; /* by default we return 0 */
++
++ switch (scno) {
++ case PRU_SC_HALT:
++ dev_info(dev, "P%d HALT\n",
++ ppc->idx);
++ return 1;
++
++ case PRU_SC_PUTC:
++ dev_info(dev, "P%d PUTC '%c'\n",
++ ppc->idx, (char)(arg0 & 0xff));
++ break;
++
++ case PRU_SC_EXIT:
++ dev_info(dev, "P%d EXIT %d\n",
++ ppc->idx, (int)arg0);
++ return 1;
++
++ case PRU_SC_PUTS:
++ /* pointers can only be in own data ram */
++ va = pru_d_da_to_va(ppc, arg0, NULL);
++ if (va == NULL) {
++ dev_err(dev, "PRU #%d SC PUTS bad 0x%x\n",
++ ppc->idx, arg0);
++ ret = (u32)-1;
++ } else {
++ dev_info(dev, "P%d PUTS '%s'\n",
++ ppc->idx, (char *)va);
++ }
++ break;
++
++ case PRU_SC_GET_CFG:
++ switch (arg0) {
++ case PRU_SC_GET_CFG_VRING_NR:
++ ret = ppc->num_vrings; /* two rings */
++ dev_dbg(dev, "P%d GET_CFG VRING_NR %d\n",
++ ppc->idx, (int)ret);
++ break;
++ case PRU_SC_GET_CFG_VRING_INFO:
++ if (arg1 >= ppc->num_vrings) {
++ dev_err(dev, "PRU #%d SC "
++ "GET_CFG_VRING_INFO "
++ "bad idx %d\n",
++ ppc->idx, arg1);
++ }
++
++ va = pru_d_da_to_va(ppc, arg2, NULL);
++ if (va == NULL) {
++ dev_err(dev, "PRU #%d SC "
++ "GET_CFG_VRING_INFO "
++ "bad 0x%x\n",
++ ppc->idx, arg2);
++ ret = (u32)-1;
++ break;
++ }
++ dvri = va;
++ vri = &ppc->vring_info[arg1];
++
++ /* fill it in */
++ dvri->paddr = vri->pa;
++ dvri->num = vri->rsc->num;
++ dvri->align = vri->rsc->align;
++ dvri->pad = 0;
++
++ dev_dbg(dev, "P%d GET_CFG VRING_INFO %d\n",
++ ppc->idx, (int)ret);
++ break;
++
++ case PRU_SC_GET_CFG_RESOURCE_TABLE:
++ /* just return the physical address */
++ ret = (u32)ppc->dev_table_pa;
++ dev_dbg(dev, "P%d GET_CFG RESOURCE_TABLE 0x%x\n",
++ ppc->idx, ret);
++ break;
++
++ default:
++ dev_err(dev, "PRU #%d SC "
++ "GET_CFG bad 0x%x\n",
++ ppc->idx, arg1);
++ ret = (u32)-1;
++ break;
++ }
++ break;
++
++ default:
++ dev_err(dev, "PRU #%d SC Unknown (%d)\n",
++ ppc->idx, scno);
++ return 1;
++ }
++
++ /* return code */
++ pdbg_write_reg(ppc, PDBG_GPREG(14), ret);
++
++ /* skip over the HALT insn */
++ val = pcntrl_read_reg(ppc, PCTRL_CONTROL);
++ val &= 0xffff;
++ addr = pcntrl_read_reg(ppc, PCTRL_STATUS);
++ val |= ((addr + 1) << 16) | CONTROL_ENABLE;
++ val &= ~CONTROL_SOFT_RST_N;
++
++ /* dev_dbg(dev, "PRU#%d new PCTRL_CONTROL=0x%08x\n",
++ ppc->idx, val); */
++
++ pcntrl_write_reg(ppc, PCTRL_CONTROL, val);
++
++ return 0;
++}
++
++static irqreturn_t pru_handler(int irq, void *data)
++{
++ struct pruproc *pp = data;
++ struct pruproc_core *ppc;
++ struct pru_sysev_target *pst;
++ struct rproc *rproc;
++ struct device *dev = &pp->pdev->dev;
++ int pru_idx, i, ev, sysint, handled, ret;
++ struct pru_vring_info *vri;
++ u32 val;
++
++ /* find out which IRQ we got */
++ for (i = 0; i < pp->num_irqs; i++)
++ if (irq == pp->irqs[i])
++ break;
++ if (i >= pp->num_irqs)
++ return IRQ_NONE;
++
++ ev = pp->events[i];
++
++ /* first, check whether the interrupt is enabled */
++ val = pintc_read_reg(pp, PINTC_HIER);
++ if ((val & (1 << ev)) == 0)
++ return IRQ_NONE;
++
++ /* check non-pending bit of specific event */
++ val = pintc_read_reg(pp, PINTC_HIPIR0 + (ev << 2));
++ if ((val & HIPIR_NOPEND) != 0)
++ return IRQ_NONE;
++
++ sysint = val & 0x3f;
++
++ /* clear event */
++ if (sysint < 32)
++ pintc_write_reg(pp, PINTC_SECR0, 1 << sysint);
++ else
++ pintc_write_reg(pp, PINTC_SECR1, 1 << (sysint - 32));
++
++ /* get the source of the sysevent */
++ pst = &pp->sysev_to_target[sysint];
++ if (pst->valid == 0 || pst->source < -1 || pst->target < -1) {
++ dev_warn(dev, "sysevent not handled %d; disabling\n",
++ sysint);
++ goto disable_int;
++ }
++
++ /* target self? not handled */
++ if (pst->source == TARGET_ARM) {
++ dev_warn(dev, "sysevent %d has host as source; disabling\n",
++ sysint);
++ goto disable_int;
++ }
++
++ /* find out which PRU was it */
++ pru_idx = TARGET_PRU_TO_PRU_IDX(pst->source);
++ ppc = pp->pru_to_pruc[pru_idx];
++ if (ppc == NULL) {
++ dev_warn(dev, "systevent %d from bad PRU; disabling\n",
++ sysint);
++ goto disable_int;
++ }
++
++ /* ok, got the source PRU */
++ rproc = ppc->rproc;
++
++ handled = 0;
++
++ /* we either handle a vring or not */
++ if (!pst->vring) {
++ ret = pru_handle_syscall(ppc);
++ if (ret == 0) /* system call handled */
++ handled++;
++ } else {
++ /* handle any vrings action */
++ for (i = 0; i < ppc->num_vrings; i++) {
++ vri = &ppc->vring_info[i];
++ if (vri->rvring == NULL)
++ continue;
++ ret = rproc_vq_interrupt(rproc, vri->rvring->notifyid);
++ if (ret == IRQ_HANDLED) {
++ dev_dbg(dev, "PRU #%d; vring irq handled\n",
++ ppc->idx);
++ handled++;
++ }
++
++ }
++ }
++
++#if 0
++ if (!handled) {
++ dev_err(dev, "sysint not handled; disabling interrupt\n");
++ goto disable_int;
++
++ }
++#endif
++
++ return IRQ_HANDLED;
++
++disable_int:
++ /* disable the interrupt */
++ pintc_write_reg(pp, PINTC_HIDISR, ev);
++ return IRQ_HANDLED;
++}
++
++static int build_rsc_table(struct platform_device *pdev,
++ struct device_node *node, struct pruproc_core *ppc)
++{
++ struct device *dev = &pdev->dev;
++ struct device_node *rnode = NULL; /* resource table node */
++ struct device_node *rvnode = NULL; /* vdev node */
++ // struct pruproc *pp = ppc->pruproc;
++ struct resource_table *rsc;
++ struct fw_rsc_hdr *rsc_hdr;
++ struct fw_rsc_vdev *rsc_vdev;
++ struct pru_vring_info *vri;
++ char vring_name[16];
++ u32 vring_data[4], val;
++ struct fw_rsc_vdev_vring *rsc_vring;
++ void *table, *p;
++ int i, err, table_size, num_vrings, num_vdevs, vdev_idx, vring_start;
++
++ /* verify OF data */
++
++ /* first find a valid resource-table node */
++ for_each_child_of_node(node, rnode) {
++ if (of_property_read_bool(rnode, "resource-table"))
++ break;
++ }
++
++ /* no resource node found */
++ if (rnode == NULL) {
++ dev_warn(dev, "No resource-table node node; slave PRU\n");
++ return 0;
++ }
++
++ /* count number of vdevs & vrings */
++
++ table_size = sizeof(struct resource_table);
++
++ num_vdevs = 0;
++ num_vrings = 0;
++ for_each_child_of_node(rnode, rvnode) {
++
++ if (!of_property_read_bool(rvnode, "vdev-rproc-serial") &&
++ !of_property_read_bool(rvnode, "vdev-rpmsg"))
++ continue;
++
++ /* size per each vdev */
++ table_size += sizeof(u32) +
++ sizeof(struct fw_rsc_hdr) +
++ sizeof(struct fw_rsc_vdev);
++
++ ppc->vdev_vring_start[num_vdevs] = num_vrings;
++ for (i = 0; num_vrings < ARRAY_SIZE(ppc->vring_info); i++) {
++ snprintf(vring_name, sizeof(vring_name), "vring-%d", i);
++ if (of_property_read_u32_array(rvnode, vring_name,
++ vring_data, ARRAY_SIZE(vring_data)) != 0)
++ break;
++ num_vrings++;
++ }
++ ppc->vdev_vring_count[num_vdevs] = i;
++
++ /* size for the rings */
++ table_size += i * sizeof(struct fw_rsc_vdev_vring);
++
++ num_vdevs++;
++ }
++
++ dev_info(dev, "PRU%d #%d vdevs, #%d vrings total\n",
++ ppc->idx, num_vdevs, num_vrings);
++
++ table = devm_kzalloc(dev, table_size, GFP_KERNEL);
++ if (table == NULL) {
++ dev_err(dev, "Failed to allocate resource table\n");
++ err = -ENOMEM;
++ goto err_fail;
++ }
++ ppc->table = table;
++ ppc->table_size = table_size;
++ ppc->num_vdevs = num_vdevs;
++ ppc->num_vrings = num_vrings;
++
++ p = table; /* pointer at start */
++
++ /* resource table */
++ rsc = p;
++ p += sizeof(*rsc);
++ rsc->ver = 1; /* resource table version 1 */
++ rsc->num = ppc->num_vdevs;
++
++ p += rsc->num * sizeof(u32); /* point after offsets */
++
++ vdev_idx = 0;
++
++ /* now loop over the vdevs */
++ for_each_child_of_node(rnode, rvnode) {
++
++ if (!of_property_read_bool(rvnode, "vdev-rproc-serial") &&
++ !of_property_read_bool(rvnode, "vdev-rpmsg"))
++ continue;
++
++ rsc_hdr = p;
++ rsc->offset[vdev_idx] = p - table;
++ /* resource header */
++ p += sizeof(*rsc_hdr);
++
++ rsc_hdr->type = RSC_VDEV;
++
++ /* vdev */
++ rsc_vdev = p;
++ p += sizeof(*rsc_vdev);
++ ppc->rsc_vdev[vdev_idx] = rsc_vdev;
++
++ if (of_property_read_bool(rvnode, "vdev-rproc-serial")) {
++ rsc_vdev->id = VIRTIO_ID_RPROC_SERIAL;
++ /* extra configuration possible here */
++ } else if (of_property_read_bool(rvnode, "vdev-rpmsg")) {
++ rsc_vdev->id = VIRTIO_ID_RPMSG;
++ /* extra configuration possible here */
++ }
++
++ err = of_property_read_u32(rvnode, "notifyid", &val);
++ if (err != 0) {
++ dev_err(dev, "no notifyid vdev property\n");
++ goto err_fail;
++ }
++ rsc_vdev->notifyid = val;
++ rsc_vdev->dfeatures = 0;
++ rsc_vdev->gfeatures = 0;
++ rsc_vdev->config_len = 0;
++ rsc_vdev->status = 0;
++
++ /* start and count for vrings for this vdev */
++ vring_start = ppc->vdev_vring_start[vdev_idx];
++ num_vrings = ppc->vdev_vring_count[vdev_idx];
++
++ rsc_vdev->num_of_vrings = num_vrings;
++
++ for (i = 0; i < num_vrings; i++) {
++ rsc_vring = p;
++ p += sizeof(*rsc_vring);
++
++ vri = &ppc->vring_info[i + vring_start];
++
++ vri->rsc = rsc_vring;
++
++ snprintf(vring_name, sizeof(vring_name), "vring-%d",
++ i);
++ err = of_property_read_u32_array(rvnode, vring_name,
++ vring_data, ARRAY_SIZE(vring_data));
++ if (err != 0) {
++ dev_err(dev, "no %s property\n", vring_name);
++ goto err_fail;
++ }
++ rsc_vring->da = vring_data[0];
++ rsc_vring->align = vring_data[1];
++ rsc_vring->num = vring_data[2];
++ rsc_vring->notifyid = vring_data[3];
++ }
++
++ vdev_idx++;
++ }
++
++ /* all done, create the device copy */
++ ppc->dev_table_va = dma_alloc_coherent(dev,
++ PAGE_ALIGN(ppc->table_size), &ppc->dev_table_pa,
++ GFP_KERNEL);
++ if (ppc->dev_table_va == NULL) {
++ dev_err(dev, "Failed to dma_alloc dev resource table\n");
++ err = -ENOMEM;
++ goto err_fail;
++ }
++
++ err = 0;
++
++err_fail:
++ of_node_put(rnode);
++
++ return err;
++}
++
++static int read_map_property(struct device *dev,
++ struct device_node *node, const char *propname,
++ int *map, int max_idx, int max_val)
++{
++ struct property *prop;
++ int i, idx, val, cnt, proplen, err;
++ u32 *arr, *p;
++
++ /* check node & propname */
++ if (node == NULL || propname == NULL) {
++ dev_err(dev, "Bad arguments\n");
++ return -EINVAL;
++ }
++
++ /* find property */
++ prop = of_find_property(node, propname, &proplen);
++ if (prop == NULL) {
++ dev_err(dev, "Can't find %s property\n", propname);
++ return -ENOENT;
++ }
++
++ /* verify valid size (must be pairs of u32 items) */
++ if ((proplen % (sizeof(u32) * 2)) != 0) {
++ dev_err(dev, "Bad length (%d) of %s property\n",
++ proplen, propname);
++ return -EINVAL;
++ }
++
++ /* allocate temporary buffer */
++ arr = devm_kzalloc(dev, proplen, GFP_KERNEL);
++ if (arr == NULL) {
++ dev_err(dev, "Alloc failed on %s property\n", propname);
++ return -ENOMEM;
++ }
++
++ /* the number of pairs */
++ cnt = proplen / (sizeof(arr[0]) * 2);
++
++ /* now read it */
++ err = of_property_read_u32_array(node, propname, arr, cnt * 2);
++ if (err != 0) {
++ dev_err(dev, "Failed to read %s property\n", propname);
++ return err;
++ }
++
++ /* now read pairs and fill in the map */
++ for (i = 0, p = arr; i < cnt; i++, p += 2) {
++ idx = p[0];
++ val = p[1];
++ if ((unsigned int)idx >= max_idx) {
++ dev_err(dev, "%s[%d] bad map idx %d\n",
++ propname, i, idx);
++ return err;
++ }
++ if ((unsigned int)val >= max_val) {
++ dev_err(dev, "%s[%d] bad map val %d\n",
++ propname, i, val);
++ return err;
++ }
++ /* fill in map */
++ map[idx] = val;
++ dev_info(dev, "%s [%d] <- %d\n", propname, idx, val);
++ }
++
++ devm_kfree(dev, arr);
++
++ return 0;
++}
++
++static int configure_pintc(struct platform_device *pdev, struct pruproc *pp)
++{
++ struct device *dev = &pdev->dev;
++ struct device_node *node = dev->of_node;
++ int err, i, idx, ch, host;
++ uint64_t sysevt_mask;
++ uint32_t ch_mask;
++ uint32_t host_mask;
++ u32 val;
++
++ /* retreive the maps */
++ err = read_map_property(dev, node, "sysevent-to-channel-map",
++ pp->sysev_to_ch, ARRAY_SIZE(pp->sysev_to_ch),
++ MAX_PRU_CHANNELS);
++ if (err != 0)
++ return err;
++
++ err = read_map_property(dev, node, "channel-to-host-interrupt-map",
++ pp->ch_to_host, ARRAY_SIZE(pp->ch_to_host),
++ MAX_PRU_HOST_INT);
++ if (err != 0)
++ return err;
++
++ err = of_property_read_u32_array(node, "target-to-sysevent-map",
++ pp->target_to_sysev, ARRAY_SIZE(pp->target_to_sysev));
++ if (err != 0)
++ return err;
++
++ /* now configure the pintc appropriately */
++
++ /* configure polarity and type (all active high & pulse) */
++ pintc_write_reg(pp, PINTC_SIPR0, 0xffffffff);
++ pintc_write_reg(pp, PINTC_SIPR1, 0xffffffff);
++
++ /* clear all channel mapping registers */
++ for (i = PINTC_CMR0; i <= PINTC_CMR15; i += 4)
++ pintc_write_reg(pp, i, 0);
++
++ sysevt_mask = 0;
++ ch_mask = 0;
++ host_mask = 0;
++
++ /* set channel mapping registers we have */
++ for (i = 0; i < ARRAY_SIZE(pp->sysev_to_ch); i++) {
++
++ ch = pp->sysev_to_ch[i];
++ if (ch < 0)
++ continue;
++
++ /* CMR format: ---CH3---CH2---CH1---CH0 */
++
++ /* 4 settings in each register */
++ idx = i / 4;
++
++ /* update CMR entry */
++ val = pintc_read_reg(pp, PINTC_CMR0 + idx * 4);
++ val |= (u32)ch << ((i & 3) * 8);
++ pintc_write_reg(pp, PINTC_CMR0 + idx * 4, val);
++
++ /* set bit in the sysevent mask */
++ sysevt_mask |= 1LLU << i;
++ /* set bit in the channel mask */
++ ch_mask |= 1U << ch;
++
++ dev_dbg(dev, "SYSEV%d -> CH%d (CMR%d 0x%08x)\n",
++ i, ch, idx,
++ pintc_read_reg(pp, PINTC_CMR0 + idx * 4));
++ }
++
++ /* clear all host mapping registers */
++ for (i = PINTC_HMR0; i <= PINTC_HMR2; i += 4)
++ pintc_write_reg(pp, i, 0);
++
++ /* set host mapping registers we have */
++ for (i = 0; i < ARRAY_SIZE(pp->ch_to_host); i++) {
++
++ host = pp->ch_to_host[i];
++ if (host < 0)
++ continue;
++
++ /* HMR format: ---HI3---HI2---HI1---HI0 */
++
++ /* 4 settings in each register */
++ idx = i / 4;
++
++ /* update HMR entry */
++ val = pintc_read_reg(pp, PINTC_HMR0 + idx * 4);
++ val |= (u32)host << ((i & 3) * 8);
++ pintc_write_reg(pp, PINTC_HMR0 + idx * 4, val);
++
++ /* set bit in the channel mask */
++ ch_mask |= 1U << i;
++ /* set bit in the sysevent mask */
++ host_mask |= 1U << host;
++
++ dev_dbg(dev, "CH%d -> HOST%d (HMR%d 0x%08x)\n",
++ i, host, idx,
++ pintc_read_reg(pp, PINTC_HMR0 + idx * 4));
++ }
++
++ /* configure polarity and type (all active high & pulse) */
++ pintc_write_reg(pp, PINTC_SITR0, 0);
++ pintc_write_reg(pp, PINTC_SITR1, 0);
++
++ dev_dbg(dev, "sysevt_mask=0x%016llx ch_mask=0x%08x host_mask=0x%08x\n",
++ sysevt_mask, ch_mask, host_mask);
++
++ /* enable sys-events */
++ pintc_write_reg(pp, PINTC_ESR0, (u32)sysevt_mask);
++ pintc_write_reg(pp, PINTC_SECR0, (u32)sysevt_mask);
++ pintc_write_reg(pp, PINTC_ESR1, (u32)(sysevt_mask >> 32));
++ pintc_write_reg(pp, PINTC_SECR1, (u32)(sysevt_mask >> 32));
++
++ /* enable host interrupts */
++ for (i = 0; i < MAX_PRU_HOST_INT; i++) {
++ if ((host_mask & (1 << i)) != 0)
++ pintc_write_reg(pp, PINTC_HIEISR, i);
++ }
++
++ /* global interrupt enable */
++ pintc_write_reg(pp, PINTC_GER, 1);
++
++ return 0;
++}
++
++static int pruproc_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct device_node *node = dev->of_node;
++ struct device_node *pnode = NULL;
++ struct pruproc *pp;
++ struct pruproc_core *ppc;
++ struct pru_sysev_target *pst;
++ const char *fw_name;
++ int pm_get = 0;
++ struct rproc *rproc = NULL;
++ struct resource *res;
++ struct pinctrl *pinctrl;
++ int err, i, j, irq, sysev;
++ u32 tmparr[4], pru_idx;
++ u32 tmpev[MAX_ARM_PRU_INTS];
++
++ /* get pinctrl */
++ pinctrl = devm_pinctrl_get_select_default(dev);
++ if (IS_ERR(pinctrl)) {
++ err = PTR_ERR(pinctrl);
++ /* deferring probe */
++ if (err == -EPROBE_DEFER) {
++ dev_warn(dev, "deferring proble\n");
++ return err;
++ }
++ dev_warn(dev, "pins are not configured from the driver\n");
++ }
++
++ /* we only work on OF */
++ if (node == NULL) {
++ dev_err(dev, "Only OF configuration supported\n");
++ err = -ENODEV;
++ goto err_fail;
++ }
++
++ pm_runtime_enable(dev);
++ err = pm_runtime_get_sync(dev);
++ if (err != 0) {
++ dev_err(dev, "pm_runtime_get_sync failed\n");
++ goto err_fail;
++ }
++ pm_get = 1;
++
++ err = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
++ if (err) {
++ dev_err(dev, "dma_set_coherent_mask: %d\n", err);
++ goto err_fail;
++ }
++
++ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
++ if (pp == NULL) {
++ dev_err(dev, "failed to allocate pruproc\n");
++ err = -ENOMEM;
++ goto err_fail;
++
++ }
++
++ /* link the device with the pruproc */
++ platform_set_drvdata(pdev, pp);
++ pp->pdev = pdev;
++
++ /* prepare the irqs */
++ for (i = 0; i < ARRAY_SIZE(pp->irqs); i++)
++ pp->irqs[i] = -1;
++
++ /* prepare the events */
++ for (i = 0; i < ARRAY_SIZE(pp->events); i++)
++ pp->events[i] = -1;
++
++ /* prepare the sysevevent to channel map */
++ for (i = 0; i < ARRAY_SIZE(pp->sysev_to_ch); i++)
++ pp->sysev_to_ch[i] = -1;
++
++ /* prepare the channel to hostint map */
++ for (i = 0; i < ARRAY_SIZE(pp->ch_to_host); i++)
++ pp->ch_to_host[i] = -1;
++
++ /* finally register the interrupts */
++ for (i = 0; i < ARRAY_SIZE(pp->irqs); i++) {
++
++ err = platform_get_irq(pdev, i);
++ if (err < 0)
++ break;
++ irq = err;
++ pp->irqs[i] = irq;
++ }
++ pp->num_irqs = i;
++ dev_info(dev, "#%d PRU interrupts registered\n", pp->num_irqs);
++
++ /* make sure this fits */
++ if (pp->num_irqs > ARRAY_SIZE(tmpev)) {
++ dev_err(dev, "Too many irqs (%d)\n", pp->num_irqs);
++ goto err_fail;
++ }
++
++ /* read the events (host ints) */
++ err = of_property_read_u32_array(node, "events", tmpev, pp->num_irqs);
++ if (err != 0) {
++ dev_err(dev, "Failed to read events array\n");
++ goto err_fail;
++ }
++
++ /* assign and check */
++ for (i = 0; i < pp->num_irqs; i++) {
++ if (tmpev[i] < MIN_PRU_HOST_INT ||
++ tmpev[i] >= MAX_PRU_HOST_INT) {
++ dev_err(dev, "Bad event property entry %u\n", tmpev[i]);
++ goto err_fail;
++ }
++ pp->events[i] = tmpev[i];
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (res == NULL) {
++ dev_err(dev, "failed to parse MEM resource\n");
++ goto err_fail;
++ }
++
++ pp->paddr = res->start;
++ pp->vaddr = devm_ioremap(dev, res->start, resource_size(res));
++ if (pp->vaddr == NULL) {
++ dev_err(dev, "failed to parse MEM resource\n");
++ goto err_fail;
++ }
++
++ err = of_property_read_u32(node, "pintc", &pp->pintc);
++ if (err != 0) {
++ dev_err(dev, "no pintc property\n");
++ goto err_fail;
++ }
++
++ /* read pdram property global, size, local */
++ err = of_property_read_u32_array(node, "pdram", tmparr, 3);
++ if (err != 0) {
++ dev_err(dev, "no pintc property\n");
++ goto err_fail;
++ }
++ pp->pdram = tmparr[0];
++ pp->pdram_sz = tmparr[1];
++ pp->pdram_da = tmparr[2];
++
++ /* configure PRU interrupt controller from DT */
++ err = configure_pintc(pdev, pp);
++ if (err != 0) {
++ dev_err(dev, "failed to configure pintc\n");
++ goto err_fail;
++ }
++
++ /* count number of child nodes with a firmwary property */
++ pp->num_prus = 0;
++ for_each_child_of_node(node, pnode) {
++ if (of_find_property(pnode, "firmware", NULL))
++ pp->num_prus++;
++ }
++ pnode = NULL;
++
++ /* found any? */
++ if (pp->num_prus == 0) {
++ dev_err(dev, "no pru nodes found\n");
++ err = -EINVAL;
++ goto err_fail;
++ }
++ /* found too many? */
++ if (pp->num_prus > MAX_PRUS) {
++ dev_err(dev, "Only 2 PRU nodes are supported\n");
++ err = -EINVAL;
++ goto err_fail;
++ }
++ dev_info(dev, "found #%d PRUs\n", pp->num_prus);
++
++ /* allocate pointers */
++ pp->pruc = devm_kzalloc(dev, sizeof(*pp->pruc) * pp->num_prus,
++ GFP_KERNEL);
++ if (pp->pruc == NULL) {
++ dev_err(dev, "Failed to allocate PRU table\n");
++ err = -ENOMEM;
++ goto err_fail;
++ }
++
++ /* now iterate over all the pru nodes */
++ i = 0;
++ for_each_child_of_node(node, pnode) {
++
++ /* only nodes with firmware are PRU nodes */
++ if (of_find_property(pnode, "firmware", NULL) == NULL)
++ continue;
++
++ /* get the hardware index of the PRU */
++ err = of_property_read_u32(pnode, "pru-index", &pru_idx);
++ if (err != 0) {
++ dev_err(dev, "can't find property %s\n", "pru-index");
++ of_node_put(pnode);
++ goto err_fail;
++ }
++
++ /* verify the index */
++ if (pru_idx >= MAX_PRUS) {
++ dev_err(dev, "Illegal pru-index property %u\n",
++ pru_idx);
++ of_node_put(pnode);
++ goto err_fail;
++ }
++
++ /* get the firmware */
++ err = of_property_read_string(pnode, "firmware", &fw_name);
++ if (err != 0) {
++ dev_err(dev, "can't find property %s\n", "firmware");
++ of_node_put(pnode);
++ goto err_fail;
++ }
++
++ /* allocate the remote proc + our private data */
++ rproc = rproc_alloc(dev, pdev->name, &pruproc_ops, fw_name,
++ sizeof(*ppc));
++ if (!rproc) {
++ dev_err(dev, "rproc_alloc failed\n");
++ err = -ENOMEM;
++ goto err_fail;
++ }
++ ppc = rproc->priv;
++ ppc->idx = pru_idx;
++ ppc->pruproc = pp;
++ ppc->rproc = rproc;
++
++ atomic_set(&ppc->bootcnt, 0);
++
++ err = of_property_read_u32_array(pnode, "iram", tmparr, 3);
++ if (err != 0) {
++ dev_err(dev, "no iram property\n");
++ goto err_fail;
++ }
++ ppc->iram = tmparr[0];
++ ppc->iram_sz = tmparr[1];
++ ppc->iram_da = tmparr[2];
++
++ err = of_property_read_u32_array(pnode, "dram", tmparr, 4);
++ if (err != 0) {
++ dev_err(dev, "no dram property\n");
++ goto err_fail;
++ }
++ ppc->dram = tmparr[0];
++ ppc->dram_sz = tmparr[1];
++ ppc->dram_da = tmparr[2];
++ ppc->dram_oda = tmparr[3];
++
++ err = of_property_read_u32(pnode, "pctrl", &ppc->pctrl);
++ if (err != 0) {
++ dev_err(dev, "no pctrl property\n");
++ goto err_fail;
++ }
++
++ err = of_property_read_u32(pnode, "pdbg", &ppc->pdbg);
++ if (err != 0) {
++ dev_err(dev, "no pdbg property\n");
++ goto err_fail;
++ }
++
++ /* read vring sysevent array */
++ err = of_property_read_u32_array(pnode, "vring-sysev", tmparr, 2);
++ if (err == 0) {
++ /* verify */
++ if (tmparr[0] >= MAX_PRU_SYS_EVENTS ||
++ tmparr[1] >= MAX_PRU_SYS_EVENTS) {
++ dev_err(dev, "illegal vring-sysev property\n");
++ goto err_fail;
++ }
++ ppc->pru_vring_sysev = tmparr[0];
++ ppc->host_vring_sysev = tmparr[1];
++ } else {
++ ppc->pru_vring_sysev = -1;
++ ppc->host_vring_sysev = -1;
++ }
++
++ /* check firmware type */
++ ppc->is_elf = of_property_read_bool(pnode, "firmware-elf");
++
++ /* build the resource table from DT */
++ err = build_rsc_table(pdev, pnode, ppc);
++ if (err != 0) {
++ dev_err(dev, "failed to build resource table\n");
++ goto err_fail;
++ }
++
++ /* Set the PRU specific firmware handler */
++ if (!ppc->is_elf)
++ rproc->fw_ops = &pruproc_bin_fw_ops;
++ else
++ rproc->fw_ops = &pruproc_elf_fw_ops;
++
++ pp->pruc[i] = ppc;
++ pp->pru_to_pruc[pru_idx] = ppc;
++ i++;
++ }
++ pnode = NULL;
++
++ /* clean up the sysev to target map */
++ memset(pp->sysev_to_target, 0, sizeof(pp->sysev_to_target));
++ for (i = 0; i < ARRAY_SIZE(pp->sysev_to_target); i++) {
++ pst = &pp->sysev_to_target[i];
++ pst->source = -1;
++ pst->target = -1;
++ }
++
++ /* fill in the sysev target map for std. signaling */
++ for (i = 0; i < MAX_TARGETS; i++) {
++ for (j = 0; j < MAX_TARGETS; j++) {
++ /* target self? don't care*/
++ if (i == j)
++ continue;
++ sysev = pp->target_to_sysev[i * MAX_TARGETS + j];
++ if (sysev >= MAX_PRU_SYS_EVENTS) {
++ dev_err(dev, "Bad SYSEV %d\n", sysev);
++ goto err_fail;
++ }
++ pst = &pp->sysev_to_target[sysev];
++ if (pst->valid) {
++ dev_err(dev, "SYSEV %d overlap\n", sysev);
++ goto err_fail;
++ }
++ pst->source = i;
++ pst->target = j;
++ pst->vring = 0;
++ pst->valid = 1;
++ }
++ }
++
++ /* fill in the sysev target map from vring info */
++ for (i = 0; i < pp->num_prus; i++) {
++ ppc = pp->pruc[i];
++ pru_idx = ppc->idx;
++
++ sysev = ppc->host_vring_sysev;
++ if (sysev != -1) {
++ pst = &pp->sysev_to_target[sysev];
++ if (pst->valid) {
++ dev_err(dev, "SYSEV %d overlap\n", sysev);
++ goto err_fail;
++ }
++ pst->source = TARGET_PRU(pru_idx);
++ pst->target = TARGET_ARM;
++ pst->vring = 1;
++ pst->valid = 1;
++ }
++
++ sysev = ppc->pru_vring_sysev;
++ if (sysev != -1) {
++ pst = &pp->sysev_to_target[sysev];
++ if (pst->valid) {
++ dev_err(dev, "SYSEV %d overlap\n", sysev);
++ goto err_fail;
++ }
++ pst->source = TARGET_ARM;
++ pst->target = TARGET_PRU(pru_idx);
++ pst->vring = 1;
++ pst->valid = 1;
++ }
++ }
++
++ /* dump the sysev target map */
++ for (i = 0; i < ARRAY_SIZE(pp->sysev_to_target); i++) {
++ pst = &pp->sysev_to_target[i];
++ if (!pst->valid)
++ continue;
++ dev_dbg(dev, "SYSEV#%d <- VR %d SRC %d TRG %d\n",
++ i, pst->vring, pst->source, pst->target);
++ }
++
++ /* register the interrupts */
++ for (i = 0; i < pp->num_irqs; i++) {
++
++ irq = pp->irqs[i];
++ err = devm_request_irq(dev, irq, pru_handler, 0,
++ dev_name(dev), pp);
++ if (err != 0) {
++ dev_err(dev, "Failed to register irq %d\n", irq);
++ goto err_fail;
++ }
++ }
++
++ /* start the remote procs */
++ for (i = 0; i < pp->num_prus; i++) {
++ ppc = pp->pruc[i];
++
++ /* Register as a remoteproc device */
++ err = rproc_add(ppc->rproc);
++ if (err) {
++ dev_err(dev, "rproc_add failed\n");
++ goto err_fail;
++ }
++
++ /* directly boot all processors that don't have VDEVs */
++ if (ppc->num_vdevs == 0) {
++ err = rproc_boot(ppc->rproc);
++ if (err) {
++ dev_err(dev, "rproc_boot failed\n");
++ goto err_fail;
++ }
++ }
++ }
++
++ err = device_create_file(dev, &dev_attr_load);
++ if (err != 0) {
++ dev_err(dev, "device_create_file failed\n");
++ goto err_fail;
++ }
++
++ err = device_create_file(dev, &dev_attr_reset);
++ if (err != 0) {
++ dev_err(dev, "device_create_file failed\n");
++ goto err_fail;
++ }
++
++ dev_info(dev, "Loaded OK\n");
++
++ (void)pru_d_read_u32;
++ (void)pru_i_write_u32;
++ (void)pru_d_write_u32;
++
++ return 0;
++err_fail:
++ /* NULL is OK */
++ of_node_put(pnode);
++
++ if (rproc)
++ rproc_put(rproc);
++ if (pm_get)
++ pm_runtime_disable(dev);
+ return err;
+ }
+
diff --git a/patches/linux-3.8.13/0437-capes-pru-Update-with-PRU-03-PRU-04.patch b/patches/linux-3.8.13/0437-capes-pru-Update-with-PRU-03-PRU-04.patch
new file mode 100644
index 0000000..96bb31e
--- /dev/null
+++ b/patches/linux-3.8.13/0437-capes-pru-Update-with-PRU-03-PRU-04.patch
@@ -0,0 +1,547 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 11 Jul 2013 19:41:07 +0300
+Subject: [PATCH] capes: pru: Update with PRU-03 & PRU-04
+
+Complex PRU capes.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ firmware/Makefile | 2 +
+ firmware/capes/BB-BONE-PRU-03-00A0.dts | 210 ++++++++++++++++++++++
+ firmware/capes/BB-BONE-PRU-04-00A0.dts | 297 ++++++++++++++++++++++++++++++++
+ 3 files changed, 509 insertions(+)
+ create mode 100644 firmware/capes/BB-BONE-PRU-03-00A0.dts
+ create mode 100644 firmware/capes/BB-BONE-PRU-04-00A0.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index 1a353ce..646eea5 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -180,6 +180,8 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ BB-BONE-PWMT-00A0.dtbo \
+ BB-BONE-PRU-01-00A0.dtbo \
+ BB-BONE-PRU-02-00A0.dtbo \
++ BB-BONE-PRU-03-00A0.dtbo \
++ BB-BONE-PRU-04-00A0.dtbo \
+ BB-BONE-RST-00A0.dtbo \
+ BB-BONE-RST2-00A0.dtbo \
+ BB-BONE-CAM3-01-00A2.dtbo \
+diff --git a/firmware/capes/BB-BONE-PRU-03-00A0.dts b/firmware/capes/BB-BONE-PRU-03-00A0.dts
+new file mode 100644
+index 0000000..7d7ba99
+--- /dev/null
++++ b/firmware/capes/BB-BONE-PRU-03-00A0.dts
+@@ -0,0 +1,210 @@
++/*
++* Copyright (C) 2013 Matt Ranostay <mranostay@gmail.com>
++*
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License version 2 as
++* published by the Free Software Foundation.
++*/
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-BONE-PRU-03";
++ version = "00A0";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.27", /* pru0: pr1_pru0_pru_r30_5 */
++ /* the hardware IP uses */
++ "pru0";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ pru_gpio_pins: pinmux_pru_gpio_pins {
++ pinctrl-single,pins = <
++ 0x1a4 0x0f /* P9 27 GPIO3_19: mcasp0_fsr.gpio3[19] | MODE7 | OUTPUT */
++ >;
++ };
++
++ pru_pru_pins: pinmux_pru_pru_pins {
++ pinctrl-single,pins = <
++ 0x1a4 0x25 /* mcasp0_fsr.pr1_pru0_pru_r30_5, MODE5 | OUTPUT | PRU */
++ >;
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&ocp>;
++
++ __overlay__ {
++
++ /* avoid stupid warning */
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ prurproc {
++ compatible = "ti,pru-rproc";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&pru_pru_pins>;
++
++ reg = <0x4a300000 0x080000>;
++
++ status = "okay";
++
++ ti,hwmods = "pruss";
++ ti,deassert-hard-reset = "pruss", "pruss";
++ interrupt-parent = <&intc>;
++
++ /* interrupts on the host */
++ interrupts = <20 21 22 23 24 25 26 27>;
++
++ /* events these interrupts map to (host interrupt) */
++ events = <2 3 4 5 6 7 8 9>;
++
++ /* PRU interrupt controller offset */
++ pintc = <0x20000>;
++
++ /* 12K Shared Data RAM global, size, local */
++ pdram = <0x10000 0x03000 0x10000>;
++
++ /*
++ * SYSEVENT ids
++ *
++ * - PRU/ARM communication
++ * PRU0_PRU1 17
++ * PRU1_PRU0 18
++ * PRU0_ARM 19
++ * PRU1_ARM 20
++ * ARM_PRU0 21
++ * ARM_PRU1 22
++ *
++ * Full SYSEVENT list
++ *
++ * parity_err_intr_pend 0
++ * pru0_r31_status_cnt16 1
++ * pru1_r31_status_cnt16 2
++ * uart_urxevt_intr_req 4
++ * uart_utxevt_intr_req 5
++ * uart_uint_intr_req 6
++ * iep_tim_cap_cmp_pend 7
++ * ecap_intr_req 15
++ * pru_mst_intr[0-15]_intr_req 16-31
++ * nirq 32 (UART1)
++ * mcasp_x_intr_pend 33 (MCASP1)
++ * mcasp_r_intr_pend 34 (MCASP1)
++ * ecap_intr_intr_pend 35 (ECAP1)
++ * ecap_intr_intr_pend 36 (ECAP2)
++ * epwm_intr_intr_pend 37 (eHRPWM2)
++ * dcan_uerr 38 (DCAN0)
++ * dcan_int1 39 (DCAN0)
++ * dcan_intr 40 (DCAN0)
++ * POINTRPEND 41 (I2C0)
++ * ecap_intr_intr_pend 42 (ECAP0)
++ * epwm_intr_intr_pend 43 (eHRPWM0)
++ * SINTERRUPTN 44 (McSPI0)
++ * eqep_intr_intr_pend 45 (eQEP0)
++ * epwm_intr_intr_pend 46 (eHRPWM1)
++ * c0_misc_pend 47 3PGSW (GEMAC)
++ * c0_tx_pend 48 3PGSW (GEMAC)
++ * c0_rx_pend 49 3PGSW (GEMAC)
++ * c0_rx_thresh_pend 50 3PGSW (GEMAC)
++ * nirq 51 (UART0)
++ * nirq 52 (UART2)
++ * gen_intr_pend 53 (ADC_TSC)
++ * mcasp_r_intr_pend 54 (McASP0)
++ * mcasp_x_intr_pend 55 (McASP1)
++ * pwm_trip_zone 56 (eHRPWM0/eHRPWM1/eHRP WM2)
++ * POINTRPEND1 57 (GPIO0)
++ * Emulation Suspend Signal 58 (Debugss)
++ * initiator_sinterrupt_q_n2 59 (Mbox0 - mail_u2_irq (mailbox interrupt for pru1))
++ * initiator_sinterrupt_q_n1 60 (Mbox0 - mail_u1_irq (mailbox interrupt for pru0))
++ * tptc_erint_pend_po 61 (TPTC0 (EDMA))
++ * tpcc_errint_pend_po 62 (TPCC (EDMA))
++ * tpcc_int_pend_po1 63 (TPCC (EDMA))
++ *
++ * HOST interrupt ids
++ *
++ * PRU0 0
++ * PRU1 1
++ * EVTOUT0-7 2-9
++ */
++
++ /* sysevent map to intc channel */
++ sysevent-to-channel-map =
++ <17 1>, /* PRU0_PRU1 -> CH1 */
++ <18 0>, /* PRU1_PRU0 -> CH0 */
++ <19 2>, /* PRU0_ARM -> CH2 */
++ <20 3>, /* PRU1_ARM -> CH3 */
++ <21 0>, /* ARM_PRU0 -> CH0 */
++ <22 1>, /* ARM_PRU1 -> CH1 */
++ <24 4>, /* VRING Host->PRU0 -> CH4 */
++ <25 5>, /* VRING PRU0->Host -> CH5 */
++ <26 6>, /* VRING Host->PRU1 -> CH6 */
++ <27 7>; /* VRING PRU1->Host -> CH7 */
++
++ /* channel to host interrupt map */
++ channel-to-host-interrupt-map =
++ <0 0>, /* CH0 -> PRU0 */
++ <1 1>, /* CH1 -> PRU1 */
++ <2 2>, /* CH2 -> EVTOUT0 */
++ <3 3>, /* CH3 -> EVTOUT1 */
++ <4 0>, /* CH4 -> PRU0 */
++ <5 6>, /* CH5 -> EVTOUT4 */
++ <6 1>, /* CH6 -> PRU1 */
++ <7 7>; /* CH7 -> EVTOUT5 */
++
++ /* indices are ARM=0, PRU0=1, PRU1=2 */
++ target-to-sysevent-map =
++ <0xffffffff 21 22>, /* ARM: DONTCARE, ARM_PRU0, ARM_PRU1 */
++ < 19 0xffffffff 17>, /* PRU0: PRU0_ARM, DONTCARE, PRU0_PRU1 */
++ < 20 18 0xffffffff>; /* PRU1: PRU1_ARM, PRU1_PRU0, DONTCARE */
++
++ /* definition for the first PRU */
++ pru0 {
++ pru-index = <0>;
++
++ /* offset, size, local */
++ iram = <0x34000 0x02000 0x00000>; /* code ram (8K) */
++
++ /* offset, size, local, other */
++ dram = <0x00000 0x02000 0x00000 0x10000>; /* data ram (8K) */
++
++ pctrl = <0x22000>;
++ pdbg = <0x22400>;
++
++ firmware-elf;
++ firmware = "prutest.elf";
++
++ /* sysevents signaling ring activity (host, pru)*/
++ vring-sysev = <24 25>;
++
++ resource_table {
++ resource-table;
++ version = <1>;
++
++ pru0_rproc_serial: pru0_vdev_rproc_serial {
++ vdev-rproc-serial;
++
++ /* notification IDs are totally bogus */
++ /* rproc will idr_alloc anyway */
++
++ notifyid = <8>; /* <- bogus */
++ /* da align num notifyid */
++ vring-0 = <0 16 8 0>;
++ vring-1 = <0 16 8 0>;
++ };
++ };
++ };
++
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/BB-BONE-PRU-04-00A0.dts b/firmware/capes/BB-BONE-PRU-04-00A0.dts
+new file mode 100644
+index 0000000..2ad0ff1
+--- /dev/null
++++ b/firmware/capes/BB-BONE-PRU-04-00A0.dts
+@@ -0,0 +1,297 @@
++/*
++* Copyright (C) 2013 Matt Ranostay <mranostay@gmail.com>
++*
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License version 2 as
++* published by the Free Software Foundation.
++*/
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-BONE-PRU-04";
++ version = "00A0";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.27", /* pru0: pr1_pru0_pru_r30_5 */
++
++ "P8.11", /* pru0: pr1_pru0_pru_r30_15 */
++ "P8.12", /* pru0: pr1_pru0_pru_r30_14 */
++ "P9.25", /* pru0: pr1_pru0_pru_r30_7 */
++ "P9.41", /* pru0: pr1_pru0_pru_r30_6 */
++ "P9.42", /* pru0: pr1_pru0_pru_r30_4 */
++ "P9.28", /* pru0: pr1_pru0_pru_r30_3 */
++ "P9.30", /* pru0: pr1_pru0_pru_r30_2 */
++ "P9.29", /* pru0: pr1_pru0_pru_r30_1 */
++ "P9.31", /* pru0: pr1_pru0_pru_r30_0 */
++ /* pru0: pr1_pru0_pru_r30_13 is on MMC0_CMD */
++ /* pru0: pr1_pru0_pru_r30_12 is on MMC0_CLK */
++ /* pru0: pr1_pru0_pru_r30_11 is on MMC0_DAT0 */
++ /* pru0: pr1_pru0_pru_r30_10 is on MMC0_DAT1 */
++ /* pru0: pr1_pru0_pru_r30_9 is on MMC0_DAT2 */
++ /* pru0: pr1_pru0_pru_r30_8 is on MMC0_DAT3 */
++
++ "P8.20", /* pru1: pr1_pru1_pru_r30_13 */
++
++ "P8.21", /* pru1: pr1_pru1_pru_r30_12 */
++ "P8.27", /* pru1: pr1_pru1_pru_r30_8 */
++ "P8.28", /* pru1: pr1_pru1_pru_r30_10 */
++ "P8.29", /* pru1: pr1_pru1_pru_r30_9 */
++ "P8.30", /* pru1: pr1_pru1_pru_r30_11 */
++ "P8.39", /* pru1: pr1_pru1_pru_r30_6 */
++ "P8.40", /* pru1: pr1_pru1_pru_r30_7 */
++ "P8.41", /* pru1: pr1_pru1_pru_r30_4 */
++ "P8.42", /* pru1: pr1_pru1_pru_r30_5 */
++ "P8.43", /* pru1: pr1_pru1_pru_r30_2 */
++ "P8.44", /* pru1: pr1_pru1_pru_r30_3 */
++ "P8.45", /* pru1: pr1_pru1_pru_r30_0 */
++ "P8.46", /* pru1: pr1_pru1_pru_r30_1 */
++ /* pru1: pr1_pru1_pru_r30_14 is on UART0_RXD */
++ /* pru1: pr1_pru1_pru_r30_15 is on UART0_TXD */
++ /* the hardware IP uses */
++ "pru0",
++ "pru1";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ pru_gpio_pins: pinmux_pru_gpio_pins {
++ pinctrl-single,pins = <
++ 0x1a4 0x0f /* P9 27 GPIO3_19: mcasp0_fsr.gpio3[19] | MODE7 | OUTPUT */
++ >;
++ };
++
++ pru_pru_pins: pinmux_pru_pru_pins {
++ pinctrl-single,pins = <
++ 0x1a4 0x25 /* mcasp0_fsr.pr1_pru0_pru_r30_5, MODE5 | OUTPUT | PRU */
++ 0x034 0x26 /* gpmc_ad13.pr1_pru0_pru_r30_15, MODE6 | OUTPUT | PRU */
++ 0x030 0x26 /* gpmc_ad12.pr1_pru0_pru_r30_14, MODE6 | OUTPUT | PRU */
++ 0x1ac 0x25 /* mcasp0_ahclkx.pr1_pru0_pru_r30_7, MODE5 | OUTPUT | PRU */
++ 0x1a8 0x25 /* mcasp0_axr1.pr1_pru0_pru_r30_6, MODE5 | OUTPUT | PRU */
++ 0x1a0 0x25 /* mcasp0_aclkr.pr1_pru0_pru_r30_4, MODE5 | OUTPUT | PRU */
++ 0x19c 0x25 /* mcasp0_ahclkr.pr1_pru0_pru_r30_3, MODE5 | OUTPUT | PRU */
++ 0x198 0x25 /* mcasp0_axr0.pr1_pru0_pru_r30_2, MODE5 | OUTPUT | PRU */
++ 0x194 0x25 /* mcasp0_fsx.pr1_pru0_pru_r30_1, MODE5 | OUTPUT | PRU */
++ 0x190 0x25 /* mcasp0_aclkx.pr1_pru0_pru_r30_0, MODE5 | OUTPUT | PRU */
++
++ 0x084 0x25 /* gpmc_csn2.pr1_pru1_pru_r30_13, MODE5 | OUTPUT | PRU */
++ 0x080 0x25 /* gpmc_csn1.pr1_pru1_pru_r30_12, MODE5 | OUTPUT | PRU */
++ 0x0e0 0x25 /* lcd_vsync.pr1_pru1_pru_r30_8, MODE5 | OUTPUT | PRU */
++ 0x0e8 0x25 /* lcd_pclk.pr1_pru1_pru_r30_10, MODE5 | OUTPUT | PRU */
++ 0x0e4 0x25 /* lcd_hsync.pr1_pru1_pru_r30_9, MODE5 | OUTPUT | PRU */
++ 0x0ec 0x25 /* lcd_ac_bias_en.pr1_pru1_pru_r30_11, MODE5 | OUTPUT | PRU */
++ 0x0bc 0x25 /* lcd_data7.pr1_pru1_pru_r30_7, MODE5 | OUTPUT | PRU */
++ 0x0b0 0x25 /* lcd_data4.pr1_pru1_pru_r30_4, MODE5 | OUTPUT | PRU */
++ 0x0b4 0x25 /* lcd_data5.pr1_pru1_pru_r30_5, MODE5 | OUTPUT | PRU */
++ 0x0ac 0x25 /* lcd_data3.pr1_pru1_pru_r30_3, MODE5 | OUTPUT | PRU */
++ 0x0a0 0x25 /* lcd_data0.pr1_pru1_pru_r30_0, MODE5 | OUTPUT | PRU */
++ 0x0a4 0x25 /* lcd_data1.pr1_pru1_pru_r30_1, MODE5 | OUTPUT | PRU */
++ >;
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&ocp>;
++
++ __overlay__ {
++
++ /* avoid stupid warning */
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ prurproc {
++ compatible = "ti,pru-rproc";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&pru_pru_pins>;
++
++ reg = <0x4a300000 0x080000>;
++
++ status = "okay";
++
++ ti,hwmods = "pruss";
++ ti,deassert-hard-reset = "pruss", "pruss";
++ interrupt-parent = <&intc>;
++
++ /* interrupts on the host */
++ interrupts = <20 21 22 23 24 25 26 27>;
++
++ /* events these interrupts map to (host interrupt) */
++ events = <2 3 4 5 6 7 8 9>;
++
++ /* PRU interrupt controller offset */
++ pintc = <0x20000>;
++
++ /* 12K Shared Data RAM global, size, local */
++ pdram = <0x10000 0x03000 0x10000>;
++
++ /*
++ * SYSEVENT ids
++ *
++ * - PRU/ARM communication
++ * PRU0_PRU1 17
++ * PRU1_PRU0 18
++ * PRU0_ARM 19
++ * PRU1_ARM 20
++ * ARM_PRU0 21
++ * ARM_PRU1 22
++ *
++ * Full SYSEVENT list
++ *
++ * parity_err_intr_pend 0
++ * pru0_r31_status_cnt16 1
++ * pru1_r31_status_cnt16 2
++ * uart_urxevt_intr_req 4
++ * uart_utxevt_intr_req 5
++ * uart_uint_intr_req 6
++ * iep_tim_cap_cmp_pend 7
++ * ecap_intr_req 15
++ * pru_mst_intr[0-15]_intr_req 16-31
++ * nirq 32 (UART1)
++ * mcasp_x_intr_pend 33 (MCASP1)
++ * mcasp_r_intr_pend 34 (MCASP1)
++ * ecap_intr_intr_pend 35 (ECAP1)
++ * ecap_intr_intr_pend 36 (ECAP2)
++ * epwm_intr_intr_pend 37 (eHRPWM2)
++ * dcan_uerr 38 (DCAN0)
++ * dcan_int1 39 (DCAN0)
++ * dcan_intr 40 (DCAN0)
++ * POINTRPEND 41 (I2C0)
++ * ecap_intr_intr_pend 42 (ECAP0)
++ * epwm_intr_intr_pend 43 (eHRPWM0)
++ * SINTERRUPTN 44 (McSPI0)
++ * eqep_intr_intr_pend 45 (eQEP0)
++ * epwm_intr_intr_pend 46 (eHRPWM1)
++ * c0_misc_pend 47 3PGSW (GEMAC)
++ * c0_tx_pend 48 3PGSW (GEMAC)
++ * c0_rx_pend 49 3PGSW (GEMAC)
++ * c0_rx_thresh_pend 50 3PGSW (GEMAC)
++ * nirq 51 (UART0)
++ * nirq 52 (UART2)
++ * gen_intr_pend 53 (ADC_TSC)
++ * mcasp_r_intr_pend 54 (McASP0)
++ * mcasp_x_intr_pend 55 (McASP1)
++ * pwm_trip_zone 56 (eHRPWM0/eHRPWM1/eHRP WM2)
++ * POINTRPEND1 57 (GPIO0)
++ * Emulation Suspend Signal 58 (Debugss)
++ * initiator_sinterrupt_q_n2 59 (Mbox0 - mail_u2_irq (mailbox interrupt for pru1))
++ * initiator_sinterrupt_q_n1 60 (Mbox0 - mail_u1_irq (mailbox interrupt for pru0))
++ * tptc_erint_pend_po 61 (TPTC0 (EDMA))
++ * tpcc_errint_pend_po 62 (TPCC (EDMA))
++ * tpcc_int_pend_po1 63 (TPCC (EDMA))
++ *
++ * HOST interrupt ids
++ *
++ * PRU0 0
++ * PRU1 1
++ * EVTOUT0-7 2-9
++ */
++
++ /* sysevent map to intc channel */
++ sysevent-to-channel-map =
++ <17 1>, /* PRU0_PRU1 -> CH1 */
++ <18 0>, /* PRU1_PRU0 -> CH0 */
++ <19 2>, /* PRU0_ARM -> CH2 */
++ <20 3>, /* PRU1_ARM -> CH3 */
++ <21 0>, /* ARM_PRU0 -> CH0 */
++ <22 1>, /* ARM_PRU1 -> CH1 */
++ <24 4>, /* VRING Host->PRU0 -> CH4 */
++ <25 5>, /* VRING PRU0->Host -> CH5 */
++ <26 6>, /* VRING Host->PRU1 -> CH6 */
++ <27 7>; /* VRING PRU1->Host -> CH7 */
++
++ /* channel to host interrupt map */
++ channel-to-host-interrupt-map =
++ <0 0>, /* CH0 -> PRU0 */
++ <1 1>, /* CH1 -> PRU1 */
++ <2 2>, /* CH2 -> EVTOUT0 */
++ <3 3>, /* CH3 -> EVTOUT1 */
++ <4 0>, /* CH4 -> PRU0 */
++ <5 6>, /* CH5 -> EVTOUT4 */
++ <6 1>, /* CH6 -> PRU1 */
++ <7 7>; /* CH7 -> EVTOUT5 */
++
++ /* indices are ARM=0, PRU0=1, PRU1=2 */
++ target-to-sysevent-map =
++ <0xffffffff 21 22>, /* ARM: DONTCARE, ARM_PRU0, ARM_PRU1 */
++ < 19 0xffffffff 17>, /* PRU0: PRU0_ARM, DONTCARE, PRU0_PRU1 */
++ < 20 18 0xffffffff>; /* PRU1: PRU1_ARM, PRU1_PRU0, DONTCARE */
++
++ /* definition for the first PRU */
++ pru0 {
++ pru-index = <0>;
++
++ /* offset, size, local */
++ iram = <0x34000 0x02000 0x00000>; /* code ram (8K) */
++
++ /* offset, size, local, other */
++ dram = <0x00000 0x02000 0x00000 0x10000>; /* data ram (8K) */
++
++ pctrl = <0x22000>;
++ pdbg = <0x22400>;
++
++ firmware-elf;
++ firmware = "testpru0";
++
++ /* sysevents signaling ring activity (host, pru)*/
++ vring-sysev = <24 25>;
++
++ resource_table {
++ resource-table;
++ version = <1>;
++
++ pru0_rproc_serial: pru0_vdev_rproc_serial {
++ vdev-rproc-serial;
++
++ /* notification IDs are totally bogus */
++ /* rproc will idr_alloc anyway */
++
++ notifyid = <8>; /* <- bogus */
++ /* da align num notifyid */
++ vring-0 = <0 16 8 0>;
++ vring-1 = <0 16 8 0>;
++ };
++
++// pru0_rproc_rpmsg: pru0_vdev_rproc_rpmsg {
++// vdev-rpmsg;
++//
++// /* notification IDs are totally bogus */
++// /* rproc will idr_alloc anyway */
++//
++// notifyid = <9>; /* <- bogus */
++// /* da align num notifyid */
++// vring-0 = <0 16 512 0>;
++// vring-1 = <0 16 512 0>;
++// };
++ };
++ };
++
++ /* definition for the second PRU */
++ pru1 {
++ pru-index = <1>;
++
++ /* offset, size, local */
++ iram = <0x38000 0x02000 0x00000>; /* code ram (8K) */
++
++ /* offset, size, local, other */
++ dram = <0x02000 0x02000 0x00000 0x10000>; /* data ram (8K) */
++
++ pctrl = <0x24000>;
++ pdbg = <0x24400>;
++
++ firmware-elf;
++ firmware = "testpru1";
++
++ /* NOTE: no resource table, no vrings for this one */
++ };
++ };
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0438-rproc-PRU-Add-downcall-RPC-capability.patch b/patches/linux-3.8.13/0438-rproc-PRU-Add-downcall-RPC-capability.patch
new file mode 100644
index 0000000..8a69b38
--- /dev/null
+++ b/patches/linux-3.8.13/0438-rproc-PRU-Add-downcall-RPC-capability.patch
@@ -0,0 +1,587 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Fri, 12 Jul 2013 19:05:58 +0300
+Subject: [PATCH] rproc: PRU: Add downcall RPC capability.
+
+Let's face it, using queues to do stuff like configuration is a drag.
+Instead use the new downcall capability to communicate with the PRU
+using synchronous RPC. Much faster and easier.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/remoteproc/pru_rproc.c | 354 ++++++++++++++++++++++++++++++++++------
+ 1 file changed, 307 insertions(+), 47 deletions(-)
+
+diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c
+index e3ec63b..ad2dfc7 100644
+--- a/drivers/remoteproc/pru_rproc.c
++++ b/drivers/remoteproc/pru_rproc.c
+@@ -74,6 +74,8 @@ struct pruproc_core;
+ #define PRU_VDEV_MAX 4
+ #define PRU_VRING_MAX (RVDEV_NUM_VRINGS * PRU_VDEV_MAX)
+
++#define PRU_HALT_INSN 0x2a000000
++
+ struct pru_vring_info {
+ struct fw_rsc_vdev_vring *rsc;
+ struct vring vr;
+@@ -122,6 +124,15 @@ struct pruproc_core {
+
+ /* boots */
+ atomic_t bootcnt;
++
++ /* downcall lock */
++ struct mutex dc_lock;
++ wait_queue_head_t dc_waitq;
++ unsigned long dc_flags;
++#define PRU_DCF_DOWNCALL_REQ 0
++#define PRU_DCF_DOWNCALL_ACK 1
++#define PRU_DCF_DOWNCALL_ISSUE 2
++#define PRU_DCF_DOWNCALL_DONE 3
+ };
+
+ struct pru_sysev_target {
+@@ -898,16 +909,17 @@ static void pruproc_kick(struct rproc *rproc, int vqid)
+
+ dev_dbg(dev, "kick #%d vqid:%d\n", ppc->idx, vqid);
+
+- /* ARM to PRUx system event */
+- sysint = pp->target_to_sysev[TARGET_ARM_TO_PRU_IDX(ppc->idx)];
++ sysint = ppc->pru_vring_sysev;
++ if (sysint < 0) {
++ dev_err(dev, "PRU#%d no vring_sysev to kick with\n", ppc->idx);
++ return;
++ }
+
+ /* signal event */
+ if (sysint < 32)
+ pintc_write_reg(pp, PINTC_SRSR0, 1 << sysint);
+ else
+ pintc_write_reg(pp, PINTC_SRSR1, 1 << (sysint - 32));
+-
+- // dump_all_vrings(ppc);
+ }
+
+ void dump_resource_table(const struct resource_table *res)
+@@ -973,10 +985,13 @@ static int pruproc_start(struct rproc *rproc)
+ u32 val;
+ int err;
+
++ dev_info(dev, "PRU#%d bootcnt=%d\n",
++ ppc->idx, atomic_read(&ppc->bootcnt));
++
+ /* start the processors only when all devices have booted */
+ if (ppc->num_vdevs == 0 || atomic_inc_return(&ppc->bootcnt) == 1) {
+
+- dev_info(dev, "start PRU #%d entry-point 0x%x\n",
++ dev_info(dev, "PRU#%d entry-point 0x%x\n",
+ ppc->idx, ppc->entry_point);
+
+ #if 1
+@@ -1044,7 +1059,7 @@ static void *pruproc_alloc_vring(struct rproc *rproc,
+ }
+
+ if (i >= ppc->num_vrings) {
+- dev_err(dev, "PRU #%d could not find rsc_vring at %p\n",
++ dev_err(dev, "PRU#%d could not find rsc_vring at %p\n",
+ ppc->idx, rsc_vring);
+ return NULL;
+ }
+@@ -1053,18 +1068,18 @@ static void *pruproc_alloc_vring(struct rproc *rproc,
+ dma = &dma_tmp;
+
+ if (rsc_vring->da != 0) {
+- dev_dbg(dev, "PRU #%d alloc vring #%d from internal memory\n",
++ dev_dbg(dev, "PRU#%d alloc vring #%d from internal memory\n",
+ ppc->idx, i);
+ va = pru_d_da_to_va_block(ppc, rsc_vring->da, dma, size);
+ } else {
+- dev_dbg(dev, "PRU #%d alloc vring #%d dma_alloc_coherent\n",
++ dev_dbg(dev, "PRU#%d alloc vring #%d dma_alloc_coherent\n",
+ ppc->idx, i);
+ va = dma_alloc_coherent(dev->parent, PAGE_ALIGN(size),
+ dma, GFP_KERNEL);
+ }
+
+ if (va == NULL) {
+- dev_err(dev, "PRU #%d could not allocate vring %p\n",
++ dev_err(dev, "PRU#%d could not allocate vring %p\n",
+ ppc->idx, rsc_vring);
+ return NULL;
+ }
+@@ -1079,7 +1094,7 @@ static void *pruproc_alloc_vring(struct rproc *rproc,
+ vri->pa = *dma;
+ vri->da = pru_d_pa_to_da(ppc, *dma);
+
+- dev_dbg(dev, "PRU #%d vring #%d da=0x%x, va=%p, dma=0x%llx size=%u\n",
++ dev_dbg(dev, "PRU#%d vring #%d da=0x%x, va=%p, dma=0x%llx size=%u\n",
+ ppc->idx, i, rsc_vring->da, va, (unsigned long long)*dma, size);
+
+ return va;
+@@ -1246,9 +1261,53 @@ static ssize_t pruproc_store_reset(struct device *dev,
+ return strlen(buf);
+ }
+
++static int pru_downcall(struct pruproc_core *ppc,
++ u32 nr, u32 arg0, u32 arg1, u32 arg2);
++
++static ssize_t pruproc_store_downcall(int idx,
++ struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct pruproc *pp = platform_get_drvdata(pdev);
++ struct pruproc_core *ppc = NULL;
++ int i, ret;
++
++ for (i = 0; i < pp->num_prus; i++) {
++ ppc = pp->pruc[i];
++ if (ppc->idx == idx)
++ break;
++ }
++ if (i >= pp->num_prus)
++ return -EINVAL;
++
++ ret = pru_downcall(ppc, 0x5, 0xaa55, 0x1234, 0x98ff);
++
++ dev_info(dev, "PRU#%d downcall test - ret = %d\n", ppc->idx, ret);
++
++ return strlen(buf);
++}
++
++static ssize_t pruproc_store_downcall0(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ return pruproc_store_downcall(0, dev, attr, buf, count);
++}
++
++static ssize_t pruproc_store_downcall1(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ return pruproc_store_downcall(1, dev, attr, buf, count);
++}
++
+ static DEVICE_ATTR(load, S_IWUSR, NULL, pruproc_store_load);
+ static DEVICE_ATTR(reset, S_IWUSR, NULL, pruproc_store_reset);
+
++static DEVICE_ATTR(downcall0, S_IWUSR, NULL, pruproc_store_downcall0);
++static DEVICE_ATTR(downcall1, S_IWUSR, NULL, pruproc_store_downcall1);
++
+ /* PRU is unregistered */
+ static int pruproc_remove(struct platform_device *pdev)
+ {
+@@ -1278,8 +1337,6 @@ static int pruproc_remove(struct platform_device *pdev)
+ return 0;
+ }
+
+-#define PRU_HALT_INSN 0x2a000000
+-
+ #define PRU_SC_HALT 0
+ #define PRU_SC_PUTC 1
+ #define PRU_SC_EXIT 2
+@@ -1289,6 +1346,9 @@ static int pruproc_remove(struct platform_device *pdev)
+ #define PRU_SC_GET_CFG_VRING_INFO 1
+ #define PRU_SC_GET_CFG_RESOURCE_TABLE 2
+
++#define PRU_SC_DOWNCALL_READY 254 /* host requested a downcall, ack it, and execute */
++#define PRU_SC_DOWNCALL_DONE 255 /* call is performed, inform the host */
++
+ struct pru_dev_vring_info {
+ u32 paddr;
+ u32 num;
+@@ -1296,44 +1356,87 @@ struct pru_dev_vring_info {
+ u32 pad;
+ };
+
+-static int pru_handle_syscall(struct pruproc_core *ppc)
++/* verify that the PRU is halted */
++static int pru_is_halted(struct pruproc_core *ppc, u32 *addrp)
+ {
+ struct pruproc *pp = ppc->pruproc;
+ struct device *dev = &pp->pdev->dev;
+- u32 val, addr, scno, arg0, arg1, arg2, ret;
+- int err, valid_sc;
+- void * __iomem va;
+- struct pru_vring_info *vri;
+- struct pru_dev_vring_info *dvri;
++ u32 val, addr;
++ int err;
+
+ /* check whether it's halted */
+ val = pcntrl_read_reg(ppc, PCTRL_CONTROL);
+ if ((val & CONTROL_RUNSTATE) != 0) {
+- dev_dbg(dev, "PRU #%d not halted\n",
++ dev_err(dev, "PRU#%d not halted\n",
+ ppc->idx);
+ return -EINVAL;
+ }
+
+ /* read the instruction */
+- addr = pcntrl_read_reg(ppc, PCTRL_STATUS) * 4;
++ addr = pcntrl_read_reg(ppc, PCTRL_STATUS) << 2;
+ err = pru_i_read_u32(ppc, addr, &val);
+ if (err != 0) {
+- dev_err(dev, "PRU #%d halted PC 0x%x bad\n", ppc->idx, addr);
++ dev_err(dev, "PRU#%d halted PC 0x%x bad\n", ppc->idx, addr);
+ return err;
+ }
+
+ /* check whether it's a halt instruction */
+ if (val != PRU_HALT_INSN) {
+- dev_err(dev, "PRU #%d not in halt insn (addr=0x%x val 0x%08x)\n",
++ dev_err(dev, "PRU#%d not in halt insn (addr=0x%x val 0x%08x)\n",
+ ppc->idx, addr, val);
+ return -EFAULT;
+ }
+
++ if (addrp != NULL)
++ *addrp = addr;
++
++ return 0;
++}
++
++static u32 pru_read_cpu_reg(struct pruproc_core *ppc, int reg)
++{
++ return pdbg_read_reg(ppc, PDBG_GPREG(reg));
++}
++
++static void pru_write_cpu_reg(struct pruproc_core *ppc, int reg, u32 val)
++{
++ pdbg_write_reg(ppc, PDBG_GPREG(reg), val);
++}
++
++/* it is assumed that the PRU is halted */
++static void pru_resume(struct pruproc_core *ppc, u32 addr)
++{
++ u32 val;
++
++ val = pcntrl_read_reg(ppc, PCTRL_CONTROL);
++ val &= 0xffff;
++ val |= ((addr >> 2) << 16) | CONTROL_ENABLE;
++ val &= ~CONTROL_SOFT_RST_N;
++ pcntrl_write_reg(ppc, PCTRL_CONTROL, val);
++}
++
++/* handle a PRU syscall */
++static int pru_handle_syscall(struct pruproc_core *ppc)
++{
++ struct pruproc *pp = ppc->pruproc;
++ struct device *dev = &pp->pdev->dev;
++ u32 addr, scno, arg0, arg1, arg2, ret;
++ int valid_sc;
++ void * __iomem va;
++ struct pru_vring_info *vri;
++ struct pru_dev_vring_info *dvri;
++
++ ret = pru_is_halted(ppc, &addr);
++ if (ret != 0) {
++ dev_err(dev, "PRU#%d not halted\n", ppc->idx);
++ return ret;
++ }
++
+ valid_sc = 0;
+- scno = pdbg_read_reg(ppc, PDBG_GPREG(14));
+- arg0 = pdbg_read_reg(ppc, PDBG_GPREG(15));
+- arg1 = pdbg_read_reg(ppc, PDBG_GPREG(16));
+- arg2 = pdbg_read_reg(ppc, PDBG_GPREG(17));
++ scno = pru_read_cpu_reg(ppc, 14);
++ arg0 = pru_read_cpu_reg(ppc, 15);
++ arg1 = pru_read_cpu_reg(ppc, 16);
++ arg2 = pru_read_cpu_reg(ppc, 17);
+ ret = 0; /* by default we return 0 */
+
+ switch (scno) {
+@@ -1356,7 +1459,7 @@ static int pru_handle_syscall(struct pruproc_core *ppc)
+ /* pointers can only be in own data ram */
+ va = pru_d_da_to_va(ppc, arg0, NULL);
+ if (va == NULL) {
+- dev_err(dev, "PRU #%d SC PUTS bad 0x%x\n",
++ dev_err(dev, "PRU#%d SC PUTS bad 0x%x\n",
+ ppc->idx, arg0);
+ ret = (u32)-1;
+ } else {
+@@ -1374,7 +1477,7 @@ static int pru_handle_syscall(struct pruproc_core *ppc)
+ break;
+ case PRU_SC_GET_CFG_VRING_INFO:
+ if (arg1 >= ppc->num_vrings) {
+- dev_err(dev, "PRU #%d SC "
++ dev_err(dev, "PRU#%d SC "
+ "GET_CFG_VRING_INFO "
+ "bad idx %d\n",
+ ppc->idx, arg1);
+@@ -1382,7 +1485,7 @@ static int pru_handle_syscall(struct pruproc_core *ppc)
+
+ va = pru_d_da_to_va(ppc, arg2, NULL);
+ if (va == NULL) {
+- dev_err(dev, "PRU #%d SC "
++ dev_err(dev, "PRU#%d SC "
+ "GET_CFG_VRING_INFO "
+ "bad 0x%x\n",
+ ppc->idx, arg2);
+@@ -1410,7 +1513,7 @@ static int pru_handle_syscall(struct pruproc_core *ppc)
+ break;
+
+ default:
+- dev_err(dev, "PRU #%d SC "
++ dev_err(dev, "PRU#%d SC "
+ "GET_CFG bad 0x%x\n",
+ ppc->idx, arg1);
+ ret = (u32)-1;
+@@ -1418,30 +1521,175 @@ static int pru_handle_syscall(struct pruproc_core *ppc)
+ }
+ break;
+
++ case PRU_SC_DOWNCALL_READY:
++ /* if we were waiting for it, wake up */
++ if (test_and_clear_bit(PRU_DCF_DOWNCALL_REQ, &ppc->dc_flags)) {
++ set_bit(PRU_DCF_DOWNCALL_ACK, &ppc->dc_flags);
++ wake_up_interruptible(&ppc->dc_waitq);
++ return 1;
++ }
++ dev_err(dev, "P%d No-one expected downcall; halting\n",
++ ppc->idx);
++ return 1;
++
++ case PRU_SC_DOWNCALL_DONE:
++ /* if we were waiting for it, wake up */
++ if (test_and_clear_bit(PRU_DCF_DOWNCALL_ISSUE, &ppc->dc_flags)) {
++ set_bit(PRU_DCF_DOWNCALL_DONE, &ppc->dc_flags);
++ wake_up_interruptible(&ppc->dc_waitq);
++ return 1;
++ }
++ dev_err(dev, "P%d No-one expected downcall; halting\n",
++ ppc->idx);
++ return 1;
++
+ default:
+- dev_err(dev, "PRU #%d SC Unknown (%d)\n",
++ dev_err(dev, "PRU#%d SC Unknown (%d)\n",
+ ppc->idx, scno);
+ return 1;
+ }
+
+ /* return code */
+- pdbg_write_reg(ppc, PDBG_GPREG(14), ret);
++ pru_write_cpu_reg(ppc, 14, ret);
+
+ /* skip over the HALT insn */
+- val = pcntrl_read_reg(ppc, PCTRL_CONTROL);
+- val &= 0xffff;
+- addr = pcntrl_read_reg(ppc, PCTRL_STATUS);
+- val |= ((addr + 1) << 16) | CONTROL_ENABLE;
+- val &= ~CONTROL_SOFT_RST_N;
++ pru_resume(ppc, addr + 4);
+
+- /* dev_dbg(dev, "PRU#%d new PCTRL_CONTROL=0x%08x\n",
+- ppc->idx, val); */
++ return 0;
++}
+
+- pcntrl_write_reg(ppc, PCTRL_CONTROL, val);
++/*
++ * The source of the downcall part on the PRU
++ *
++ * .global sc_downcall
++ *sc_downcall:
++ * MOV R0.w0, R14.w0 ;* save the pointer to the function
++ * ;* first issue the downcall ready
++ * LDI R14, DOWNCALL_READY
++ * LDI R31, SYSCALL_VALUE
++ * HALT ;* host must save R3.w0 locally
++ * ;* the host will manipulate our state so that the arguments are correct
++ * JAL R3.w0, R0.w0 ;* call
++ * MOV R0, R14 ;* save the return code
++ * ;* when we return here, we will inform the host of the result
++ * LDI R14, DOWNCALL_DONE ;
++ * LDI R31, SYSCALL_VALUE
++ * HALT ;* host must return to save R3.w0
++ */
+
+- return 0;
++/* perform the downcall */
++static int pru_downcall(struct pruproc_core *ppc,
++ u32 nr, u32 arg0, u32 arg1, u32 arg2)
++{
++ struct pruproc *pp = ppc->pruproc;
++ struct device *dev = &pp->pdev->dev;
++ int sysint;
++ int ret;
++ long intr;
++ u32 addr, r3in;
++
++ sysint = pp->target_to_sysev[TARGET_ARM_TO_PRU_IDX(ppc->idx)];
++ if (sysint == -1)
++ return -EINVAL;
++
++ /* we might sleep, warn with a backtrace */
++ might_sleep();
++
++ mutex_lock(&ppc->dc_lock);
++
++ /* state machine out of sync */
++ if (ppc->dc_flags != 0) {
++ ret = -EBUSY;
++ goto ret_unlock;
++ }
++
++ if (test_and_set_bit(PRU_DCF_DOWNCALL_REQ, &ppc->dc_flags) != 0) {
++ dev_err(dev, "PRU#%d downcall failed due to mangled req bit\n",
++ ppc->idx);
++ ret = -EBUSY;
++ goto ret_unlock;
++ }
++
++ /* signal downcall event */
++ if (sysint < 32)
++ pintc_write_reg(pp, PINTC_SRSR0, 1 << sysint);
++ else
++ pintc_write_reg(pp, PINTC_SRSR1, 1 << (sysint - 32));
++
++ /* now waiting until we get the downcall ready (maximum 100ms) */
++ intr = wait_event_interruptible_timeout(ppc->dc_waitq,
++ test_and_clear_bit(PRU_DCF_DOWNCALL_ACK, &ppc->dc_flags),
++ HZ / 10);
++ if (intr < 0) {
++ ret = (int)intr;
++ dev_err(dev, "PRU#%d error waiting for downcall ready (%d)\n",
++ ppc->idx, ret);
++ goto ret_call_failed;
++ }
++ if (intr == 0) {
++ dev_err(dev, "PRU#%d failed to issue downcall ready in 100ms\n",
++ ppc->idx);
++ ret = -ETIMEDOUT;
++ goto ret_call_failed;
++ }
++ dev_dbg(dev, "PRU#%d got downcall ready\n", ppc->idx);
++
++ ret = pru_is_halted(ppc, &addr);
++ if (ret != 0) {
++ dev_err(dev, "PRU#%d not halted\n",
++ ppc->idx);
++ ret = -EFAULT;
++ goto ret_call_failed;
++ }
++
++ /* get the actual return address */
++ r3in = pru_read_cpu_reg(ppc, 3) << 2;
++
++ /* write the arguments */
++ pru_write_cpu_reg(ppc, 14, nr);
++ pru_write_cpu_reg(ppc, 15, arg0);
++ pru_write_cpu_reg(ppc, 16, arg1);
++ pru_write_cpu_reg(ppc, 17, arg2);
++
++ set_bit(PRU_DCF_DOWNCALL_ISSUE, &ppc->dc_flags);
++
++ /* skip over the HALT insn */
++ pru_resume(ppc, addr + 4);
++
++ /* now waiting until we get the downcall ready (maximum 100ms) */
++ intr = wait_event_interruptible_timeout(ppc->dc_waitq,
++ test_and_clear_bit(PRU_DCF_DOWNCALL_DONE, &ppc->dc_flags),
++ HZ / 10);
++ if (intr < 0) {
++ ret = (int)intr;
++ dev_err(dev, "PRU#%d error waiting for downcall done (%d)\n",
++ ppc->idx, ret);
++ goto ret_call_failed;
++ }
++ if (intr == 0) {
++ dev_err(dev, "PRU#%d failed to issue downcall done in 100ms\n",
++ ppc->idx);
++ ret = -ETIMEDOUT;
++ goto ret_call_failed;
++ }
++ dev_dbg(dev, "PRU#%d got downcall done\n", ppc->idx);
++
++ /* return */
++ ret = pru_read_cpu_reg(ppc, 0);
++
++ /* and we're done */
++ pru_resume(ppc, r3in);
++
++ret_call_failed:
++ ppc->dc_flags = 0;
++
++ret_unlock:
++ mutex_unlock(&ppc->dc_lock);
++
++ return ret;
+ }
+
++
+ static irqreturn_t pru_handler(int irq, void *data)
+ {
+ struct pruproc *pp = data;
+@@ -1512,7 +1760,7 @@ static irqreturn_t pru_handler(int irq, void *data)
+ /* we either handle a vring or not */
+ if (!pst->vring) {
+ ret = pru_handle_syscall(ppc);
+- if (ret == 0) /* system call handled */
++ if (ret >= 0) /* system call handled */
+ handled++;
+ } else {
+ /* handle any vrings action */
+@@ -1522,7 +1770,7 @@ static irqreturn_t pru_handler(int irq, void *data)
+ continue;
+ ret = rproc_vq_interrupt(rproc, vri->rvring->notifyid);
+ if (ret == IRQ_HANDLED) {
+- dev_dbg(dev, "PRU #%d; vring irq handled\n",
++ dev_dbg(dev, "PRU#%d; vring irq handled\n",
+ ppc->idx);
+ handled++;
+ }
+@@ -1530,13 +1778,11 @@ static irqreturn_t pru_handler(int irq, void *data)
+ }
+ }
+
+-#if 0
+ if (!handled) {
+ dev_err(dev, "sysint not handled; disabling interrupt\n");
+- goto disable_int;
++ return IRQ_NONE;
+
+ }
+-#endif
+
+ return IRQ_HANDLED;
+
+@@ -1552,7 +1798,6 @@ static int build_rsc_table(struct platform_device *pdev,
+ struct device *dev = &pdev->dev;
+ struct device_node *rnode = NULL; /* resource table node */
+ struct device_node *rvnode = NULL; /* vdev node */
+- // struct pruproc *pp = ppc->pruproc;
+ struct resource_table *rsc;
+ struct fw_rsc_hdr *rsc_hdr;
+ struct fw_rsc_vdev *rsc_vdev;
+@@ -2144,6 +2389,9 @@ static int pruproc_probe(struct platform_device *pdev)
+
+ atomic_set(&ppc->bootcnt, 0);
+
++ mutex_init(&ppc->dc_lock);
++ init_waitqueue_head(&ppc->dc_waitq);
++
+ err = of_property_read_u32_array(pnode, "iram", tmparr, 3);
+ if (err != 0) {
+ dev_err(dev, "no iram property\n");
+@@ -2330,6 +2578,18 @@ static int pruproc_probe(struct platform_device *pdev)
+ goto err_fail;
+ }
+
++ err = device_create_file(dev, &dev_attr_downcall0);
++ if (err != 0) {
++ dev_err(dev, "device_create_file failed\n");
++ goto err_fail;
++ }
++
++ err = device_create_file(dev, &dev_attr_downcall1);
++ if (err != 0) {
++ dev_err(dev, "device_create_file failed\n");
++ goto err_fail;
++ }
++
+ dev_info(dev, "Loaded OK\n");
+
+ (void)pru_d_read_u32;
diff --git a/patches/linux-3.8.13/0439-rproc-pru-Implement-a-software-defined-PWM-channel-s.patch b/patches/linux-3.8.13/0439-rproc-pru-Implement-a-software-defined-PWM-channel-s.patch
new file mode 100644
index 0000000..861e3ea
--- /dev/null
+++ b/patches/linux-3.8.13/0439-rproc-pru-Implement-a-software-defined-PWM-channel-s.patch
@@ -0,0 +1,326 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Fri, 12 Jul 2013 20:51:16 +0300
+Subject: [PATCH] rproc: pru: Implement a software defined PWM channel set
+
+Implement a fully working PWM software defined peripheral.
+Your Linux client only see a standard PWM interface, while
+everything is implemented by software on the PRUs.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/remoteproc/pru_rproc.c | 223 +++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 208 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c
+index ad2dfc7..6e42db6 100644
+--- a/drivers/remoteproc/pru_rproc.c
++++ b/drivers/remoteproc/pru_rproc.c
+@@ -30,6 +30,8 @@
+ #include <linux/virtio_ring.h>
+ #include <asm/atomic.h>
+
++#include <linux/pwm.h>
++
+ #include "remoteproc_internal.h"
+
+ /* PRU_EVTOUT0 is halt (system call) */
+@@ -76,6 +78,15 @@ struct pruproc_core;
+
+ #define PRU_HALT_INSN 0x2a000000
+
++/* down call IDs */
++#define DC_PWM_CONFIG 0 /* pwm, hi, lo */
++#define DC_PWM_ENABLE 1 /* pwm */
++#define DC_PWM_DISABLE 2 /* pwm */
++#define DC_PWM_MAX 3
++
++/* maximum PWMs */
++#define PRU_PWM_MAX 32
++
+ struct pru_vring_info {
+ struct fw_rsc_vdev_vring *rsc;
+ struct vring vr;
+@@ -166,6 +177,18 @@ struct pruproc {
+ u32 num_prus;
+ struct pruproc_core **pruc;
+ struct pruproc_core *pru_to_pruc[MAX_PRUS];
++
++ /* PRU clock period in ns */
++ u32 clock_freq;
++
++ /* the actual linux devices */
++ struct {
++ struct pwm_chip chip;
++ int count;
++ u32 map[PRU_PWM_MAX]; /* maximum pwm channels is 32 */
++ int controller;
++ u32 dc_ids[DC_PWM_MAX];
++ } pwm;
+ };
+
+ /* global memory map (for am33xx) (almost the same as local) */
+@@ -1262,7 +1285,10 @@ static ssize_t pruproc_store_reset(struct device *dev,
+ }
+
+ static int pru_downcall(struct pruproc_core *ppc,
+- u32 nr, u32 arg0, u32 arg1, u32 arg2);
++ u32 nr, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
++
++static int pru_downcall_idx(struct pruproc *pp, int idx,
++ u32 nr, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+
+ static ssize_t pruproc_store_downcall(int idx,
+ struct device *dev, struct device_attribute *attr,
+@@ -1270,20 +1296,11 @@ static ssize_t pruproc_store_downcall(int idx,
+ {
+ struct platform_device *pdev = to_platform_device(dev);
+ struct pruproc *pp = platform_get_drvdata(pdev);
+- struct pruproc_core *ppc = NULL;
+- int i, ret;
+-
+- for (i = 0; i < pp->num_prus; i++) {
+- ppc = pp->pruc[i];
+- if (ppc->idx == idx)
+- break;
+- }
+- if (i >= pp->num_prus)
+- return -EINVAL;
++ int ret;
+
+- ret = pru_downcall(ppc, 0x5, 0xaa55, 0x1234, 0x98ff);
++ ret = pru_downcall_idx(pp, idx, 0x5, 0xaa55, 0x1234, 0x98ff, 0, 0);
+
+- dev_info(dev, "PRU#%d downcall test - ret = %d\n", ppc->idx, ret);
++ dev_info(dev, "PRU#%d downcall test - ret = %d\n", idx, ret);
+
+ return strlen(buf);
+ }
+@@ -1579,7 +1596,7 @@ static int pru_handle_syscall(struct pruproc_core *ppc)
+
+ /* perform the downcall */
+ static int pru_downcall(struct pruproc_core *ppc,
+- u32 nr, u32 arg0, u32 arg1, u32 arg2)
++ u32 nr, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
+ {
+ struct pruproc *pp = ppc->pruproc;
+ struct device *dev = &pp->pdev->dev;
+@@ -1650,6 +1667,8 @@ static int pru_downcall(struct pruproc_core *ppc,
+ pru_write_cpu_reg(ppc, 15, arg0);
+ pru_write_cpu_reg(ppc, 16, arg1);
+ pru_write_cpu_reg(ppc, 17, arg2);
++ pru_write_cpu_reg(ppc, 18, arg3);
++ pru_write_cpu_reg(ppc, 19, arg4);
+
+ set_bit(PRU_DCF_DOWNCALL_ISSUE, &ppc->dc_flags);
+
+@@ -1689,6 +1708,22 @@ ret_unlock:
+ return ret;
+ }
+
++static int pru_downcall_idx(struct pruproc *pp, int idx,
++ u32 nr, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
++{
++ struct pruproc_core *ppc = NULL;
++ int i;
++
++ for (i = 0; i < pp->num_prus; i++) {
++ ppc = pp->pruc[i];
++ if (ppc->idx == idx)
++ break;
++ }
++ if (i >= pp->num_prus)
++ return -EINVAL;
++
++ return pru_downcall(ppc, nr, arg0, arg1, arg2, arg3, arg4);
++}
+
+ static irqreturn_t pru_handler(int irq, void *data)
+ {
+@@ -2162,6 +2197,153 @@ static int configure_pintc(struct platform_device *pdev, struct pruproc *pp)
+ return 0;
+ }
+
++static int pru_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
++ int duty_ns, int period_ns)
++{
++ struct device *dev = chip->dev;
++ struct platform_device *pdev = to_platform_device(dev);
++ struct pruproc *pp = platform_get_drvdata(pdev);
++ int hwpwm, prupwm, ret;
++ u32 hi, lo;
++
++ hwpwm = pwm->hwpwm;
++ if (hwpwm >= pp->pwm.count)
++ return -EINVAL;
++ prupwm = pp->pwm.map[hwpwm];
++
++ dev_dbg(&pdev->dev, "%s (%d/%d) duty_ns=%d period_ns=%d\n", __func__,
++ hwpwm, prupwm, duty_ns, period_ns);
++
++ hi = div_u64((u64)duty_ns * pp->clock_freq, 1000000000);
++ lo = div_u64((u64)(period_ns - duty_ns) * pp->clock_freq, 1000000000);
++ ret = pru_downcall_idx(pp, pp->pwm.controller,
++ pp->pwm.dc_ids[DC_PWM_CONFIG], prupwm, hi, lo, 0, 0);
++ return ret;
++}
++
++static int pru_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++ struct device *dev = chip->dev;
++ struct platform_device *pdev = to_platform_device(dev);
++ struct pruproc *pp = platform_get_drvdata(pdev);
++ int hwpwm, prupwm, ret;
++
++ hwpwm = pwm->hwpwm;
++ if (hwpwm >= pp->pwm.count)
++ return -EINVAL;
++ prupwm = pp->pwm.map[hwpwm];
++
++ dev_dbg(&pdev->dev, "%s (%d/%d)\n", __func__, hwpwm, prupwm);
++
++ ret = pru_downcall_idx(pp, pp->pwm.controller,
++ pp->pwm.dc_ids[DC_PWM_ENABLE], prupwm, 0, 0, 0, 0);
++ return ret;
++}
++
++static void pru_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++ struct device *dev = chip->dev;
++ struct platform_device *pdev = to_platform_device(dev);
++ struct pruproc *pp = platform_get_drvdata(pdev);
++ int hwpwm, prupwm;
++
++ hwpwm = pwm->hwpwm;
++ if (hwpwm >= pp->pwm.count)
++ return;
++ prupwm = pp->pwm.map[hwpwm];
++
++ dev_dbg(&pdev->dev, "%s (%d/%d)\n", __func__, hwpwm, prupwm);
++
++ pru_downcall_idx(pp, pp->pwm.controller,
++ pp->pwm.dc_ids[DC_PWM_DISABLE], prupwm, 0, 0, 0, 0);
++}
++
++static const struct pwm_ops pru_pwm_ops = {
++ .config = pru_pwm_config,
++ .enable = pru_pwm_enable,
++ .disable = pru_pwm_disable,
++};
++
++static int pruproc_create_pwm_devices(struct pruproc *pp)
++{
++ struct platform_device *pdev = pp->pdev;
++ struct device *dev = &pdev->dev;
++ struct device_node *np = dev->of_node;
++ struct property *prop;
++ u32 val;
++ int err, i, cnt, proplen;
++
++ /* pwms */
++
++ /* find property */
++ prop = of_find_property(np, "pru-pwm-channels", &proplen);
++ if (prop == NULL)
++ return 0;
++
++ cnt = proplen / sizeof(u32);
++ if (cnt >= ARRAY_SIZE(pp->pwm.map)) {
++ dev_err(dev, "Too many PWMs %d (max %d)\n",
++ cnt, ARRAY_SIZE(pp->pwm.map));
++ return -EINVAL;
++ }
++ pp->pwm.count = cnt;
++
++ /* now read it */
++ err = of_property_read_u32_array(np, "pru-pwm-channels",
++ pp->pwm.map, cnt);
++ if (err != 0) {
++ dev_err(dev, "Failed to read %s property\n",
++ "pru-pwm-channels");
++ return err;
++ }
++
++ if (of_property_read_u32(np, "pru-pwm-controller", &val) == 0)
++ pp->pwm.controller = val;
++ else
++ pp->pwm.controller = 0; /* default is PRU0 */
++
++ /* verify they are sane */
++ for (i = 0; i < cnt; i++) {
++ if (pp->pwm.map[i] >= ARRAY_SIZE(pp->pwm.map)) {
++ dev_err(dev, "Bad PWM number\n");
++ return -EINVAL;
++ }
++ }
++
++ /* get the PWM DC IDs */
++ err = of_property_read_u32_array(np, "pru-pwm-dc-ids",
++ pp->pwm.dc_ids, ARRAY_SIZE(pp->pwm.dc_ids));
++ if (err != 0) {
++ dev_err(dev, "Failed to read %s array\n",
++ "pru-pwm-dc-ids");
++ return err;
++ }
++
++ pp->pwm.chip.dev = dev;
++ pp->pwm.chip.ops = &pru_pwm_ops;
++ pp->pwm.chip.base = pdev->id; /* ? */
++ pp->pwm.chip.npwm = cnt;
++
++ /* add the pwms */
++ err = pwmchip_add(&pp->pwm.chip);
++ if (err != 0) {
++ dev_err(dev, "pwmchip_add failed\n");
++ return err;
++ }
++
++ return 0;
++}
++
++/* after all is configured create the linux devices */
++static int pruproc_create_devices(struct pruproc *pp)
++{
++ int ret;
++
++ ret = pruproc_create_pwm_devices(pp);
++
++ return ret;
++}
++
+ static int pruproc_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -2176,7 +2358,7 @@ static int pruproc_probe(struct platform_device *pdev)
+ struct resource *res;
+ struct pinctrl *pinctrl;
+ int err, i, j, irq, sysev;
+- u32 tmparr[4], pru_idx;
++ u32 tmparr[4], pru_idx, val;
+ u32 tmpev[MAX_ARM_PRU_INTS];
+
+ /* get pinctrl */
+@@ -2304,6 +2486,14 @@ static int pruproc_probe(struct platform_device *pdev)
+ pp->pdram_sz = tmparr[1];
+ pp->pdram_da = tmparr[2];
+
++ /* get the clock frequency */
++ err = of_property_read_u32(node, "clock-freq", &val);
++ if (err != 0) {
++ dev_warn(dev, "no clock-freq property; assuming default 200MHz\n");
++ val = 200000000;
++ }
++ pp->clock_freq = val;
++
+ /* configure PRU interrupt controller from DT */
+ err = configure_pintc(pdev, pp);
+ if (err != 0) {
+@@ -2592,6 +2782,9 @@ static int pruproc_probe(struct platform_device *pdev)
+
+ dev_info(dev, "Loaded OK\n");
+
++ /* creating devices */
++ pruproc_create_devices(pp);
++
+ (void)pru_d_read_u32;
+ (void)pru_i_write_u32;
+ (void)pru_d_write_u32;
diff --git a/patches/linux-3.8.13/0440-capes-PRU-PWM-channels-information.patch b/patches/linux-3.8.13/0440-capes-PRU-PWM-channels-information.patch
new file mode 100644
index 0000000..414c56a
--- /dev/null
+++ b/patches/linux-3.8.13/0440-capes-PRU-PWM-channels-information.patch
@@ -0,0 +1,59 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 15 Jul 2013 15:29:11 +0300
+Subject: [PATCH] capes: PRU: PWM channels information
+
+---
+ firmware/capes/BB-BONE-PRU-03-00A0.dts | 5 ++++-
+ firmware/capes/BB-BONE-PRU-04-00A0.dts | 13 ++++++++++++-
+ 2 files changed, 16 insertions(+), 2 deletions(-)
+
+diff --git a/firmware/capes/BB-BONE-PRU-03-00A0.dts b/firmware/capes/BB-BONE-PRU-03-00A0.dts
+index 7d7ba99..ae2d033 100644
+--- a/firmware/capes/BB-BONE-PRU-03-00A0.dts
++++ b/firmware/capes/BB-BONE-PRU-03-00A0.dts
+@@ -1,5 +1,5 @@
+ /*
+-* Copyright (C) 2013 Matt Ranostay <mranostay@gmail.com>
++* Copyright (C) 2013 Pantelis Antoniou <panto@antoniou-consulting.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+@@ -167,6 +167,9 @@
+ < 19 0xffffffff 17>, /* PRU0: PRU0_ARM, DONTCARE, PRU0_PRU1 */
+ < 20 18 0xffffffff>; /* PRU1: PRU1_ARM, PRU1_PRU0, DONTCARE */
+
++ /* both the PRUs have 200MHz frequency so period is 5ns */
++ clock-freq = <200000000>;
++
+ /* definition for the first PRU */
+ pru0 {
+ pru-index = <0>;
+diff --git a/firmware/capes/BB-BONE-PRU-04-00A0.dts b/firmware/capes/BB-BONE-PRU-04-00A0.dts
+index 2ad0ff1..bf96ccf 100644
+--- a/firmware/capes/BB-BONE-PRU-04-00A0.dts
++++ b/firmware/capes/BB-BONE-PRU-04-00A0.dts
+@@ -1,5 +1,5 @@
+ /*
+-* Copyright (C) 2013 Matt Ranostay <mranostay@gmail.com>
++* Copyright (C) 2013 Pantelis Antoniou <panto@antoniou-consulting.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+@@ -224,6 +224,17 @@
+ < 19 0xffffffff 17>, /* PRU0: PRU0_ARM, DONTCARE, PRU0_PRU1 */
+ < 20 18 0xffffffff>; /* PRU1: PRU1_ARM, PRU1_PRU0, DONTCARE */
+
++ /* both the PRUs have 200MHz frequency so period is 5ns */
++ clock-freq = <200000000>;
++
++ /* the linux pwms we support */
++ pru-pwm-channels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 21>;
++ /* first PRU controls the PWMs */
++ pru-pwm-controller = <0>;
++ /* the IDs of the downcalls the firmware expects for PWMs */
++ /* CONFIG=0, ENABLE=1, DISABLE=2 */
++ pru-pwm-dc-ids = <0 1 2>;
++
+ /* definition for the first PRU */
+ pru0 {
+ pru-index = <0>;
diff --git a/patches/linux-3.8.4/0359-drivers-usb-phy-add-a-new-driver-for-usb-part-of-con.patch b/patches/linux-3.8.13/0441-drivers-usb-phy-add-a-new-driver-for-usb-part-of-con.patch
index 3bf60c9..3bf60c9 100644
--- a/patches/linux-3.8.4/0359-drivers-usb-phy-add-a-new-driver-for-usb-part-of-con.patch
+++ b/patches/linux-3.8.13/0441-drivers-usb-phy-add-a-new-driver-for-usb-part-of-con.patch
diff --git a/patches/linux-3.8.4/0360-drivers-usb-start-using-the-control-module-driver.patch b/patches/linux-3.8.13/0442-drivers-usb-start-using-the-control-module-driver.patch
index ac7e56e..ac7e56e 100644
--- a/patches/linux-3.8.4/0360-drivers-usb-start-using-the-control-module-driver.patch
+++ b/patches/linux-3.8.13/0442-drivers-usb-start-using-the-control-module-driver.patch
diff --git a/patches/linux-3.8.4/0361-usb-otg-Add-an-API-to-bind-the-USB-controller-and-PH.patch b/patches/linux-3.8.13/0443-usb-otg-Add-an-API-to-bind-the-USB-controller-and-PH.patch
index 966afa0..966afa0 100644
--- a/patches/linux-3.8.4/0361-usb-otg-Add-an-API-to-bind-the-USB-controller-and-PH.patch
+++ b/patches/linux-3.8.13/0443-usb-otg-Add-an-API-to-bind-the-USB-controller-and-PH.patch
diff --git a/patches/linux-3.8.4/0362-usb-otg-utils-add-facilities-in-phy-lib-to-support-m.patch b/patches/linux-3.8.13/0444-usb-otg-utils-add-facilities-in-phy-lib-to-support-m.patch
index 240af40..240af40 100644
--- a/patches/linux-3.8.4/0362-usb-otg-utils-add-facilities-in-phy-lib-to-support-m.patch
+++ b/patches/linux-3.8.13/0444-usb-otg-utils-add-facilities-in-phy-lib-to-support-m.patch
diff --git a/patches/linux-3.8.4/0363-ARM-OMAP-USB-Add-phy-binding-information.patch b/patches/linux-3.8.13/0445-ARM-OMAP-USB-Add-phy-binding-information.patch
index e1993b2..e1993b2 100644
--- a/patches/linux-3.8.4/0363-ARM-OMAP-USB-Add-phy-binding-information.patch
+++ b/patches/linux-3.8.13/0445-ARM-OMAP-USB-Add-phy-binding-information.patch
diff --git a/patches/linux-3.8.4/0364-drivers-usb-musb-omap-make-use-of-the-new-PHY-lib-AP.patch b/patches/linux-3.8.13/0446-drivers-usb-musb-omap-make-use-of-the-new-PHY-lib-AP.patch
index a9e5886..a9e5886 100644
--- a/patches/linux-3.8.4/0364-drivers-usb-musb-omap-make-use-of-the-new-PHY-lib-AP.patch
+++ b/patches/linux-3.8.13/0446-drivers-usb-musb-omap-make-use-of-the-new-PHY-lib-AP.patch
diff --git a/patches/linux-3.8.4/0365-usb-otg-add-device-tree-support-to-otg-library.patch b/patches/linux-3.8.13/0447-usb-otg-add-device-tree-support-to-otg-library.patch
index 37b526e..37b526e 100644
--- a/patches/linux-3.8.4/0365-usb-otg-add-device-tree-support-to-otg-library.patch
+++ b/patches/linux-3.8.13/0447-usb-otg-add-device-tree-support-to-otg-library.patch
diff --git a/patches/linux-3.8.4/0366-USB-MUSB-OMAP-get-PHY-by-phandle-for-dt-boot.patch b/patches/linux-3.8.13/0448-USB-MUSB-OMAP-get-PHY-by-phandle-for-dt-boot.patch
index 8ebbba8..8ebbba8 100644
--- a/patches/linux-3.8.4/0366-USB-MUSB-OMAP-get-PHY-by-phandle-for-dt-boot.patch
+++ b/patches/linux-3.8.13/0448-USB-MUSB-OMAP-get-PHY-by-phandle-for-dt-boot.patch
diff --git a/patches/linux-3.8.4/0367-MUSB-Hack-around-to-make-host-port-to-work.patch b/patches/linux-3.8.13/0449-MUSB-Hack-around-to-make-host-port-to-work.patch
index 8dccb20..bb6aee8 100644
--- a/patches/linux-3.8.4/0367-MUSB-Hack-around-to-make-host-port-to-work.patch
+++ b/patches/linux-3.8.13/0449-MUSB-Hack-around-to-make-host-port-to-work.patch
@@ -15,10 +15,10 @@ Crappy, I know, but at least works.
5 files changed, 105 insertions(+), 11 deletions(-)
diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
-index 3dfbb86..3352859 100644
+index d525195..90178e2 100644
--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
+++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
-@@ -417,3 +417,9 @@
+@@ -475,3 +475,9 @@
&aes {
status = "okay";
};
@@ -29,7 +29,7 @@ index 3dfbb86..3352859 100644
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
-index 29ab2fd..1d27635 100644
+index 5d4f913..6b71632 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -399,11 +399,15 @@
diff --git a/patches/linux-3.8.4/0368-make-sure-we-register-unregister-the-NOP-xceiver-onl.patch b/patches/linux-3.8.13/0450-make-sure-we-register-unregister-the-NOP-xceiver-onl.patch
index db41380..db41380 100644
--- a/patches/linux-3.8.4/0368-make-sure-we-register-unregister-the-NOP-xceiver-onl.patch
+++ b/patches/linux-3.8.13/0450-make-sure-we-register-unregister-the-NOP-xceiver-onl.patch
diff --git a/patches/linux-3.8.13/0451-ARM-OMAP-am335x-musb-use-250-for-power.patch b/patches/linux-3.8.13/0451-ARM-OMAP-am335x-musb-use-250-for-power.patch
new file mode 100644
index 0000000..a3cc4ad
--- /dev/null
+++ b/patches/linux-3.8.13/0451-ARM-OMAP-am335x-musb-use-250-for-power.patch
@@ -0,0 +1,42 @@
+From: Robert Nelson <robertcnelson@gmail.com>
+Date: Wed, 3 Apr 2013 13:25:38 -0500
+Subject: [PATCH] ARM: OMAP: am335x: musb use 250 for power
+
+Issue first noticed by: Randy Rodes <randyrodesnn@gmail.com>
+https://groups.google.com/d/msg/beagleboard/qzlwO9ldULE/kXzFAY9rv8cJ
+
+According to the docs, the power value is only 8 bits, to specify 500mA
+this needs to be set to a value of 250: value * 2 = XmA
+
+Documentation/devicetree/bindings/usb/omap-usb.txt
+
+Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
+---
+ arch/arm/boot/dts/am335x-bone-common.dtsi | 2 +-
+ arch/arm/boot/dts/am335x-tester.dts | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
+index 90178e2..89ec6f2 100644
+--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
+@@ -478,6 +478,6 @@
+
+ &usb_otg_hs {
+ interface_type = <1>;
+- power = <500>;
++ power = <250>;
+ status = "okay";
+ };
+diff --git a/arch/arm/boot/dts/am335x-tester.dts b/arch/arm/boot/dts/am335x-tester.dts
+index 4a5ae294..c6ac8bf 100644
+--- a/arch/arm/boot/dts/am335x-tester.dts
++++ b/arch/arm/boot/dts/am335x-tester.dts
+@@ -478,6 +478,6 @@
+
+ &usb_otg_hs {
+ interface_type = <1>;
+- power = <500>;
++ power = <250>;
+ status = "okay";
+ };
diff --git a/patches/linux-3.8.13/0452-ARM-OMAP2-MUSB-Specify-omap4-has-mailbox.patch b/patches/linux-3.8.13/0452-ARM-OMAP2-MUSB-Specify-omap4-has-mailbox.patch
new file mode 100644
index 0000000..4f2f001
--- /dev/null
+++ b/patches/linux-3.8.13/0452-ARM-OMAP2-MUSB-Specify-omap4-has-mailbox.patch
@@ -0,0 +1,42 @@
+From: Kishon Vijay Abraham I <kishon@ti.com>
+Date: Wed, 6 Feb 2013 13:28:49 +0000
+Subject: [PATCH] ARM: OMAP2: MUSB: Specify omap4 has mailbox
+
+Added has_mailbox to the musb platform data to specify that omap uses
+an external mailbox (in control module) to communicate with the musb
+core during device connect and disconnect.
+
+Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
+Acked-by: Tony Lindgren <tony@atomide.com>
+---
+ arch/arm/mach-omap2/usb-musb.c | 3 +++
+ include/linux/usb/musb.h | 2 ++
+ 2 files changed, 5 insertions(+)
+
+diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
+index 7b33b37..9d27e3f 100644
+--- a/arch/arm/mach-omap2/usb-musb.c
++++ b/arch/arm/mach-omap2/usb-musb.c
+@@ -85,6 +85,9 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
+ musb_plat.mode = board_data->mode;
+ musb_plat.extvbus = board_data->extvbus;
+
++ if (cpu_is_omap44xx())
++ musb_plat.has_mailbox = true;
++
+ if (soc_is_am35xx()) {
+ oh_name = "am35x_otg_hs";
+ name = "musb-am35x";
+diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h
+index eb50525..053c268 100644
+--- a/include/linux/usb/musb.h
++++ b/include/linux/usb/musb.h
+@@ -99,6 +99,8 @@ struct musb_hdrc_platform_data {
+ /* MUSB_HOST, MUSB_PERIPHERAL, or MUSB_OTG */
+ u8 mode;
+
++ u8 has_mailbox:1;
++
+ /* for clk_get() */
+ const char *clock;
+
diff --git a/patches/linux-3.8.13/0453-usb-musb-avoid-stopping-the-session-in-host-mode.patch b/patches/linux-3.8.13/0453-usb-musb-avoid-stopping-the-session-in-host-mode.patch
new file mode 100644
index 0000000..1f24bc4
--- /dev/null
+++ b/patches/linux-3.8.13/0453-usb-musb-avoid-stopping-the-session-in-host-mode.patch
@@ -0,0 +1,30 @@
+From: Jan Luebbe <jlu@pengutronix.de>
+Date: Wed, 15 May 2013 16:41:04 +0200
+Subject: [PATCH] usb: musb: avoid stopping the session in host mode
+
+Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
+---
+ drivers/usb/musb/musb_dsps.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
+index 077c1e7..c9946b9 100644
+--- a/drivers/usb/musb/musb_dsps.c
++++ b/drivers/usb/musb/musb_dsps.c
+@@ -230,8 +230,14 @@ static void otg_timer(unsigned long _musb)
+ spin_lock_irqsave(&musb->lock, flags);
+ switch (musb->xceiv->state) {
+ case OTG_STATE_A_WAIT_BCON:
+- devctl &= ~MUSB_DEVCTL_SESSION;
+- dsps_writeb(musb->mregs, MUSB_DEVCTL, devctl);
++ /*
++ * We need to avoid stopping the session in host mode,
++ * otherwise we don't see any newly connected devices
++ */
++ if (!is_host_active(musb)) {
++ devctl &= ~MUSB_DEVCTL_SESSION;
++ dsps_writeb(musb->mregs, MUSB_DEVCTL, devctl);
++ }
+
+ devctl = dsps_readb(musb->mregs, MUSB_DEVCTL);
+ if (devctl & MUSB_DEVCTL_BDEVICE) {
diff --git a/patches/linux-3.8.4/0369-beaglebone-black-1ghz-hack.patch b/patches/linux-3.8.13/0454-beaglebone-black-1ghz-hack.patch
index d67e4a8..f5a24a8 100644
--- a/patches/linux-3.8.4/0369-beaglebone-black-1ghz-hack.patch
+++ b/patches/linux-3.8.13/0454-beaglebone-black-1ghz-hack.patch
@@ -9,10 +9,10 @@ Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts
-index e88723c..fdcbb60 100644
+index 5434bfd..1abf267 100644
--- a/arch/arm/boot/dts/am335x-boneblack.dts
+++ b/arch/arm/boot/dts/am335x-boneblack.dts
-@@ -33,3 +33,19 @@
+@@ -43,3 +43,19 @@
status = "okay";
};
@@ -33,7 +33,7 @@ index e88723c..fdcbb60 100644
+};
+
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
-index 1d27635..119ce8d 100644
+index 6b71632..6c24c9b 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -24,7 +24,7 @@
diff --git a/patches/linux-3.8.4/0370-ARM-AM33xx-Add-SoC-specific-restart-hook.patch b/patches/linux-3.8.13/0455-ARM-AM33xx-Add-SoC-specific-restart-hook.patch
index 2958f3f..061980a 100644
--- a/patches/linux-3.8.4/0370-ARM-AM33xx-Add-SoC-specific-restart-hook.patch
+++ b/patches/linux-3.8.13/0455-ARM-AM33xx-Add-SoC-specific-restart-hook.patch
@@ -80,7 +80,7 @@ index 53cb380b..fac00f0 100644
#endif
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
-index 948bcaa..0c3a991 100644
+index b9adf69..f077fbd 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -119,6 +119,14 @@ static inline void omap2xxx_restart(char mode, const char *cmd)
diff --git a/patches/linux-3.8.4/0371-iio-common-Add-STMicroelectronics-common-library.patch b/patches/linux-3.8.13/0456-iio-common-Add-STMicroelectronics-common-library.patch
index 27b1cad..27b1cad 100644
--- a/patches/linux-3.8.4/0371-iio-common-Add-STMicroelectronics-common-library.patch
+++ b/patches/linux-3.8.13/0456-iio-common-Add-STMicroelectronics-common-library.patch
diff --git a/patches/linux-3.8.4/0372-iio-accel-Add-STMicroelectronics-accelerometers-driv.patch b/patches/linux-3.8.13/0457-iio-accel-Add-STMicroelectronics-accelerometers-driv.patch
index 9c6a09f..9c6a09f 100644
--- a/patches/linux-3.8.4/0372-iio-accel-Add-STMicroelectronics-accelerometers-driv.patch
+++ b/patches/linux-3.8.13/0457-iio-accel-Add-STMicroelectronics-accelerometers-driv.patch
diff --git a/patches/linux-3.8.4/0373-iio-gyro-Add-STMicroelectronics-gyroscopes-driver.patch b/patches/linux-3.8.13/0458-iio-gyro-Add-STMicroelectronics-gyroscopes-driver.patch
index a6bee82..a6bee82 100644
--- a/patches/linux-3.8.4/0373-iio-gyro-Add-STMicroelectronics-gyroscopes-driver.patch
+++ b/patches/linux-3.8.13/0458-iio-gyro-Add-STMicroelectronics-gyroscopes-driver.patch
diff --git a/patches/linux-3.8.4/0374-iio-magnetometer-Add-STMicroelectronics-magnetometer.patch b/patches/linux-3.8.13/0459-iio-magnetometer-Add-STMicroelectronics-magnetometer.patch
index c57d9b2..c57d9b2 100644
--- a/patches/linux-3.8.4/0374-iio-magnetometer-Add-STMicroelectronics-magnetometer.patch
+++ b/patches/linux-3.8.13/0459-iio-magnetometer-Add-STMicroelectronics-magnetometer.patch
diff --git a/patches/linux-3.8.4/0375-iio-magn-Add-sensors_supported-in-st_magn_sensors.patch b/patches/linux-3.8.13/0460-iio-magn-Add-sensors_supported-in-st_magn_sensors.patch
index 936b0e8..936b0e8 100644
--- a/patches/linux-3.8.4/0375-iio-magn-Add-sensors_supported-in-st_magn_sensors.patch
+++ b/patches/linux-3.8.13/0460-iio-magn-Add-sensors_supported-in-st_magn_sensors.patch
diff --git a/patches/linux-3.8.4/0376-pwm-pca9685-skeleton-i2c-client-driver-for-PCA9685-1.patch b/patches/linux-3.8.13/0461-pwm-pca9685-skeleton-i2c-client-driver-for-PCA9685-1.patch
index 26bc333..52c73fb 100644
--- a/patches/linux-3.8.4/0376-pwm-pca9685-skeleton-i2c-client-driver-for-PCA9685-1.patch
+++ b/patches/linux-3.8.13/0461-pwm-pca9685-skeleton-i2c-client-driver-for-PCA9685-1.patch
@@ -12,10 +12,10 @@ Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
create mode 100644 drivers/pwm/pwm-pca9685.c
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
-index 74f5084..85a348d 100644
+index 6755f2b..3175564 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
-@@ -85,6 +85,16 @@ config PWM_MXS
+@@ -97,6 +97,16 @@ config PWM_MXS
To compile this driver as a module, choose M here: the module
will be called pwm-mxs.
diff --git a/patches/linux-3.8.13/0462-Invensense-MPU6050-Device-Driver.patch b/patches/linux-3.8.13/0462-Invensense-MPU6050-Device-Driver.patch
new file mode 100644
index 0000000..d06ad8a
--- /dev/null
+++ b/patches/linux-3.8.13/0462-Invensense-MPU6050-Device-Driver.patch
@@ -0,0 +1,1553 @@
+From: Ge Gao <ggao@invensense.com>
+Date: Sat, 2 Feb 2013 00:26:00 +0000
+Subject: [PATCH] Invensense MPU6050 Device Driver.
+
+This the basic functional Invensense MPU6050 Device driver.
+
+Signed-off-by: Ge Gao <ggao@invensense.com>
+Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+---
+ Documentation/ABI/testing/sysfs-bus-iio-mpu6050 | 13 +
+ drivers/iio/imu/Kconfig | 2 +
+ drivers/iio/imu/Makefile | 2 +
+ drivers/iio/imu/inv_mpu6050/Kconfig | 13 +
+ drivers/iio/imu/inv_mpu6050/Makefile | 6 +
+ drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 795 ++++++++++++++++++++++
+ drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 246 +++++++
+ drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 196 ++++++
+ drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c | 155 +++++
+ include/linux/platform_data/invensense_mpu6050.h | 31 +
+ 10 files changed, 1459 insertions(+)
+ create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-mpu6050
+ create mode 100644 drivers/iio/imu/inv_mpu6050/Kconfig
+ create mode 100644 drivers/iio/imu/inv_mpu6050/Makefile
+ create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+ create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+ create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
+ create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
+ create mode 100644 include/linux/platform_data/invensense_mpu6050.h
+
+diff --git a/Documentation/ABI/testing/sysfs-bus-iio-mpu6050 b/Documentation/ABI/testing/sysfs-bus-iio-mpu6050
+new file mode 100644
+index 0000000..cb53737
+--- /dev/null
++++ b/Documentation/ABI/testing/sysfs-bus-iio-mpu6050
+@@ -0,0 +1,13 @@
++What: /sys/bus/iio/devices/iio:deviceX/in_gyro_matrix
++What: /sys/bus/iio/devices/iio:deviceX/in_accel_matrix
++What: /sys/bus/iio/devices/iio:deviceX/in_magn_matrix
++KernelVersion: 3.4.0
++Contact: linux-iio@vger.kernel.org
++Description:
++ This is mounting matrix for motion sensors. Mounting matrix
++ is a 3x3 unitary matrix. A typical mounting matrix would look like
++ [0, 1, 0; 1, 0, 0; 0, 0, -1]. Using this information, it would be
++ easy to tell the relative positions among sensors as well as their
++ positions relative to the board that holds these sensors. Identity matrix
++ [1, 0, 0; 0, 1, 0; 0, 0, 1] means sensor chip and device are perfectly
++ aligned with each other. All axes are exactly the same.
+diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
+index 3d79a40..723563b 100644
+--- a/drivers/iio/imu/Kconfig
++++ b/drivers/iio/imu/Kconfig
+@@ -25,3 +25,5 @@ config IIO_ADIS_LIB_BUFFER
+ help
+ A set of buffer helper functions for the Analog Devices ADIS* device
+ family.
++
++source "drivers/iio/imu/inv_mpu6050/Kconfig"
+diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
+index cfe5763..1b41584 100644
+--- a/drivers/iio/imu/Makefile
++++ b/drivers/iio/imu/Makefile
+@@ -8,3 +8,5 @@ adis_lib-y += adis.o
+ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_trigger.o
+ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o
+ obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o
++
++obj-y += inv_mpu6050/
+diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
+new file mode 100644
+index 0000000..b5cfa3a
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu6050/Kconfig
+@@ -0,0 +1,13 @@
++#
++# inv-mpu6050 drivers for Invensense MPU devices and combos
++#
++
++config INV_MPU6050_IIO
++ tristate "Invensense MPU6050 devices"
++ depends on I2C && SYSFS
++ select IIO_TRIGGERED_BUFFER
++ help
++ This driver supports the Invensense MPU6050 devices.
++ It is a gyroscope/accelerometer combo device.
++ This driver can be built as a module. The module will be called
++ inv-mpu6050.
+diff --git a/drivers/iio/imu/inv_mpu6050/Makefile b/drivers/iio/imu/inv_mpu6050/Makefile
+new file mode 100644
+index 0000000..3a677c7
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu6050/Makefile
+@@ -0,0 +1,6 @@
++#
++# Makefile for Invensense MPU6050 device.
++#
++
++obj-$(CONFIG_INV_MPU6050_IIO) += inv-mpu6050.o
++inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o
+diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+new file mode 100644
+index 0000000..37ca05b
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+@@ -0,0 +1,795 @@
++/*
++* Copyright (C) 2012 Invensense, Inc.
++*
++* This software is licensed under the terms of the GNU General Public
++* License version 2, as published by the Free Software Foundation, and
++* may be copied, distributed, and modified under those terms.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++* GNU General Public License for more details.
++*/
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/err.h>
++#include <linux/delay.h>
++#include <linux/sysfs.h>
++#include <linux/jiffies.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/kfifo.h>
++#include <linux/spinlock.h>
++#include "inv_mpu_iio.h"
++
++/*
++ * this is the gyro scale translated from dynamic range plus/minus
++ * {250, 500, 1000, 2000} to rad/s
++ */
++static const int gyro_scale_6050[] = {133090, 266181, 532362, 1064724};
++
++/*
++ * this is the accel scale translated from dynamic range plus/minus
++ * {2, 4, 8, 16} to m/s^2
++ */
++static const int accel_scale[] = {598, 1196, 2392, 4785};
++
++static const struct inv_mpu6050_reg_map reg_set_6050 = {
++ .sample_rate_div = INV_MPU6050_REG_SAMPLE_RATE_DIV,
++ .lpf = INV_MPU6050_REG_CONFIG,
++ .user_ctrl = INV_MPU6050_REG_USER_CTRL,
++ .fifo_en = INV_MPU6050_REG_FIFO_EN,
++ .gyro_config = INV_MPU6050_REG_GYRO_CONFIG,
++ .accl_config = INV_MPU6050_REG_ACCEL_CONFIG,
++ .fifo_count_h = INV_MPU6050_REG_FIFO_COUNT_H,
++ .fifo_r_w = INV_MPU6050_REG_FIFO_R_W,
++ .raw_gyro = INV_MPU6050_REG_RAW_GYRO,
++ .raw_accl = INV_MPU6050_REG_RAW_ACCEL,
++ .temperature = INV_MPU6050_REG_TEMPERATURE,
++ .int_enable = INV_MPU6050_REG_INT_ENABLE,
++ .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1,
++ .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2,
++};
++
++static const struct inv_mpu6050_chip_config chip_config_6050 = {
++ .fsr = INV_MPU6050_FSR_2000DPS,
++ .lpf = INV_MPU6050_FILTER_20HZ,
++ .fifo_rate = INV_MPU6050_INIT_FIFO_RATE,
++ .gyro_fifo_enable = false,
++ .accl_fifo_enable = false,
++ .accl_fs = INV_MPU6050_FS_02G,
++};
++
++static const struct inv_mpu6050_hw hw_info[INV_NUM_PARTS] = {
++ {
++ .num_reg = 117,
++ .name = "MPU6050",
++ .reg = &reg_set_6050,
++ .config = &chip_config_6050,
++ },
++};
++
++int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 d)
++{
++ return i2c_smbus_write_i2c_block_data(st->client, reg, 1, &d);
++}
++
++int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask)
++{
++ u8 d, mgmt_1;
++ int result;
++
++ /* switch clock needs to be careful. Only when gyro is on, can
++ clock source be switched to gyro. Otherwise, it must be set to
++ internal clock */
++ if (INV_MPU6050_BIT_PWR_GYRO_STBY == mask) {
++ result = i2c_smbus_read_i2c_block_data(st->client,
++ st->reg->pwr_mgmt_1, 1, &mgmt_1);
++ if (result != 1)
++ return result;
++
++ mgmt_1 &= ~INV_MPU6050_BIT_CLK_MASK;
++ }
++
++ if ((INV_MPU6050_BIT_PWR_GYRO_STBY == mask) && (!en)) {
++ /* turning off gyro requires switch to internal clock first.
++ Then turn off gyro engine */
++ mgmt_1 |= INV_CLK_INTERNAL;
++ result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1, mgmt_1);
++ if (result)
++ return result;
++ }
++
++ result = i2c_smbus_read_i2c_block_data(st->client,
++ st->reg->pwr_mgmt_2, 1, &d);
++ if (result != 1)
++ return result;
++ if (en)
++ d &= ~mask;
++ else
++ d |= mask;
++ result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_2, d);
++ if (result)
++ return result;
++
++ if (en) {
++ /* Wait for output stablize */
++ msleep(INV_MPU6050_TEMP_UP_TIME);
++ if (INV_MPU6050_BIT_PWR_GYRO_STBY == mask) {
++ /* switch internal clock to PLL */
++ mgmt_1 |= INV_CLK_PLL;
++ result = inv_mpu6050_write_reg(st,
++ st->reg->pwr_mgmt_1, mgmt_1);
++ if (result)
++ return result;
++ }
++ }
++
++ return 0;
++}
++
++int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on)
++{
++ int result;
++
++ if (power_on)
++ result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1, 0);
++ else
++ result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1,
++ INV_MPU6050_BIT_SLEEP);
++ if (result)
++ return result;
++
++ if (power_on)
++ msleep(INV_MPU6050_REG_UP_TIME);
++
++ return 0;
++}
++
++/**
++ * inv_mpu6050_init_config() - Initialize hardware, disable FIFO.
++ *
++ * Initial configuration:
++ * FSR: ± 2000DPS
++ * DLPF: 20Hz
++ * FIFO rate: 50Hz
++ * Clock source: Gyro PLL
++ */
++static int inv_mpu6050_init_config(struct iio_dev *indio_dev)
++{
++ int result;
++ u8 d;
++ struct inv_mpu6050_state *st = iio_priv(indio_dev);
++
++ result = inv_mpu6050_set_power_itg(st, true);
++ if (result)
++ return result;
++ d = (INV_MPU6050_FSR_2000DPS << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT);
++ result = inv_mpu6050_write_reg(st, st->reg->gyro_config, d);
++ if (result)
++ return result;
++
++ d = INV_MPU6050_FILTER_20HZ;
++ result = inv_mpu6050_write_reg(st, st->reg->lpf, d);
++ if (result)
++ return result;
++
++ d = INV_MPU6050_ONE_K_HZ / INV_MPU6050_INIT_FIFO_RATE - 1;
++ result = inv_mpu6050_write_reg(st, st->reg->sample_rate_div, d);
++ if (result)
++ return result;
++
++ d = (INV_MPU6050_FS_02G << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
++ result = inv_mpu6050_write_reg(st, st->reg->accl_config, d);
++ if (result)
++ return result;
++
++ memcpy(&st->chip_config, hw_info[st->chip_type].config,
++ sizeof(struct inv_mpu6050_chip_config));
++ result = inv_mpu6050_set_power_itg(st, false);
++
++ return result;
++}
++
++static int inv_mpu6050_sensor_show(struct inv_mpu6050_state *st, int reg,
++ int axis, int *val)
++{
++ int ind, result;
++ __be16 d;
++
++ ind = (axis - IIO_MOD_X) * 2;
++ result = i2c_smbus_read_i2c_block_data(st->client, reg + ind, 2,
++ (u8 *)&d);
++ if (result != 2)
++ return -EINVAL;
++ *val = (short)be16_to_cpup(&d);
++
++ return IIO_VAL_INT;
++}
++
++static int inv_mpu6050_read_raw(struct iio_dev *indio_dev,
++ struct iio_chan_spec const *chan,
++ int *val,
++ int *val2,
++ long mask) {
++ struct inv_mpu6050_state *st = iio_priv(indio_dev);
++
++ switch (mask) {
++ case IIO_CHAN_INFO_RAW:
++ {
++ int ret, result;
++
++ ret = IIO_VAL_INT;
++ result = 0;
++ mutex_lock(&indio_dev->mlock);
++ if (!st->chip_config.enable) {
++ result = inv_mpu6050_set_power_itg(st, true);
++ if (result)
++ goto error_read_raw;
++ }
++ /* when enable is on, power is already on */
++ switch (chan->type) {
++ case IIO_ANGL_VEL:
++ if (!st->chip_config.gyro_fifo_enable ||
++ !st->chip_config.enable) {
++ result = inv_mpu6050_switch_engine(st, true,
++ INV_MPU6050_BIT_PWR_GYRO_STBY);
++ if (result)
++ goto error_read_raw;
++ }
++ ret = inv_mpu6050_sensor_show(st, st->reg->raw_gyro,
++ chan->channel2, val);
++ if (!st->chip_config.gyro_fifo_enable ||
++ !st->chip_config.enable) {
++ result = inv_mpu6050_switch_engine(st, false,
++ INV_MPU6050_BIT_PWR_GYRO_STBY);
++ if (result)
++ goto error_read_raw;
++ }
++ break;
++ case IIO_ACCEL:
++ if (!st->chip_config.accl_fifo_enable ||
++ !st->chip_config.enable) {
++ result = inv_mpu6050_switch_engine(st, true,
++ INV_MPU6050_BIT_PWR_ACCL_STBY);
++ if (result)
++ goto error_read_raw;
++ }
++ ret = inv_mpu6050_sensor_show(st, st->reg->raw_accl,
++ chan->channel2, val);
++ if (!st->chip_config.accl_fifo_enable ||
++ !st->chip_config.enable) {
++ result = inv_mpu6050_switch_engine(st, false,
++ INV_MPU6050_BIT_PWR_ACCL_STBY);
++ if (result)
++ goto error_read_raw;
++ }
++ break;
++ case IIO_TEMP:
++ /* wait for stablization */
++ msleep(INV_MPU6050_SENSOR_UP_TIME);
++ inv_mpu6050_sensor_show(st, st->reg->temperature,
++ IIO_MOD_X, val);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++error_read_raw:
++ if (!st->chip_config.enable)
++ result |= inv_mpu6050_set_power_itg(st, false);
++ mutex_unlock(&indio_dev->mlock);
++ if (result)
++ return result;
++
++ return ret;
++ }
++ case IIO_CHAN_INFO_SCALE:
++ switch (chan->type) {
++ case IIO_ANGL_VEL:
++ *val = 0;
++ *val2 = gyro_scale_6050[st->chip_config.fsr];
++
++ return IIO_VAL_INT_PLUS_NANO;
++ case IIO_ACCEL:
++ *val = 0;
++ *val2 = accel_scale[st->chip_config.accl_fs];
++
++ return IIO_VAL_INT_PLUS_MICRO;
++ case IIO_TEMP:
++ *val = 0;
++ *val2 = INV_MPU6050_TEMP_SCALE;
++
++ return IIO_VAL_INT_PLUS_MICRO;
++ default:
++ return -EINVAL;
++ }
++ case IIO_CHAN_INFO_OFFSET:
++ switch (chan->type) {
++ case IIO_TEMP:
++ *val = INV_MPU6050_TEMP_OFFSET;
++
++ return IIO_VAL_INT;
++ default:
++ return -EINVAL;
++ }
++ default:
++ return -EINVAL;
++ }
++}
++
++static int inv_mpu6050_write_fsr(struct inv_mpu6050_state *st, int fsr)
++{
++ int result;
++ u8 d;
++
++ if (fsr < 0 || fsr > INV_MPU6050_MAX_GYRO_FS_PARAM)
++ return -EINVAL;
++ if (fsr == st->chip_config.fsr)
++ return 0;
++
++ d = (fsr << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT);
++ result = inv_mpu6050_write_reg(st, st->reg->gyro_config, d);
++ if (result)
++ return result;
++ st->chip_config.fsr = fsr;
++
++ return 0;
++}
++
++static int inv_mpu6050_write_accel_fs(struct inv_mpu6050_state *st, int fs)
++{
++ int result;
++ u8 d;
++
++ if (fs < 0 || fs > INV_MPU6050_MAX_ACCL_FS_PARAM)
++ return -EINVAL;
++ if (fs == st->chip_config.accl_fs)
++ return 0;
++
++ d = (fs << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
++ result = inv_mpu6050_write_reg(st, st->reg->accl_config, d);
++ if (result)
++ return result;
++ st->chip_config.accl_fs = fs;
++
++ return 0;
++}
++
++static int inv_mpu6050_write_raw(struct iio_dev *indio_dev,
++ struct iio_chan_spec const *chan,
++ int val,
++ int val2,
++ long mask) {
++ struct inv_mpu6050_state *st = iio_priv(indio_dev);
++ int result;
++
++ mutex_lock(&indio_dev->mlock);
++ /* we should only update scale when the chip is disabled, i.e.,
++ not running */
++ if (st->chip_config.enable) {
++ result = -EBUSY;
++ goto error_write_raw;
++ }
++ result = inv_mpu6050_set_power_itg(st, true);
++ if (result)
++ goto error_write_raw;
++
++ switch (mask) {
++ case IIO_CHAN_INFO_SCALE:
++ switch (chan->type) {
++ case IIO_ANGL_VEL:
++ result = inv_mpu6050_write_fsr(st, val);
++ break;
++ case IIO_ACCEL:
++ result = inv_mpu6050_write_accel_fs(st, val);
++ break;
++ default:
++ result = -EINVAL;
++ break;
++ }
++ break;
++ default:
++ result = -EINVAL;
++ break;
++ }
++
++error_write_raw:
++ result |= inv_mpu6050_set_power_itg(st, false);
++ mutex_unlock(&indio_dev->mlock);
++
++ return result;
++}
++
++/**
++ * inv_mpu6050_set_lpf() - set low pass filer based on fifo rate.
++ *
++ * Based on the Nyquist principle, the sampling rate must
++ * exceed twice of the bandwidth of the signal, or there
++ * would be alising. This function basically search for the
++ * correct low pass parameters based on the fifo rate, e.g,
++ * sampling frequency.
++ */
++static int inv_mpu6050_set_lpf(struct inv_mpu6050_state *st, int rate)
++{
++ const int hz[] = {188, 98, 42, 20, 10, 5};
++ const int d[] = {INV_MPU6050_FILTER_188HZ, INV_MPU6050_FILTER_98HZ,
++ INV_MPU6050_FILTER_42HZ, INV_MPU6050_FILTER_20HZ,
++ INV_MPU6050_FILTER_10HZ, INV_MPU6050_FILTER_5HZ};
++ int i, h, result;
++ u8 data;
++
++ h = (rate >> 1);
++ i = 0;
++ while ((h < hz[i]) && (i < ARRAY_SIZE(d) - 1))
++ i++;
++ data = d[i];
++ result = inv_mpu6050_write_reg(st, st->reg->lpf, data);
++ if (result)
++ return result;
++ st->chip_config.lpf = data;
++
++ return 0;
++}
++
++/**
++ * inv_mpu6050_fifo_rate_store() - Set fifo rate.
++ */
++static ssize_t inv_mpu6050_fifo_rate_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t count)
++{
++ s32 fifo_rate;
++ u8 d;
++ int result;
++ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
++ struct inv_mpu6050_state *st = iio_priv(indio_dev);
++
++ if (kstrtoint(buf, 10, &fifo_rate))
++ return -EINVAL;
++ if (fifo_rate < INV_MPU6050_MIN_FIFO_RATE ||
++ fifo_rate > INV_MPU6050_MAX_FIFO_RATE)
++ return -EINVAL;
++ if (fifo_rate == st->chip_config.fifo_rate)
++ return count;
++
++ mutex_lock(&indio_dev->mlock);
++ if (st->chip_config.enable) {
++ result = -EBUSY;
++ goto fifo_rate_fail;
++ }
++ result = inv_mpu6050_set_power_itg(st, true);
++ if (result)
++ goto fifo_rate_fail;
++
++ d = INV_MPU6050_ONE_K_HZ / fifo_rate - 1;
++ result = inv_mpu6050_write_reg(st, st->reg->sample_rate_div, d);
++ if (result)
++ goto fifo_rate_fail;
++ st->chip_config.fifo_rate = fifo_rate;
++
++ result = inv_mpu6050_set_lpf(st, fifo_rate);
++ if (result)
++ goto fifo_rate_fail;
++
++fifo_rate_fail:
++ result |= inv_mpu6050_set_power_itg(st, false);
++ mutex_unlock(&indio_dev->mlock);
++ if (result)
++ return result;
++
++ return count;
++}
++
++/**
++ * inv_fifo_rate_show() - Get the current sampling rate.
++ */
++static ssize_t inv_fifo_rate_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct inv_mpu6050_state *st = iio_priv(dev_to_iio_dev(dev));
++
++ return sprintf(buf, "%d\n", st->chip_config.fifo_rate);
++}
++
++/**
++ * inv_attr_show() - calling this function will show current
++ * parameters.
++ */
++static ssize_t inv_attr_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct inv_mpu6050_state *st = iio_priv(dev_to_iio_dev(dev));
++ struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
++ s8 *m;
++
++ switch (this_attr->address) {
++ /* In MPU6050, the two matrix are the same because gyro and accel
++ are integrated in one chip */
++ case ATTR_GYRO_MATRIX:
++ case ATTR_ACCL_MATRIX:
++ m = st->plat_data.orientation;
++
++ return sprintf(buf, "%d, %d, %d; %d, %d, %d; %d, %d, %d\n",
++ m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]);
++ default:
++ return -EINVAL;
++ }
++}
++
++/**
++ * inv_mpu6050_validate_trigger() - validate_trigger callback for invensense
++ * MPU6050 device.
++ * @indio_dev: The IIO device
++ * @trig: The new trigger
++ *
++ * Returns: 0 if the 'trig' matches the trigger registered by the MPU6050
++ * device, -EINVAL otherwise.
++ */
++static int inv_mpu6050_validate_trigger(struct iio_dev *indio_dev,
++ struct iio_trigger *trig)
++{
++ struct inv_mpu6050_state *st = iio_priv(indio_dev);
++
++ if (st->trig != trig)
++ return -EINVAL;
++
++ return 0;
++}
++
++#define INV_MPU6050_CHAN(_type, _channel2, _index) \
++ { \
++ .type = _type, \
++ .modified = 1, \
++ .channel2 = _channel2, \
++ .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT \
++ | IIO_CHAN_INFO_RAW_SEPARATE_BIT, \
++ .scan_index = _index, \
++ .scan_type = { \
++ .sign = 's', \
++ .realbits = 16, \
++ .storagebits = 16, \
++ .shift = 0 , \
++ .endianness = IIO_BE, \
++ }, \
++ }
++
++static const struct iio_chan_spec inv_mpu_channels[] = {
++ IIO_CHAN_SOFT_TIMESTAMP(INV_MPU6050_SCAN_TIMESTAMP),
++ /*
++ * Note that temperature should only be via polled reading only,
++ * not the final scan elements output.
++ */
++ {
++ .type = IIO_TEMP,
++ .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT
++ | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT
++ | IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
++ .scan_index = -1,
++ },
++ INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU6050_SCAN_GYRO_X),
++ INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_MPU6050_SCAN_GYRO_Y),
++ INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_MPU6050_SCAN_GYRO_Z),
++
++ INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_MPU6050_SCAN_ACCL_X),
++ INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_MPU6050_SCAN_ACCL_Y),
++ INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z),
++};
++
++/* constant IIO attribute */
++static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 20 50 100 200 500");
++static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, inv_fifo_rate_show,
++ inv_mpu6050_fifo_rate_store);
++static IIO_DEVICE_ATTR(in_gyro_matrix, S_IRUGO, inv_attr_show, NULL,
++ ATTR_GYRO_MATRIX);
++static IIO_DEVICE_ATTR(in_accel_matrix, S_IRUGO, inv_attr_show, NULL,
++ ATTR_ACCL_MATRIX);
++
++static struct attribute *inv_attributes[] = {
++ &iio_dev_attr_in_gyro_matrix.dev_attr.attr,
++ &iio_dev_attr_in_accel_matrix.dev_attr.attr,
++ &iio_dev_attr_sampling_frequency.dev_attr.attr,
++ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
++ NULL,
++};
++
++static const struct attribute_group inv_attribute_group = {
++ .attrs = inv_attributes
++};
++
++static const struct iio_info mpu_info = {
++ .driver_module = THIS_MODULE,
++ .read_raw = &inv_mpu6050_read_raw,
++ .write_raw = &inv_mpu6050_write_raw,
++ .attrs = &inv_attribute_group,
++ .validate_trigger = inv_mpu6050_validate_trigger,
++};
++
++/**
++ * inv_check_and_setup_chip() - check and setup chip.
++ */
++static int inv_check_and_setup_chip(struct inv_mpu6050_state *st,
++ const struct i2c_device_id *id)
++{
++ int result;
++
++ st->chip_type = INV_MPU6050;
++ st->hw = &hw_info[st->chip_type];
++ st->reg = hw_info[st->chip_type].reg;
++
++ /* reset to make sure previous state are not there */
++ result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1,
++ INV_MPU6050_BIT_H_RESET);
++ if (result)
++ return result;
++ msleep(INV_MPU6050_POWER_UP_TIME);
++ /* toggle power state. After reset, the sleep bit could be on
++ or off depending on the OTP settings. Toggling power would
++ make it in a definite state as well as making the hardware
++ state align with the software state */
++ result = inv_mpu6050_set_power_itg(st, false);
++ if (result)
++ return result;
++ result = inv_mpu6050_set_power_itg(st, true);
++ if (result)
++ return result;
++
++ result = inv_mpu6050_switch_engine(st, false,
++ INV_MPU6050_BIT_PWR_ACCL_STBY);
++ if (result)
++ return result;
++ result = inv_mpu6050_switch_engine(st, false,
++ INV_MPU6050_BIT_PWR_GYRO_STBY);
++ if (result)
++ return result;
++
++ return 0;
++}
++
++/**
++ * inv_mpu_probe() - probe function.
++ * @client: i2c client.
++ * @id: i2c device id.
++ *
++ * Returns 0 on success, a negative error code otherwise.
++ */
++static int inv_mpu_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct inv_mpu6050_state *st;
++ struct iio_dev *indio_dev;
++ int result;
++
++ if (!i2c_check_functionality(client->adapter,
++ I2C_FUNC_SMBUS_READ_I2C_BLOCK |
++ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
++ result = -ENOSYS;
++ goto out_no_free;
++ }
++ indio_dev = iio_device_alloc(sizeof(*st));
++ if (indio_dev == NULL) {
++ result = -ENOMEM;
++ goto out_no_free;
++ }
++ st = iio_priv(indio_dev);
++ st->client = client;
++ st->plat_data = *(struct inv_mpu6050_platform_data
++ *)dev_get_platdata(&client->dev);
++ /* power is turned on inside check chip type*/
++ result = inv_check_and_setup_chip(st, id);
++ if (result)
++ goto out_free;
++
++ result = inv_mpu6050_init_config(indio_dev);
++ if (result) {
++ dev_err(&client->dev,
++ "Could not initialize device.\n");
++ goto out_free;
++ }
++
++ i2c_set_clientdata(client, indio_dev);
++ indio_dev->dev.parent = &client->dev;
++ indio_dev->name = id->name;
++ indio_dev->channels = inv_mpu_channels;
++ indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
++
++ indio_dev->info = &mpu_info;
++ indio_dev->modes = INDIO_BUFFER_TRIGGERED;
++
++ result = iio_triggered_buffer_setup(indio_dev,
++ inv_mpu6050_irq_handler,
++ inv_mpu6050_read_fifo,
++ NULL);
++ if (result) {
++ dev_err(&st->client->dev, "configure buffer fail %d\n",
++ result);
++ goto out_free;
++ }
++ result = inv_mpu6050_probe_trigger(indio_dev);
++ if (result) {
++ dev_err(&st->client->dev, "trigger probe fail %d\n", result);
++ goto out_unreg_ring;
++ }
++
++ INIT_KFIFO(st->timestamps);
++ spin_lock_init(&st->time_stamp_lock);
++ result = iio_device_register(indio_dev);
++ if (result) {
++ dev_err(&st->client->dev, "IIO register fail %d\n", result);
++ goto out_remove_trigger;
++ }
++
++ return 0;
++
++out_remove_trigger:
++ inv_mpu6050_remove_trigger(st);
++out_unreg_ring:
++ iio_triggered_buffer_cleanup(indio_dev);
++out_free:
++ iio_device_free(indio_dev);
++out_no_free:
++
++ return result;
++}
++
++static int inv_mpu_remove(struct i2c_client *client)
++{
++ struct iio_dev *indio_dev = i2c_get_clientdata(client);
++ struct inv_mpu6050_state *st = iio_priv(indio_dev);
++
++ iio_device_unregister(indio_dev);
++ inv_mpu6050_remove_trigger(st);
++ iio_triggered_buffer_cleanup(indio_dev);
++ iio_device_free(indio_dev);
++
++ return 0;
++}
++#ifdef CONFIG_PM_SLEEP
++
++static int inv_mpu_resume(struct device *dev)
++{
++ return inv_mpu6050_set_power_itg(
++ iio_priv(i2c_get_clientdata(to_i2c_client(dev))), true);
++}
++
++static int inv_mpu_suspend(struct device *dev)
++{
++ return inv_mpu6050_set_power_itg(
++ iio_priv(i2c_get_clientdata(to_i2c_client(dev))), false);
++}
++static SIMPLE_DEV_PM_OPS(inv_mpu_pmops, inv_mpu_suspend, inv_mpu_resume);
++
++#define INV_MPU6050_PMOPS (&inv_mpu_pmops)
++#else
++#define INV_MPU6050_PMOPS NULL
++#endif /* CONFIG_PM_SLEEP */
++
++/*
++ * device id table is used to identify what device can be
++ * supported by this driver
++ */
++static const struct i2c_device_id inv_mpu_id[] = {
++ {"mpu6050", INV_MPU6050},
++ {}
++};
++
++MODULE_DEVICE_TABLE(i2c, inv_mpu_id);
++
++static struct i2c_driver inv_mpu_driver = {
++ .probe = inv_mpu_probe,
++ .remove = inv_mpu_remove,
++ .id_table = inv_mpu_id,
++ .driver = {
++ .owner = THIS_MODULE,
++ .name = "inv-mpu6050",
++ .pm = INV_MPU6050_PMOPS,
++ },
++};
++
++module_i2c_driver(inv_mpu_driver);
++
++MODULE_AUTHOR("Invensense Corporation");
++MODULE_DESCRIPTION("Invensense device MPU6050 driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+new file mode 100644
+index 0000000..f383955
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+@@ -0,0 +1,246 @@
++/*
++* Copyright (C) 2012 Invensense, Inc.
++*
++* This software is licensed under the terms of the GNU General Public
++* License version 2, as published by the Free Software Foundation, and
++* may be copied, distributed, and modified under those terms.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++* GNU General Public License for more details.
++*/
++#include <linux/i2c.h>
++#include <linux/kfifo.h>
++#include <linux/spinlock.h>
++#include <linux/iio/iio.h>
++#include <linux/iio/buffer.h>
++#include <linux/iio/sysfs.h>
++#include <linux/iio/kfifo_buf.h>
++#include <linux/iio/trigger.h>
++#include <linux/iio/triggered_buffer.h>
++#include <linux/iio/trigger_consumer.h>
++#include <linux/platform_data/invensense_mpu6050.h>
++
++/**
++ * struct inv_mpu6050_reg_map - Notable registers.
++ * @sample_rate_div: Divider applied to gyro output rate.
++ * @lpf: Configures internal low pass filter.
++ * @user_ctrl: Enables/resets the FIFO.
++ * @fifo_en: Determines which data will appear in FIFO.
++ * @gyro_config: gyro config register.
++ * @accl_config: accel config register
++ * @fifo_count_h: Upper byte of FIFO count.
++ * @fifo_r_w: FIFO register.
++ * @raw_gyro: Address of first gyro register.
++ * @raw_accl: Address of first accel register.
++ * @temperature: temperature register
++ * @int_enable: Interrupt enable register.
++ * @pwr_mgmt_1: Controls chip's power state and clock source.
++ * @pwr_mgmt_2: Controls power state of individual sensors.
++ */
++struct inv_mpu6050_reg_map {
++ u8 sample_rate_div;
++ u8 lpf;
++ u8 user_ctrl;
++ u8 fifo_en;
++ u8 gyro_config;
++ u8 accl_config;
++ u8 fifo_count_h;
++ u8 fifo_r_w;
++ u8 raw_gyro;
++ u8 raw_accl;
++ u8 temperature;
++ u8 int_enable;
++ u8 pwr_mgmt_1;
++ u8 pwr_mgmt_2;
++};
++
++/*device enum */
++enum inv_devices {
++ INV_MPU6050,
++ INV_NUM_PARTS
++};
++
++/**
++ * struct inv_mpu6050_chip_config - Cached chip configuration data.
++ * @fsr: Full scale range.
++ * @lpf: Digital low pass filter frequency.
++ * @accl_fs: accel full scale range.
++ * @enable: master enable state.
++ * @accl_fifo_enable: enable accel data output
++ * @gyro_fifo_enable: enable gyro data output
++ * @fifo_rate: FIFO update rate.
++ */
++struct inv_mpu6050_chip_config {
++ unsigned int fsr:2;
++ unsigned int lpf:3;
++ unsigned int accl_fs:2;
++ unsigned int enable:1;
++ unsigned int accl_fifo_enable:1;
++ unsigned int gyro_fifo_enable:1;
++ u16 fifo_rate;
++};
++
++/**
++ * struct inv_mpu6050_hw - Other important hardware information.
++ * @num_reg: Number of registers on device.
++ * @name: name of the chip.
++ * @reg: register map of the chip.
++ * @config: configuration of the chip.
++ */
++struct inv_mpu6050_hw {
++ u8 num_reg;
++ u8 *name;
++ const struct inv_mpu6050_reg_map *reg;
++ const struct inv_mpu6050_chip_config *config;
++};
++
++/*
++ * struct inv_mpu6050_state - Driver state variables.
++ * @TIMESTAMP_FIFO_SIZE: fifo size for timestamp.
++ * @trig: IIO trigger.
++ * @chip_config: Cached attribute information.
++ * @reg: Map of important registers.
++ * @hw: Other hardware-specific information.
++ * @chip_type: chip type.
++ * @time_stamp_lock: spin lock to time stamp.
++ * @client: i2c client handle.
++ * @plat_data: platform data.
++ * @timestamps: kfifo queue to store time stamp.
++ */
++struct inv_mpu6050_state {
++#define TIMESTAMP_FIFO_SIZE 16
++ struct iio_trigger *trig;
++ struct inv_mpu6050_chip_config chip_config;
++ const struct inv_mpu6050_reg_map *reg;
++ const struct inv_mpu6050_hw *hw;
++ enum inv_devices chip_type;
++ spinlock_t time_stamp_lock;
++ struct i2c_client *client;
++ struct inv_mpu6050_platform_data plat_data;
++ DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE);
++};
++
++/*register and associated bit definition*/
++#define INV_MPU6050_REG_SAMPLE_RATE_DIV 0x19
++#define INV_MPU6050_REG_CONFIG 0x1A
++#define INV_MPU6050_REG_GYRO_CONFIG 0x1B
++#define INV_MPU6050_REG_ACCEL_CONFIG 0x1C
++
++#define INV_MPU6050_REG_FIFO_EN 0x23
++#define INV_MPU6050_BIT_ACCEL_OUT 0x08
++#define INV_MPU6050_BITS_GYRO_OUT 0x70
++
++#define INV_MPU6050_REG_INT_ENABLE 0x38
++#define INV_MPU6050_BIT_DATA_RDY_EN 0x01
++#define INV_MPU6050_BIT_DMP_INT_EN 0x02
++
++#define INV_MPU6050_REG_RAW_ACCEL 0x3B
++#define INV_MPU6050_REG_TEMPERATURE 0x41
++#define INV_MPU6050_REG_RAW_GYRO 0x43
++
++#define INV_MPU6050_REG_USER_CTRL 0x6A
++#define INV_MPU6050_BIT_FIFO_RST 0x04
++#define INV_MPU6050_BIT_DMP_RST 0x08
++#define INV_MPU6050_BIT_I2C_MST_EN 0x20
++#define INV_MPU6050_BIT_FIFO_EN 0x40
++#define INV_MPU6050_BIT_DMP_EN 0x80
++
++#define INV_MPU6050_REG_PWR_MGMT_1 0x6B
++#define INV_MPU6050_BIT_H_RESET 0x80
++#define INV_MPU6050_BIT_SLEEP 0x40
++#define INV_MPU6050_BIT_CLK_MASK 0x7
++
++#define INV_MPU6050_REG_PWR_MGMT_2 0x6C
++#define INV_MPU6050_BIT_PWR_ACCL_STBY 0x38
++#define INV_MPU6050_BIT_PWR_GYRO_STBY 0x07
++
++#define INV_MPU6050_REG_FIFO_COUNT_H 0x72
++#define INV_MPU6050_REG_FIFO_R_W 0x74
++
++#define INV_MPU6050_BYTES_PER_3AXIS_SENSOR 6
++#define INV_MPU6050_FIFO_COUNT_BYTE 2
++#define INV_MPU6050_FIFO_THRESHOLD 500
++#define INV_MPU6050_POWER_UP_TIME 100
++#define INV_MPU6050_TEMP_UP_TIME 100
++#define INV_MPU6050_SENSOR_UP_TIME 30
++#define INV_MPU6050_REG_UP_TIME 5
++
++#define INV_MPU6050_TEMP_OFFSET 12421
++#define INV_MPU6050_TEMP_SCALE 2941
++#define INV_MPU6050_MAX_GYRO_FS_PARAM 3
++#define INV_MPU6050_MAX_ACCL_FS_PARAM 3
++#define INV_MPU6050_THREE_AXIS 3
++#define INV_MPU6050_GYRO_CONFIG_FSR_SHIFT 3
++#define INV_MPU6050_ACCL_CONFIG_FSR_SHIFT 3
++
++/* 6 + 6 round up and plus 8 */
++#define INV_MPU6050_OUTPUT_DATA_SIZE 24
++
++/* init parameters */
++#define INV_MPU6050_INIT_FIFO_RATE 50
++#define INV_MPU6050_TIME_STAMP_TOR 5
++#define INV_MPU6050_MAX_FIFO_RATE 1000
++#define INV_MPU6050_MIN_FIFO_RATE 4
++#define INV_MPU6050_ONE_K_HZ 1000
++
++/* scan element definition */
++enum inv_mpu6050_scan {
++ INV_MPU6050_SCAN_ACCL_X,
++ INV_MPU6050_SCAN_ACCL_Y,
++ INV_MPU6050_SCAN_ACCL_Z,
++ INV_MPU6050_SCAN_GYRO_X,
++ INV_MPU6050_SCAN_GYRO_Y,
++ INV_MPU6050_SCAN_GYRO_Z,
++ INV_MPU6050_SCAN_TIMESTAMP,
++};
++
++enum inv_mpu6050_filter_e {
++ INV_MPU6050_FILTER_256HZ_NOLPF2 = 0,
++ INV_MPU6050_FILTER_188HZ,
++ INV_MPU6050_FILTER_98HZ,
++ INV_MPU6050_FILTER_42HZ,
++ INV_MPU6050_FILTER_20HZ,
++ INV_MPU6050_FILTER_10HZ,
++ INV_MPU6050_FILTER_5HZ,
++ INV_MPU6050_FILTER_2100HZ_NOLPF,
++ NUM_MPU6050_FILTER
++};
++
++/* IIO attribute address */
++enum INV_MPU6050_IIO_ATTR_ADDR {
++ ATTR_GYRO_MATRIX,
++ ATTR_ACCL_MATRIX,
++};
++
++enum inv_mpu6050_accl_fs_e {
++ INV_MPU6050_FS_02G = 0,
++ INV_MPU6050_FS_04G,
++ INV_MPU6050_FS_08G,
++ INV_MPU6050_FS_16G,
++ NUM_ACCL_FSR
++};
++
++enum inv_mpu6050_fsr_e {
++ INV_MPU6050_FSR_250DPS = 0,
++ INV_MPU6050_FSR_500DPS,
++ INV_MPU6050_FSR_1000DPS,
++ INV_MPU6050_FSR_2000DPS,
++ NUM_MPU6050_FSR
++};
++
++enum inv_mpu6050_clock_sel_e {
++ INV_CLK_INTERNAL = 0,
++ INV_CLK_PLL,
++ NUM_CLK
++};
++
++irqreturn_t inv_mpu6050_irq_handler(int irq, void *p);
++irqreturn_t inv_mpu6050_read_fifo(int irq, void *p);
++int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev);
++void inv_mpu6050_remove_trigger(struct inv_mpu6050_state *st);
++int inv_reset_fifo(struct iio_dev *indio_dev);
++int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask);
++int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 val);
++int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on);
+diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
+new file mode 100644
+index 0000000..331781f
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
+@@ -0,0 +1,196 @@
++/*
++* Copyright (C) 2012 Invensense, Inc.
++*
++* This software is licensed under the terms of the GNU General Public
++* License version 2, as published by the Free Software Foundation, and
++* may be copied, distributed, and modified under those terms.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++* GNU General Public License for more details.
++*/
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/i2c.h>
++#include <linux/err.h>
++#include <linux/delay.h>
++#include <linux/sysfs.h>
++#include <linux/jiffies.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/kfifo.h>
++#include <linux/poll.h>
++#include "inv_mpu_iio.h"
++
++int inv_reset_fifo(struct iio_dev *indio_dev)
++{
++ int result;
++ u8 d;
++ struct inv_mpu6050_state *st = iio_priv(indio_dev);
++
++ /* disable interrupt */
++ result = inv_mpu6050_write_reg(st, st->reg->int_enable, 0);
++ if (result) {
++ dev_err(&st->client->dev, "int_enable failed %d\n", result);
++ return result;
++ }
++ /* disable the sensor output to FIFO */
++ result = inv_mpu6050_write_reg(st, st->reg->fifo_en, 0);
++ if (result)
++ goto reset_fifo_fail;
++ /* disable fifo reading */
++ result = inv_mpu6050_write_reg(st, st->reg->user_ctrl, 0);
++ if (result)
++ goto reset_fifo_fail;
++
++ /* reset FIFO*/
++ result = inv_mpu6050_write_reg(st, st->reg->user_ctrl,
++ INV_MPU6050_BIT_FIFO_RST);
++ if (result)
++ goto reset_fifo_fail;
++ /* enable interrupt */
++ if (st->chip_config.accl_fifo_enable ||
++ st->chip_config.gyro_fifo_enable) {
++ result = inv_mpu6050_write_reg(st, st->reg->int_enable,
++ INV_MPU6050_BIT_DATA_RDY_EN);
++ if (result)
++ return result;
++ }
++ /* enable FIFO reading and I2C master interface*/
++ result = inv_mpu6050_write_reg(st, st->reg->user_ctrl,
++ INV_MPU6050_BIT_FIFO_EN);
++ if (result)
++ goto reset_fifo_fail;
++ /* enable sensor output to FIFO */
++ d = 0;
++ if (st->chip_config.gyro_fifo_enable)
++ d |= INV_MPU6050_BITS_GYRO_OUT;
++ if (st->chip_config.accl_fifo_enable)
++ d |= INV_MPU6050_BIT_ACCEL_OUT;
++ result = inv_mpu6050_write_reg(st, st->reg->fifo_en, d);
++ if (result)
++ goto reset_fifo_fail;
++
++ return 0;
++
++reset_fifo_fail:
++ dev_err(&st->client->dev, "reset fifo failed %d\n", result);
++ result = inv_mpu6050_write_reg(st, st->reg->int_enable,
++ INV_MPU6050_BIT_DATA_RDY_EN);
++
++ return result;
++}
++
++static void inv_clear_kfifo(struct inv_mpu6050_state *st)
++{
++ unsigned long flags;
++
++ /* take the spin lock sem to avoid interrupt kick in */
++ spin_lock_irqsave(&st->time_stamp_lock, flags);
++ kfifo_reset(&st->timestamps);
++ spin_unlock_irqrestore(&st->time_stamp_lock, flags);
++}
++
++/**
++ * inv_mpu6050_irq_handler() - Cache a timestamp at each data ready interrupt.
++ */
++irqreturn_t inv_mpu6050_irq_handler(int irq, void *p)
++{
++ struct iio_poll_func *pf = p;
++ struct iio_dev *indio_dev = pf->indio_dev;
++ struct inv_mpu6050_state *st = iio_priv(indio_dev);
++ s64 timestamp;
++
++ timestamp = iio_get_time_ns();
++ spin_lock(&st->time_stamp_lock);
++ kfifo_in(&st->timestamps, &timestamp, 1);
++ spin_unlock(&st->time_stamp_lock);
++
++ return IRQ_WAKE_THREAD;
++}
++
++/**
++ * inv_mpu6050_read_fifo() - Transfer data from hardware FIFO to KFIFO.
++ */
++irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
++{
++ struct iio_poll_func *pf = p;
++ struct iio_dev *indio_dev = pf->indio_dev;
++ struct inv_mpu6050_state *st = iio_priv(indio_dev);
++ size_t bytes_per_datum;
++ int result;
++ u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
++ u16 fifo_count;
++ s64 timestamp;
++ u64 *tmp;
++
++ mutex_lock(&indio_dev->mlock);
++ if (!(st->chip_config.accl_fifo_enable |
++ st->chip_config.gyro_fifo_enable))
++ goto end_session;
++ bytes_per_datum = 0;
++ if (st->chip_config.accl_fifo_enable)
++ bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR;
++
++ if (st->chip_config.gyro_fifo_enable)
++ bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR;
++
++ /*
++ * read fifo_count register to know how many bytes inside FIFO
++ * right now
++ */
++ result = i2c_smbus_read_i2c_block_data(st->client,
++ st->reg->fifo_count_h,
++ INV_MPU6050_FIFO_COUNT_BYTE, data);
++ if (result != INV_MPU6050_FIFO_COUNT_BYTE)
++ goto end_session;
++ fifo_count = be16_to_cpup((__be16 *)(&data[0]));
++ if (fifo_count < bytes_per_datum)
++ goto end_session;
++ /* fifo count can't be odd number, if it is odd, reset fifo*/
++ if (fifo_count & 1)
++ goto flush_fifo;
++ if (fifo_count > INV_MPU6050_FIFO_THRESHOLD)
++ goto flush_fifo;
++ /* Timestamp mismatch. */
++ if (kfifo_len(&st->timestamps) >
++ fifo_count / bytes_per_datum + INV_MPU6050_TIME_STAMP_TOR)
++ goto flush_fifo;
++ while (fifo_count >= bytes_per_datum) {
++ result = i2c_smbus_read_i2c_block_data(st->client,
++ st->reg->fifo_r_w,
++ bytes_per_datum, data);
++ if (result != bytes_per_datum)
++ goto flush_fifo;
++
++ result = kfifo_out(&st->timestamps, &timestamp, 1);
++ /* when there is no timestamp, put timestamp as 0 */
++ if (0 == result)
++ timestamp = 0;
++
++ tmp = (u64 *)data;
++ tmp[DIV_ROUND_UP(bytes_per_datum, 8)] = timestamp;
++ result = iio_push_to_buffers(indio_dev, data);
++ if (result)
++ goto flush_fifo;
++ fifo_count -= bytes_per_datum;
++ }
++
++end_session:
++ mutex_unlock(&indio_dev->mlock);
++ iio_trigger_notify_done(indio_dev->trig);
++
++ return IRQ_HANDLED;
++
++flush_fifo:
++ /* Flush HW and SW FIFOs. */
++ inv_reset_fifo(indio_dev);
++ inv_clear_kfifo(st);
++ mutex_unlock(&indio_dev->mlock);
++ iio_trigger_notify_done(indio_dev->trig);
++
++ return IRQ_HANDLED;
++}
+diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
+new file mode 100644
+index 0000000..e1d0869
+--- /dev/null
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
+@@ -0,0 +1,155 @@
++/*
++* Copyright (C) 2012 Invensense, Inc.
++*
++* This software is licensed under the terms of the GNU General Public
++* License version 2, as published by the Free Software Foundation, and
++* may be copied, distributed, and modified under those terms.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++* GNU General Public License for more details.
++*/
++
++#include "inv_mpu_iio.h"
++
++static void inv_scan_query(struct iio_dev *indio_dev)
++{
++ struct inv_mpu6050_state *st = iio_priv(indio_dev);
++
++ st->chip_config.gyro_fifo_enable =
++ test_bit(INV_MPU6050_SCAN_GYRO_X,
++ indio_dev->active_scan_mask) ||
++ test_bit(INV_MPU6050_SCAN_GYRO_Y,
++ indio_dev->active_scan_mask) ||
++ test_bit(INV_MPU6050_SCAN_GYRO_Z,
++ indio_dev->active_scan_mask);
++
++ st->chip_config.accl_fifo_enable =
++ test_bit(INV_MPU6050_SCAN_ACCL_X,
++ indio_dev->active_scan_mask) ||
++ test_bit(INV_MPU6050_SCAN_ACCL_Y,
++ indio_dev->active_scan_mask) ||
++ test_bit(INV_MPU6050_SCAN_ACCL_Z,
++ indio_dev->active_scan_mask);
++}
++
++/**
++ * inv_mpu6050_set_enable() - enable chip functions.
++ * @indio_dev: Device driver instance.
++ * @enable: enable/disable
++ */
++static int inv_mpu6050_set_enable(struct iio_dev *indio_dev, bool enable)
++{
++ struct inv_mpu6050_state *st = iio_priv(indio_dev);
++ int result;
++
++ if (enable) {
++ result = inv_mpu6050_set_power_itg(st, true);
++ if (result)
++ return result;
++ inv_scan_query(indio_dev);
++ if (st->chip_config.gyro_fifo_enable) {
++ result = inv_mpu6050_switch_engine(st, true,
++ INV_MPU6050_BIT_PWR_GYRO_STBY);
++ if (result)
++ return result;
++ }
++ if (st->chip_config.accl_fifo_enable) {
++ result = inv_mpu6050_switch_engine(st, true,
++ INV_MPU6050_BIT_PWR_ACCL_STBY);
++ if (result)
++ return result;
++ }
++ result = inv_reset_fifo(indio_dev);
++ if (result)
++ return result;
++ } else {
++ result = inv_mpu6050_write_reg(st, st->reg->fifo_en, 0);
++ if (result)
++ return result;
++
++ result = inv_mpu6050_write_reg(st, st->reg->int_enable, 0);
++ if (result)
++ return result;
++
++ result = inv_mpu6050_write_reg(st, st->reg->user_ctrl, 0);
++ if (result)
++ return result;
++
++ result = inv_mpu6050_switch_engine(st, false,
++ INV_MPU6050_BIT_PWR_GYRO_STBY);
++ if (result)
++ return result;
++
++ result = inv_mpu6050_switch_engine(st, false,
++ INV_MPU6050_BIT_PWR_ACCL_STBY);
++ if (result)
++ return result;
++ result = inv_mpu6050_set_power_itg(st, false);
++ if (result)
++ return result;
++ }
++ st->chip_config.enable = enable;
++
++ return 0;
++}
++
++/**
++ * inv_mpu_data_rdy_trigger_set_state() - set data ready interrupt state
++ * @trig: Trigger instance
++ * @state: Desired trigger state
++ */
++static int inv_mpu_data_rdy_trigger_set_state(struct iio_trigger *trig,
++ bool state)
++{
++ return inv_mpu6050_set_enable(trig->private_data, state);
++}
++
++static const struct iio_trigger_ops inv_mpu_trigger_ops = {
++ .owner = THIS_MODULE,
++ .set_trigger_state = &inv_mpu_data_rdy_trigger_set_state,
++};
++
++int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev)
++{
++ int ret;
++ struct inv_mpu6050_state *st = iio_priv(indio_dev);
++
++ st->trig = iio_trigger_alloc("%s-dev%d",
++ indio_dev->name,
++ indio_dev->id);
++ if (st->trig == NULL) {
++ ret = -ENOMEM;
++ goto error_ret;
++ }
++ ret = request_irq(st->client->irq, &iio_trigger_generic_data_rdy_poll,
++ IRQF_TRIGGER_RISING,
++ "inv_mpu",
++ st->trig);
++ if (ret)
++ goto error_free_trig;
++ st->trig->dev.parent = &st->client->dev;
++ st->trig->private_data = indio_dev;
++ st->trig->ops = &inv_mpu_trigger_ops;
++ ret = iio_trigger_register(st->trig);
++ if (ret)
++ goto error_free_irq;
++ indio_dev->trig = st->trig;
++
++ return 0;
++
++error_free_irq:
++ free_irq(st->client->irq, st->trig);
++error_free_trig:
++ iio_trigger_free(st->trig);
++error_ret:
++ return ret;
++}
++
++void inv_mpu6050_remove_trigger(struct inv_mpu6050_state *st)
++{
++ iio_trigger_unregister(st->trig);
++ free_irq(st->client->irq, st->trig);
++ iio_trigger_free(st->trig);
++}
+diff --git a/include/linux/platform_data/invensense_mpu6050.h b/include/linux/platform_data/invensense_mpu6050.h
+new file mode 100644
+index 0000000..ad3aa7b
+--- /dev/null
++++ b/include/linux/platform_data/invensense_mpu6050.h
+@@ -0,0 +1,31 @@
++/*
++* Copyright (C) 2012 Invensense, Inc.
++*
++* This software is licensed under the terms of the GNU General Public
++* License version 2, as published by the Free Software Foundation, and
++* may be copied, distributed, and modified under those terms.
++*
++* This program is distributed in the hope that it will be useful,
++* but WITHOUT ANY WARRANTY; without even the implied warranty of
++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++* GNU General Public License for more details.
++*/
++
++#ifndef __INV_MPU6050_PLATFORM_H_
++#define __INV_MPU6050_PLATFORM_H_
++
++/**
++ * struct inv_mpu6050_platform_data - Platform data for the mpu driver
++ * @orientation: Orientation matrix of the chip
++ *
++ * Contains platform specific information on how to configure the MPU6050 to
++ * work on this platform. The orientation matricies are 3x3 rotation matricies
++ * that are applied to the data to rotate from the mounting orientation to the
++ * platform orientation. The values must be one of 0, 1, or -1 and each row and
++ * column should have exactly 1 non-zero value.
++ */
++struct inv_mpu6050_platform_data {
++ __s8 orientation[9];
++};
++
++#endif
diff --git a/patches/linux-3.8.13/0463-iio-imu-inv_mpu6050-depends-on-IIO_BUFFER.patch b/patches/linux-3.8.13/0463-iio-imu-inv_mpu6050-depends-on-IIO_BUFFER.patch
new file mode 100644
index 0000000..8f9c50e
--- /dev/null
+++ b/patches/linux-3.8.13/0463-iio-imu-inv_mpu6050-depends-on-IIO_BUFFER.patch
@@ -0,0 +1,31 @@
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Fri, 1 Mar 2013 15:21:00 +0000
+Subject: [PATCH] iio/imu: inv_mpu6050 depends on IIO_BUFFER
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Fix:
+
+drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c: In function ‘inv_mpu6050_read_fifo’:
+drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c:176:3: error: implicit declaration of
+function ‘iio_push_to_buffers’ [-Werror=implicit-function-declaration]
+
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+---
+ drivers/iio/imu/inv_mpu6050/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
+index b5cfa3a..361b232 100644
+--- a/drivers/iio/imu/inv_mpu6050/Kconfig
++++ b/drivers/iio/imu/inv_mpu6050/Kconfig
+@@ -5,6 +5,7 @@
+ config INV_MPU6050_IIO
+ tristate "Invensense MPU6050 devices"
+ depends on I2C && SYSFS
++ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ This driver supports the Invensense MPU6050 devices.
diff --git a/patches/linux-3.8.13/0464-using-kfifo_in_spinlocked-instead-of-separate-code.patch b/patches/linux-3.8.13/0464-using-kfifo_in_spinlocked-instead-of-separate-code.patch
new file mode 100644
index 0000000..c116043
--- /dev/null
+++ b/patches/linux-3.8.13/0464-using-kfifo_in_spinlocked-instead-of-separate-code.patch
@@ -0,0 +1,26 @@
+From: Ge Gao <ggao@invensense.com>
+Date: Mon, 4 Mar 2013 23:27:00 +0000
+Subject: [PATCH] using kfifo_in_spinlocked instead of separate code.
+
+Signed-off-by: Ge Gao <ggao@invensense.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+---
+ drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
+index 331781f..7da0832 100644
+--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
++++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
+@@ -105,9 +105,8 @@ irqreturn_t inv_mpu6050_irq_handler(int irq, void *p)
+ s64 timestamp;
+
+ timestamp = iio_get_time_ns();
+- spin_lock(&st->time_stamp_lock);
+- kfifo_in(&st->timestamps, &timestamp, 1);
+- spin_unlock(&st->time_stamp_lock);
++ kfifo_in_spinlocked(&st->timestamps, &timestamp, 1,
++ &st->time_stamp_lock);
+
+ return IRQ_WAKE_THREAD;
+ }
diff --git a/patches/linux-3.8.4/0377-W1-w1-gpio-switch-to-using-dev_pm_ops.patch b/patches/linux-3.8.13/0465-W1-w1-gpio-switch-to-using-dev_pm_ops.patch
index b6764be..b6764be 100644
--- a/patches/linux-3.8.4/0377-W1-w1-gpio-switch-to-using-dev_pm_ops.patch
+++ b/patches/linux-3.8.13/0465-W1-w1-gpio-switch-to-using-dev_pm_ops.patch
diff --git a/patches/linux-3.8.4/0378-W1-w1-gpio-guard-DT-IDs-with-CONFIG_OF.patch b/patches/linux-3.8.13/0466-W1-w1-gpio-guard-DT-IDs-with-CONFIG_OF.patch
index 163b0f9..163b0f9 100644
--- a/patches/linux-3.8.4/0378-W1-w1-gpio-guard-DT-IDs-with-CONFIG_OF.patch
+++ b/patches/linux-3.8.13/0466-W1-w1-gpio-guard-DT-IDs-with-CONFIG_OF.patch
diff --git a/patches/linux-3.8.4/0379-W1-w1-gpio-rework-handling-of-platform-data.patch b/patches/linux-3.8.13/0467-W1-w1-gpio-rework-handling-of-platform-data.patch
index ae6a2bf..ae6a2bf 100644
--- a/patches/linux-3.8.4/0379-W1-w1-gpio-rework-handling-of-platform-data.patch
+++ b/patches/linux-3.8.13/0467-W1-w1-gpio-rework-handling-of-platform-data.patch
diff --git a/patches/linux-3.8.4/0380-W1-w1-gpio-switch-to-using-managed-resources-devm.patch b/patches/linux-3.8.13/0468-W1-w1-gpio-switch-to-using-managed-resources-devm.patch
index a1402e5..a1402e5 100644
--- a/patches/linux-3.8.4/0380-W1-w1-gpio-switch-to-using-managed-resources-devm.patch
+++ b/patches/linux-3.8.13/0468-W1-w1-gpio-switch-to-using-managed-resources-devm.patch
diff --git a/patches/linux-3.8.13/0469-ARM-OMAP-Clear-GPMC-bits-when-applying-new-setting.patch b/patches/linux-3.8.13/0469-ARM-OMAP-Clear-GPMC-bits-when-applying-new-setting.patch
new file mode 100644
index 0000000..787baed
--- /dev/null
+++ b/patches/linux-3.8.13/0469-ARM-OMAP-Clear-GPMC-bits-when-applying-new-setting.patch
@@ -0,0 +1,54 @@
+From: Mark Jackson <mpfj-list@mimc.co.uk>
+Date: Tue, 5 Mar 2013 10:13:40 +0000
+Subject: [PATCH] ARM: OMAP: Clear GPMC bits when applying new setting.
+
+When setting the GPMC device type, make sure any previous
+bits are cleared down, before applying the new setting.
+
+For OMAP4+ devices MUXADDDATA is a 2-bit field (bits 9:8)
+where as for OMAP2/3 devices it was only a one bit field
+(bit 9). For OMAP2/3 devices bit 8 is reserved and the
+OMAP documentation says to write a 0 to this bit. So
+clearing bit 8 on OMAP2/3 devices should not be a problem.
+Hence update the code to handle both bits 8 and 9 for all
+devices.
+
+Signed-off-by: Mark Jackson <mpfj@newflow.co.uk>
+[jon-hunter@ti.com: updated changelog]
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+---
+ arch/arm/mach-omap2/gpmc.c | 4 ++++
+ arch/arm/mach-omap2/gpmc.h | 5 ++++-
+ 2 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index 8033cb7..f4219c1 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -606,6 +606,10 @@ int gpmc_cs_configure(int cs, int cmd, int wval)
+
+ case GPMC_CONFIG_DEV_TYPE:
+ regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
++ /* clear 4 target bits */
++ regval &= ~(GPMC_CONFIG1_DEVICETYPE(3) |
++ GPMC_CONFIG1_MUXTYPE(3));
++ /* set the proper value */
+ regval |= GPMC_CONFIG1_DEVICETYPE(wval);
+ if (wval == GPMC_DEVICETYPE_NOR)
+ regval |= GPMC_CONFIG1_MUXADDDATA;
+diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
+index fe0a844..f79cbde 100644
+--- a/arch/arm/mach-omap2/gpmc.h
++++ b/arch/arm/mach-omap2/gpmc.h
+@@ -58,7 +58,10 @@
+ #define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1)
+ #define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10)
+ #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0)
+-#define GPMC_CONFIG1_MUXADDDATA (1 << 9)
++#define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8)
++#define GPMC_CONFIG1_MUXNONMUX GPMC_CONFIG1_MUXTYPE(0)
++#define GPMC_CONFIG1_MUXAAD GPMC_CONFIG1_MUXTYPE(1)
++#define GPMC_CONFIG1_MUXADDDATA GPMC_CONFIG1_MUXTYPE(2)
+ #define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4)
+ #define GPMC_CONFIG1_FCLK_DIV(val) (val & 3)
+ #define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1))
diff --git a/patches/linux-3.8.13/0470-ARM-omap2-gpmc-Mark-local-scoped-functions-static.patch b/patches/linux-3.8.13/0470-ARM-omap2-gpmc-Mark-local-scoped-functions-static.patch
new file mode 100644
index 0000000..cc0edf7
--- /dev/null
+++ b/patches/linux-3.8.13/0470-ARM-omap2-gpmc-Mark-local-scoped-functions-static.patch
@@ -0,0 +1,107 @@
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 12 Feb 2013 16:22:17 -0300
+Subject: [PATCH] ARM: omap2: gpmc: Mark local scoped functions static
+
+This patch marks a bunch of functions that are local
+to gpmc.c file only as static.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Reviewed-by: Jon Hunter <jon-hunter@ti.com>
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+---
+ arch/arm/mach-omap2/gpmc.c | 14 +++++++-------
+ arch/arm/mach-omap2/gpmc.h | 7 -------
+ 2 files changed, 7 insertions(+), 14 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index f4219c1..20de0f6 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -174,7 +174,7 @@ void gpmc_cs_write_reg(int cs, int idx, u32 val)
+ __raw_writel(val, reg_addr);
+ }
+
+-u32 gpmc_cs_read_reg(int cs, int idx)
++static u32 gpmc_cs_read_reg(int cs, int idx)
+ {
+ void __iomem *reg_addr;
+
+@@ -183,7 +183,7 @@ u32 gpmc_cs_read_reg(int cs, int idx)
+ }
+
+ /* TODO: Add support for gpmc_fck to clock framework and use it */
+-unsigned long gpmc_get_fclk_period(void)
++static unsigned long gpmc_get_fclk_period(void)
+ {
+ unsigned long rate = clk_get_rate(gpmc_l3_clk);
+
+@@ -198,7 +198,7 @@ unsigned long gpmc_get_fclk_period(void)
+ return rate;
+ }
+
+-unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
++static unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
+ {
+ unsigned long tick_ps;
+
+@@ -208,7 +208,7 @@ unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
+ return (time_ns * 1000 + tick_ps - 1) / tick_ps;
+ }
+
+-unsigned int gpmc_ps_to_ticks(unsigned int time_ps)
++static unsigned int gpmc_ps_to_ticks(unsigned int time_ps)
+ {
+ unsigned long tick_ps;
+
+@@ -223,7 +223,7 @@ unsigned int gpmc_ticks_to_ns(unsigned int ticks)
+ return ticks * gpmc_get_fclk_period() / 1000;
+ }
+
+-unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
++static unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
+ {
+ unsigned long ticks = gpmc_ns_to_ticks(time_ns);
+
+@@ -441,7 +441,7 @@ static int gpmc_cs_mem_enabled(int cs)
+ return l & GPMC_CONFIG7_CSVALID;
+ }
+
+-int gpmc_cs_set_reserved(int cs, int reserved)
++static int gpmc_cs_set_reserved(int cs, int reserved)
+ {
+ if (cs > GPMC_CS_NUM)
+ return -ENODEV;
+@@ -452,7 +452,7 @@ int gpmc_cs_set_reserved(int cs, int reserved)
+ return 0;
+ }
+
+-int gpmc_cs_reserved(int cs)
++static int gpmc_cs_reserved(int cs)
+ {
+ if (cs > GPMC_CS_NUM)
+ return -ENODEV;
+diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
+index f79cbde..697ff42 100644
+--- a/arch/arm/mach-omap2/gpmc.h
++++ b/arch/arm/mach-omap2/gpmc.h
+@@ -198,20 +198,13 @@ extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
+ extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
+ extern int gpmc_get_client_irq(unsigned irq_config);
+
+-extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
+-extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps);
+ extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
+-extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns);
+-extern unsigned long gpmc_get_fclk_period(void);
+
+ extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
+-extern u32 gpmc_cs_read_reg(int cs, int idx);
+ extern int gpmc_calc_divider(unsigned int sync_clk);
+ extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t);
+ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
+ extern void gpmc_cs_free(int cs);
+-extern int gpmc_cs_set_reserved(int cs, int reserved);
+-extern int gpmc_cs_reserved(int cs);
+ extern void omap3_gpmc_save_context(void);
+ extern void omap3_gpmc_restore_context(void);
+ extern int gpmc_cs_configure(int cs, int cmd, int wval);
diff --git a/patches/linux-3.8.13/0471-ARM-omap2-gpmc-Remove-unused-gpmc_round_ns_to_ticks-.patch b/patches/linux-3.8.13/0471-ARM-omap2-gpmc-Remove-unused-gpmc_round_ns_to_ticks-.patch
new file mode 100644
index 0000000..38442ce
--- /dev/null
+++ b/patches/linux-3.8.13/0471-ARM-omap2-gpmc-Remove-unused-gpmc_round_ns_to_ticks-.patch
@@ -0,0 +1,33 @@
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 12 Feb 2013 16:22:18 -0300
+Subject: [PATCH] ARM: omap2: gpmc: Remove unused gpmc_round_ns_to_ticks()
+ function
+
+This function is not used anywhere, so it's safe to remove it.
+This means less code to maintain.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Reviewed-by: Jon Hunter <jon-hunter@ti.com>
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+---
+ arch/arm/mach-omap2/gpmc.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index 20de0f6..d7add37 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -223,13 +223,6 @@ unsigned int gpmc_ticks_to_ns(unsigned int ticks)
+ return ticks * gpmc_get_fclk_period() / 1000;
+ }
+
+-static unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
+-{
+- unsigned long ticks = gpmc_ns_to_ticks(time_ns);
+-
+- return ticks * gpmc_get_fclk_period() / 1000;
+-}
+-
+ static unsigned int gpmc_ticks_to_ps(unsigned int ticks)
+ {
+ return ticks * gpmc_get_fclk_period();
diff --git a/patches/linux-3.8.13/0472-ARM-omap2-gpmc-Fix-gpmc_cs_reserved-return-value.patch b/patches/linux-3.8.13/0472-ARM-omap2-gpmc-Fix-gpmc_cs_reserved-return-value.patch
new file mode 100644
index 0000000..1f76f42
--- /dev/null
+++ b/patches/linux-3.8.13/0472-ARM-omap2-gpmc-Fix-gpmc_cs_reserved-return-value.patch
@@ -0,0 +1,37 @@
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 12 Feb 2013 16:22:19 -0300
+Subject: [PATCH] ARM: omap2: gpmc: Fix gpmc_cs_reserved() return value
+
+Currently gpmc_cs_reserved() return value is somewhat inconsistent,
+returning a negative value on an error condition, a positive value
+if the chip select is reserved and zero if it's available.
+
+Fix this by returning a boolean value as the function name suggests:
+ * true if the chip select is reserved,
+ * false if it's available
+
+Suggested-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Reviewed-by: Jon Hunter <jon-hunter@ti.com>
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+---
+ arch/arm/mach-omap2/gpmc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index d7add37..83430a2 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -445,10 +445,10 @@ static int gpmc_cs_set_reserved(int cs, int reserved)
+ return 0;
+ }
+
+-static int gpmc_cs_reserved(int cs)
++static bool gpmc_cs_reserved(int cs)
+ {
+ if (cs > GPMC_CS_NUM)
+- return -ENODEV;
++ return true;
+
+ return gpmc_cs_map & (1 << cs);
+ }
diff --git a/patches/linux-3.8.13/0473-ARM-omap2-gpmc-nand-Print-something-useful-on-CS-req.patch b/patches/linux-3.8.13/0473-ARM-omap2-gpmc-nand-Print-something-useful-on-CS-req.patch
new file mode 100644
index 0000000..baf04bb
--- /dev/null
+++ b/patches/linux-3.8.13/0473-ARM-omap2-gpmc-nand-Print-something-useful-on-CS-req.patch
@@ -0,0 +1,29 @@
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 12 Feb 2013 16:22:20 -0300
+Subject: [PATCH] ARM: omap2: gpmc-nand: Print something useful on CS request
+ failure
+
+If CS request fails the current error message is rather unhelpful.
+Fix it by printing the failing chip select and the error code.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Reviewed-by: Jon Hunter <jon-hunter@ti.com>
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+---
+ arch/arm/mach-omap2/gpmc-nand.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
+index db969a5..6027dd0 100644
+--- a/arch/arm/mach-omap2/gpmc-nand.c
++++ b/arch/arm/mach-omap2/gpmc-nand.c
+@@ -121,7 +121,8 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
+ err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE,
+ (unsigned long *)&gpmc_nand_resource[0].start);
+ if (err < 0) {
+- dev_err(dev, "Cannot request GPMC CS\n");
++ dev_err(dev, "Cannot request GPMC CS %d, error %d\n",
++ gpmc_nand_data->cs, err);
+ return err;
+ }
+
diff --git a/patches/linux-3.8.13/0474-ARM-omap2-gpmc-onenand-Print-something-useful-on-CS-.patch b/patches/linux-3.8.13/0474-ARM-omap2-gpmc-onenand-Print-something-useful-on-CS-.patch
new file mode 100644
index 0000000..8d3e9fd
--- /dev/null
+++ b/patches/linux-3.8.13/0474-ARM-omap2-gpmc-onenand-Print-something-useful-on-CS-.patch
@@ -0,0 +1,29 @@
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 12 Feb 2013 16:22:21 -0300
+Subject: [PATCH] ARM: omap2: gpmc-onenand: Print something useful on CS
+ request failure
+
+If CS request fails the current error message is rather unhelpful.
+Fix it by printing the failing chip select and the error code.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Reviewed-by: Jon Hunter <jon-hunter@ti.com>
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+---
+ arch/arm/mach-omap2/gpmc-onenand.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
+index 94a349e..80d756b 100644
+--- a/arch/arm/mach-omap2/gpmc-onenand.c
++++ b/arch/arm/mach-omap2/gpmc-onenand.c
+@@ -379,7 +379,8 @@ void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
+ err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE,
+ (unsigned long *)&gpmc_onenand_resource.start);
+ if (err < 0) {
+- pr_err("%s: Cannot request GPMC CS\n", __func__);
++ pr_err("%s: Cannot request GPMC CS %d, error %d\n",
++ __func__, gpmc_onenand_data->cs, err);
+ return;
+ }
+
diff --git a/patches/linux-3.8.13/0475-ARM-omap2-gpmc-onenand-Replace-pr_err-with-dev_err.patch b/patches/linux-3.8.13/0475-ARM-omap2-gpmc-onenand-Replace-pr_err-with-dev_err.patch
new file mode 100644
index 0000000..16d53c4
--- /dev/null
+++ b/patches/linux-3.8.13/0475-ARM-omap2-gpmc-onenand-Replace-pr_err-with-dev_err.patch
@@ -0,0 +1,46 @@
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 12 Feb 2013 16:22:22 -0300
+Subject: [PATCH] ARM: omap2: gpmc-onenand: Replace pr_err() with dev_err()
+
+Do this becasue dev_err() is preferred over pr_err() and because
+it will match gpmc-nand, thus the code shows looks more consistent.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Reviewed-by: Jon Hunter <jon-hunter@ti.com>
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+---
+ arch/arm/mach-omap2/gpmc-onenand.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
+index 80d756b..e1daf94 100644
+--- a/arch/arm/mach-omap2/gpmc-onenand.c
++++ b/arch/arm/mach-omap2/gpmc-onenand.c
+@@ -359,6 +359,7 @@ static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
+ void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
+ {
+ int err;
++ struct device *dev = &gpmc_onenand_device.dev;
+
+ gpmc_onenand_data = _onenand_data;
+ gpmc_onenand_data->onenand_setup = gpmc_onenand_setup;
+@@ -379,8 +380,8 @@ void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
+ err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE,
+ (unsigned long *)&gpmc_onenand_resource.start);
+ if (err < 0) {
+- pr_err("%s: Cannot request GPMC CS %d, error %d\n",
+- __func__, gpmc_onenand_data->cs, err);
++ dev_err(dev, "Cannot request GPMC CS %d, error %d\n",
++ gpmc_onenand_data->cs, err);
+ return;
+ }
+
+@@ -388,7 +389,7 @@ void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
+ ONENAND_IO_SIZE - 1;
+
+ if (platform_device_register(&gpmc_onenand_device) < 0) {
+- pr_err("%s: Unable to register OneNAND device\n", __func__);
++ dev_err(dev, "Unable to register OneNAND device\n");
+ gpmc_cs_free(gpmc_onenand_data->cs);
+ return;
+ }
diff --git a/patches/linux-3.8.13/0476-ARM-omap2-gpmc-onenand-Replace-printk-KERN_ERR-with-.patch b/patches/linux-3.8.13/0476-ARM-omap2-gpmc-onenand-Replace-printk-KERN_ERR-with-.patch
new file mode 100644
index 0000000..e84991e
--- /dev/null
+++ b/patches/linux-3.8.13/0476-ARM-omap2-gpmc-onenand-Replace-printk-KERN_ERR-with-.patch
@@ -0,0 +1,28 @@
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 12 Feb 2013 16:22:23 -0300
+Subject: [PATCH] ARM: omap2: gpmc-onenand: Replace printk KERN_ERR with
+ dev_warn()
+
+Since the condition is not an error but a warning, replace
+printk KERN_ERR with dev_warn.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Reviewed-by: Jon Hunter <jon-hunter@ti.com>
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+---
+ arch/arm/mach-omap2/gpmc-onenand.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
+index e1daf94..428cb19 100644
+--- a/arch/arm/mach-omap2/gpmc-onenand.c
++++ b/arch/arm/mach-omap2/gpmc-onenand.c
+@@ -367,7 +367,7 @@ void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
+
+ if (cpu_is_omap24xx() &&
+ (gpmc_onenand_data->flags & ONENAND_SYNC_READWRITE)) {
+- printk(KERN_ERR "Onenand using only SYNC_READ on 24xx\n");
++ dev_warn(dev, "OneNAND using only SYNC_READ on 24xx\n");
+ gpmc_onenand_data->flags &= ~ONENAND_SYNC_READWRITE;
+ gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
+ }
diff --git a/patches/linux-3.8.13/0477-ARM-omap2-gpmc-Remove-redundant-chip-select-out-of-r.patch b/patches/linux-3.8.13/0477-ARM-omap2-gpmc-Remove-redundant-chip-select-out-of-r.patch
new file mode 100644
index 0000000..bc5d614
--- /dev/null
+++ b/patches/linux-3.8.13/0477-ARM-omap2-gpmc-Remove-redundant-chip-select-out-of-r.patch
@@ -0,0 +1,44 @@
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Tue, 12 Feb 2013 16:22:24 -0300
+Subject: [PATCH] ARM: omap2: gpmc: Remove redundant chip select out of range
+ check
+
+This check is done before the call to gpmc_cs_reserved() and
+gpmc_cs_set_reserved() and it's redundant to do it again in each
+function. This simplifies the code a bit.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Reviewed-by: Jon Hunter <jon-hunter@ti.com>
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+---
+ arch/arm/mach-omap2/gpmc.c | 10 +---------
+ 1 file changed, 1 insertion(+), 9 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index 83430a2..901dacd 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -434,22 +434,14 @@ static int gpmc_cs_mem_enabled(int cs)
+ return l & GPMC_CONFIG7_CSVALID;
+ }
+
+-static int gpmc_cs_set_reserved(int cs, int reserved)
++static void gpmc_cs_set_reserved(int cs, int reserved)
+ {
+- if (cs > GPMC_CS_NUM)
+- return -ENODEV;
+-
+ gpmc_cs_map &= ~(1 << cs);
+ gpmc_cs_map |= (reserved ? 1 : 0) << cs;
+-
+- return 0;
+ }
+
+ static bool gpmc_cs_reserved(int cs)
+ {
+- if (cs > GPMC_CS_NUM)
+- return true;
+-
+ return gpmc_cs_map & (1 << cs);
+ }
+
diff --git a/patches/linux-3.8.13/0478-ARM-OMAP2-Simplify-code-configuring-ONENAND-devices.patch b/patches/linux-3.8.13/0478-ARM-OMAP2-Simplify-code-configuring-ONENAND-devices.patch
new file mode 100644
index 0000000..433338a
--- /dev/null
+++ b/patches/linux-3.8.13/0478-ARM-OMAP2-Simplify-code-configuring-ONENAND-devices.patch
@@ -0,0 +1,103 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Thu, 21 Feb 2013 15:20:53 -0600
+Subject: [PATCH] ARM: OMAP2+: Simplify code configuring ONENAND devices
+
+The OMAP2+ code that configures the GPMC for ONENAND devices is copying
+structures between functions unnecessarily. Avoid this by passing
+pointers instead and simplify the code.
+
+A pointer to structure "omap_onenand_platform_data" is passed to the
+function omap2_onenand_calc_sync_timings(), but only the flags member
+of the structure is used. Simplify the code by only passing the flags
+member and not the entire structure.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ arch/arm/mach-omap2/gpmc-onenand.c | 26 ++++++++++----------------
+ 1 file changed, 10 insertions(+), 16 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
+index 428cb19..b7f73c5 100644
+--- a/arch/arm/mach-omap2/gpmc-onenand.c
++++ b/arch/arm/mach-omap2/gpmc-onenand.c
+@@ -47,10 +47,9 @@ static struct platform_device gpmc_onenand_device = {
+ .resource = &gpmc_onenand_resource,
+ };
+
+-static struct gpmc_timings omap2_onenand_calc_async_timings(void)
++static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
+ {
+ struct gpmc_device_timings dev_t;
+- struct gpmc_timings t;
+
+ const int t_cer = 15;
+ const int t_avdp = 12;
+@@ -76,9 +75,7 @@ static struct gpmc_timings omap2_onenand_calc_async_timings(void)
+ dev_t.t_wpl = t_wpl * 1000;
+ dev_t.t_wph = t_wph * 1000;
+
+- gpmc_calc_timings(&t, &dev_t);
+-
+- return t;
++ gpmc_calc_timings(t, &dev_t);
+ }
+
+ static int gpmc_set_async_mode(int cs, struct gpmc_timings *t)
+@@ -158,12 +155,11 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
+ return freq;
+ }
+
+-static struct gpmc_timings
+-omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
+- int freq)
++static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
++ unsigned int flags,
++ int freq)
+ {
+ struct gpmc_device_timings dev_t;
+- struct gpmc_timings t;
+ const int t_cer = 15;
+ const int t_avdp = 12;
+ const int t_cez = 20; /* max of t_cez, t_oez */
+@@ -172,9 +168,9 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
+ int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
+ int div, gpmc_clk_ns;
+
+- if (cfg->flags & ONENAND_SYNC_READ)
++ if (flags & ONENAND_SYNC_READ)
+ onenand_flags = ONENAND_FLAG_SYNCREAD;
+- else if (cfg->flags & ONENAND_SYNC_READWRITE)
++ else if (flags & ONENAND_SYNC_READWRITE)
+ onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE;
+
+ switch (freq) {
+@@ -265,9 +261,7 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
+ dev_t.cyc_aavdh_oe = 1;
+ dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
+
+- gpmc_calc_timings(&t, &dev_t);
+-
+- return t;
++ gpmc_calc_timings(t, &dev_t);
+ }
+
+ static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t)
+@@ -300,7 +294,7 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base)
+
+ omap2_onenand_set_async_mode(onenand_base);
+
+- t = omap2_onenand_calc_async_timings();
++ omap2_onenand_calc_async_timings(&t);
+
+ ret = gpmc_set_async_mode(gpmc_onenand_data->cs, &t);
+ if (IS_ERR_VALUE(ret))
+@@ -322,7 +316,7 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
+ set_onenand_cfg(onenand_base);
+ }
+
+- t = omap2_onenand_calc_sync_timings(gpmc_onenand_data, freq);
++ omap2_onenand_calc_sync_timings(&t, gpmc_onenand_data->flags, freq);
+
+ ret = gpmc_set_sync_mode(gpmc_onenand_data->cs, &t);
+ if (IS_ERR_VALUE(ret))
diff --git a/patches/linux-3.8.13/0479-ARM-OMAP2-Add-variable-to-store-number-of-GPMC-waitp.patch b/patches/linux-3.8.13/0479-ARM-OMAP2-Add-variable-to-store-number-of-GPMC-waitp.patch
new file mode 100644
index 0000000..fe77f8c
--- /dev/null
+++ b/patches/linux-3.8.13/0479-ARM-OMAP2-Add-variable-to-store-number-of-GPMC-waitp.patch
@@ -0,0 +1,285 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Wed, 20 Feb 2013 15:53:38 -0600
+Subject: [PATCH] ARM: OMAP2+: Add variable to store number of GPMC waitpins
+
+The GPMC has wait-pin signals that can be assigned to a chip-select
+to monitor the ready signal of an external device. Add a variable to
+indicate the total number of wait-pins for a given device. This will
+allow us to detect if the wait-pin being selected is valid or not.
+
+When booting with device-tree read the number of wait-pins from the
+device-tree blob. When device-tree is not used set the number of
+wait-pins to 4 which is valid for OMAP2-5 devices. Newer devices
+that have less wait-pins (such as AM335x) only support booting with
+device-tree and so hard-coding the wait-pin number when not using
+device-tree is fine.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ arch/arm/mach-omap2/gpmc.c | 231 +++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 230 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index 901dacd..1346f3e 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -102,6 +102,8 @@
+ #define GPMC_HAS_WR_ACCESS 0x1
+ #define GPMC_HAS_WR_DATA_MUX_BUS 0x2
+
++#define GPMC_NR_WAITPINS 4
++
+ /* XXX: Only NAND irq has been considered,currently these are the only ones used
+ */
+ #define GPMC_NR_IRQ 2
+@@ -145,7 +147,9 @@ static unsigned gpmc_irq_start;
+ static struct resource gpmc_mem_root;
+ static struct resource gpmc_cs_mem[GPMC_CS_NUM];
+ static DEFINE_SPINLOCK(gpmc_mem_lock);
+-static unsigned int gpmc_cs_map; /* flag for cs which are initialized */
++/* Define chip-selects as reserved by default until probe completes */
++static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1);
++static unsigned int gpmc_nr_waitpins;
+ static struct device *gpmc_dev;
+ static int gpmc_irq;
+ static resource_size_t phys_base, mem_size;
+@@ -1110,6 +1114,217 @@ int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
+ return 0;
+ }
+
++#ifdef CONFIG_OF
++static struct of_device_id gpmc_dt_ids[] = {
++ { .compatible = "ti,omap2420-gpmc" },
++ { .compatible = "ti,omap2430-gpmc" },
++ { .compatible = "ti,omap3430-gpmc" }, /* omap3430 & omap3630 */
++ { .compatible = "ti,omap4430-gpmc" }, /* omap4430 & omap4460 & omap543x */
++ { .compatible = "ti,am3352-gpmc" }, /* am335x devices */
++ { }
++};
++MODULE_DEVICE_TABLE(of, gpmc_dt_ids);
++
++static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
++ struct gpmc_timings *gpmc_t)
++{
++ u32 val;
++
++ memset(gpmc_t, 0, sizeof(*gpmc_t));
++
++ /* minimum clock period for syncronous mode */
++ if (!of_property_read_u32(np, "gpmc,sync-clk", &val))
++ gpmc_t->sync_clk = val;
++
++ /* chip select timtings */
++ if (!of_property_read_u32(np, "gpmc,cs-on", &val))
++ gpmc_t->cs_on = val;
++
++ if (!of_property_read_u32(np, "gpmc,cs-rd-off", &val))
++ gpmc_t->cs_rd_off = val;
++
++ if (!of_property_read_u32(np, "gpmc,cs-wr-off", &val))
++ gpmc_t->cs_wr_off = val;
++
++ /* ADV signal timings */
++ if (!of_property_read_u32(np, "gpmc,adv-on", &val))
++ gpmc_t->adv_on = val;
++
++ if (!of_property_read_u32(np, "gpmc,adv-rd-off", &val))
++ gpmc_t->adv_rd_off = val;
++
++ if (!of_property_read_u32(np, "gpmc,adv-wr-off", &val))
++ gpmc_t->adv_wr_off = val;
++
++ /* WE signal timings */
++ if (!of_property_read_u32(np, "gpmc,we-on", &val))
++ gpmc_t->we_on = val;
++
++ if (!of_property_read_u32(np, "gpmc,we-off", &val))
++ gpmc_t->we_off = val;
++
++ /* OE signal timings */
++ if (!of_property_read_u32(np, "gpmc,oe-on", &val))
++ gpmc_t->oe_on = val;
++
++ if (!of_property_read_u32(np, "gpmc,oe-off", &val))
++ gpmc_t->oe_off = val;
++
++ /* access and cycle timings */
++ if (!of_property_read_u32(np, "gpmc,page-burst-access", &val))
++ gpmc_t->page_burst_access = val;
++
++ if (!of_property_read_u32(np, "gpmc,access", &val))
++ gpmc_t->access = val;
++
++ if (!of_property_read_u32(np, "gpmc,rd-cycle", &val))
++ gpmc_t->rd_cycle = val;
++
++ if (!of_property_read_u32(np, "gpmc,wr-cycle", &val))
++ gpmc_t->wr_cycle = val;
++
++ /* only for OMAP3430 */
++ if (!of_property_read_u32(np, "gpmc,wr-access", &val))
++ gpmc_t->wr_access = val;
++
++ if (!of_property_read_u32(np, "gpmc,wr-data-mux-bus", &val))
++ gpmc_t->wr_data_mux_bus = val;
++}
++
++#ifdef CONFIG_MTD_NAND
++
++static const char * const nand_ecc_opts[] = {
++ [OMAP_ECC_HAMMING_CODE_DEFAULT] = "sw",
++ [OMAP_ECC_HAMMING_CODE_HW] = "hw",
++ [OMAP_ECC_HAMMING_CODE_HW_ROMCODE] = "hw-romcode",
++ [OMAP_ECC_BCH4_CODE_HW] = "bch4",
++ [OMAP_ECC_BCH8_CODE_HW] = "bch8",
++};
++
++static int gpmc_probe_nand_child(struct platform_device *pdev,
++ struct device_node *child)
++{
++ u32 val;
++ const char *s;
++ struct gpmc_timings gpmc_t;
++ struct omap_nand_platform_data *gpmc_nand_data;
++
++ if (of_property_read_u32(child, "reg", &val) < 0) {
++ dev_err(&pdev->dev, "%s has no 'reg' property\n",
++ child->full_name);
++ return -ENODEV;
++ }
++
++ gpmc_nand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_nand_data),
++ GFP_KERNEL);
++ if (!gpmc_nand_data)
++ return -ENOMEM;
++
++ gpmc_nand_data->cs = val;
++ gpmc_nand_data->of_node = child;
++
++ if (!of_property_read_string(child, "ti,nand-ecc-opt", &s))
++ for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++)
++ if (!strcasecmp(s, nand_ecc_opts[val])) {
++ gpmc_nand_data->ecc_opt = val;
++ break;
++ }
++
++ val = of_get_nand_bus_width(child);
++ if (val == 16)
++ gpmc_nand_data->devsize = NAND_BUSWIDTH_16;
++
++ gpmc_read_timings_dt(child, &gpmc_t);
++ gpmc_nand_init(gpmc_nand_data, &gpmc_t);
++
++ return 0;
++}
++#else
++static int gpmc_probe_nand_child(struct platform_device *pdev,
++ struct device_node *child)
++{
++ return 0;
++}
++#endif
++
++#ifdef CONFIG_MTD_ONENAND
++static int gpmc_probe_onenand_child(struct platform_device *pdev,
++ struct device_node *child)
++{
++ u32 val;
++ struct omap_onenand_platform_data *gpmc_onenand_data;
++
++ if (of_property_read_u32(child, "reg", &val) < 0) {
++ dev_err(&pdev->dev, "%s has no 'reg' property\n",
++ child->full_name);
++ return -ENODEV;
++ }
++
++ gpmc_onenand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_onenand_data),
++ GFP_KERNEL);
++ if (!gpmc_onenand_data)
++ return -ENOMEM;
++
++ gpmc_onenand_data->cs = val;
++ gpmc_onenand_data->of_node = child;
++ gpmc_onenand_data->dma_channel = -1;
++
++ if (!of_property_read_u32(child, "dma-channel", &val))
++ gpmc_onenand_data->dma_channel = val;
++
++ gpmc_onenand_init(gpmc_onenand_data);
++
++ return 0;
++}
++#else
++static int gpmc_probe_onenand_child(struct platform_device *pdev,
++ struct device_node *child)
++{
++ return 0;
++}
++#endif
++
++static int gpmc_probe_dt(struct platform_device *pdev)
++{
++ int ret;
++ struct device_node *child;
++ const struct of_device_id *of_id =
++ of_match_device(gpmc_dt_ids, &pdev->dev);
++
++ if (!of_id)
++ return 0;
++
++ ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins",
++ &gpmc_nr_waitpins);
++ if (ret < 0) {
++ pr_err("%s: number of wait pins not found!\n", __func__);
++ return ret;
++ }
++
++ for_each_node_by_name(child, "nand") {
++ ret = gpmc_probe_nand_child(pdev, child);
++ if (ret < 0) {
++ of_node_put(child);
++ return ret;
++ }
++ }
++
++ for_each_node_by_name(child, "onenand") {
++ ret = gpmc_probe_onenand_child(pdev, child);
++ if (ret < 0) {
++ of_node_put(child);
++ return ret;
++ }
++ }
++ return 0;
++}
++#else
++static int gpmc_probe_dt(struct platform_device *pdev)
++{
++ return 0;
++}
++#endif
++
+ static int gpmc_probe(struct platform_device *pdev)
+ {
+ int rc;
+@@ -1163,6 +1378,20 @@ static int gpmc_probe(struct platform_device *pdev)
+ if (IS_ERR_VALUE(gpmc_setup_irq()))
+ dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
+
++ /* Now the GPMC is initialised, unreserve the chip-selects */
++ gpmc_cs_map = 0;
++
++ if (!pdev->dev.of_node)
++ gpmc_nr_waitpins = GPMC_NR_WAITPINS;
++
++ rc = gpmc_probe_dt(pdev);
++ if (rc < 0) {
++ clk_disable_unprepare(gpmc_l3_clk);
++ clk_put(gpmc_l3_clk);
++ dev_err(gpmc_dev, "failed to probe DT parameters\n");
++ return rc;
++ }
++
+ return 0;
+ }
+
diff --git a/patches/linux-3.8.13/0480-ARM-OMAP2-Add-structure-for-storing-GPMC-settings.patch b/patches/linux-3.8.13/0480-ARM-OMAP2-Add-structure-for-storing-GPMC-settings.patch
new file mode 100644
index 0000000..6158aab
--- /dev/null
+++ b/patches/linux-3.8.13/0480-ARM-OMAP2-Add-structure-for-storing-GPMC-settings.patch
@@ -0,0 +1,323 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Thu, 21 Feb 2013 13:46:22 -0600
+Subject: [PATCH] ARM: OMAP2+: Add structure for storing GPMC settings
+
+The GPMC has various different configuration options such as bus-width,
+synchronous or asychronous mode selection, burst mode options etc.
+Currently, there is no central structure for storing all these options
+when configuring the GPMC for a given device. Some of the options are
+stored in the GPMC timing structure and some are directly programmed
+into the GPMC configuration register. Add a new structure to store
+these options and convert code to use this structure. Adding this
+structure will allow us to create a common function for configuring
+these options.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ arch/arm/mach-omap2/gpmc-onenand.c | 18 ++++++++++-----
+ arch/arm/mach-omap2/gpmc-smc91x.c | 2 +-
+ arch/arm/mach-omap2/gpmc.c | 45 +++++++++++++++++++++---------------
+ arch/arm/mach-omap2/gpmc.h | 28 ++++++++++++++++------
+ arch/arm/mach-omap2/usb-tusb6010.c | 19 ++++++++-------
+ 5 files changed, 72 insertions(+), 40 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
+index b7f73c5..d2bf43e 100644
+--- a/arch/arm/mach-omap2/gpmc-onenand.c
++++ b/arch/arm/mach-omap2/gpmc-onenand.c
+@@ -47,6 +47,15 @@ static struct platform_device gpmc_onenand_device = {
+ .resource = &gpmc_onenand_resource,
+ };
+
++static struct gpmc_settings onenand_async = {
++ .mux_add_data = GPMC_MUX_AD,
++};
++
++static struct gpmc_settings onenand_sync = {
++ .burst_read = true,
++ .mux_add_data = GPMC_MUX_AD,
++};
++
+ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
+ {
+ struct gpmc_device_timings dev_t;
+@@ -63,7 +72,6 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
+
+ memset(&dev_t, 0, sizeof(dev_t));
+
+- dev_t.mux = true;
+ dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000;
+ dev_t.t_avdp_w = dev_t.t_avdp_r;
+ dev_t.t_aavdh = t_aavdh * 1000;
+@@ -75,7 +83,7 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
+ dev_t.t_wpl = t_wpl * 1000;
+ dev_t.t_wph = t_wph * 1000;
+
+- gpmc_calc_timings(t, &dev_t);
++ gpmc_calc_timings(t, &onenand_async, &dev_t);
+ }
+
+ static int gpmc_set_async_mode(int cs, struct gpmc_timings *t)
+@@ -235,10 +243,8 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
+ /* Set synchronous read timings */
+ memset(&dev_t, 0, sizeof(dev_t));
+
+- dev_t.mux = true;
+- dev_t.sync_read = true;
+ if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
+- dev_t.sync_write = true;
++ onenand_sync.sync_write = true;
+ } else {
+ dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
+ dev_t.t_wpl = t_wpl * 1000;
+@@ -261,7 +267,7 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
+ dev_t.cyc_aavdh_oe = 1;
+ dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
+
+- gpmc_calc_timings(t, &dev_t);
++ gpmc_calc_timings(t, &onenand_sync, &dev_t);
+ }
+
+ static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t)
+diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c
+index 11d0b75..4b78338 100644
+--- a/arch/arm/mach-omap2/gpmc-smc91x.c
++++ b/arch/arm/mach-omap2/gpmc-smc91x.c
+@@ -104,7 +104,7 @@ static int smc91c96_gpmc_retime(void)
+ dev_t.t_cez_w = t4_w * 1000;
+ dev_t.t_wr_cycle = (t20 - t3) * 1000;
+
+- gpmc_calc_timings(&t, &dev_t);
++ gpmc_calc_timings(&t, NULL, &dev_t);
+
+ return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
+ }
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index 1346f3e..888c4b4 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -814,9 +814,9 @@ static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
+
+ /* XXX: can the cycles be avoided ? */
+ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
+- struct gpmc_device_timings *dev_t)
++ struct gpmc_device_timings *dev_t,
++ bool mux)
+ {
+- bool mux = dev_t->mux;
+ u32 temp;
+
+ /* adv_rd_off */
+@@ -869,9 +869,9 @@ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
+ }
+
+ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
+- struct gpmc_device_timings *dev_t)
++ struct gpmc_device_timings *dev_t,
++ bool mux)
+ {
+- bool mux = dev_t->mux;
+ u32 temp;
+
+ /* adv_wr_off */
+@@ -931,9 +931,9 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
+ }
+
+ static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
+- struct gpmc_device_timings *dev_t)
++ struct gpmc_device_timings *dev_t,
++ bool mux)
+ {
+- bool mux = dev_t->mux;
+ u32 temp;
+
+ /* adv_rd_off */
+@@ -971,9 +971,9 @@ static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
+ }
+
+ static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
+- struct gpmc_device_timings *dev_t)
++ struct gpmc_device_timings *dev_t,
++ bool mux)
+ {
+- bool mux = dev_t->mux;
+ u32 temp;
+
+ /* adv_wr_off */
+@@ -1043,7 +1043,8 @@ static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
+ }
+
+ static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
+- struct gpmc_device_timings *dev_t)
++ struct gpmc_device_timings *dev_t,
++ bool sync)
+ {
+ u32 temp;
+
+@@ -1057,7 +1058,7 @@ static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
+ gpmc_t->cs_on + dev_t->t_ce_avd);
+ gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp);
+
+- if (dev_t->sync_write || dev_t->sync_read)
++ if (sync)
+ gpmc_calc_sync_common_timings(gpmc_t, dev_t);
+
+ return 0;
+@@ -1092,21 +1093,29 @@ static void gpmc_convert_ps_to_ns(struct gpmc_timings *t)
+ }
+
+ int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
+- struct gpmc_device_timings *dev_t)
++ struct gpmc_settings *gpmc_s,
++ struct gpmc_device_timings *dev_t)
+ {
++ bool mux = false, sync = false;
++
++ if (gpmc_s) {
++ mux = gpmc_s->mux_add_data ? true : false;
++ sync = (gpmc_s->sync_read || gpmc_s->sync_write);
++ }
++
+ memset(gpmc_t, 0, sizeof(*gpmc_t));
+
+- gpmc_calc_common_timings(gpmc_t, dev_t);
++ gpmc_calc_common_timings(gpmc_t, dev_t, sync);
+
+- if (dev_t->sync_read)
+- gpmc_calc_sync_read_timings(gpmc_t, dev_t);
++ if (gpmc_s && gpmc_s->sync_read)
++ gpmc_calc_sync_read_timings(gpmc_t, dev_t, mux);
+ else
+- gpmc_calc_async_read_timings(gpmc_t, dev_t);
++ gpmc_calc_async_read_timings(gpmc_t, dev_t, mux);
+
+- if (dev_t->sync_write)
+- gpmc_calc_sync_write_timings(gpmc_t, dev_t);
++ if (gpmc_s && gpmc_s->sync_write)
++ gpmc_calc_sync_write_timings(gpmc_t, dev_t, mux);
+ else
+- gpmc_calc_async_write_timings(gpmc_t, dev_t);
++ gpmc_calc_async_write_timings(gpmc_t, dev_t, mux);
+
+ /* TODO: remove, see function definition */
+ gpmc_convert_ps_to_ns(gpmc_t);
+diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
+index 697ff42..39e4e04 100644
+--- a/arch/arm/mach-omap2/gpmc.h
++++ b/arch/arm/mach-omap2/gpmc.h
+@@ -60,8 +60,8 @@
+ #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0)
+ #define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8)
+ #define GPMC_CONFIG1_MUXNONMUX GPMC_CONFIG1_MUXTYPE(0)
+-#define GPMC_CONFIG1_MUXAAD GPMC_CONFIG1_MUXTYPE(1)
+-#define GPMC_CONFIG1_MUXADDDATA GPMC_CONFIG1_MUXTYPE(2)
++#define GPMC_CONFIG1_MUXAAD GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AAD)
++#define GPMC_CONFIG1_MUXADDDATA GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AD)
+ #define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4)
+ #define GPMC_CONFIG1_FCLK_DIV(val) (val & 3)
+ #define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1))
+@@ -76,6 +76,8 @@
+ #define GPMC_IRQ_FIFOEVENTENABLE 0x01
+ #define GPMC_IRQ_COUNT_EVENT 0x02
+
++#define GPMC_MUX_AAD 1 /* Addr-Addr-Data multiplex */
++#define GPMC_MUX_AD 2 /* Addr-Data multiplex */
+
+ /* bool type time settings */
+ struct gpmc_bool_timings {
+@@ -181,10 +183,6 @@ struct gpmc_device_timings {
+ u8 cyc_wpl; /* write deassertion time in cycles */
+ u32 cyc_iaa; /* initial access time in cycles */
+
+- bool mux; /* address & data muxed */
+- bool sync_write;/* synchronous write */
+- bool sync_read; /* synchronous read */
+-
+ /* extra delays */
+ bool ce_xdelay;
+ bool avd_xdelay;
+@@ -192,8 +190,24 @@ struct gpmc_device_timings {
+ bool we_xdelay;
+ };
+
++struct gpmc_settings {
++ bool burst_wrap; /* enables wrap bursting */
++ bool burst_read; /* enables read page/burst mode */
++ bool burst_write; /* enables write page/burst mode */
++ bool device_nand; /* device is NAND */
++ bool sync_read; /* enables synchronous reads */
++ bool sync_write; /* enables synchronous writes */
++ bool wait_on_read; /* monitor wait on reads */
++ bool wait_on_write; /* monitor wait on writes */
++ u32 burst_len; /* page/burst length */
++ u32 device_width; /* device bus width (8 or 16 bit) */
++ u32 mux_add_data; /* multiplex address & data */
++ u32 wait_pin; /* wait-pin to be used */
++};
++
+ extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
+- struct gpmc_device_timings *dev_t);
++ struct gpmc_settings *gpmc_s,
++ struct gpmc_device_timings *dev_t);
+
+ extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
+ extern int gpmc_get_client_irq(unsigned irq_config);
+diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
+index c5a3c6f..faaf96d 100644
+--- a/arch/arm/mach-omap2/usb-tusb6010.c
++++ b/arch/arm/mach-omap2/usb-tusb6010.c
+@@ -26,6 +26,15 @@
+ static u8 async_cs, sync_cs;
+ static unsigned refclk_psec;
+
++static struct gpmc_settings tusb_async = {
++ .mux_add_data = GPMC_MUX_AD,
++};
++
++static struct gpmc_settings tusb_sync = {
++ .sync_read = true,
++ .sync_write = true,
++ .mux_add_data = GPMC_MUX_AD,
++};
+
+ /* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
+
+@@ -37,8 +46,6 @@ static int tusb_set_async_mode(unsigned sysclk_ps)
+
+ memset(&dev_t, 0, sizeof(dev_t));
+
+- dev_t.mux = true;
+-
+ dev_t.t_ceasu = 8 * 1000;
+ dev_t.t_avdasu = t_acsnh_advnh - 7000;
+ dev_t.t_ce_avd = 1000;
+@@ -52,7 +59,7 @@ static int tusb_set_async_mode(unsigned sysclk_ps)
+ dev_t.t_wpl = 300;
+ dev_t.cyc_aavdh_we = 1;
+
+- gpmc_calc_timings(&t, &dev_t);
++ gpmc_calc_timings(&t, &tusb_async, &dev_t);
+
+ return gpmc_cs_set_timings(async_cs, &t);
+ }
+@@ -65,10 +72,6 @@ static int tusb_set_sync_mode(unsigned sysclk_ps)
+
+ memset(&dev_t, 0, sizeof(dev_t));
+
+- dev_t.mux = true;
+- dev_t.sync_read = true;
+- dev_t.sync_write = true;
+-
+ dev_t.clk = 11100;
+ dev_t.t_bacc = 1000;
+ dev_t.t_ces = 1000;
+@@ -84,7 +87,7 @@ static int tusb_set_sync_mode(unsigned sysclk_ps)
+ dev_t.cyc_wpl = 6;
+ dev_t.t_ce_rdyz = 7000;
+
+- gpmc_calc_timings(&t, &dev_t);
++ gpmc_calc_timings(&t, &tusb_sync, &dev_t);
+
+ return gpmc_cs_set_timings(sync_cs, &t);
+ }
diff --git a/patches/linux-3.8.13/0481-ARM-OMAP2-Add-function-for-configuring-GPMC-settings.patch b/patches/linux-3.8.13/0481-ARM-OMAP2-Add-function-for-configuring-GPMC-settings.patch
new file mode 100644
index 0000000..f27137e
--- /dev/null
+++ b/patches/linux-3.8.13/0481-ARM-OMAP2-Add-function-for-configuring-GPMC-settings.patch
@@ -0,0 +1,176 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Thu, 21 Feb 2013 15:25:23 -0600
+Subject: [PATCH] ARM: OMAP2+: Add function for configuring GPMC settings
+
+The GPMC has various different configuration options such as bus-width,
+synchronous or asychronous mode selection, burst mode options etc.
+Currently, there is no common function for configuring these options and
+various devices set these options by either programming the GPMC CONFIG1
+register directly or by calling gpmc_cs_configure() to set some of the
+options.
+
+Add a new function for configuring all of the GPMC options. Having a common
+function for configuring this options will simplify code and ease the
+migration to device-tree.
+
+Also add a new capability flag to detect devices that support the
+address-address-data multiplexing mode.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ arch/arm/mach-omap2/gpmc.c | 100 ++++++++++++++++++++++++++++++++++++++++++++
+ arch/arm/mach-omap2/gpmc.h | 6 +++
+ 2 files changed, 106 insertions(+)
+
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index 888c4b4..0302a03 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -101,6 +101,7 @@
+
+ #define GPMC_HAS_WR_ACCESS 0x1
+ #define GPMC_HAS_WR_DATA_MUX_BUS 0x2
++#define GPMC_HAS_MUX_AAD 0x4
+
+ #define GPMC_NR_WAITPINS 4
+
+@@ -1123,6 +1124,90 @@ int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
+ return 0;
+ }
+
++/**
++ * gpmc_cs_program_settings - programs non-timing related settings
++ * @cs: GPMC chip-select to program
++ * @p: pointer to GPMC settings structure
++ *
++ * Programs non-timing related settings for a GPMC chip-select, such as
++ * bus-width, burst configuration, etc. Function should be called once
++ * for each chip-select that is being used and must be called before
++ * calling gpmc_cs_set_timings() as timing parameters in the CONFIG1
++ * register will be initialised to zero by this function. Returns 0 on
++ * success and appropriate negative error code on failure.
++ */
++int gpmc_cs_program_settings(int cs, struct gpmc_settings *p)
++{
++ u32 config1;
++
++ if ((!p->device_width) || (p->device_width > GPMC_DEVWIDTH_16BIT)) {
++ pr_err("%s: invalid width %d!", __func__, p->device_width);
++ return -EINVAL;
++ }
++
++ /* Address-data multiplexing not supported for NAND devices */
++ if (p->device_nand && p->mux_add_data) {
++ pr_err("%s: invalid configuration!\n", __func__);
++ return -EINVAL;
++ }
++
++ if ((p->mux_add_data > GPMC_MUX_AD) ||
++ ((p->mux_add_data == GPMC_MUX_AAD) &&
++ !(gpmc_capability & GPMC_HAS_MUX_AAD))) {
++ pr_err("%s: invalid multiplex configuration!\n", __func__);
++ return -EINVAL;
++ }
++
++ /* Page/burst mode supports lengths of 4, 8 and 16 bytes */
++ if (p->burst_read || p->burst_write) {
++ switch (p->burst_len) {
++ case GPMC_BURST_4:
++ case GPMC_BURST_8:
++ case GPMC_BURST_16:
++ break;
++ default:
++ pr_err("%s: invalid page/burst-length (%d)\n",
++ __func__, p->burst_len);
++ return -EINVAL;
++ }
++ }
++
++ if ((p->wait_on_read || p->wait_on_write) &&
++ (p->wait_pin > gpmc_nr_waitpins)) {
++ pr_err("%s: invalid wait-pin (%d)\n", __func__, p->wait_pin);
++ return -EINVAL;
++ }
++
++ config1 = GPMC_CONFIG1_DEVICESIZE((p->device_width - 1));
++
++ if (p->sync_read)
++ config1 |= GPMC_CONFIG1_READTYPE_SYNC;
++ if (p->sync_write)
++ config1 |= GPMC_CONFIG1_WRITETYPE_SYNC;
++ if (p->wait_on_read)
++ config1 |= GPMC_CONFIG1_WAIT_READ_MON;
++ if (p->wait_on_write)
++ config1 |= GPMC_CONFIG1_WAIT_WRITE_MON;
++ if (p->wait_on_read || p->wait_on_write)
++ config1 |= GPMC_CONFIG1_WAIT_PIN_SEL(p->wait_pin);
++ if (p->device_nand)
++ config1 |= GPMC_CONFIG1_DEVICETYPE(GPMC_DEVICETYPE_NAND);
++ if (p->mux_add_data)
++ config1 |= GPMC_CONFIG1_MUXTYPE(p->mux_add_data);
++ if (p->burst_read)
++ config1 |= GPMC_CONFIG1_READMULTIPLE_SUPP;
++ if (p->burst_write)
++ config1 |= GPMC_CONFIG1_WRITEMULTIPLE_SUPP;
++ if (p->burst_read || p->burst_write) {
++ config1 |= GPMC_CONFIG1_PAGE_LEN(p->burst_len >> 3);
++ config1 |= p->burst_wrap ? GPMC_CONFIG1_WRAPBURST_SUPP : 0;
++ }
++
++ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1);
++
++ return 0;
++}
++
+ #ifdef CONFIG_OF
+ static struct of_device_id gpmc_dt_ids[] = {
+ { .compatible = "ti,omap2420-gpmc" },
+@@ -1371,8 +1456,23 @@ static int gpmc_probe(struct platform_device *pdev)
+ gpmc_dev = &pdev->dev;
+
+ l = gpmc_read_reg(GPMC_REVISION);
++
++ /*
++ * FIXME: Once device-tree migration is complete the below flags
++ * should be populated based upon the device-tree compatible
++ * string. For now just use the IP revision. OMAP3+ devices have
++ * the wr_access and wr_data_mux_bus register fields. OMAP4+
++ * devices support the addr-addr-data multiplex protocol.
++ *
++ * GPMC IP revisions:
++ * - OMAP24xx = 2.0
++ * - OMAP3xxx = 5.0
++ * - OMAP44xx/54xx/AM335x = 6.0
++ */
+ if (GPMC_REVISION_MAJOR(l) > 0x4)
+ gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS;
++ if (GPMC_REVISION_MAJOR(l) > 0x5)
++ gpmc_capability |= GPMC_HAS_MUX_AAD;
+ dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l),
+ GPMC_REVISION_MINOR(l));
+
+diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
+index 39e4e04..ce6ae21 100644
+--- a/arch/arm/mach-omap2/gpmc.h
++++ b/arch/arm/mach-omap2/gpmc.h
+@@ -76,6 +76,11 @@
+ #define GPMC_IRQ_FIFOEVENTENABLE 0x01
+ #define GPMC_IRQ_COUNT_EVENT 0x02
+
++#define GPMC_BURST_4 4 /* 4 word burst */
++#define GPMC_BURST_8 8 /* 8 word burst */
++#define GPMC_BURST_16 16 /* 16 word burst */
++#define GPMC_DEVWIDTH_8BIT 1 /* 8-bit device width */
++#define GPMC_DEVWIDTH_16BIT 2 /* 16-bit device width */
+ #define GPMC_MUX_AAD 1 /* Addr-Addr-Data multiplex */
+ #define GPMC_MUX_AD 2 /* Addr-Data multiplex */
+
+@@ -217,6 +222,7 @@ extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
+ extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
+ extern int gpmc_calc_divider(unsigned int sync_clk);
+ extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t);
++extern int gpmc_cs_program_settings(int cs, struct gpmc_settings *p);
+ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
+ extern void gpmc_cs_free(int cs);
+ extern void omap3_gpmc_save_context(void);
diff --git a/patches/linux-3.8.13/0482-ARM-OMAP2-Convert-ONENAND-to-use-gpmc_cs_program_set.patch b/patches/linux-3.8.13/0482-ARM-OMAP2-Convert-ONENAND-to-use-gpmc_cs_program_set.patch
new file mode 100644
index 0000000..91cbb30
--- /dev/null
+++ b/patches/linux-3.8.13/0482-ARM-OMAP2-Convert-ONENAND-to-use-gpmc_cs_program_set.patch
@@ -0,0 +1,133 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Thu, 21 Feb 2013 12:42:22 -0600
+Subject: [PATCH] ARM: OMAP2+: Convert ONENAND to use
+ gpmc_cs_program_settings()
+
+Convert the OMAP2+ ONENAND code to use the gpmc_cs_program_settings()
+function for configuring the various GPMC options instead of directly
+programming the CONFIG1 register.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ arch/arm/mach-omap2/gpmc-onenand.c | 57 +++++++++++++++---------------------
+ 1 file changed, 23 insertions(+), 34 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
+index d2bf43e..dae6e05 100644
+--- a/arch/arm/mach-omap2/gpmc-onenand.c
++++ b/arch/arm/mach-omap2/gpmc-onenand.c
+@@ -48,18 +48,22 @@ static struct platform_device gpmc_onenand_device = {
+ };
+
+ static struct gpmc_settings onenand_async = {
++ .device_width = GPMC_DEVWIDTH_16BIT,
+ .mux_add_data = GPMC_MUX_AD,
+ };
+
+ static struct gpmc_settings onenand_sync = {
+ .burst_read = true,
++ .burst_wrap = true,
++ .burst_len = GPMC_BURST_16,
++ .device_width = GPMC_DEVWIDTH_16BIT,
+ .mux_add_data = GPMC_MUX_AD,
++ .wait_pin = 0,
+ };
+
+ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
+ {
+ struct gpmc_device_timings dev_t;
+-
+ const int t_cer = 15;
+ const int t_avdp = 12;
+ const int t_aavdh = 7;
+@@ -86,16 +90,6 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
+ gpmc_calc_timings(t, &onenand_async, &dev_t);
+ }
+
+-static int gpmc_set_async_mode(int cs, struct gpmc_timings *t)
+-{
+- /* Configure GPMC for asynchronous read */
+- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
+- GPMC_CONFIG1_DEVICESIZE_16 |
+- GPMC_CONFIG1_MUXADDDATA);
+-
+- return gpmc_cs_set_timings(cs, t);
+-}
+-
+ static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
+ {
+ u32 reg;
+@@ -243,8 +237,11 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
+ /* Set synchronous read timings */
+ memset(&dev_t, 0, sizeof(dev_t));
+
++ if (onenand_flags & ONENAND_FLAG_SYNCREAD)
++ onenand_sync.sync_read = true;
+ if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
+ onenand_sync.sync_write = true;
++ onenand_sync.burst_write = true;
+ } else {
+ dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
+ dev_t.t_wpl = t_wpl * 1000;
+@@ -270,29 +267,6 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
+ gpmc_calc_timings(t, &onenand_sync, &dev_t);
+ }
+
+-static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t)
+-{
+- unsigned sync_read = onenand_flags & ONENAND_FLAG_SYNCREAD;
+- unsigned sync_write = onenand_flags & ONENAND_FLAG_SYNCWRITE;
+-
+- /* Configure GPMC for synchronous read */
+- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
+- GPMC_CONFIG1_WRAPBURST_SUPP |
+- GPMC_CONFIG1_READMULTIPLE_SUPP |
+- (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
+- (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
+- (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
+- GPMC_CONFIG1_PAGE_LEN(2) |
+- (cpu_is_omap34xx() ? 0 :
+- (GPMC_CONFIG1_WAIT_READ_MON |
+- GPMC_CONFIG1_WAIT_PIN_SEL(0))) |
+- GPMC_CONFIG1_DEVICESIZE_16 |
+- GPMC_CONFIG1_DEVICETYPE_NOR |
+- GPMC_CONFIG1_MUXADDDATA);
+-
+- return gpmc_cs_set_timings(cs, t);
+-}
+-
+ static int omap2_onenand_setup_async(void __iomem *onenand_base)
+ {
+ struct gpmc_timings t;
+@@ -302,6 +276,10 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base)
+
+ omap2_onenand_calc_async_timings(&t);
+
++ ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_async);
++ if (ret < 0)
++ return ret;
++
+ ret = gpmc_set_async_mode(gpmc_onenand_data->cs, &t);
+ if (IS_ERR_VALUE(ret))
+ return ret;
+@@ -322,8 +300,19 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
+ set_onenand_cfg(onenand_base);
+ }
+
++ /*
++ * FIXME: Appears to be legacy code from initial ONENAND commit.
++ * Unclear what boards this is for and if this can be removed.
++ */
++ if (!cpu_is_omap34xx())
++ onenand_sync.wait_on_read = true;
++
+ omap2_onenand_calc_sync_timings(&t, gpmc_onenand_data->flags, freq);
+
++ ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_sync);
++ if (ret < 0)
++ return ret;
++
+ ret = gpmc_set_sync_mode(gpmc_onenand_data->cs, &t);
+ if (IS_ERR_VALUE(ret))
+ return ret;
diff --git a/patches/linux-3.8.13/0483-ARM-OMAP2-Convert-NAND-to-use-gpmc_cs_program_settin.patch b/patches/linux-3.8.13/0483-ARM-OMAP2-Convert-NAND-to-use-gpmc_cs_program_settin.patch
new file mode 100644
index 0000000..74b4cf8
--- /dev/null
+++ b/patches/linux-3.8.13/0483-ARM-OMAP2-Convert-NAND-to-use-gpmc_cs_program_settin.patch
@@ -0,0 +1,84 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Thu, 21 Feb 2013 15:43:08 -0600
+Subject: [PATCH] ARM: OMAP2+: Convert NAND to use gpmc_cs_program_settings()
+
+Convert the OMAP2+ NAND code to use the gpmc_cs_program_settings()
+function for configuring the various GPMC options instead of directly
+programming the CONFIG1 register.
+
+This moves the configuration of some GPMC options outside the
+nand_gpmc_retime() because these options should only need to be set once
+regardless of whether the gpmc timing is changing dynamically at runtime.
+The programming of where the wait-pin is also moved slightly, but this
+will not have any impact to existing devices as no boards are currently
+setting the dev_ready variable.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ arch/arm/mach-omap2/gpmc-nand.c | 35 +++++++++++++++++++++++------------
+ 1 file changed, 23 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
+index 6027dd0..d8ad997 100644
+--- a/arch/arm/mach-omap2/gpmc-nand.c
++++ b/arch/arm/mach-omap2/gpmc-nand.c
+@@ -74,14 +74,6 @@ static int omap2_nand_gpmc_retime(
+ t.cs_wr_off = gpmc_t->cs_wr_off;
+ t.wr_cycle = gpmc_t->wr_cycle;
+
+- /* Configure GPMC */
+- if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
+- gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_DEV_SIZE, 1);
+- else
+- gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_DEV_SIZE, 0);
+- gpmc_cs_configure(gpmc_nand_data->cs,
+- GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND);
+- gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_WP, 0);
+ err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t);
+ if (err)
+ return err;
+@@ -114,8 +106,11 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
+ struct gpmc_timings *gpmc_t)
+ {
+ int err = 0;
++ struct gpmc_settings s;
+ struct device *dev = &gpmc_nand_device.dev;
+
++ memset(&s, 0, sizeof(struct gpmc_settings));
++
+ gpmc_nand_device.dev.platform_data = gpmc_nand_data;
+
+ err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE,
+@@ -140,11 +135,27 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
+ dev_err(dev, "Unable to set gpmc timings: %d\n", err);
+ return err;
+ }
+- }
+
+- /* Enable RD PIN Monitoring Reg */
+- if (gpmc_nand_data->dev_ready) {
+- gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_RDY_BSY, 1);
++ s.device_nand = true;
++
++ /* Enable RD PIN Monitoring Reg */
++ if (gpmc_nand_data->dev_ready) {
++ s.wait_on_read = true;
++ s.wait_on_write = true;
++ }
++
++ if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
++ s.device_width = GPMC_DEVWIDTH_16BIT;
++ else
++ s.device_width = GPMC_DEVWIDTH_8BIT;
++
++ err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s);
++ if (err < 0)
++ goto out_free_cs;
++
++ err = gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_WP, 0);
++ if (err < 0)
++ goto out_free_cs;
+ }
+
+ gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs);
diff --git a/patches/linux-3.8.13/0484-ARM-OMAP2-Convert-SMC91x-to-use-gpmc_cs_program_sett.patch b/patches/linux-3.8.13/0484-ARM-OMAP2-Convert-SMC91x-to-use-gpmc_cs_program_sett.patch
new file mode 100644
index 0000000..08043f1
--- /dev/null
+++ b/patches/linux-3.8.13/0484-ARM-OMAP2-Convert-SMC91x-to-use-gpmc_cs_program_sett.patch
@@ -0,0 +1,81 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Thu, 21 Feb 2013 13:01:37 -0600
+Subject: [PATCH] ARM: OMAP2+: Convert SMC91x to use
+ gpmc_cs_program_settings()
+
+Convert the OMAP2+ SMC91x code to use the gpmc_cs_program_settings()
+function for configuring the various GPMC options instead of directly
+programming the CONFIG1 register.
+
+Move configuration of the GPMC settings outside retime function and
+this does not need to be done if the timings are changed dynamically
+at runtime.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ arch/arm/mach-omap2/gpmc-smc91x.c | 30 +++++++++++++++++-------------
+ 1 file changed, 17 insertions(+), 13 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c
+index 4b78338..61a0635 100644
+--- a/arch/arm/mach-omap2/gpmc-smc91x.c
++++ b/arch/arm/mach-omap2/gpmc-smc91x.c
+@@ -49,6 +49,10 @@ static struct platform_device gpmc_smc91x_device = {
+ .resource = gpmc_smc91x_resources,
+ };
+
++static struct gpmc_settings smc91x_settings = {
++ .device_width = GPMC_DEVWIDTH_16BIT,
++};
++
+ /*
+ * Set the gpmc timings for smc91c96. The timings are taken
+ * from the data sheet available at:
+@@ -67,18 +71,6 @@ static int smc91c96_gpmc_retime(void)
+ const int t7 = 5; /* Figure 12.4 write */
+ const int t8 = 5; /* Figure 12.4 write */
+ const int t20 = 185; /* Figure 12.2 read and 12.4 write */
+- u32 l;
+-
+- l = GPMC_CONFIG1_DEVICESIZE_16;
+- if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
+- l |= GPMC_CONFIG1_MUXADDDATA;
+- if (gpmc_cfg->flags & GPMC_READ_MON)
+- l |= GPMC_CONFIG1_WAIT_READ_MON;
+- if (gpmc_cfg->flags & GPMC_WRITE_MON)
+- l |= GPMC_CONFIG1_WAIT_WRITE_MON;
+- if (gpmc_cfg->wait_pin)
+- l |= GPMC_CONFIG1_WAIT_PIN_SEL(gpmc_cfg->wait_pin);
+- gpmc_cs_write_reg(gpmc_cfg->cs, GPMC_CS_CONFIG1, l);
+
+ /*
+ * FIXME: Calculate the address and data bus muxed timings.
+@@ -104,7 +96,7 @@ static int smc91c96_gpmc_retime(void)
+ dev_t.t_cez_w = t4_w * 1000;
+ dev_t.t_wr_cycle = (t20 - t3) * 1000;
+
+- gpmc_calc_timings(&t, NULL, &dev_t);
++ gpmc_calc_timings(&t, &smc91x_settings, &dev_t);
+
+ return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
+ }
+@@ -133,6 +125,18 @@ void __init gpmc_smc91x_init(struct omap_smc91x_platform_data *board_data)
+ gpmc_smc91x_resources[0].end = cs_mem_base + 0x30f;
+ gpmc_smc91x_resources[1].flags |= (gpmc_cfg->flags & IRQF_TRIGGER_MASK);
+
++ if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
++ smc91x_settings.mux_add_data = GPMC_MUX_AD;
++ if (gpmc_cfg->flags & GPMC_READ_MON)
++ smc91x_settings.wait_on_read = true;
++ if (gpmc_cfg->flags & GPMC_WRITE_MON)
++ smc91x_settings.wait_on_write = true;
++ if (gpmc_cfg->wait_pin)
++ smc91x_settings.wait_pin = gpmc_cfg->wait_pin;
++ ret = gpmc_cs_program_settings(gpmc_cfg->cs, &smc91x_settings);
++ if (ret < 0)
++ goto free1;
++
+ if (gpmc_cfg->retime) {
+ ret = gpmc_cfg->retime();
+ if (ret != 0)
diff --git a/patches/linux-3.8.13/0485-ARM-OMAP2-Convert-TUSB-to-use-gpmc_cs_program_settin.patch b/patches/linux-3.8.13/0485-ARM-OMAP2-Convert-TUSB-to-use-gpmc_cs_program_settin.patch
new file mode 100644
index 0000000..715042d
--- /dev/null
+++ b/patches/linux-3.8.13/0485-ARM-OMAP2-Convert-TUSB-to-use-gpmc_cs_program_settin.patch
@@ -0,0 +1,98 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Thu, 21 Feb 2013 13:01:47 -0600
+Subject: [PATCH] ARM: OMAP2+: Convert TUSB to use gpmc_cs_program_settings()
+
+Convert the OMAP2+ TUSB code to use the gpmc_cs_program_settings()
+function for configuring the various GPMC options instead of directly
+programming the CONFIG1 register.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ arch/arm/mach-omap2/usb-tusb6010.c | 43 ++++++++++++++++--------------------
+ 1 file changed, 19 insertions(+), 24 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
+index faaf96d..e832bc7 100644
+--- a/arch/arm/mach-omap2/usb-tusb6010.c
++++ b/arch/arm/mach-omap2/usb-tusb6010.c
+@@ -8,6 +8,7 @@
+ * published by the Free Software Foundation.
+ */
+
++#include <linux/err.h>
+ #include <linux/string.h>
+ #include <linux/types.h>
+ #include <linux/errno.h>
+@@ -27,12 +28,21 @@ static u8 async_cs, sync_cs;
+ static unsigned refclk_psec;
+
+ static struct gpmc_settings tusb_async = {
++ .wait_on_read = true,
++ .wait_on_write = true,
++ .device_width = GPMC_DEVWIDTH_16BIT,
+ .mux_add_data = GPMC_MUX_AD,
+ };
+
+ static struct gpmc_settings tusb_sync = {
++ .burst_read = true,
++ .burst_write = true,
+ .sync_read = true,
+ .sync_write = true,
++ .wait_on_read = true,
++ .wait_on_write = true,
++ .burst_len = GPMC_BURST_16,
++ .device_width = GPMC_DEVWIDTH_16BIT,
+ .mux_add_data = GPMC_MUX_AD,
+ };
+
+@@ -168,18 +178,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
+ return status;
+ }
+ tusb_resources[0].end = tusb_resources[0].start + 0x9ff;
++ tusb_async.wait_pin = waitpin;
+ async_cs = async;
+- gpmc_cs_write_reg(async, GPMC_CS_CONFIG1,
+- GPMC_CONFIG1_PAGE_LEN(2)
+- | GPMC_CONFIG1_WAIT_READ_MON
+- | GPMC_CONFIG1_WAIT_WRITE_MON
+- | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin)
+- | GPMC_CONFIG1_READTYPE_ASYNC
+- | GPMC_CONFIG1_WRITETYPE_ASYNC
+- | GPMC_CONFIG1_DEVICESIZE_16
+- | GPMC_CONFIG1_DEVICETYPE_NOR
+- | GPMC_CONFIG1_MUXADDDATA);
+
++ status = gpmc_cs_program_settings(async_cs, &tusb_async);
++ if (status < 0)
++ return status;
+
+ /* SYNC region, primarily for DMA */
+ status = gpmc_cs_request(sync, SZ_16M, (unsigned long *)
+@@ -189,21 +193,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
+ return status;
+ }
+ tusb_resources[1].end = tusb_resources[1].start + 0x9ff;
++ tusb_sync.wait_pin = waitpin;
+ sync_cs = sync;
+- gpmc_cs_write_reg(sync, GPMC_CS_CONFIG1,
+- GPMC_CONFIG1_READMULTIPLE_SUPP
+- | GPMC_CONFIG1_READTYPE_SYNC
+- | GPMC_CONFIG1_WRITEMULTIPLE_SUPP
+- | GPMC_CONFIG1_WRITETYPE_SYNC
+- | GPMC_CONFIG1_PAGE_LEN(2)
+- | GPMC_CONFIG1_WAIT_READ_MON
+- | GPMC_CONFIG1_WAIT_WRITE_MON
+- | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin)
+- | GPMC_CONFIG1_DEVICESIZE_16
+- | GPMC_CONFIG1_DEVICETYPE_NOR
+- | GPMC_CONFIG1_MUXADDDATA
+- /* fclk divider gets set later */
+- );
++
++ status = gpmc_cs_program_settings(sync_cs, &tusb_sync);
++ if (status < 0)
++ return status;
+
+ /* IRQ */
+ status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq");
diff --git a/patches/linux-3.8.13/0486-ARM-OMAP2-Don-t-configure-of-chip-select-options-in-.patch b/patches/linux-3.8.13/0486-ARM-OMAP2-Don-t-configure-of-chip-select-options-in-.patch
new file mode 100644
index 0000000..770cde4
--- /dev/null
+++ b/patches/linux-3.8.13/0486-ARM-OMAP2-Don-t-configure-of-chip-select-options-in-.patch
@@ -0,0 +1,129 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Thu, 21 Feb 2013 13:00:21 -0600
+Subject: [PATCH] ARM: OMAP2+: Don't configure of chip-select options in
+ gpmc_cs_configure()
+
+With the addition of the gpmc_cs_program_settings(), we no longer need
+or use gpmc_cs_configure() to configure some of the GPMC chip-select
+options. So rename the function to gpmc_configure() and remove code that
+modifies options in the CONFIG1 register.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ arch/arm/mach-omap2/gpmc-nand.c | 2 +-
+ arch/arm/mach-omap2/gpmc.c | 49 ++++++---------------------------------
+ arch/arm/mach-omap2/gpmc.h | 5 +---
+ 3 files changed, 9 insertions(+), 47 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
+index d8ad997..7c70752 100644
+--- a/arch/arm/mach-omap2/gpmc-nand.c
++++ b/arch/arm/mach-omap2/gpmc-nand.c
+@@ -153,7 +153,7 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
+ if (err < 0)
+ goto out_free_cs;
+
+- err = gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_WP, 0);
++ err = gpmc_configure(GPMC_CONFIG_WP, 0);
+ if (err < 0)
+ goto out_free_cs;
+ }
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index 0302a03..de8be1e 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -544,16 +544,14 @@ void gpmc_cs_free(int cs)
+ EXPORT_SYMBOL(gpmc_cs_free);
+
+ /**
+- * gpmc_cs_configure - write request to configure gpmc
+- * @cs: chip select number
++ * gpmc_configure - write request to configure gpmc
+ * @cmd: command type
+ * @wval: value to write
+ * @return status of the operation
+ */
+-int gpmc_cs_configure(int cs, int cmd, int wval)
++int gpmc_configure(int cmd, int wval)
+ {
+- int err = 0;
+- u32 regval = 0;
++ u32 regval;
+
+ switch (cmd) {
+ case GPMC_ENABLE_IRQ:
+@@ -573,47 +571,14 @@ int gpmc_cs_configure(int cs, int cmd, int wval)
+ gpmc_write_reg(GPMC_CONFIG, regval);
+ break;
+
+- case GPMC_CONFIG_RDY_BSY:
+- regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+- if (wval)
+- regval |= WR_RD_PIN_MONITORING;
+- else
+- regval &= ~WR_RD_PIN_MONITORING;
+- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval);
+- break;
+-
+- case GPMC_CONFIG_DEV_SIZE:
+- regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+-
+- /* clear 2 target bits */
+- regval &= ~GPMC_CONFIG1_DEVICESIZE(3);
+-
+- /* set the proper value */
+- regval |= GPMC_CONFIG1_DEVICESIZE(wval);
+-
+- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval);
+- break;
+-
+- case GPMC_CONFIG_DEV_TYPE:
+- regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+- /* clear 4 target bits */
+- regval &= ~(GPMC_CONFIG1_DEVICETYPE(3) |
+- GPMC_CONFIG1_MUXTYPE(3));
+- /* set the proper value */
+- regval |= GPMC_CONFIG1_DEVICETYPE(wval);
+- if (wval == GPMC_DEVICETYPE_NOR)
+- regval |= GPMC_CONFIG1_MUXADDDATA;
+- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval);
+- break;
+-
+ default:
+- printk(KERN_ERR "gpmc_configure_cs: Not supported\n");
+- err = -EINVAL;
++ pr_err("%s: command not supported\n", __func__);
++ return -EINVAL;
+ }
+
+- return err;
++ return 0;
+ }
+-EXPORT_SYMBOL(gpmc_cs_configure);
++EXPORT_SYMBOL(gpmc_configure);
+
+ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
+ {
+diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
+index ce6ae21..87d2a22 100644
+--- a/arch/arm/mach-omap2/gpmc.h
++++ b/arch/arm/mach-omap2/gpmc.h
+@@ -59,9 +59,6 @@
+ #define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10)
+ #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0)
+ #define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8)
+-#define GPMC_CONFIG1_MUXNONMUX GPMC_CONFIG1_MUXTYPE(0)
+-#define GPMC_CONFIG1_MUXAAD GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AAD)
+-#define GPMC_CONFIG1_MUXADDDATA GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AD)
+ #define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4)
+ #define GPMC_CONFIG1_FCLK_DIV(val) (val & 3)
+ #define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1))
+@@ -227,6 +224,6 @@ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
+ extern void gpmc_cs_free(int cs);
+ extern void omap3_gpmc_save_context(void);
+ extern void omap3_gpmc_restore_context(void);
+-extern int gpmc_cs_configure(int cs, int cmd, int wval);
++extern int gpmc_configure(int cmd, int wval);
+
+ #endif
diff --git a/patches/linux-3.8.13/0487-ARM-OMAP2-Add-function-to-read-GPMC-settings-from-de.patch b/patches/linux-3.8.13/0487-ARM-OMAP2-Add-function-to-read-GPMC-settings-from-de.patch
new file mode 100644
index 0000000..5c03a1a
--- /dev/null
+++ b/patches/linux-3.8.13/0487-ARM-OMAP2-Add-function-to-read-GPMC-settings-from-de.patch
@@ -0,0 +1,196 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Wed, 20 Feb 2013 15:53:12 -0600
+Subject: [PATCH] ARM: OMAP2+: Add function to read GPMC settings from
+ device-tree
+
+Adds a function to read the various GPMC chip-select settings from
+device-tree and store them in the gpmc_settings structure.
+
+Update the GPMC device-tree binding documentation to describe these
+options.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ Documentation/devicetree/bindings/bus/ti-gpmc.txt | 107 +++++++++++++++++++++
+ arch/arm/mach-omap2/gpmc.c | 40 ++++++++
+ arch/arm/mach-omap2/gpmc.h | 2 +
+ 3 files changed, 149 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/bus/ti-gpmc.txt
+
+diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
+new file mode 100644
+index 0000000..6fde1cf
+--- /dev/null
++++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
+@@ -0,0 +1,107 @@
++Device tree bindings for OMAP general purpose memory controllers (GPMC)
++
++The actual devices are instantiated from the child nodes of a GPMC node.
++
++Required properties:
++
++ - compatible: Should be set to one of the following:
++
++ ti,omap2420-gpmc (omap2420)
++ ti,omap2430-gpmc (omap2430)
++ ti,omap3430-gpmc (omap3430 & omap3630)
++ ti,omap4430-gpmc (omap4430 & omap4460 & omap543x)
++ ti,am3352-gpmc (am335x devices)
++
++ - reg: A resource specifier for the register space
++ (see the example below)
++ - ti,hwmods: Should be set to "ti,gpmc" until the DT transition is
++ completed.
++ - #address-cells: Must be set to 2 to allow memory address translation
++ - #size-cells: Must be set to 1 to allow CS address passing
++ - gpmc,num-cs: The maximum number of chip-select lines that controller
++ can support.
++ - gpmc,num-waitpins: The maximum number of wait pins that controller can
++ support.
++ - ranges: Must be set up to reflect the memory layout with four
++ integer values for each chip-select line in use:
++
++ <cs-number> 0 <physical address of mapping> <size>
++
++ Currently, calculated values derived from the contents
++ of the per-CS register GPMC_CONFIG7 (as set up by the
++ bootloader) are used for the physical address decoding.
++ As this will change in the future, filling correct
++ values here is a requirement.
++
++Timing properties for child nodes. All are optional and default to 0.
++
++ - gpmc,sync-clk: Minimum clock period for synchronous mode, in picoseconds
++
++ Chip-select signal timings corresponding to GPMC_CONFIG2:
++ - gpmc,cs-on: Assertion time
++ - gpmc,cs-rd-off: Read deassertion time
++ - gpmc,cs-wr-off: Write deassertion time
++
++ ADV signal timings corresponding to GPMC_CONFIG3:
++ - gpmc,adv-on: Assertion time
++ - gpmc,adv-rd-off: Read deassertion time
++ - gpmc,adv-wr-off: Write deassertion time
++
++ WE signals timings corresponding to GPMC_CONFIG4:
++ - gpmc,we-on: Assertion time
++ - gpmc,we-off: Deassertion time
++
++ OE signals timings corresponding to GPMC_CONFIG4:
++ - gpmc,oe-on: Assertion time
++ - gpmc,oe-off: Deassertion time
++
++ Access time and cycle time timings corresponding to GPMC_CONFIG5:
++ - gpmc,page-burst-access: Multiple access word delay
++ - gpmc,access: Start-cycle to first data valid delay
++ - gpmc,rd-cycle: Total read cycle time
++ - gpmc,wr-cycle: Total write cycle time
++
++The following are only applicable to OMAP3+ and AM335x:
++ - gpmc,wr-access
++ - gpmc,wr-data-mux-bus
++
++GPMC chip-select settings properties for child nodes. All are optional.
++
++- gpmc,burst-length Page/burst length. Must be 4, 8 or 16.
++- gpmc,burst-wrap Enables wrap bursting
++- gpmc,burst-read Enables read page/burst mode
++- gpmc,burst-write Enables write page/burst mode
++- gpmc,device-nand Device is NAND
++- gpmc,device-width Total width of device(s) connected to a GPMC
++ chip-select in bytes. The GPMC supports 8-bit
++ and 16-bit devices and so this property must be
++ 1 or 2.
++- gpmc,mux-add-data Address and data multiplexing configuration.
++ Valid values are 1 for address-address-data
++ multiplexing mode and 2 for address-data
++ multiplexing mode.
++- gpmc,sync-read Enables synchronous read. Defaults to asynchronous
++ is this is not set.
++- gpmc,sync-write Enables synchronous writes. Defaults to asynchronous
++ is this is not set.
++- gpmc,wait-pin Wait-pin used by client. Must be less than
++ "gpmc,num-waitpins".
++- gpmc,wait-on-read Enables wait monitoring on reads.
++- gpmc,wait-on-write Enables wait monitoring on writes.
++
++Example for an AM33xx board:
++
++ gpmc: gpmc@50000000 {
++ compatible = "ti,am3352-gpmc";
++ ti,hwmods = "gpmc";
++ reg = <0x50000000 0x2000>;
++ interrupts = <100>;
++
++ gpmc,num-cs = <8>;
++ gpmc,num-waitpins = <2>;
++ #address-cells = <2>;
++ #size-cells = <1>;
++ ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */
++
++ /* child nodes go here */
++ };
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index de8be1e..dd2c72c 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -1184,6 +1184,46 @@ static struct of_device_id gpmc_dt_ids[] = {
+ };
+ MODULE_DEVICE_TABLE(of, gpmc_dt_ids);
+
++/**
++ * gpmc_read_settings_dt - read gpmc settings from device-tree
++ * @np: pointer to device-tree node for a gpmc child device
++ * @p: pointer to gpmc settings structure
++ *
++ * Reads the GPMC settings for a GPMC child device from device-tree and
++ * stores them in the GPMC settings structure passed. The GPMC settings
++ * structure is initialised to zero by this function and so any
++ * previously stored settings will be cleared.
++ */
++void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p)
++{
++ memset(p, 0, sizeof(struct gpmc_settings));
++
++ p->sync_read = of_property_read_bool(np, "gpmc,sync-read");
++ p->sync_write = of_property_read_bool(np, "gpmc,sync-write");
++ p->device_nand = of_property_read_bool(np, "gpmc,device-nand");
++ of_property_read_u32(np, "gpmc,device-width", &p->device_width);
++ of_property_read_u32(np, "gpmc,mux-add-data", &p->mux_add_data);
++
++ if (!of_property_read_u32(np, "gpmc,burst-length", &p->burst_len)) {
++ p->burst_wrap = of_property_read_bool(np, "gpmc,burst-wrap");
++ p->burst_read = of_property_read_bool(np, "gpmc,burst-read");
++ p->burst_write = of_property_read_bool(np, "gpmc,burst-write");
++ if (!p->burst_read && !p->burst_write)
++ pr_warn("%s: page/burst-length set but not used!\n",
++ __func__);
++ }
++
++ if (!of_property_read_u32(np, "gpmc,wait-pin", &p->wait_pin)) {
++ p->wait_on_read = of_property_read_bool(np,
++ "gpmc,wait-on-read");
++ p->wait_on_write = of_property_read_bool(np,
++ "gpmc,wait-on-write");
++ if (!p->wait_on_read && !p->wait_on_write)
++ pr_warn("%s: read/write wait monitoring not enabled!\n",
++ __func__);
++ }
++}
++
+ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
+ struct gpmc_timings *gpmc_t)
+ {
+diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
+index 87d2a22..707f6d5 100644
+--- a/arch/arm/mach-omap2/gpmc.h
++++ b/arch/arm/mach-omap2/gpmc.h
+@@ -225,5 +225,7 @@ extern void gpmc_cs_free(int cs);
+ extern void omap3_gpmc_save_context(void);
+ extern void omap3_gpmc_restore_context(void);
+ extern int gpmc_configure(int cmd, int wval);
++extern void gpmc_read_settings_dt(struct device_node *np,
++ struct gpmc_settings *p);
+
+ #endif
diff --git a/patches/linux-3.8.13/0488-ARM-OMAP2-Add-additional-GPMC-timing-parameters.patch b/patches/linux-3.8.13/0488-ARM-OMAP2-Add-additional-GPMC-timing-parameters.patch
new file mode 100644
index 0000000..6a9d313
--- /dev/null
+++ b/patches/linux-3.8.13/0488-ARM-OMAP2-Add-additional-GPMC-timing-parameters.patch
@@ -0,0 +1,238 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Thu, 21 Feb 2013 18:51:27 -0600
+Subject: [PATCH] ARM: OMAP2+: Add additional GPMC timing parameters
+
+Some of the GPMC timings parameters are currently missing from the GPMC
+device-tree binding. Add these parameters to the binding documentation
+as well as code to read them. Also add either "-ps" or "-ns" suffix to
+the GPMC timing properties to indicate whether the timing is in
+picoseconds or nanoseconds.
+
+The existing code in gpmc_read_timings_dt() is checking the value of
+of_property_read_u32() and only is successful storing the value read
+in the gpmc_timings structure. Checking the return value in this case
+is not necessary and we can simply read the value, if present, and
+store directly in the gpmc_timings structure. Therefore, simplify the
+code by removing these checks.
+
+The comment in the gpmc_read_timings_dt() function, "only for OMAP3430"
+is also incorrect as it is applicable to all OMAP3+ devices. So correct
+this too.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ Documentation/devicetree/bindings/bus/ti-gpmc.txt | 78 +++++++++++------
+ arch/arm/mach-omap2/gpmc.c | 94 ++++++++++-----------
+ 2 files changed, 98 insertions(+), 74 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
+index 6fde1cf..4b87ea1 100644
+--- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt
++++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
+@@ -35,35 +35,59 @@ Required properties:
+
+ Timing properties for child nodes. All are optional and default to 0.
+
+- - gpmc,sync-clk: Minimum clock period for synchronous mode, in picoseconds
+-
+- Chip-select signal timings corresponding to GPMC_CONFIG2:
+- - gpmc,cs-on: Assertion time
+- - gpmc,cs-rd-off: Read deassertion time
+- - gpmc,cs-wr-off: Write deassertion time
+-
+- ADV signal timings corresponding to GPMC_CONFIG3:
+- - gpmc,adv-on: Assertion time
+- - gpmc,adv-rd-off: Read deassertion time
+- - gpmc,adv-wr-off: Write deassertion time
+-
+- WE signals timings corresponding to GPMC_CONFIG4:
+- - gpmc,we-on: Assertion time
+- - gpmc,we-off: Deassertion time
+-
+- OE signals timings corresponding to GPMC_CONFIG4:
+- - gpmc,oe-on: Assertion time
+- - gpmc,oe-off: Deassertion time
+-
+- Access time and cycle time timings corresponding to GPMC_CONFIG5:
+- - gpmc,page-burst-access: Multiple access word delay
+- - gpmc,access: Start-cycle to first data valid delay
+- - gpmc,rd-cycle: Total read cycle time
+- - gpmc,wr-cycle: Total write cycle time
++ - gpmc,sync-clk-ps: Minimum clock period for synchronous mode, in picoseconds
++
++ Chip-select signal timings (in nanoseconds) corresponding to GPMC_CONFIG2:
++ - gpmc,cs-on-ns: Assertion time
++ - gpmc,cs-rd-off-ns: Read deassertion time
++ - gpmc,cs-wr-off-ns: Write deassertion time
++
++ ADV signal timings (in nanoseconds) corresponding to GPMC_CONFIG3:
++ - gpmc,adv-on-ns: Assertion time
++ - gpmc,adv-rd-off-ns: Read deassertion time
++ - gpmc,adv-wr-off-ns: Write deassertion time
++
++ WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
++ - gpmc,we-on-ns Assertion time
++ - gpmc,we-off-ns: Deassertion time
++
++ OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
++ - gpmc,oe-on-ns: Assertion time
++ - gpmc,oe-off-ns: Deassertion time
++
++ Access time and cycle time timings (in nanoseconds) corresponding to
++ GPMC_CONFIG5:
++ - gpmc,page-burst-access-ns: Multiple access word delay
++ - gpmc,access-ns: Start-cycle to first data valid delay
++ - gpmc,rd-cycle-ns: Total read cycle time
++ - gpmc,wr-cycle-ns: Total write cycle time
++ - gpmc,bus-turnaround-ns: Turn-around time between successive accesses
++ - gpmc,cycle2cycle-delay-ns: Delay between chip-select pulses
++ - gpmc,clk-activation-ns: GPMC clock activation time
++ - gpmc,wait-monitoring-ns: Start of wait monitoring with regard to valid
++ data
++
++Boolean timing parameters. If property is present parameter enabled and
++disabled if omitted:
++ - gpmc,adv-extra-delay: ADV signal is delayed by half GPMC clock
++ - gpmc,cs-extra-delay: CS signal is delayed by half GPMC clock
++ - gpmc,cycle2cycle-diffcsen: Add "cycle2cycle-delay" between successive
++ accesses to a different CS
++ - gpmc,cycle2cycle-samecsen: Add "cycle2cycle-delay" between successive
++ accesses to the same CS
++ - gpmc,oe-extra-delay: OE signal is delayed by half GPMC clock
++ - gpmc,we-extra-delay: WE signal is delayed by half GPMC clock
++ - gpmc,time-para-granularity: Multiply all access times by 2
+
+ The following are only applicable to OMAP3+ and AM335x:
+- - gpmc,wr-access
+- - gpmc,wr-data-mux-bus
++ - gpmc,wr-access-ns: In synchronous write mode, for single or
++ burst accesses, defines the number of
++ GPMC_FCLK cycles from start access time
++ to the GPMC_CLK rising edge used by the
++ memory device for the first data capture.
++ - gpmc,wr-data-mux-bus-ns: In address-data multiplex mode, specifies
++ the time when the first data is driven on
++ the address-data bus.
+
+ GPMC chip-select settings properties for child nodes. All are optional.
+
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index dd2c72c..c127e75 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -1227,67 +1227,67 @@ void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p)
+ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
+ struct gpmc_timings *gpmc_t)
+ {
+- u32 val;
++ struct gpmc_bool_timings *p;
++
++ if (!np || !gpmc_t)
++ return;
+
+ memset(gpmc_t, 0, sizeof(*gpmc_t));
+
+ /* minimum clock period for syncronous mode */
+- if (!of_property_read_u32(np, "gpmc,sync-clk", &val))
+- gpmc_t->sync_clk = val;
++ of_property_read_u32(np, "gpmc,sync-clk-ps", &gpmc_t->sync_clk);
+
+ /* chip select timtings */
+- if (!of_property_read_u32(np, "gpmc,cs-on", &val))
+- gpmc_t->cs_on = val;
+-
+- if (!of_property_read_u32(np, "gpmc,cs-rd-off", &val))
+- gpmc_t->cs_rd_off = val;
+-
+- if (!of_property_read_u32(np, "gpmc,cs-wr-off", &val))
+- gpmc_t->cs_wr_off = val;
++ of_property_read_u32(np, "gpmc,cs-on-ns", &gpmc_t->cs_on);
++ of_property_read_u32(np, "gpmc,cs-rd-off-ns", &gpmc_t->cs_rd_off);
++ of_property_read_u32(np, "gpmc,cs-wr-off-ns", &gpmc_t->cs_wr_off);
+
+ /* ADV signal timings */
+- if (!of_property_read_u32(np, "gpmc,adv-on", &val))
+- gpmc_t->adv_on = val;
+-
+- if (!of_property_read_u32(np, "gpmc,adv-rd-off", &val))
+- gpmc_t->adv_rd_off = val;
+-
+- if (!of_property_read_u32(np, "gpmc,adv-wr-off", &val))
+- gpmc_t->adv_wr_off = val;
++ of_property_read_u32(np, "gpmc,adv-on-ns", &gpmc_t->adv_on);
++ of_property_read_u32(np, "gpmc,adv-rd-off-ns", &gpmc_t->adv_rd_off);
++ of_property_read_u32(np, "gpmc,adv-wr-off-ns", &gpmc_t->adv_wr_off);
+
+ /* WE signal timings */
+- if (!of_property_read_u32(np, "gpmc,we-on", &val))
+- gpmc_t->we_on = val;
+-
+- if (!of_property_read_u32(np, "gpmc,we-off", &val))
+- gpmc_t->we_off = val;
++ of_property_read_u32(np, "gpmc,we-on-ns", &gpmc_t->we_on);
++ of_property_read_u32(np, "gpmc,we-off-ns", &gpmc_t->we_off);
+
+ /* OE signal timings */
+- if (!of_property_read_u32(np, "gpmc,oe-on", &val))
+- gpmc_t->oe_on = val;
+-
+- if (!of_property_read_u32(np, "gpmc,oe-off", &val))
+- gpmc_t->oe_off = val;
++ of_property_read_u32(np, "gpmc,oe-on-ns", &gpmc_t->oe_on);
++ of_property_read_u32(np, "gpmc,oe-off-ns", &gpmc_t->oe_off);
+
+ /* access and cycle timings */
+- if (!of_property_read_u32(np, "gpmc,page-burst-access", &val))
+- gpmc_t->page_burst_access = val;
+-
+- if (!of_property_read_u32(np, "gpmc,access", &val))
+- gpmc_t->access = val;
+-
+- if (!of_property_read_u32(np, "gpmc,rd-cycle", &val))
+- gpmc_t->rd_cycle = val;
+-
+- if (!of_property_read_u32(np, "gpmc,wr-cycle", &val))
+- gpmc_t->wr_cycle = val;
+-
+- /* only for OMAP3430 */
+- if (!of_property_read_u32(np, "gpmc,wr-access", &val))
+- gpmc_t->wr_access = val;
+-
+- if (!of_property_read_u32(np, "gpmc,wr-data-mux-bus", &val))
+- gpmc_t->wr_data_mux_bus = val;
++ of_property_read_u32(np, "gpmc,page-burst-access-ns",
++ &gpmc_t->page_burst_access);
++ of_property_read_u32(np, "gpmc,access-ns", &gpmc_t->access);
++ of_property_read_u32(np, "gpmc,rd-cycle-ns", &gpmc_t->rd_cycle);
++ of_property_read_u32(np, "gpmc,wr-cycle-ns", &gpmc_t->wr_cycle);
++ of_property_read_u32(np, "gpmc,bus-turnaround-ns",
++ &gpmc_t->bus_turnaround);
++ of_property_read_u32(np, "gpmc,cycle2cycle-delay-ns",
++ &gpmc_t->cycle2cycle_delay);
++ of_property_read_u32(np, "gpmc,wait-monitoring-ns",
++ &gpmc_t->wait_monitoring);
++ of_property_read_u32(np, "gpmc,clk-activation-ns",
++ &gpmc_t->clk_activation);
++
++ /* only applicable to OMAP3+ */
++ of_property_read_u32(np, "gpmc,wr-access-ns", &gpmc_t->wr_access);
++ of_property_read_u32(np, "gpmc,wr-data-mux-bus-ns",
++ &gpmc_t->wr_data_mux_bus);
++
++ /* bool timing parameters */
++ p = &gpmc_t->bool_timings;
++
++ p->cycle2cyclediffcsen =
++ of_property_read_bool(np, "gpmc,cycle2cycle-diffcsen");
++ p->cycle2cyclesamecsen =
++ of_property_read_bool(np, "gpmc,cycle2cycle-samecsen");
++ p->we_extra_delay = of_property_read_bool(np, "gpmc,we-extra-delay");
++ p->oe_extra_delay = of_property_read_bool(np, "gpmc,oe-extra-delay");
++ p->adv_extra_delay = of_property_read_bool(np, "gpmc,adv-extra-delay");
++ p->cs_extra_delay = of_property_read_bool(np, "gpmc,cs-extra-delay");
++ p->time_para_granularity =
++ of_property_read_bool(np, "gpmc,time-para-granularity");
+ }
+
+ #ifdef CONFIG_MTD_NAND
diff --git a/patches/linux-3.8.13/0489-ARM-OMAP2-Add-device-tree-support-for-NOR-flash.patch b/patches/linux-3.8.13/0489-ARM-OMAP2-Add-device-tree-support-for-NOR-flash.patch
new file mode 100644
index 0000000..22fa14b
--- /dev/null
+++ b/patches/linux-3.8.13/0489-ARM-OMAP2-Add-device-tree-support-for-NOR-flash.patch
@@ -0,0 +1,273 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Fri, 8 Feb 2013 16:46:13 -0600
+Subject: [PATCH] ARM: OMAP2+: Add device-tree support for NOR flash
+
+NOR flash is not currently supported when booting with device-tree
+on OMAP2+ devices. Add support to detect and configure NOR devices
+when booting with device-tree.
+
+Add documentation for the TI GPMC NOR binding.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ Documentation/devicetree/bindings/mtd/gpmc-nor.txt | 98 ++++++++++++++++
+ arch/arm/mach-omap2/gpmc.c | 119 ++++++++++++++++++++
+ 2 files changed, 217 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nor.txt
+
+diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nor.txt b/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
+new file mode 100644
+index 0000000..420b3ab
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
+@@ -0,0 +1,98 @@
++Device tree bindings for NOR flash connect to TI GPMC
++
++NOR flash connected to the TI GPMC (found on OMAP boards) are represented as
++child nodes of the GPMC controller with a name of "nor".
++
++All timing relevant properties as well as generic GPMC child properties are
++explained in a separate documents. Please refer to
++Documentation/devicetree/bindings/bus/ti-gpmc.txt
++
++Required properties:
++- bank-width: Width of NOR flash in bytes. GPMC supports 8-bit and
++ 16-bit devices and so must be either 1 or 2 bytes.
++- compatible: Documentation/devicetree/bindings/mtd/mtd-physmap.txt
++- gpmc,cs-on-ns: Chip-select assertion time
++- gpmc,cs-rd-off-ns: Chip-select de-assertion time for reads
++- gpmc,cs-wr-off-ns: Chip-select de-assertion time for writes
++- gpmc,oe-on-ns: Output-enable assertion time
++- gpmc,oe-off-ns: Output-enable de-assertion time
++- gpmc,we-on-ns Write-enable assertion time
++- gpmc,we-off-ns: Write-enable de-assertion time
++- gpmc,access-ns: Start cycle to first data capture (read access)
++- gpmc,rd-cycle-ns: Total read cycle time
++- gpmc,wr-cycle-ns: Total write cycle time
++- linux,mtd-name: Documentation/devicetree/bindings/mtd/mtd-physmap.txt
++- reg: Chip-select, base address (relative to chip-select)
++ and size of NOR flash. Note that base address will be
++ typically 0 as this is the start of the chip-select.
++
++Optional properties:
++- gpmc,XXX Additional GPMC timings and settings parameters. See
++ Documentation/devicetree/bindings/bus/ti-gpmc.txt
++
++Optional properties for partiton table parsing:
++- #address-cells: should be set to 1
++- #size-cells: should be set to 1
++
++Example:
++
++gpmc: gpmc@6e000000 {
++ compatible = "ti,omap3430-gpmc", "simple-bus";
++ ti,hwmods = "gpmc";
++ reg = <0x6e000000 0x1000>;
++ interrupts = <20>;
++ gpmc,num-cs = <8>;
++ gpmc,num-waitpins = <4>;
++ #address-cells = <2>;
++ #size-cells = <1>;
++
++ ranges = <0 0 0x10000000 0x08000000>;
++
++ nor@0,0 {
++ compatible = "cfi-flash";
++ linux,mtd-name= "intel,pf48f6000m0y1be";
++ #address-cells = <1>;
++ #size-cells = <1>;
++ reg = <0 0 0x08000000>;
++ bank-width = <2>;
++
++ gpmc,mux-add-data;
++ gpmc,cs-on-ns = <0>;
++ gpmc,cs-rd-off-ns = <186>;
++ gpmc,cs-wr-off-ns = <186>;
++ gpmc,adv-on-ns = <12>;
++ gpmc,adv-rd-off-ns = <48>;
++ gpmc,adv-wr-off-ns = <48>;
++ gpmc,oe-on-ns = <54>;
++ gpmc,oe-off-ns = <168>;
++ gpmc,we-on-ns = <54>;
++ gpmc,we-off-ns = <168>;
++ gpmc,rd-cycle-ns = <186>;
++ gpmc,wr-cycle-ns = <186>;
++ gpmc,access-ns = <114>;
++ gpmc,page-burst-access-ns = <6>;
++ gpmc,bus-turnaround-ns = <12>;
++ gpmc,cycle2cycle-delay-ns = <18>;
++ gpmc,wr-data-mux-bus-ns = <90>;
++ gpmc,wr-access-ns = <186>;
++ gpmc,cycle2cycle-samecsen;
++ gpmc,cycle2cycle-diffcsen;
++
++ partition@0 {
++ label = "bootloader-nor";
++ reg = <0 0x40000>;
++ };
++ partition@0x40000 {
++ label = "params-nor";
++ reg = <0x40000 0x40000>;
++ };
++ partition@0x80000 {
++ label = "kernel-nor";
++ reg = <0x80000 0x200000>;
++ };
++ partition@0x280000 {
++ label = "filesystem-nor";
++ reg = <0x240000 0x7d80000>;
++ };
++ };
++};
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index c127e75..80dd023 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -25,6 +25,11 @@
+ #include <linux/module.h>
+ #include <linux/interrupt.h>
+ #include <linux/platform_device.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_mtd.h>
++#include <linux/of_device.h>
++#include <linux/mtd/nand.h>
+
+ #include <linux/platform_data/mtd-nand-omap2.h>
+
+@@ -493,6 +498,37 @@ static int gpmc_cs_delete_mem(int cs)
+ return r;
+ }
+
++/**
++ * gpmc_cs_remap - remaps a chip-select physical base address
++ * @cs: chip-select to remap
++ * @base: physical base address to re-map chip-select to
++ *
++ * Re-maps a chip-select to a new physical base address specified by
++ * "base". Returns 0 on success and appropriate negative error code
++ * on failure.
++ */
++static int gpmc_cs_remap(int cs, u32 base)
++{
++ int ret;
++ u32 old_base, size;
++
++ if (cs > GPMC_CS_NUM)
++ return -ENODEV;
++ gpmc_cs_get_memconf(cs, &old_base, &size);
++ if (base == old_base)
++ return 0;
++ gpmc_cs_disable_mem(cs);
++ ret = gpmc_cs_delete_mem(cs);
++ if (ret < 0)
++ return ret;
++ ret = gpmc_cs_insert_mem(cs, base, size);
++ if (ret < 0)
++ return ret;
++ gpmc_cs_enable_mem(cs, base, size);
++
++ return 0;
++}
++
+ int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
+ {
+ struct resource *res = &gpmc_cs_mem[cs];
+@@ -1383,6 +1419,80 @@ static int gpmc_probe_onenand_child(struct platform_device *pdev,
+ }
+ #endif
+
++/**
++ * gpmc_probe_nor_child - configures the gpmc for a nor device
++ * @pdev: pointer to gpmc platform device
++ * @child: pointer to device-tree node for nor device
++ *
++ * Allocates and configures a GPMC chip-select for a NOR flash device.
++ * Returns 0 on success and appropriate negative error code on failure.
++ */
++static int gpmc_probe_nor_child(struct platform_device *pdev,
++ struct device_node *child)
++{
++ struct gpmc_settings gpmc_s;
++ struct gpmc_timings gpmc_t;
++ struct resource res;
++ unsigned long base;
++ int ret, cs;
++
++ if (of_property_read_u32(child, "reg", &cs) < 0) {
++ dev_err(&pdev->dev, "%s has no 'reg' property\n",
++ child->full_name);
++ return -ENODEV;
++ }
++
++ if (of_address_to_resource(child, 0, &res) < 0) {
++ dev_err(&pdev->dev, "%s has malformed 'reg' property\n",
++ child->full_name);
++ return -ENODEV;
++ }
++
++ ret = gpmc_cs_request(cs, resource_size(&res), &base);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs);
++ return ret;
++ }
++
++ /*
++ * FIXME: gpmc_cs_request() will map the CS to an arbitary
++ * location in the gpmc address space. When booting with
++ * device-tree we want the NOR flash to be mapped to the
++ * location specified in the device-tree blob. So remap the
++ * CS to this location. Once DT migration is complete should
++ * just make gpmc_cs_request() map a specific address.
++ */
++ ret = gpmc_cs_remap(cs, res.start);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "cannot remap GPMC CS %d to 0x%x\n",
++ cs, res.start);
++ goto err;
++ }
++
++ gpmc_read_settings_dt(child, &gpmc_s);
++
++ ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width);
++ if (ret < 0)
++ goto err;
++
++ ret = gpmc_cs_program_settings(cs, &gpmc_s);
++ if (ret < 0)
++ goto err;
++
++ gpmc_read_timings_dt(child, &gpmc_t);
++ gpmc_cs_set_timings(cs, &gpmc_t);
++
++ if (of_platform_device_create(child, NULL, &pdev->dev))
++ return 0;
++
++ dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name);
++
++err:
++ gpmc_cs_free(cs);
++
++ return ret;
++}
++
+ static int gpmc_probe_dt(struct platform_device *pdev)
+ {
+ int ret;
+@@ -1415,6 +1525,15 @@ static int gpmc_probe_dt(struct platform_device *pdev)
+ return ret;
+ }
+ }
++
++ for_each_node_by_name(child, "nor") {
++ ret = gpmc_probe_nor_child(pdev, child);
++ if (ret < 0) {
++ of_node_put(child);
++ return ret;
++ }
++ }
++
+ return 0;
+ }
+ #else
diff --git a/patches/linux-3.8.13/0490-ARM-OMAP2-Convert-NAND-to-retrieve-GPMC-settings-fro.patch b/patches/linux-3.8.13/0490-ARM-OMAP2-Convert-NAND-to-retrieve-GPMC-settings-fro.patch
new file mode 100644
index 0000000..20fabba
--- /dev/null
+++ b/patches/linux-3.8.13/0490-ARM-OMAP2-Convert-NAND-to-retrieve-GPMC-settings-fro.patch
@@ -0,0 +1,42 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Mon, 25 Feb 2013 11:36:47 -0600
+Subject: [PATCH] ARM: OMAP2+: Convert NAND to retrieve GPMC settings from DT
+
+When booting with device-tree, retrieve GPMC settings for NAND from
+the device-tree blob. This will allow us to remove all static settings
+stored in the gpmc-nand.c in the future once the migration to
+device-tree is complete.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ arch/arm/mach-omap2/gpmc-nand.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
+index 7c70752..026785c 100644
+--- a/arch/arm/mach-omap2/gpmc-nand.c
++++ b/arch/arm/mach-omap2/gpmc-nand.c
+@@ -136,12 +136,16 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
+ return err;
+ }
+
+- s.device_nand = true;
+-
+- /* Enable RD PIN Monitoring Reg */
+- if (gpmc_nand_data->dev_ready) {
+- s.wait_on_read = true;
+- s.wait_on_write = true;
++ if (gpmc_nand_data->of_node) {
++ gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
++ } else {
++ s.device_nand = true;
++
++ /* Enable RD PIN Monitoring Reg */
++ if (gpmc_nand_data->dev_ready) {
++ s.wait_on_read = true;
++ s.wait_on_write = true;
++ }
+ }
+
+ if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
diff --git a/patches/linux-3.8.13/0491-ARM-OMAP2-Convert-ONENAND-to-retrieve-GPMC-settings-.patch b/patches/linux-3.8.13/0491-ARM-OMAP2-Convert-ONENAND-to-retrieve-GPMC-settings-.patch
new file mode 100644
index 0000000..e94826a
--- /dev/null
+++ b/patches/linux-3.8.13/0491-ARM-OMAP2-Convert-ONENAND-to-retrieve-GPMC-settings-.patch
@@ -0,0 +1,122 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Mon, 25 Feb 2013 11:37:58 -0600
+Subject: [PATCH] ARM: OMAP2+: Convert ONENAND to retrieve GPMC settings from
+ DT
+
+When booting with device-tree, retrieve GPMC settings for ONENAND from
+the device-tree blob. This will allow us to remove all static settings
+stored in the gpmc-nand.c in the future once the migration to
+device-tree is complete.
+
+The user must now specify the ONENAND device width in the device-tree
+binding so that the GPMC can be programmed correctly. Therefore, update
+the device-tree binding documentation for ONENAND devices connected to
+the GPMC to reflect this.
+
+Please note that this does not include GPMC timings for ONENAND. The
+timings are being calculated at runtime.
+
+There is some legacy code that only enables read wait monitoring for
+non-OMAP3 devices. There are no known OMAP3 device issues that prevent
+this feature being enabled and so when booting with device-tree use the
+wait-monitoring settings described in the device-tree blob.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ .../devicetree/bindings/mtd/gpmc-onenand.txt | 46 ++++++++++++++++++++
+ arch/arm/mach-omap2/gpmc-onenand.c | 21 ++++++---
+ 2 files changed, 61 insertions(+), 6 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
+
+diff --git a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
+new file mode 100644
+index 0000000..b752942
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
+@@ -0,0 +1,46 @@
++Device tree bindings for GPMC connected OneNANDs
++
++GPMC connected OneNAND (found on OMAP boards) are represented as child nodes of
++the GPMC controller with a name of "onenand".
++
++All timing relevant properties as well as generic gpmc child properties are
++explained in a separate documents - please refer to
++Documentation/devicetree/bindings/bus/ti-gpmc.txt
++
++Required properties:
++
++ - reg: The CS line the peripheral is connected to
++ - gpmc,device-width Width of the ONENAND device connected to the GPMC
++ in bytes. Must be 1 or 2.
++
++Optional properties:
++
++ - dma-channel: DMA Channel index
++
++For inline partiton table parsing (optional):
++
++ - #address-cells: should be set to 1
++ - #size-cells: should be set to 1
++
++Example for an OMAP3430 board:
++
++ gpmc: gpmc@6e000000 {
++ compatible = "ti,omap3430-gpmc";
++ ti,hwmods = "gpmc";
++ reg = <0x6e000000 0x1000000>;
++ interrupts = <20>;
++ gpmc,num-cs = <8>;
++ gpmc,num-waitpins = <4>;
++ #address-cells = <2>;
++ #size-cells = <1>;
++
++ onenand@0 {
++ reg = <0 0 0>; /* CS0, offset 0 */
++ gpmc,device-width = <2>;
++
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ /* partitions go here */
++ };
++ };
+diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
+index dae6e05..1a2b84e 100644
+--- a/arch/arm/mach-omap2/gpmc-onenand.c
++++ b/arch/arm/mach-omap2/gpmc-onenand.c
+@@ -272,6 +272,10 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base)
+ struct gpmc_timings t;
+ int ret;
+
++ if (gpmc_onenand_data->of_node)
++ gpmc_read_settings_dt(gpmc_onenand_data->of_node,
++ &onenand_async);
++
+ omap2_onenand_set_async_mode(onenand_base);
+
+ omap2_onenand_calc_async_timings(&t);
+@@ -300,12 +304,17 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
+ set_onenand_cfg(onenand_base);
+ }
+
+- /*
+- * FIXME: Appears to be legacy code from initial ONENAND commit.
+- * Unclear what boards this is for and if this can be removed.
+- */
+- if (!cpu_is_omap34xx())
+- onenand_sync.wait_on_read = true;
++ if (gpmc_onenand_data->of_node) {
++ gpmc_read_settings_dt(gpmc_onenand_data->of_node,
++ &onenand_sync);
++ } else {
++ /*
++ * FIXME: Appears to be legacy code from initial ONENAND commit.
++ * Unclear what boards this is for and if this can be removed.
++ */
++ if (!cpu_is_omap34xx())
++ onenand_sync.wait_on_read = true;
++ }
+
+ omap2_onenand_calc_sync_timings(&t, gpmc_onenand_data->flags, freq);
+
diff --git a/patches/linux-3.8.13/0492-ARM-OMAP2-Detect-incorrectly-aligned-GPMC-base-addre.patch b/patches/linux-3.8.13/0492-ARM-OMAP2-Detect-incorrectly-aligned-GPMC-base-addre.patch
new file mode 100644
index 0000000..9ffb942
--- /dev/null
+++ b/patches/linux-3.8.13/0492-ARM-OMAP2-Detect-incorrectly-aligned-GPMC-base-addre.patch
@@ -0,0 +1,76 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Wed, 6 Mar 2013 12:00:10 -0600
+Subject: [PATCH] ARM: OMAP2+: Detect incorrectly aligned GPMC base address
+
+Each GPMC chip-select can be configured to map 16MB, 32MB, 64MB or 128MB
+of address space. The physical base address where a chip-select starts
+is also configurable and must be aligned on a boundary that is equal to
+or greater than the size of the address space mapped bt the chip-select.
+When enabling a GPMC chip-select, ensure that the base address is aligned
+to the appropriate boundary.
+
+Reported-by: Mark Jackson <mpfj-list@mimc.co.uk>
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ arch/arm/mach-omap2/gpmc.c | 22 +++++++++++++++++++---
+ 1 file changed, 19 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index 80dd023..9fed934 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -401,11 +401,18 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
+ return 0;
+ }
+
+-static void gpmc_cs_enable_mem(int cs, u32 base, u32 size)
++static int gpmc_cs_enable_mem(int cs, u32 base, u32 size)
+ {
+ u32 l;
+ u32 mask;
+
++ /*
++ * Ensure that base address is aligned on a
++ * boundary equal to or greater than size.
++ */
++ if (base & (size - 1))
++ return -EINVAL;
++
+ mask = (1 << GPMC_SECTION_SHIFT) - size;
+ l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+ l &= ~0x3f;
+@@ -414,6 +421,8 @@ static void gpmc_cs_enable_mem(int cs, u32 base, u32 size)
+ l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8;
+ l |= GPMC_CONFIG7_CSVALID;
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
++
++ return 0;
+ }
+
+ static void gpmc_cs_disable_mem(int cs)
+@@ -524,7 +533,9 @@ static int gpmc_cs_remap(int cs, u32 base)
+ ret = gpmc_cs_insert_mem(cs, base, size);
+ if (ret < 0)
+ return ret;
+- gpmc_cs_enable_mem(cs, base, size);
++ ret = gpmc_cs_enable_mem(cs, base, size);
++ if (ret < 0)
++ return ret;
+
+ return 0;
+ }
+@@ -554,7 +565,12 @@ int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
+ if (r < 0)
+ goto out;
+
+- gpmc_cs_enable_mem(cs, res->start, resource_size(res));
++ r = gpmc_cs_enable_mem(cs, res->start, resource_size(res));
++ if (r < 0) {
++ release_resource(res);
++ goto out;
++ }
++
+ *base = res->start;
+ gpmc_cs_set_reserved(cs, 1);
+ out:
diff --git a/patches/linux-3.8.13/0493-ARM-OMAP2-Remove-unnecesssary-GPMC-definitions-and-v.patch b/patches/linux-3.8.13/0493-ARM-OMAP2-Remove-unnecesssary-GPMC-definitions-and-v.patch
new file mode 100644
index 0000000..586d677
--- /dev/null
+++ b/patches/linux-3.8.13/0493-ARM-OMAP2-Remove-unnecesssary-GPMC-definitions-and-v.patch
@@ -0,0 +1,52 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Wed, 6 Mar 2013 14:12:59 -0600
+Subject: [PATCH] ARM: OMAP2+: Remove unnecesssary GPMC definitions and
+ variable
+
+With commit 21cc2bd (ARM: OMAP2+: Remove apollon board support) the
+variable "boot_rom_space" is now not needed and the code surrounding
+this variable can be cleaned up and simplified. Remove unnecessary
+definitions and clean-up the comment as well.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ arch/arm/mach-omap2/gpmc.c | 15 +++++----------
+ 1 file changed, 5 insertions(+), 10 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index 9fed934..3f87752 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -90,9 +90,7 @@
+ #define GPMC_CS_SIZE 0x30
+ #define GPMC_BCH_SIZE 0x10
+
+-#define GPMC_MEM_START 0x00000000
+ #define GPMC_MEM_END 0x3FFFFFFF
+-#define BOOT_ROM_SPACE 0x100000 /* 1MB */
+
+ #define GPMC_CHUNK_SHIFT 24 /* 16 MB */
+ #define GPMC_SECTION_SHIFT 28 /* 128 MB */
+@@ -788,16 +786,13 @@ static void gpmc_mem_exit(void)
+ static int gpmc_mem_init(void)
+ {
+ int cs, rc;
+- unsigned long boot_rom_space = 0;
+
+- /* never allocate the first page, to facilitate bug detection;
+- * even if we didn't boot from ROM.
++ /*
++ * The first 1MB of GPMC address space is typically mapped to
++ * the internal ROM. Never allocate the first page, to
++ * facilitate bug detection; even if we didn't boot from ROM.
+ */
+- boot_rom_space = BOOT_ROM_SPACE;
+- /* In apollon the CS0 is mapped as 0x0000 0000 */
+- if (machine_is_omap_apollon())
+- boot_rom_space = 0;
+- gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space;
++ gpmc_mem_root.start = SZ_1M;
+ gpmc_mem_root.end = GPMC_MEM_END;
+
+ /* Reserve all regions that has been set up by bootloader */
diff --git a/patches/linux-3.8.13/0494-ARM-OMAP2-Allow-GPMC-probe-to-complete-even-if-CS-ma.patch b/patches/linux-3.8.13/0494-ARM-OMAP2-Allow-GPMC-probe-to-complete-even-if-CS-ma.patch
new file mode 100644
index 0000000..709459c
--- /dev/null
+++ b/patches/linux-3.8.13/0494-ARM-OMAP2-Allow-GPMC-probe-to-complete-even-if-CS-ma.patch
@@ -0,0 +1,79 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Wed, 6 Mar 2013 14:36:47 -0600
+Subject: [PATCH] ARM: OMAP2+: Allow GPMC probe to complete even if CS mapping
+ fails
+
+When the GPMC driver is probed, we call gpmc_mem_init() to see which
+chip-selects have already been configured and enabled by the boot-loader
+and allocate space for them. If we fail to allocate space for one
+chip-select, then we return failure from the probe and the GPMC driver
+will not be available.
+
+Rather than render the GPMC useless for all GPMC devices, if we fail to
+allocate space for one chip-select print a warning and disable the
+chip-select. This way other GPMC clients can still be used.
+
+There is no downside to this approach, because all GPMC clients need to
+request a chip-select before they can use the GPMC and on requesting a
+chip-select, if memory has not already been reserved for the chip-select
+then it will be.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ arch/arm/mach-omap2/gpmc.c | 25 ++++++++-----------------
+ 1 file changed, 8 insertions(+), 17 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index 3f87752..5482d23 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -783,9 +783,9 @@ static void gpmc_mem_exit(void)
+
+ }
+
+-static int gpmc_mem_init(void)
++static void gpmc_mem_init(void)
+ {
+- int cs, rc;
++ int cs;
+
+ /*
+ * The first 1MB of GPMC address space is typically mapped to
+@@ -802,16 +802,13 @@ static int gpmc_mem_init(void)
+ if (!gpmc_cs_mem_enabled(cs))
+ continue;
+ gpmc_cs_get_memconf(cs, &base, &size);
+- rc = gpmc_cs_insert_mem(cs, base, size);
+- if (IS_ERR_VALUE(rc)) {
+- while (--cs >= 0)
+- if (gpmc_cs_mem_enabled(cs))
+- gpmc_cs_delete_mem(cs);
+- return rc;
++
++ if (gpmc_cs_insert_mem(cs, base, size)) {
++ pr_warn("%s: disabling cs %d mapped at 0x%x-0x%x\n",
++ __func__, cs, base, base + size);
++ gpmc_cs_disable_mem(cs);
+ }
+ }
+-
+- return 0;
+ }
+
+ static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
+@@ -1611,13 +1608,7 @@ static int gpmc_probe(struct platform_device *pdev)
+ dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l),
+ GPMC_REVISION_MINOR(l));
+
+- rc = gpmc_mem_init();
+- if (IS_ERR_VALUE(rc)) {
+- clk_disable_unprepare(gpmc_l3_clk);
+- clk_put(gpmc_l3_clk);
+- dev_err(gpmc_dev, "failed to reserve memory\n");
+- return rc;
+- }
++ gpmc_mem_init();
+
+ if (IS_ERR_VALUE(gpmc_setup_irq()))
+ dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
diff --git a/patches/linux-3.8.13/0495-ARM-OMAP2-return-ENODEV-if-GPMC-child-device-creatio.patch b/patches/linux-3.8.13/0495-ARM-OMAP2-return-ENODEV-if-GPMC-child-device-creatio.patch
new file mode 100644
index 0000000..8258f69
--- /dev/null
+++ b/patches/linux-3.8.13/0495-ARM-OMAP2-return-ENODEV-if-GPMC-child-device-creatio.patch
@@ -0,0 +1,34 @@
+From: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
+Date: Thu, 14 Mar 2013 16:09:20 +0100
+Subject: [PATCH] ARM: OMAP2+: return -ENODEV if GPMC child device creation
+ fails
+
+gpmc_probe_nor_child() calls of_platform_device_create() to create a
+platform device for the NOR child. If this function fails the value
+of ret is returned to the caller but this value is zero since it was
+assigned the return of a previous call to gpmc_cs_program_settings()
+that had to succeed or otherwise gpmc_probe_nor_child() would have
+returned before.
+
+This means that if of_platform_device_create() fails, 0 will be returned
+to the caller instead of an appropriate error code.
+
+Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+---
+ arch/arm/mach-omap2/gpmc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index 5482d23..e20c6d0 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -1494,6 +1494,7 @@ static int gpmc_probe_nor_child(struct platform_device *pdev,
+ return 0;
+
+ dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name);
++ ret = -ENODEV;
+
+ err:
+ gpmc_cs_free(cs);
diff --git a/patches/linux-3.8.13/0496-ARM-OMAP2-rename-gpmc_probe_nor_child-to-gpmc_probe_.patch b/patches/linux-3.8.13/0496-ARM-OMAP2-rename-gpmc_probe_nor_child-to-gpmc_probe_.patch
new file mode 100644
index 0000000..554a372
--- /dev/null
+++ b/patches/linux-3.8.13/0496-ARM-OMAP2-rename-gpmc_probe_nor_child-to-gpmc_probe_.patch
@@ -0,0 +1,52 @@
+From: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
+Date: Thu, 14 Mar 2013 16:09:21 +0100
+Subject: [PATCH] ARM: OMAP2+: rename gpmc_probe_nor_child() to
+ gpmc_probe_generic_child()
+
+The gpmc_probe_nor_child() function is used in the GPMC driver to
+configure the GPMC for a NOR child device node.
+
+But this function is quite generic and all the NOR specific configuration
+is made by the driver of the actual NOR flash memory used.
+
+Other Pseudo-SRAM devices such as ethernet controllers need a similar
+setup so by making this function generic it can be used for those too.
+
+Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+---
+ arch/arm/mach-omap2/gpmc.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index e20c6d0..780cb12 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -1428,14 +1428,14 @@ static int gpmc_probe_onenand_child(struct platform_device *pdev,
+ #endif
+
+ /**
+- * gpmc_probe_nor_child - configures the gpmc for a nor device
++ * gpmc_probe_generic_child - configures the gpmc for a child device
+ * @pdev: pointer to gpmc platform device
+- * @child: pointer to device-tree node for nor device
++ * @child: pointer to device-tree node for child device
+ *
+- * Allocates and configures a GPMC chip-select for a NOR flash device.
++ * Allocates and configures a GPMC chip-select for a child device.
+ * Returns 0 on success and appropriate negative error code on failure.
+ */
+-static int gpmc_probe_nor_child(struct platform_device *pdev,
++static int gpmc_probe_generic_child(struct platform_device *pdev,
+ struct device_node *child)
+ {
+ struct gpmc_settings gpmc_s;
+@@ -1536,7 +1536,7 @@ static int gpmc_probe_dt(struct platform_device *pdev)
+ }
+
+ for_each_node_by_name(child, "nor") {
+- ret = gpmc_probe_nor_child(pdev, child);
++ ret = gpmc_probe_generic_child(pdev, child);
+ if (ret < 0) {
+ of_node_put(child);
+ return ret;
diff --git a/patches/linux-3.8.13/0497-ARM-OMAP2-Add-GPMC-DT-support-for-Ethernet-child-nod.patch b/patches/linux-3.8.13/0497-ARM-OMAP2-Add-GPMC-DT-support-for-Ethernet-child-nod.patch
new file mode 100644
index 0000000..a2ef1af
--- /dev/null
+++ b/patches/linux-3.8.13/0497-ARM-OMAP2-Add-GPMC-DT-support-for-Ethernet-child-nod.patch
@@ -0,0 +1,142 @@
+From: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
+Date: Thu, 14 Mar 2013 22:54:11 +0100
+Subject: [PATCH] ARM: OMAP2+: Add GPMC DT support for Ethernet child nodes
+
+Besides being used to interface with external memory devices,
+the General-Purpose Memory Controller can be used to connect
+Pseudo-SRAM devices such as ethernet controllers to OMAP2+
+processors using the TI GPMC as a data bus.
+
+This patch allows an ethernet chip to be defined as an GPMC
+child device node.
+
+Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+---
+ Documentation/devicetree/bindings/net/gpmc-eth.txt | 97 ++++++++++++++++++++
+ arch/arm/mach-omap2/gpmc.c | 8 ++
+ 2 files changed, 105 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/net/gpmc-eth.txt
+
+diff --git a/Documentation/devicetree/bindings/net/gpmc-eth.txt b/Documentation/devicetree/bindings/net/gpmc-eth.txt
+new file mode 100644
+index 0000000..24cb4e4
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/gpmc-eth.txt
+@@ -0,0 +1,97 @@
++Device tree bindings for Ethernet chip connected to TI GPMC
++
++Besides being used to interface with external memory devices, the
++General-Purpose Memory Controller can be used to connect Pseudo-SRAM devices
++such as ethernet controllers to processors using the TI GPMC as a data bus.
++
++Ethernet controllers connected to TI GPMC are represented as child nodes of
++the GPMC controller with an "ethernet" name.
++
++All timing relevant properties as well as generic GPMC child properties are
++explained in a separate documents. Please refer to
++Documentation/devicetree/bindings/bus/ti-gpmc.txt
++
++For the properties relevant to the ethernet controller connected to the GPMC
++refer to the binding documentation of the device. For example, the documentation
++for the SMSC 911x is Documentation/devicetree/bindings/net/smsc911x.txt
++
++Child nodes need to specify the GPMC bus address width using the "bank-width"
++property but is possible that an ethernet controller also has a property to
++specify the I/O registers address width. Even when the GPMC has a maximum 16-bit
++address width, it supports devices with 32-bit word registers.
++For example with an SMSC LAN911x/912x controller connected to the TI GPMC on an
++OMAP2+ board, "bank-width = <2>;" and "reg-io-width = <4>;".
++
++Required properties:
++- bank-width: Address width of the device in bytes. GPMC supports 8-bit
++ and 16-bit devices and so must be either 1 or 2 bytes.
++- compatible: Compatible string property for the ethernet child device.
++- gpmc,cs-on: Chip-select assertion time
++- gpmc,cs-rd-off: Chip-select de-assertion time for reads
++- gpmc,cs-wr-off: Chip-select de-assertion time for writes
++- gpmc,oe-on: Output-enable assertion time
++- gpmc,oe-off Output-enable de-assertion time
++- gpmc,we-on: Write-enable assertion time
++- gpmc,we-off: Write-enable de-assertion time
++- gpmc,access: Start cycle to first data capture (read access)
++- gpmc,rd-cycle: Total read cycle time
++- gpmc,wr-cycle: Total write cycle time
++- reg: Chip-select, base address (relative to chip-select)
++ and size of the memory mapped for the device.
++ Note that base address will be typically 0 as this
++ is the start of the chip-select.
++
++Optional properties:
++- gpmc,XXX Additional GPMC timings and settings parameters. See
++ Documentation/devicetree/bindings/bus/ti-gpmc.txt
++
++Example:
++
++gpmc: gpmc@6e000000 {
++ compatible = "ti,omap3430-gpmc";
++ ti,hwmods = "gpmc";
++ reg = <0x6e000000 0x1000>;
++ interrupts = <20>;
++ gpmc,num-cs = <8>;
++ gpmc,num-waitpins = <4>;
++ #address-cells = <2>;
++ #size-cells = <1>;
++
++ ranges = <5 0 0x2c000000 0x1000000>;
++
++ ethernet@5,0 {
++ compatible = "smsc,lan9221", "smsc,lan9115";
++ reg = <5 0 0xff>;
++ bank-width = <2>;
++
++ gpmc,mux-add-data;
++ gpmc,cs-on = <0>;
++ gpmc,cs-rd-off = <186>;
++ gpmc,cs-wr-off = <186>;
++ gpmc,adv-on = <12>;
++ gpmc,adv-rd-off = <48>;
++ gpmc,adv-wr-off = <48>;
++ gpmc,oe-on = <54>;
++ gpmc,oe-off = <168>;
++ gpmc,we-on = <54>;
++ gpmc,we-off = <168>;
++ gpmc,rd-cycle = <186>;
++ gpmc,wr-cycle = <186>;
++ gpmc,access = <114>;
++ gpmc,page-burst-access = <6>;
++ gpmc,bus-turnaround = <12>;
++ gpmc,cycle2cycle-delay = <18>;
++ gpmc,wr-data-mux-bus = <90>;
++ gpmc,wr-access = <186>;
++ gpmc,cycle2cycle-samecsen;
++ gpmc,cycle2cycle-diffcsen;
++
++ interrupt-parent = <&gpio6>;
++ interrupts = <16>;
++ vmmc-supply = <&vddvario>;
++ vmmc_aux-supply = <&vdd33a>;
++ reg-io-width = <4>;
++
++ smsc,save-mac-address;
++ };
++};
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index 780cb12..52c32c9 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -1543,6 +1543,14 @@ static int gpmc_probe_dt(struct platform_device *pdev)
+ }
+ }
+
++ for_each_node_by_name(child, "ethernet") {
++ ret = gpmc_probe_generic_child(pdev, child);
++ if (ret < 0) {
++ of_node_put(child);
++ return ret;
++ }
++ }
++
+ return 0;
+ }
+ #else
diff --git a/patches/linux-3.8.4/0382-mtd-omap-nand-pass-device_node-in-platform-data.patch b/patches/linux-3.8.13/0498-mtd-omap-nand-pass-device_node-in-platform-data.patch
index 640d516..42030b9 100644
--- a/patches/linux-3.8.4/0382-mtd-omap-nand-pass-device_node-in-platform-data.patch
+++ b/patches/linux-3.8.13/0498-mtd-omap-nand-pass-device_node-in-platform-data.patch
@@ -10,6 +10,9 @@ can be parsed.
For non-DT boards, this change has no effect.
Signed-off-by: Daniel Mack <zonque@gmail.com>
+Acked-by: Grant Likely <grant.likely@secretlab.ca>
+Acked-by: Artem Bityutskiy <dedekind1@gmail.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
---
drivers/mtd/nand/omap2.c | 4 +++-
include/linux/platform_data/mtd-nand-omap2.h | 4 +++-
diff --git a/patches/linux-3.8.4/0383-ARM-OMAP-gpmc-nand-drop-__init-annotation.patch b/patches/linux-3.8.13/0499-ARM-OMAP-gpmc-nand-drop-__init-annotation.patch
index d9ec84c..9fd276d 100644
--- a/patches/linux-3.8.4/0383-ARM-OMAP-gpmc-nand-drop-__init-annotation.patch
+++ b/patches/linux-3.8.13/0499-ARM-OMAP-gpmc-nand-drop-__init-annotation.patch
@@ -1,5 +1,5 @@
From: Daniel Mack <zonque@gmail.com>
-Date: Fri, 14 Dec 2012 10:36:42 +0000
+Date: Fri, 14 Dec 2012 11:36:42 +0100
Subject: [PATCH] ARM: OMAP: gpmc-nand: drop __init annotation
gpmc_nand_init() will be called from another driver's probe() function,
@@ -7,15 +7,17 @@ so the easiest way to prevent section mismatches is to drop the
annotation here.
Signed-off-by: Daniel Mack <zonque@gmail.com>
+Acked-by: Grant Likely <grant.likely@secretlab.ca>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/mach-omap2/gpmc-nand.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
-index db969a5..3059f5e 100644
+index 026785c..b966784 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
-@@ -89,7 +89,7 @@ static int omap2_nand_gpmc_retime(
+@@ -81,7 +81,7 @@ static int omap2_nand_gpmc_retime(
return 0;
}
@@ -24,7 +26,7 @@ index db969a5..3059f5e 100644
{
/* support only OMAP3 class */
if (!cpu_is_omap34xx()) {
-@@ -110,8 +110,8 @@ static bool __init gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
+@@ -102,8 +102,8 @@ static bool __init gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
return 1;
}
@@ -34,4 +36,4 @@ index db969a5..3059f5e 100644
+ struct gpmc_timings *gpmc_t)
{
int err = 0;
- struct device *dev = &gpmc_nand_device.dev;
+ struct gpmc_settings s;
diff --git a/patches/linux-3.8.4/0384-ARM-OMAP-gpmc-enable-hwecc-for-AM33xx-SoCs.patch b/patches/linux-3.8.13/0500-ARM-OMAP-gpmc-enable-hwecc-for-AM33xx-SoCs.patch
index 2292de8..39b082a 100644
--- a/patches/linux-3.8.4/0384-ARM-OMAP-gpmc-enable-hwecc-for-AM33xx-SoCs.patch
+++ b/patches/linux-3.8.13/0500-ARM-OMAP-gpmc-enable-hwecc-for-AM33xx-SoCs.patch
@@ -1,20 +1,22 @@
From: Daniel Mack <zonque@gmail.com>
-Date: Fri, 14 Dec 2012 10:36:43 +0000
+Date: Fri, 14 Dec 2012 11:36:43 +0100
Subject: [PATCH] ARM: OMAP: gpmc: enable hwecc for AM33xx SoCs
The am33xx is capable of handling bch error correction modes, so
enable that feature in the driver.
Signed-off-by: Daniel Mack <zonque@gmail.com>
+Acked-by: Grant Likely <grant.likely@secretlab.ca>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/mach-omap2/gpmc-nand.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
-index 3059f5e..afc1e8c 100644
+index b966784..d9c2719 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
-@@ -92,17 +92,18 @@ static int omap2_nand_gpmc_retime(
+@@ -84,17 +84,18 @@ static int omap2_nand_gpmc_retime(
static bool gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
{
/* support only OMAP3 class */
diff --git a/patches/linux-3.8.4/0381-ARM-OMAP-gpmc-don-t-create-devices-from-initcall-on-.patch b/patches/linux-3.8.13/0501-ARM-OMAP-gpmc-don-t-create-devices-from-initcall-on-.patch
index 7b78b84..57af696 100644
--- a/patches/linux-3.8.4/0381-ARM-OMAP-gpmc-don-t-create-devices-from-initcall-on-.patch
+++ b/patches/linux-3.8.13/0501-ARM-OMAP-gpmc-don-t-create-devices-from-initcall-on-.patch
@@ -1,20 +1,22 @@
From: Daniel Mack <zonque@gmail.com>
-Date: Fri, 14 Dec 2012 10:36:40 +0000
+Date: Fri, 14 Dec 2012 11:36:40 +0100
Subject: [PATCH] ARM: OMAP: gpmc: don't create devices from initcall on DT
On DT driven boards, the gpmc node will match the driver. Hence, there's
no need to do that unconditionally from the initcall.
Signed-off-by: Daniel Mack <zonque@gmail.com>
+Acked-by: Grant Likely <grant.likely@secretlab.ca>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/mach-omap2/gpmc.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
-index 8033cb7..1f0ec79 100644
+index 52c32c9..de43b61 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
-@@ -1214,6 +1214,13 @@ static int __init omap_gpmc_init(void)
+@@ -1676,6 +1676,13 @@ static int __init omap_gpmc_init(void)
struct platform_device *pdev;
char *oh_name = "gpmc";
diff --git a/patches/linux-3.8.13/0502-ARM-OMAP2-gpmc-onenand-drop-__init-annotation.patch b/patches/linux-3.8.13/0502-ARM-OMAP2-gpmc-onenand-drop-__init-annotation.patch
new file mode 100644
index 0000000..c54bfd9
--- /dev/null
+++ b/patches/linux-3.8.13/0502-ARM-OMAP2-gpmc-onenand-drop-__init-annotation.patch
@@ -0,0 +1,26 @@
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Fri, 25 Jan 2013 09:23:10 -0300
+Subject: [PATCH] ARM: OMAP2+: gpmc-onenand: drop __init annotation
+
+gpmc_onenand_init() will be called from another driver's probe() function,
+so drop the __init annotation, in order to prevent section mismatches.
+
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+---
+ arch/arm/mach-omap2/gpmc-onenand.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
+index 1a2b84e..3df9230 100644
+--- a/arch/arm/mach-omap2/gpmc-onenand.c
++++ b/arch/arm/mach-omap2/gpmc-onenand.c
+@@ -354,7 +354,7 @@ static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
+ return ret;
+ }
+
+-void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
++void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
+ {
+ int err;
+ struct device *dev = &gpmc_onenand_device.dev;
diff --git a/patches/linux-3.8.13/0503-gpmc-Add-missing-gpmc-includes.patch b/patches/linux-3.8.13/0503-gpmc-Add-missing-gpmc-includes.patch
new file mode 100644
index 0000000..e205028
--- /dev/null
+++ b/patches/linux-3.8.13/0503-gpmc-Add-missing-gpmc-includes.patch
@@ -0,0 +1,22 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Tue, 23 Apr 2013 20:14:46 +0300
+Subject: [PATCH] gpmc: Add missing gpmc includes.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ arch/arm/mach-omap2/gpmc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index de43b61..6f9fb7a 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -39,6 +39,8 @@
+ #include "common.h"
+ #include "omap_device.h"
+ #include "gpmc.h"
++#include "gpmc-nand.h"
++#include "gpmc-onenand.h"
+
+ #define DEVICE_NAME "omap-gpmc"
+
diff --git a/patches/linux-3.8.13/0504-mtd-omap-onenand-pass-device_node-in-platform-data.patch b/patches/linux-3.8.13/0504-mtd-omap-onenand-pass-device_node-in-platform-data.patch
new file mode 100644
index 0000000..a6f1782
--- /dev/null
+++ b/patches/linux-3.8.13/0504-mtd-omap-onenand-pass-device_node-in-platform-data.patch
@@ -0,0 +1,54 @@
+From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Date: Fri, 25 Jan 2013 09:23:09 -0300
+Subject: [PATCH] mtd: omap-onenand: pass device_node in platform data
+
+Pass an optional device_node pointer in the platform data,
+which in turn will be put into a mtd_part_parser_data.
+This way, code that sets up the platform devices can pass
+along the node from DT so that the partitions can be parsed.
+
+For non-DT boards, this change has no effect.
+
+Acked-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
+Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+---
+ drivers/mtd/onenand/omap2.c | 4 +++-
+ include/linux/platform_data/mtd-onenand-omap2.h | 3 +++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
+index 065f3fe..eec2aed 100644
+--- a/drivers/mtd/onenand/omap2.c
++++ b/drivers/mtd/onenand/omap2.c
+@@ -637,6 +637,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
+ struct onenand_chip *this;
+ int r;
+ struct resource *res;
++ struct mtd_part_parser_data ppdata = {};
+
+ pdata = pdev->dev.platform_data;
+ if (pdata == NULL) {
+@@ -767,7 +768,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
+ if ((r = onenand_scan(&c->mtd, 1)) < 0)
+ goto err_release_regulator;
+
+- r = mtd_device_parse_register(&c->mtd, NULL, NULL,
++ ppdata.of_node = pdata->of_node;
++ r = mtd_device_parse_register(&c->mtd, NULL, &ppdata,
+ pdata ? pdata->parts : NULL,
+ pdata ? pdata->nr_parts : 0);
+ if (r)
+diff --git a/include/linux/platform_data/mtd-onenand-omap2.h b/include/linux/platform_data/mtd-onenand-omap2.h
+index 685af7e..e9a9fb1 100644
+--- a/include/linux/platform_data/mtd-onenand-omap2.h
++++ b/include/linux/platform_data/mtd-onenand-omap2.h
+@@ -29,5 +29,8 @@ struct omap_onenand_platform_data {
+ u8 flags;
+ u8 regulator_can_sleep;
+ u8 skip_initial_unlocking;
++
++ /* for passing the partitions */
++ struct device_node *of_node;
+ };
+ #endif
diff --git a/patches/linux-3.8.13/0505-ARM-OMAP2-Convert-ONENAND-to-use-gpmc_cs_program_set.patch b/patches/linux-3.8.13/0505-ARM-OMAP2-Convert-ONENAND-to-use-gpmc_cs_program_set.patch
new file mode 100644
index 0000000..0d3179f
--- /dev/null
+++ b/patches/linux-3.8.13/0505-ARM-OMAP2-Convert-ONENAND-to-use-gpmc_cs_program_set.patch
@@ -0,0 +1,44 @@
+From: Jon Hunter <jon-hunter@ti.com>
+Date: Thu, 21 Feb 2013 12:42:22 -0600
+Subject: [PATCH] ARM: OMAP2+: Convert ONENAND to use
+ gpmc_cs_program_settings()
+
+Convert the OMAP2+ ONENAND code to use the gpmc_cs_program_settings()
+function for configuring the various GPMC options instead of directly
+programming the CONFIG1 register.
+
+Signed-off-by: Jon Hunter <jon-hunter@ti.com>
+Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+
+Conflicts:
+ arch/arm/mach-omap2/gpmc-onenand.c
+---
+ arch/arm/mach-omap2/gpmc-onenand.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
+index 3df9230..64b5a83 100644
+--- a/arch/arm/mach-omap2/gpmc-onenand.c
++++ b/arch/arm/mach-omap2/gpmc-onenand.c
+@@ -284,8 +284,8 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base)
+ if (ret < 0)
+ return ret;
+
+- ret = gpmc_set_async_mode(gpmc_onenand_data->cs, &t);
+- if (IS_ERR_VALUE(ret))
++ ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t);
++ if (ret < 0)
+ return ret;
+
+ omap2_onenand_set_async_mode(onenand_base);
+@@ -322,8 +322,8 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
+ if (ret < 0)
+ return ret;
+
+- ret = gpmc_set_sync_mode(gpmc_onenand_data->cs, &t);
+- if (IS_ERR_VALUE(ret))
++ ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t);
++ if (ret < 0)
+ return ret;
+
+ set_onenand_cfg(onenand_base);
diff --git a/patches/linux-3.8.13/0506-omap-gpmc-Various-driver-fixes.patch b/patches/linux-3.8.13/0506-omap-gpmc-Various-driver-fixes.patch
new file mode 100644
index 0000000..e862db3
--- /dev/null
+++ b/patches/linux-3.8.13/0506-omap-gpmc-Various-driver-fixes.patch
@@ -0,0 +1,203 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Fri, 26 Apr 2013 01:21:49 +0300
+Subject: [PATCH] omap: gpmc: Various driver fixes
+
+Various fixes:
+
+* clk_activation option added
+* pinctrl support add
+* Add camera device
+* Fix child node handling
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ arch/arm/mach-omap2/gpmc.c | 94 +++++++++++++++++++++++---------------------
+ arch/arm/mach-omap2/gpmc.h | 1 +
+ 2 files changed, 51 insertions(+), 44 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index 6f9fb7a..993cb5e 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -30,6 +30,7 @@
+ #include <linux/of_mtd.h>
+ #include <linux/of_device.h>
+ #include <linux/mtd/nand.h>
++#include <linux/pinctrl/consumer.h>
+
+ #include <linux/platform_data/mtd-nand-omap2.h>
+
+@@ -1213,6 +1214,8 @@ int gpmc_cs_program_settings(int cs, struct gpmc_settings *p)
+ config1 |= GPMC_CONFIG1_PAGE_LEN(p->burst_len >> 3);
+ config1 |= p->burst_wrap ? GPMC_CONFIG1_WRAPBURST_SUPP : 0;
+ }
++ if (p->clk_activation)
++ config1 |= GPMC_CONFIG1_CLKACTIVATIONTIME(p->clk_activation);
+
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1);
+
+@@ -1249,6 +1252,7 @@ void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p)
+ p->device_nand = of_property_read_bool(np, "gpmc,device-nand");
+ of_property_read_u32(np, "gpmc,device-width", &p->device_width);
+ of_property_read_u32(np, "gpmc,mux-add-data", &p->mux_add_data);
++ of_property_read_u32(np, "gpmc,clk-activation", &p->clk_activation);
+
+ if (!of_property_read_u32(np, "gpmc,burst-length", &p->burst_len)) {
+ p->burst_wrap = of_property_read_bool(np, "gpmc,burst-wrap");
+@@ -1464,30 +1468,40 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
+ return ret;
+ }
+
+- /*
+- * FIXME: gpmc_cs_request() will map the CS to an arbitary
+- * location in the gpmc address space. When booting with
+- * device-tree we want the NOR flash to be mapped to the
+- * location specified in the device-tree blob. So remap the
+- * CS to this location. Once DT migration is complete should
+- * just make gpmc_cs_request() map a specific address.
+- */
+- ret = gpmc_cs_remap(cs, res.start);
+- if (ret < 0) {
+- dev_err(&pdev->dev, "cannot remap GPMC CS %d to 0x%x\n",
+- cs, res.start);
+- goto err;
++ if (!of_property_read_bool(child, "gpmc,no-remap")) {
++ /*
++ * FIXME: gpmc_cs_request() will map the CS to an arbitary
++ * location in the gpmc address space. When booting with
++ * device-tree we want the NOR flash to be mapped to the
++ * location specified in the device-tree blob. So remap the
++ * CS to this location. Once DT migration is complete should
++ * just make gpmc_cs_request() map a specific address.
++ */
++ ret = gpmc_cs_remap(cs, res.start);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "cannot remap GPMC CS %d to 0x%x\n",
++ cs, res.start);
++ goto err;
++ }
++
++ dev_info(&pdev->dev, "GPMC%d: res.start=0x%x\n", cs, (unsigned int)res.start);
+ }
+
+ gpmc_read_settings_dt(child, &gpmc_s);
+
+ ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width);
+- if (ret < 0)
++ if (ret < 0) {
++ dev_err(&pdev->dev, "%s has no 'bank-width' property\n",
++ child->full_name);
+ goto err;
++ }
+
+ ret = gpmc_cs_program_settings(cs, &gpmc_s);
+- if (ret < 0)
++ if (ret < 0) {
++ dev_err(&pdev->dev, "%s failed to program settings\n",
++ child->full_name);
+ goto err;
++ }
+
+ gpmc_read_timings_dt(child, &gpmc_t);
+ gpmc_cs_set_timings(cs, &gpmc_t);
+@@ -1507,46 +1521,31 @@ err:
+ static int gpmc_probe_dt(struct platform_device *pdev)
+ {
+ int ret;
++ struct device_node *node = pdev->dev.of_node;
+ struct device_node *child;
+- const struct of_device_id *of_id =
+- of_match_device(gpmc_dt_ids, &pdev->dev);
+-
+- if (!of_id)
+- return 0;
+
+- ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins",
++ ret = of_property_read_u32(node, "gpmc,num-waitpins",
+ &gpmc_nr_waitpins);
+ if (ret < 0) {
+ pr_err("%s: number of wait pins not found!\n", __func__);
+ return ret;
+ }
+
+- for_each_node_by_name(child, "nand") {
+- ret = gpmc_probe_nand_child(pdev, child);
+- if (ret < 0) {
+- of_node_put(child);
+- return ret;
+- }
+- }
++ for_each_available_child_of_node(node, child) {
+
+- for_each_node_by_name(child, "onenand") {
+- ret = gpmc_probe_onenand_child(pdev, child);
+- if (ret < 0) {
+- of_node_put(child);
+- return ret;
+- }
+- }
++ if (!child->name)
++ continue;
+
+- for_each_node_by_name(child, "nor") {
+- ret = gpmc_probe_generic_child(pdev, child);
+- if (ret < 0) {
+- of_node_put(child);
+- return ret;
+- }
+- }
++ ret = 0;
++ if (of_node_cmp(child->name, "nand") == 0)
++ ret = gpmc_probe_nand_child(pdev, child);
++ else if (of_node_cmp(child->name, "onenand") == 0)
++ ret = gpmc_probe_onenand_child(pdev, child);
++ else if (of_node_cmp(child->name, "nor") == 0 ||
++ of_node_cmp(child->name, "ethernet") == 0 ||
++ of_node_cmp(child->name, "camera") == 0)
++ ret = gpmc_probe_generic_child(pdev, child);
+
+- for_each_node_by_name(child, "ethernet") {
+- ret = gpmc_probe_generic_child(pdev, child);
+ if (ret < 0) {
+ of_node_put(child);
+ return ret;
+@@ -1567,6 +1566,11 @@ static int gpmc_probe(struct platform_device *pdev)
+ int rc;
+ u32 l;
+ struct resource *res;
++ struct pinctrl *pinctrl;
++
++ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
++ if (IS_ERR(pinctrl))
++ dev_warn(&pdev->dev, "unable to select pin group\n");
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL)
+@@ -1637,6 +1641,7 @@ static int gpmc_probe(struct platform_device *pdev)
+ dev_err(gpmc_dev, "failed to probe DT parameters\n");
+ return rc;
+ }
++ dev_info(gpmc_dev, "loaded OK\n");
+
+ return 0;
+ }
+@@ -1655,6 +1660,7 @@ static struct platform_driver gpmc_driver = {
+ .driver = {
+ .name = DEVICE_NAME,
+ .owner = THIS_MODULE,
++ .of_match_table = of_match_ptr(gpmc_dt_ids),
+ },
+ };
+
+diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
+index 707f6d5..b329bb8 100644
+--- a/arch/arm/mach-omap2/gpmc.h
++++ b/arch/arm/mach-omap2/gpmc.h
+@@ -205,6 +205,7 @@ struct gpmc_settings {
+ u32 device_width; /* device bus width (8 or 16 bit) */
+ u32 mux_add_data; /* multiplex address & data */
+ u32 wait_pin; /* wait-pin to be used */
++ u32 clk_activation; /* clock activation time */
+ };
+
+ extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
diff --git a/patches/linux-3.8.13/0507-gpmc-Add-DT-node-for-gpmc-on-am33xx.patch b/patches/linux-3.8.13/0507-gpmc-Add-DT-node-for-gpmc-on-am33xx.patch
new file mode 100644
index 0000000..76f7476
--- /dev/null
+++ b/patches/linux-3.8.13/0507-gpmc-Add-DT-node-for-gpmc-on-am33xx.patch
@@ -0,0 +1,35 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 1 May 2013 18:38:25 +0300
+Subject: [PATCH] gpmc: Add DT node for gpmc on am33xx
+
+Add am33xx gpmc device.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ arch/arm/boot/dts/am33xx.dtsi | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
+index 6c24c9b..76fa03b 100644
+--- a/arch/arm/boot/dts/am33xx.dtsi
++++ b/arch/arm/boot/dts/am33xx.dtsi
+@@ -399,6 +399,19 @@
+
+ };
+
++ gpmc: gpmc@50000000 {
++ compatible = "ti,am3352-gpmc";
++ ti,hwmods = "gpmc";
++ reg = <0x50000000 0x01000000>;
++ interrupts = <100>;
++ gpmc,num-cs = <7>;
++ gpmc,num-waitpins = <2>;
++ #address-cells = <2>;
++ #size-cells = <1>;
++
++ status = "disabled";
++ };
++
+ nop-phy@0 {
+ compatible = "nop-xceiv-usb";
+ };
diff --git a/patches/linux-3.8.13/0508-CHROMIUM-Input-atmel_mxt_ts-refactor-i2c-error-handl.patch b/patches/linux-3.8.13/0508-CHROMIUM-Input-atmel_mxt_ts-refactor-i2c-error-handl.patch
new file mode 100644
index 0000000..24d0ae0
--- /dev/null
+++ b/patches/linux-3.8.13/0508-CHROMIUM-Input-atmel_mxt_ts-refactor-i2c-error-handl.patch
@@ -0,0 +1,163 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Wed, 19 Dec 2012 17:22:16 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - refactor i2c error handling
+
+A recent patch refactored i2c error handling in the register read/write
+path. This adds similar handling to the other i2c paths used in fw_update
+and bootloader state detection.
+
+The generic i2c layer can return values indicating a partial transaction.
+From the atmel_mxt driver's perspective, this is an IO error, so we use
+some helper functions to convert these partial transfers to -EIO in a
+uniform way. Other error codes might still be useful, though, so we pass
+them up unmodified.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+Change-Id: I59eabbb80dea610a89c01a3be06f0d165f4b4431
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 92 ++++++++++++++++++------------
+ 1 file changed, 54 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index d04f810..a222bd8 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -324,16 +324,62 @@ static void mxt_dump_message(struct device *dev,
+ message->reportid, 7, message->message);
+ }
+
++static int mxt_i2c_recv(struct i2c_client *client, u8 *buf, size_t count)
++{
++ int ret;
++
++ ret = i2c_master_recv(client, buf, count);
++ if (ret == count) {
++ ret = 0;
++ } else if (ret != count) {
++ ret = (ret < 0) ? ret : -EIO;
++ dev_err(&client->dev, "i2c recv failed (%d)\n", ret);
++ }
++
++ return ret;
++}
++
++static int mxt_i2c_send(struct i2c_client *client, const u8 *buf, size_t count)
++{
++ int ret;
++
++ ret = i2c_master_send(client, buf, count);
++ if (ret == count) {
++ ret = 0;
++ } else if (ret != count) {
++ ret = (ret < 0) ? ret : -EIO;
++ dev_err(&client->dev, "i2c send failed (%d)\n", ret);
++ }
++
++ return ret;
++}
++
++static int mxt_i2c_transfer(struct i2c_client *client, struct i2c_msg *msgs,
++ size_t count)
++{
++ int ret;
++
++ ret = i2c_transfer(client->adapter, msgs, count);
++ if (ret == count) {
++ ret = 0;
++ } else {
++ ret = (ret < 0) ? ret : -EIO;
++ dev_err(&client->dev, "i2c transfer failed (%d)\n", ret);
++ }
++
++ return ret;
++}
++
+ static int mxt_check_bootloader(struct i2c_client *client,
+ unsigned int state)
+ {
+ u8 val;
++ int ret;
+
+ recheck:
+- if (i2c_master_recv(client, &val, 1) != 1) {
+- dev_err(&client->dev, "%s: i2c recv failed\n", __func__);
+- return -EIO;
+- }
++ ret = mxt_i2c_recv(client, &val, 1);
++ if (ret)
++ return ret;
+
+ switch (state) {
+ case MXT_WAITING_BOOTLOAD_CMD:
+@@ -363,23 +409,13 @@ static int mxt_unlock_bootloader(struct i2c_client *client)
+ buf[0] = MXT_UNLOCK_CMD_LSB;
+ buf[1] = MXT_UNLOCK_CMD_MSB;
+
+- if (i2c_master_send(client, buf, 2) != 2) {
+- dev_err(&client->dev, "%s: i2c send failed\n", __func__);
+- return -EIO;
+- }
+-
+- return 0;
++ return mxt_i2c_send(client, buf, 2);
+ }
+
+ static int mxt_fw_write(struct i2c_client *client,
+ const u8 *data, unsigned int frame_size)
+ {
+- if (i2c_master_send(client, data, frame_size) != frame_size) {
+- dev_err(&client->dev, "%s: i2c send failed\n", __func__);
+- return -EIO;
+- }
+-
+- return 0;
++ return mxt_i2c_send(client, data, frame_size);
+ }
+
+ static int __mxt_read_reg(struct i2c_client *client,
+@@ -387,7 +423,6 @@ static int __mxt_read_reg(struct i2c_client *client,
+ {
+ struct i2c_msg xfer[2];
+ u8 buf[2];
+- int ret;
+
+ buf[0] = reg & 0xff;
+ buf[1] = (reg >> 8) & 0xff;
+@@ -404,17 +439,7 @@ static int __mxt_read_reg(struct i2c_client *client,
+ xfer[1].len = len;
+ xfer[1].buf = val;
+
+- ret = i2c_transfer(client->adapter, xfer, 2);
+- if (ret == 2) {
+- ret = 0;
+- } else {
+- if (ret >= 0)
+- ret = -EIO;
+- dev_err(&client->dev, "%s: i2c transfer failed (%d)\n",
+- __func__, ret);
+- }
+-
+- return ret;
++ return mxt_i2c_transfer(client, xfer, 2);
+ }
+
+ static int mxt_read_reg(struct i2c_client *client, u16 reg, u8 *val)
+@@ -438,16 +463,7 @@ static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len,
+ buf[1] = (reg >> 8) & 0xff;
+ memcpy(&buf[2], val, len);
+
+- ret = i2c_master_send(client, buf, count);
+- if (ret == count) {
+- ret = 0;
+- } else {
+- if (ret >= 0)
+- ret = -EIO;
+- dev_err(&client->dev, "%s: i2c send failed (%d)\n",
+- __func__, ret);
+- }
+-
++ ret = mxt_i2c_send(client, buf, count);
+ kfree(buf);
+ return ret;
+ }
diff --git a/patches/linux-3.8.13/0509-CHROMIUM-Input-atmel_mxt_ts-register-input-device-be.patch b/patches/linux-3.8.13/0509-CHROMIUM-Input-atmel_mxt_ts-register-input-device-be.patch
new file mode 100644
index 0000000..5a0fd3d
--- /dev/null
+++ b/patches/linux-3.8.13/0509-CHROMIUM-Input-atmel_mxt_ts-register-input-device-be.patch
@@ -0,0 +1,109 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Fri, 27 Apr 2012 22:08:52 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - register input device before
+ request_irq
+
+As soon as the irq is request, input event interrupts could occur that
+the isr should handle. Similarly, if there are input events queued up
+in the device output buffer, it will send them immediately when we
+drain the message buffer with mxt_handle_messages.
+
+Therefore, register the input device before enabling the irq (or handling
+messages).
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chromium-os:27713
+TEST=cat /sys/bus/i2c/drivers/atmel_mxt_ts/2-004b/object
+
+Change-Id: I16172901d963cd2e60533e12e455012cb62cdfe5
+Reviewed-on: https://gerrit.chromium.org/gerrit/21061
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+
+[djkurtz: v3.8 rebase]
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 32 +++++++++++++++++++-----------
+ 1 file changed, 20 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index a222bd8..84f0408 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -1124,8 +1124,13 @@ static int mxt_probe(struct i2c_client *client,
+ return -EINVAL;
+
+ data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL);
++ if (!data) {
++ dev_err(&client->dev, "Failed to allocate memory\n");
++ return -ENOMEM;
++ }
++
+ input_dev = input_allocate_device();
+- if (!data || !input_dev) {
++ if (!input_dev) {
+ dev_err(&client->dev, "Failed to allocate memory\n");
+ error = -ENOMEM;
+ goto err_free_mem;
+@@ -1167,8 +1172,11 @@ static int mxt_probe(struct i2c_client *client,
+ /* For multi touch */
+ num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1;
+ error = input_mt_init_slots(input_dev, num_mt_slots, 0);
+- if (error)
++ if (error) {
++ input_free_device(input_dev);
+ goto err_free_object;
++ }
++
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
+ 0, MXT_MAX_AREA, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+@@ -1181,37 +1189,37 @@ static int mxt_probe(struct i2c_client *client,
+ input_set_drvdata(input_dev, data);
+ i2c_set_clientdata(client, data);
+
++ error = input_register_device(input_dev);
++ if (error) {
++ input_free_device(input_dev);
++ goto err_free_object;
++ }
++
+ error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
+ pdata->irqflags | IRQF_ONESHOT,
+ client->name, data);
+ if (error) {
+ dev_err(&client->dev, "Failed to register interrupt\n");
+- goto err_free_object;
++ goto err_unregister_device;
+ }
+
+ error = mxt_make_highchg(data);
+ if (error)
+ goto err_free_irq;
+
+- error = input_register_device(input_dev);
+- if (error)
+- goto err_free_irq;
+-
+ error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group);
+ if (error)
+- goto err_unregister_device;
++ goto err_free_irq;
+
+ return 0;
+
+-err_unregister_device:
+- input_unregister_device(input_dev);
+- input_dev = NULL;
+ err_free_irq:
+ free_irq(client->irq, data);
++err_unregister_device:
++ input_unregister_device(data->input_dev);
+ err_free_object:
+ kfree(data->object_table);
+ err_free_mem:
+- input_free_device(input_dev);
+ kfree(data);
+ return error;
+ }
diff --git a/patches/linux-3.8.13/0510-CHROMIUM-Input-atmel_mxt_ts-refactor-input-device-cr.patch b/patches/linux-3.8.13/0510-CHROMIUM-Input-atmel_mxt_ts-refactor-input-device-cr.patch
new file mode 100644
index 0000000..d5548bd
--- /dev/null
+++ b/patches/linux-3.8.13/0510-CHROMIUM-Input-atmel_mxt_ts-refactor-input-device-cr.patch
@@ -0,0 +1,157 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Fri, 27 Apr 2012 22:15:16 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - refactor input device
+ creation
+
+Move input device initialization to its own helper function.
+This is in preparation of a future patch that makes input device
+conditional on the device not being in its bootloader.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chrome-os-partner:9103
+TEST=builds clean; input device created as before.
+
+Change-Id: Ife128dc63a4c23c162ed116c21cc0dd3d076a559
+Reviewed-on: https://gerrit.chromium.org/gerrit/20844
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+[djkurtz: v3.8-rc3 rebase]
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 91 ++++++++++++++++--------------
+ 1 file changed, 50 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 84f0408..9afc26e 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -1111,52 +1111,23 @@ static void mxt_input_close(struct input_dev *dev)
+ mxt_stop(data);
+ }
+
+-static int mxt_probe(struct i2c_client *client,
+- const struct i2c_device_id *id)
++static int mxt_input_dev_create(struct mxt_data *data)
+ {
+- const struct mxt_platform_data *pdata = client->dev.platform_data;
+- struct mxt_data *data;
+ struct input_dev *input_dev;
+ int error;
+ unsigned int num_mt_slots;
+
+- if (!pdata)
+- return -EINVAL;
+-
+- data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL);
+- if (!data) {
+- dev_err(&client->dev, "Failed to allocate memory\n");
++ data->input_dev = input_dev = input_allocate_device();
++ if (!input_dev)
+ return -ENOMEM;
+- }
+-
+- input_dev = input_allocate_device();
+- if (!input_dev) {
+- dev_err(&client->dev, "Failed to allocate memory\n");
+- error = -ENOMEM;
+- goto err_free_mem;
+- }
+
+ input_dev->name = "Atmel maXTouch Touchscreen";
+- snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
+- client->adapter->nr, client->addr);
+ input_dev->phys = data->phys;
+-
+ input_dev->id.bustype = BUS_I2C;
+- input_dev->dev.parent = &client->dev;
++ input_dev->dev.parent = &data->client->dev;
+ input_dev->open = mxt_input_open;
+ input_dev->close = mxt_input_close;
+
+- data->client = client;
+- data->input_dev = input_dev;
+- data->pdata = pdata;
+- data->irq = client->irq;
+-
+- mxt_calc_resolution(data);
+-
+- error = mxt_initialize(data);
+- if (error)
+- goto err_free_mem;
+-
+ __set_bit(EV_ABS, input_dev->evbit);
+ __set_bit(EV_KEY, input_dev->evbit);
+ __set_bit(BTN_TOUCH, input_dev->keybit);
+@@ -1172,10 +1143,8 @@ static int mxt_probe(struct i2c_client *client,
+ /* For multi touch */
+ num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1;
+ error = input_mt_init_slots(input_dev, num_mt_slots, 0);
+- if (error) {
+- input_free_device(input_dev);
+- goto err_free_object;
+- }
++ if (error)
++ goto err_free_device;
+
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
+ 0, MXT_MAX_AREA, 0, 0);
+@@ -1187,14 +1156,54 @@ static int mxt_probe(struct i2c_client *client,
+ 0, 255, 0, 0);
+
+ input_set_drvdata(input_dev, data);
+- i2c_set_clientdata(client, data);
+
+ error = input_register_device(input_dev);
+- if (error) {
+- input_free_device(input_dev);
+- goto err_free_object;
++ if (error)
++ goto err_free_device;
++
++ return 0;
++
++err_free_device:
++ input_free_device(data->input_dev);
++ data->input_dev = NULL;
++ return error;
++}
++
++static int __devinit mxt_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ const struct mxt_platform_data *pdata = client->dev.platform_data;
++ struct mxt_data *data;
++ int error;
++
++ if (!pdata)
++ return -EINVAL;
++
++ data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL);
++ if (!data) {
++ dev_err(&client->dev, "Failed to allocate memory\n");
++ return -ENOMEM;
+ }
+
++ snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
++ client->adapter->nr, client->addr);
++
++ data->client = client;
++ i2c_set_clientdata(client, data);
++
++ data->pdata = pdata;
++ data->irq = client->irq;
++
++ mxt_calc_resolution(data);
++
++ error = mxt_initialize(data);
++ if (error)
++ goto err_free_mem;
++
++ error = mxt_input_dev_create(data);
++ if (error)
++ goto err_free_object;
++
+ error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
+ pdata->irqflags | IRQF_ONESHOT,
+ client->name, data);
diff --git a/patches/linux-3.8.13/0511-CHROMIUM-Input-atmel_mxt_ts-handle-bootloader-mode-a.patch b/patches/linux-3.8.13/0511-CHROMIUM-Input-atmel_mxt_ts-handle-bootloader-mode-a.patch
new file mode 100644
index 0000000..d623a68
--- /dev/null
+++ b/patches/linux-3.8.13/0511-CHROMIUM-Input-atmel_mxt_ts-handle-bootloader-mode-a.patch
@@ -0,0 +1,180 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Fri, 21 Dec 2012 09:26:54 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - handle bootloader mode at
+ probe
+
+In some cases it is possible for a device to be in its bootloader at
+driver probe time. This is detected by the driver when probe() is called
+with an i2c_client which has one of the Atmel Bootloader i2c addresses.
+
+In this case, we should load enough driver functionality to still loading
+new firmware using:
+ echo 1 > update_fw
+
+However, we must be very careful not to follow any code paths that would try
+to access the as-yet uninitialized object table or input device.
+In particular:
+ 1) mxt_remove calls input_unregister_device on input_dev.
+ 2) mxt_suspend/resume reads and writes from the object table.
+ 3) Spurious or bootloader induced interrupts
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chrome-os-partner:8733, chrome-os-partner:16507
+TEST=Interrupt a firmware update. Boot the system. Ensure
+ that the atmel_mxt_ts driver brings up the device using one of
+ the two MXT_BOOT i2c addresses. From there, it should be possible
+ to echo 1 > update_fw and recover.
+TEST=First, get the touch device into a bad state by doing the following:
+ 1. Modify chromeos/config/base.config and set CONFIG_TOUCHSCREEN_ATMEL_MXT=m
+ 2. Build, boot this kernel, and make sure that the touch device works.
+ 3. /opt/google/touch/firmware/chromeos-touch-firmwareupdate.sh \
+ -d atmel_mxt_ts -n maxtouch-ts.fw -f
+ 4. Before it can finish, CTRL-C to interrupt the firmware update.
+ This will ensure that the touch device is stuck in bootloader mode.
+TEST=No crash on mxt_remove:
+ 1. rmmod atmel_mxt_ts
+ 2. check that the system does not reboot.
+ 3. modprobe chromeos_mxt_ts
+TEST=No crash on suspend/resume:
+ 1. Close the lid to suspend the system.
+ 2. Open the lid to suspend the system.
+ 3. Check that the system did not reboot.
+
+Original-Change-Id: If86e6f0065bb24a5da340ac69adca4ac61d675c9
+Reviewed-on: https://gerrit.chromium.org/gerrit/19637
+Original-Change-Id: I83e517d21738cb75d0c2b0ab8bf16398044e52f3
+Reviewed-on: https://gerrit.chromium.org/gerrit/39022
+Reviewed-by: Yufeng Shen <miletus@chromium.org>
+Commit-Ready: Benson Leung <bleung@chromium.org>
+Tested-by: Benson Leung <bleung@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+Change-Id: I2b65ec6cc3c9506372499785f4f8599faf4aa353
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 51 +++++++++++++++++++++++-------
+ 1 file changed, 40 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 9afc26e..6c2c712 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -324,6 +324,12 @@ static void mxt_dump_message(struct device *dev,
+ message->reportid, 7, message->message);
+ }
+
++static bool mxt_in_bootloader(struct mxt_data *data)
++{
++ struct i2c_client *client = data->client;
++ return (client->addr == MXT_BOOT_LOW || client->addr == MXT_BOOT_HIGH);
++}
++
+ static int mxt_i2c_recv(struct i2c_client *client, u8 *buf, size_t count)
+ {
+ int ret;
+@@ -584,6 +590,9 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
+ u8 reportid;
+ bool update_input = false;
+
++ if (mxt_in_bootloader(data))
++ goto end;
++
+ do {
+ if (mxt_read_message(data, &message)) {
+ dev_err(dev, "Failed to read message\n");
+@@ -975,6 +984,9 @@ static int mxt_load_fw(struct device *dev, const char *fn)
+ return ret;
+ }
+
++ if (mxt_in_bootloader(data))
++ goto bootloader_ready;
++
+ /* Change to the bootloader mode */
+ mxt_write_object(data, MXT_GEN_COMMAND_T6,
+ MXT_COMMAND_RESET, MXT_BOOT_VALUE);
+@@ -986,6 +998,7 @@ static int mxt_load_fw(struct device *dev, const char *fn)
+ else
+ client->addr = MXT_BOOT_HIGH;
+
++bootloader_ready:
+ ret = mxt_check_bootloader(client, MXT_WAITING_BOOTLOAD_CMD);
+ if (ret)
+ goto out;
+@@ -1196,25 +1209,34 @@ static int __devinit mxt_probe(struct i2c_client *client,
+
+ mxt_calc_resolution(data);
+
+- error = mxt_initialize(data);
+- if (error)
+- goto err_free_mem;
++ if (mxt_in_bootloader(data)) {
++ dev_info(&client->dev, "Device in bootloader at probe\n");
++ } else {
++ error = mxt_initialize(data);
++ if (error)
++ goto err_free_mem;
+
+- error = mxt_input_dev_create(data);
+- if (error)
+- goto err_free_object;
++ error = mxt_input_dev_create(data);
++ if (error)
++ goto err_free_object;
++ }
+
+ error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
+ pdata->irqflags | IRQF_ONESHOT,
+ client->name, data);
+ if (error) {
+ dev_err(&client->dev, "Failed to register interrupt\n");
+- goto err_unregister_device;
++ if (mxt_in_bootloader(data))
++ goto err_free_mem;
++ else
++ goto err_unregister_device;
+ }
+
+- error = mxt_make_highchg(data);
+- if (error)
+- goto err_free_irq;
++ if (!mxt_in_bootloader(data)) {
++ error = mxt_make_highchg(data);
++ if (error)
++ goto err_free_irq;
++ }
+
+ error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group);
+ if (error)
+@@ -1239,7 +1261,8 @@ static int mxt_remove(struct i2c_client *client)
+
+ sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
+ free_irq(data->irq, data);
+- input_unregister_device(data->input_dev);
++ if (data->input_dev)
++ input_unregister_device(data->input_dev);
+ kfree(data->object_table);
+ kfree(data);
+
+@@ -1253,6 +1276,9 @@ static int mxt_suspend(struct device *dev)
+ struct mxt_data *data = i2c_get_clientdata(client);
+ struct input_dev *input_dev = data->input_dev;
+
++ if (mxt_in_bootloader(data))
++ return 0;
++
+ mutex_lock(&input_dev->mutex);
+
+ if (input_dev->users)
+@@ -1269,6 +1295,9 @@ static int mxt_resume(struct device *dev)
+ struct mxt_data *data = i2c_get_clientdata(client);
+ struct input_dev *input_dev = data->input_dev;
+
++ if (mxt_in_bootloader(data))
++ return 0;
++
+ /* Soft reset */
+ mxt_write_object(data, MXT_GEN_COMMAND_T6,
+ MXT_COMMAND_RESET, 1);
diff --git a/patches/linux-3.8.13/0512-CHROMIUM-Input-atmel_mxt_ts-handle-errors-during-fw-.patch b/patches/linux-3.8.13/0512-CHROMIUM-Input-atmel_mxt_ts-handle-errors-during-fw-.patch
new file mode 100644
index 0000000..2efb4bd
--- /dev/null
+++ b/patches/linux-3.8.13/0512-CHROMIUM-Input-atmel_mxt_ts-handle-errors-during-fw-.patch
@@ -0,0 +1,74 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Thu, 20 Dec 2012 23:16:35 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - handle errors during fw
+ update
+
+If there are any (i2c) errors during fw update, abort the update, but
+leave the i2c address assigned to the bootloader address.
+
+Note that an error when trying to reset the device into the bootloader
+will leave the i2c address assigned to the application address.
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+Change-Id: I2933505115dd55aa4dcf07e333f0e1d56e9e246e
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 6c2c712..76a25d3 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -988,8 +988,10 @@ static int mxt_load_fw(struct device *dev, const char *fn)
+ goto bootloader_ready;
+
+ /* Change to the bootloader mode */
+- mxt_write_object(data, MXT_GEN_COMMAND_T6,
++ ret = mxt_write_object(data, MXT_GEN_COMMAND_T6,
+ MXT_COMMAND_RESET, MXT_BOOT_VALUE);
++ if (ret)
++ goto out;
+ msleep(MXT_RESET_TIME);
+
+ /* Change to slave address of bootloader */
+@@ -1004,7 +1006,9 @@ bootloader_ready:
+ goto out;
+
+ /* Unlock bootloader */
+- mxt_unlock_bootloader(client);
++ ret = mxt_unlock_bootloader(client);
++ if (ret)
++ goto out;
+
+ while (pos < fw->size) {
+ ret = mxt_check_bootloader(client,
+@@ -1020,7 +1024,9 @@ bootloader_ready:
+ frame_size += 2;
+
+ /* Write one frame to device */
+- mxt_fw_write(client, fw->data + pos, frame_size);
++ ret = mxt_fw_write(client, fw->data + pos, frame_size);
++ if (ret)
++ goto out;
+
+ ret = mxt_check_bootloader(client,
+ MXT_FRAME_CRC_PASS);
+@@ -1032,14 +1038,13 @@ bootloader_ready:
+ dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size);
+ }
+
+-out:
+- release_firmware(fw);
+-
+ /* Change to slave address of application */
+ if (client->addr == MXT_BOOT_LOW)
+ client->addr = MXT_APP_LOW;
+ else
+ client->addr = MXT_APP_HIGH;
++out:
++ release_firmware(fw);
+
+ return ret;
+ }
diff --git a/patches/linux-3.8.13/0513-CHROMIUM-Input-atmel_mxt_ts-destroy-state-before-fw-.patch b/patches/linux-3.8.13/0513-CHROMIUM-Input-atmel_mxt_ts-destroy-state-before-fw-.patch
new file mode 100644
index 0000000..7589f11
--- /dev/null
+++ b/patches/linux-3.8.13/0513-CHROMIUM-Input-atmel_mxt_ts-destroy-state-before-fw-.patch
@@ -0,0 +1,51 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Thu, 20 Dec 2012 23:38:08 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - destroy state before fw
+ update and restore after
+
+After firmware update, the device may have a completely different object
+table which corresponds to an input device with different properties.
+So, destroy the old state before firmware update, and completely
+reinitialize the driver afterward.
+
+Two benefits of this:
+ 1) Since there is no input device during fw update, no need to worry
+about device open/close events.
+ 2) If firmware update fails, the device and driver will still be in
+bootloader mode and an improperly configured input device will not exist.
+
+Change-Id: I42e6b946e2206b4957c313be00b9b45b9dd02b60
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 76a25d3..c74f5a5 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -1001,6 +1001,13 @@ static int mxt_load_fw(struct device *dev, const char *fn)
+ client->addr = MXT_BOOT_HIGH;
+
+ bootloader_ready:
++ /* Free any driver state. It will get reinitialized after fw update. */
++ mxt_free_object_table(data);
++ if (data->input_dev) {
++ input_unregister_device(data->input_dev);
++ data->input_dev = NULL;
++ }
++
+ ret = mxt_check_bootloader(client, MXT_WAITING_BOOTLOAD_CMD);
+ if (ret)
+ goto out;
+@@ -1068,9 +1075,8 @@ static ssize_t mxt_update_fw_store(struct device *dev,
+ /* Wait for reset */
+ msleep(MXT_FWRESET_TIME);
+
+- mxt_free_object_table(data);
+-
+ mxt_initialize(data);
++ mxt_input_dev_create(data);
+ }
+
+ enable_irq(data->irq);
diff --git a/patches/linux-3.8.13/0514-CHROMIUM-Input-atmel_mxt_ts-refactor-bootloader-entr.patch b/patches/linux-3.8.13/0514-CHROMIUM-Input-atmel_mxt_ts-refactor-bootloader-entr.patch
new file mode 100644
index 0000000..7efd8ac
--- /dev/null
+++ b/patches/linux-3.8.13/0514-CHROMIUM-Input-atmel_mxt_ts-refactor-bootloader-entr.patch
@@ -0,0 +1,239 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Thu, 3 May 2012 13:57:46 -0700
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - refactor bootloader
+ entry/exit
+
+Refactor bootloading into a three parts:
+ 1) bl enter that only happens when device is not yet in bl.
+ bl enter frees old driver state and switches to BL i2c addr.
+ 2) the actual fw_update
+ 3) bl exit that only happens if fw update is successful.
+ bl exit switches to APP i2c addr and reloads object table and creates
+ a new input device.
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+
+BUG=chrome-os-partner:8716,chrome-os-partner:9103,chrome-os-partner:10688
+TEST=Place an firmware file at /lib/firmware/maxtouch.fw
+echo 1 > update_fw
+Ensure that a normal firmware update works.
+TEST=update the firmware and then check that the input device
+ is still working, by using evtest/xinput.
+TEST=The following instructions will write the wrong firmware to the
+touchpad device.
+1. cd /sys/bus/i2c/devices/1-004b
+2. echo maxtouch-ts.fw > fw_file
+3. echo 1 > update_fw
+4. dmesg | tail
+This will result in a failed touchpad update. Check that dmesg shows:
+[ 158.495164] atmel_mxt_ts 1-004b: bootloader version: 32
+[ 170.563491] atmel_mxt_ts 1-004b: mxt_read_reg: i2c read failed
+[ 170.563513] atmel_mxt_ts 1-004b: Failed to initialize on exit bl. error = -6
+Check that the system does not panic in this situation.
+
+To recover from this state, simply shut the machine down completely using
+sudo shutdown -P now
+
+Original-Change-Id: I49bf582be90ffc8c4dd2696413ceff060fd8926e
+Reviewed-on: https://gerrit.chromium.org/gerrit/21831
+Original-Change-Id: I2ec8b4c96954151495238c450301eddd48085e18
+Reviewed-on: https://gerrit.chromium.org/gerrit/23256
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Yufeng Shen <miletus@chromium.org>
+Commit-Ready: Yufeng Shen <miletus@chromium.org>
+Original-Change-Id: Ib773efd8b76aced9f5faab0b51745db7192e78f9
+Reviewed-on: https://gerrit.chromium.org/gerrit/37860
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 128 ++++++++++++++++++++----------
+ 1 file changed, 87 insertions(+), 41 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index c74f5a5..be96be3 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -253,6 +253,11 @@ struct mxt_data {
+ u8 T9_reportid_max;
+ };
+
++static void mxt_free_object_table(struct mxt_data *data);
++static int mxt_initialize(struct mxt_data *data);
++static int mxt_input_dev_create(struct mxt_data *data);
++static int mxt_make_highchg(struct mxt_data *data);
++
+ static bool mxt_object_readable(unsigned int type)
+ {
+ switch (type) {
+@@ -402,6 +407,8 @@ recheck:
+
+ if (val != state) {
+ dev_err(&client->dev, "Unvalid bootloader mode state\n");
++ dev_err(&client->dev, "Invalid bootloader mode state %d, %d\n",
++ val, state);
+ return -EINVAL;
+ }
+
+@@ -581,6 +588,81 @@ static bool mxt_is_T9_message(struct mxt_data *data, struct mxt_message *msg)
+ return (id >= data->T9_reportid_min && id <= data->T9_reportid_max);
+ }
+
++static int mxt_enter_bl(struct mxt_data *data)
++{
++ struct i2c_client *client = data->client;
++ int ret;
++
++ if (mxt_in_bootloader(data))
++ return 0;
++
++ disable_irq(data->irq);
++
++ /* Change to the bootloader mode */
++ ret = mxt_write_object(data, MXT_GEN_COMMAND_T6,
++ MXT_COMMAND_RESET, MXT_BOOT_VALUE);
++ if (ret) {
++ enable_irq(data->irq);
++ return ret;
++ }
++
++ /* Change to slave address of bootloader */
++ if (client->addr == MXT_APP_LOW)
++ client->addr = MXT_BOOT_LOW;
++ else
++ client->addr = MXT_BOOT_HIGH;
++
++ /* Free any driver state. It will get reinitialized after fw update. */
++ mxt_free_object_table(data);
++ if (data->input_dev) {
++ input_unregister_device(data->input_dev);
++ data->input_dev = NULL;
++ }
++
++ enable_irq(data->irq);
++ msleep(MXT_RESET_TIME);
++ return 0;
++}
++
++static void mxt_exit_bl(struct mxt_data *data)
++{
++ struct i2c_client *client = data->client;
++ struct device *dev = &client->dev;
++ int error;
++
++ if (!mxt_in_bootloader(data))
++ return;
++
++ disable_irq(data->irq);
++ /* Wait for reset */
++ msleep(MXT_FWRESET_TIME);
++
++ if (client->addr == MXT_BOOT_LOW)
++ client->addr = MXT_APP_LOW;
++ else
++ client->addr = MXT_APP_HIGH;
++
++ error = mxt_initialize(data);
++ if (error) {
++ dev_err(dev, "Failed to initialize on exit bl. error = %d\n",
++ error);
++ return;
++ }
++
++ error = mxt_input_dev_create(data);
++ if (error) {
++ dev_err(dev, "Create input dev failed after init. error = %d\n",
++ error);
++ return;
++ }
++
++ error = mxt_make_highchg(data);
++ if (error)
++ dev_err(dev, "Failed to clear CHG after init. error = %d\n",
++ error);
++ enable_irq(data->irq);
++}
++
+ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
+ {
+ struct mxt_data *data = dev_id;
+@@ -984,28 +1066,10 @@ static int mxt_load_fw(struct device *dev, const char *fn)
+ return ret;
+ }
+
+- if (mxt_in_bootloader(data))
+- goto bootloader_ready;
+-
+- /* Change to the bootloader mode */
+- ret = mxt_write_object(data, MXT_GEN_COMMAND_T6,
+- MXT_COMMAND_RESET, MXT_BOOT_VALUE);
+- if (ret)
++ ret = mxt_enter_bl(data);
++ if (ret) {
++ dev_err(dev, "Failed to reset to bootloader.\n");
+ goto out;
+- msleep(MXT_RESET_TIME);
+-
+- /* Change to slave address of bootloader */
+- if (client->addr == MXT_APP_LOW)
+- client->addr = MXT_BOOT_LOW;
+- else
+- client->addr = MXT_BOOT_HIGH;
+-
+-bootloader_ready:
+- /* Free any driver state. It will get reinitialized after fw update. */
+- mxt_free_object_table(data);
+- if (data->input_dev) {
+- input_unregister_device(data->input_dev);
+- data->input_dev = NULL;
+ }
+
+ ret = mxt_check_bootloader(client, MXT_WAITING_BOOTLOAD_CMD);
+@@ -1045,11 +1109,8 @@ bootloader_ready:
+ dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size);
+ }
+
+- /* Change to slave address of application */
+- if (client->addr == MXT_BOOT_LOW)
+- client->addr = MXT_APP_LOW;
+- else
+- client->addr = MXT_APP_HIGH;
++ /* Device exits bl mode to app mode only if successful */
++ mxt_exit_bl(data);
+ out:
+ release_firmware(fw);
+
+@@ -1060,31 +1121,16 @@ static ssize_t mxt_update_fw_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
+- struct mxt_data *data = dev_get_drvdata(dev);
+ int error;
+
+- disable_irq(data->irq);
+-
+ error = mxt_load_fw(dev, MXT_FW_NAME);
+ if (error) {
+ dev_err(dev, "The firmware update failed(%d)\n", error);
+ count = error;
+ } else {
+ dev_dbg(dev, "The firmware update succeeded\n");
+-
+- /* Wait for reset */
+- msleep(MXT_FWRESET_TIME);
+-
+- mxt_initialize(data);
+- mxt_input_dev_create(data);
+ }
+
+- enable_irq(data->irq);
+-
+- error = mxt_make_highchg(data);
+- if (error)
+- return error;
+-
+ return count;
+ }
+
diff --git a/patches/linux-3.8.13/0515-CHROMIUM-Input-atmel_mxt_ts-wait-for-CHG-assert-in-m.patch b/patches/linux-3.8.13/0515-CHROMIUM-Input-atmel_mxt_ts-wait-for-CHG-assert-in-m.patch
new file mode 100644
index 0000000..6548fba
--- /dev/null
+++ b/patches/linux-3.8.13/0515-CHROMIUM-Input-atmel_mxt_ts-wait-for-CHG-assert-in-m.patch
@@ -0,0 +1,170 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Wed, 25 Apr 2012 23:08:12 -0700
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - wait for CHG assert in
+ mxt_check_bootloader
+
+The driver should not immediately read bootloader status when
+in Application Update Mode. The CHG line will assert when the device
+has made a state transition and is ready to report a new status
+via i2c.
+
+This change adds a wait for completion in mxt_check_bootloader,
+and changes the mxt_interrupt handler to signal the completion.
+
+This will allow this commit in the intel_i2c driver to be reverted,
+as the time is no longer spent waiting for i2c read:
+3414f39 CHROMIUM: drm/i915/intel_i2c: Increase bitbang fallback timeout for atmel_mx
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+
+BUG=chrome-os-partner:8730
+TEST=(a) Verify when device not in BL (normal case), no functional change.
+TEST=(b) Verify fw update works, and device is initialized properly
+ after.
+
+Change-Id: I5d20a9d63361fb91cb59aa7351e581f55422b924
+Reviewed-on: https://gerrit.chromium.org/gerrit/21173
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 63 ++++++++++++++++++++++++++----
+ 1 file changed, 55 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index be96be3..d0f91ff 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -13,6 +13,7 @@
+
+ #include <linux/module.h>
+ #include <linux/init.h>
++#include <linux/completion.h>
+ #include <linux/delay.h>
+ #include <linux/firmware.h>
+ #include <linux/i2c.h>
+@@ -251,6 +252,9 @@ struct mxt_data {
+ u8 T6_reportid;
+ u8 T9_reportid_min;
+ u8 T9_reportid_max;
++
++ /* for fw update in bootloader */
++ struct completion bl_completion;
+ };
+
+ static void mxt_free_object_table(struct mxt_data *data);
+@@ -381,19 +385,58 @@ static int mxt_i2c_transfer(struct i2c_client *client, struct i2c_msg *msgs,
+ return ret;
+ }
+
+-static int mxt_check_bootloader(struct i2c_client *client,
+- unsigned int state)
++static int mxt_wait_for_chg(struct mxt_data *data, unsigned int timeout_ms)
+ {
++ struct device *dev = &data->client->dev;
++ struct completion *comp = &data->bl_completion;
++ unsigned long timeout = msecs_to_jiffies(timeout_ms);
++ long ret;
++
++ ret = wait_for_completion_interruptible_timeout(comp, timeout);
++ if (ret < 0) {
++ dev_err(dev, "Wait for completion interrupted.\n");
++ /*
++ * TODO: handle -EINTR better by terminating fw update process
++ * before returning to userspace by writing length 0x000 to
++ * device (iff we are in WAITING_FRAME_DATA state).
++ */
++ return -EINTR;
++ } else if (ret == 0) {
++ dev_err(dev, "Wait for completion timed out.\n");
++ return -ETIMEDOUT;
++ }
++ return 0;
++}
++
++static int mxt_check_bootloader(struct mxt_data *data, unsigned int state)
++{
++ struct i2c_client *client = data->client;
+ u8 val;
+ int ret;
+
+ recheck:
++ if (state != MXT_WAITING_BOOTLOAD_CMD) {
++ /*
++ * In application update mode, the interrupt
++ * line signals state transitions. We must wait for the
++ * CHG assertion before reading the status byte.
++ * Once the status byte has been read, the line is deasserted.
++ */
++ int ret = mxt_wait_for_chg(data, 300);
++ if (ret) {
++ dev_err(&client->dev, "Update wait error %d\n", ret);
++ return ret;
++ }
++ }
++
+ ret = mxt_i2c_recv(client, &val, 1);
+ if (ret)
+ return ret;
+
+ switch (state) {
+ case MXT_WAITING_BOOTLOAD_CMD:
++ dev_info(&client->dev, "bootloader version: %d\n",
++ val & MXT_BOOT_STATUS_MASK);
+ case MXT_WAITING_FRAME_DATA:
+ val &= ~MXT_BOOT_STATUS_MASK;
+ break;
+@@ -672,8 +715,11 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
+ u8 reportid;
+ bool update_input = false;
+
+- if (mxt_in_bootloader(data))
++ if (mxt_in_bootloader(data)) {
++ /* bootloader state transition completion */
++ complete(&data->bl_completion);
+ goto end;
++ }
+
+ do {
+ if (mxt_read_message(data, &message)) {
+@@ -1072,18 +1118,18 @@ static int mxt_load_fw(struct device *dev, const char *fn)
+ goto out;
+ }
+
+- ret = mxt_check_bootloader(client, MXT_WAITING_BOOTLOAD_CMD);
++ ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD);
+ if (ret)
+ goto out;
+
++ INIT_COMPLETION(data->bl_completion);
+ /* Unlock bootloader */
+ ret = mxt_unlock_bootloader(client);
+ if (ret)
+ goto out;
+
+ while (pos < fw->size) {
+- ret = mxt_check_bootloader(client,
+- MXT_WAITING_FRAME_DATA);
++ ret = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA);
+ if (ret)
+ goto out;
+
+@@ -1099,8 +1145,7 @@ static int mxt_load_fw(struct device *dev, const char *fn)
+ if (ret)
+ goto out;
+
+- ret = mxt_check_bootloader(client,
+- MXT_FRAME_CRC_PASS);
++ ret = mxt_check_bootloader(data, MXT_FRAME_CRC_PASS);
+ if (ret)
+ goto out;
+
+@@ -1264,6 +1309,8 @@ static int __devinit mxt_probe(struct i2c_client *client,
+ data->pdata = pdata;
+ data->irq = client->irq;
+
++ init_completion(&data->bl_completion);
++
+ mxt_calc_resolution(data);
+
+ if (mxt_in_bootloader(data)) {
diff --git a/patches/linux-3.8.13/0516-CHROMIUM-Input-atmel_mxt_ts-wait-for-CHG-after-bootl.patch b/patches/linux-3.8.13/0516-CHROMIUM-Input-atmel_mxt_ts-wait-for-CHG-after-bootl.patch
new file mode 100644
index 0000000..d90dd56
--- /dev/null
+++ b/patches/linux-3.8.13/0516-CHROMIUM-Input-atmel_mxt_ts-wait-for-CHG-after-bootl.patch
@@ -0,0 +1,84 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Wed, 2 May 2012 20:21:12 -0700
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - wait for CHG after
+ bootloader resets
+
+Rather than msleep for MXT_RESET_TIME and MXT_FWRESET_TIME
+during the transition to bootloader mode and the transition
+back from app, wait for the CHG assert to indicate that the
+transition is done.
+
+This change replaces the msleep with a wait for completion that
+the mxt_interrupt handler signals.
+
+This improves firmware update time at 300ms as we no longer
+wait longer than necessary for each reset.
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+
+BUG=chrome-os-partner:8716,chrome-os-partner:8732
+TEST=Verify fw update works, and device is initialized properly after.
+
+Change-Id: Id8982144d3966ccd8227da2a2ea47f9e73115d8e
+Reviewed-on: https://gerrit.chromium.org/gerrit/21832
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 19 +++++++++++++++----
+ 1 file changed, 15 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index d0f91ff..ef867d3 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -634,6 +634,7 @@ static bool mxt_is_T9_message(struct mxt_data *data, struct mxt_message *msg)
+ static int mxt_enter_bl(struct mxt_data *data)
+ {
+ struct i2c_client *client = data->client;
++ struct device *dev = &client->dev;
+ int ret;
+
+ if (mxt_in_bootloader(data))
+@@ -662,8 +663,19 @@ static int mxt_enter_bl(struct mxt_data *data)
+ data->input_dev = NULL;
+ }
+
++ INIT_COMPLETION(data->bl_completion);
+ enable_irq(data->irq);
+- msleep(MXT_RESET_TIME);
++
++ /* Wait for CHG assert to indicate successful reset into bootloader */
++ ret = mxt_wait_for_chg(data, MXT_RESET_TIME);
++ if (ret) {
++ dev_err(dev, "Failed waiting for reset to bootloader.\n");
++ if (client->addr == MXT_BOOT_LOW)
++ client->addr = MXT_APP_LOW;
++ else
++ client->addr = MXT_APP_HIGH;
++ return ret;
++ }
+ return 0;
+ }
+
+@@ -676,10 +688,10 @@ static void mxt_exit_bl(struct mxt_data *data)
+ if (!mxt_in_bootloader(data))
+ return;
+
+- disable_irq(data->irq);
+ /* Wait for reset */
+- msleep(MXT_FWRESET_TIME);
++ mxt_wait_for_chg(data, MXT_FWRESET_TIME);
+
++ disable_irq(data->irq);
+ if (client->addr == MXT_BOOT_LOW)
+ client->addr = MXT_APP_LOW;
+ else
+@@ -1122,7 +1134,6 @@ static int mxt_load_fw(struct device *dev, const char *fn)
+ if (ret)
+ goto out;
+
+- INIT_COMPLETION(data->bl_completion);
+ /* Unlock bootloader */
+ ret = mxt_unlock_bootloader(client);
+ if (ret)
diff --git a/patches/linux-3.8.13/0517-CHROMIUM-Input-atmel_mxt_ts-change-MXT_BOOT_LOW-to-0.patch b/patches/linux-3.8.13/0517-CHROMIUM-Input-atmel_mxt_ts-change-MXT_BOOT_LOW-to-0.patch
new file mode 100644
index 0000000..4aa3da8
--- /dev/null
+++ b/patches/linux-3.8.13/0517-CHROMIUM-Input-atmel_mxt_ts-change-MXT_BOOT_LOW-to-0.patch
@@ -0,0 +1,37 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Wed, 4 Apr 2012 17:26:47 -0700
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - change MXT_BOOT_LOW to 0x26
+
+Changed to support address on new part. This is contrary to
+Atmel documentation, and we are still working with them
+to clear up this inconsistency. In the meantime,
+change it for now to allow existing systems to update.
+
+BUG=chrome-os-partner:8734
+TEST=Firmware update works.
+
+Change-Id: Ib2db2a066126df291c7a85208743c80c5357d55d
+Signed-off-by: Benson Leung <bleung@chromium.org>
+Reviewed-on: https://gerrit.chromium.org/gerrit/19639
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index ef867d3..0aae3fb 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -30,7 +30,11 @@
+ /* Slave addresses */
+ #define MXT_APP_LOW 0x4a
+ #define MXT_APP_HIGH 0x4b
+-#define MXT_BOOT_LOW 0x24
++/*
++ * MXT_BOOT_LOW disagrees with Atmel documentation, but has been
++ * updated to support new touch hardware that pairs 0x26 boot with 0x4a app.
++ */
++#define MXT_BOOT_LOW 0x26
+ #define MXT_BOOT_HIGH 0x25
+
+ /* Firmware */
diff --git a/patches/linux-3.8.13/0518-CHROMIUM-Input-atmel_mxt_ts-Increase-FWRESET_TIME.patch b/patches/linux-3.8.13/0518-CHROMIUM-Input-atmel_mxt_ts-Increase-FWRESET_TIME.patch
new file mode 100644
index 0000000..6852cf9
--- /dev/null
+++ b/patches/linux-3.8.13/0518-CHROMIUM-Input-atmel_mxt_ts-Increase-FWRESET_TIME.patch
@@ -0,0 +1,31 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Wed, 4 Apr 2012 19:34:52 -0700
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Increase FWRESET_TIME
+
+175ms is not enough time to update the firmware. Set to
+500ms.
+
+BUG=chrome-os-partner:8731
+TEST=firmware update. ensure that transitions back to app mode at the end.
+
+Change-Id: Idaec72cb4f326a10d3513ffb82bf4b144c68b30c
+Signed-off-by: Benson Leung <bleung@chromium.org>
+Reviewed-on: https://gerrit.chromium.org/gerrit/19640
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 0aae3fb..b9b9b3f 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -184,7 +184,7 @@
+ #define MXT_BACKUP_TIME 25 /* msec */
+ #define MXT_RESET_TIME 65 /* msec */
+
+-#define MXT_FWRESET_TIME 175 /* msec */
++#define MXT_FWRESET_TIME 500 /* msec */
+
+ /* Command to unlock bootloader */
+ #define MXT_UNLOCK_CMD_MSB 0xaa
diff --git a/patches/linux-3.8.13/0519-CHROMIUM-Input-atmel_mxt_ts-add-calibrate-sysfs-entr.patch b/patches/linux-3.8.13/0519-CHROMIUM-Input-atmel_mxt_ts-add-calibrate-sysfs-entr.patch
new file mode 100644
index 0000000..807fc6e
--- /dev/null
+++ b/patches/linux-3.8.13/0519-CHROMIUM-Input-atmel_mxt_ts-add-calibrate-sysfs-entr.patch
@@ -0,0 +1,80 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Sun, 22 Apr 2012 23:29:25 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - add calibrate sysfs entry
+
+In some situations, a touch surface may get out of calibration.
+It is useful to provide a means for userspace to trigger a recal, so add a
+calibrate sysfs entry.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chrome-os-partner:9148
+TEST=echo 1 > /sys/bus/i2c/drivers/atmel_mxt_ts/<dev>/calibrate
+
+Change-Id: Idbdd7bf4f412f03e36604a2a1fae162f059234d3
+Reviewed-on: https://gerrit.chromium.org/gerrit/20812
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index b9b9b3f..00968a1 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -183,6 +183,7 @@
+ #define MXT_BACKUP_VALUE 0x55
+ #define MXT_BACKUP_TIME 25 /* msec */
+ #define MXT_RESET_TIME 65 /* msec */
++#define MXT_CAL_TIME 25 /* msec */
+
+ #define MXT_FWRESET_TIME 500 /* msec */
+
+@@ -1033,6 +1034,27 @@ static void mxt_calc_resolution(struct mxt_data *data)
+ }
+ }
+
++static ssize_t mxt_calibrate_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct mxt_data *data = dev_get_drvdata(dev);
++ int ret;
++
++ disable_irq(data->irq);
++
++ /* Perform touch surface recalibration */
++ ret = mxt_write_object(data, MXT_GEN_COMMAND_T6,
++ MXT_COMMAND_CALIBRATE, 1);
++ if (ret)
++ goto out;
++ msleep(MXT_CAL_TIME);
++
++out:
++ enable_irq(data->irq);
++ return ret ?: count;
++}
++
+ /* Firmware Version is returned as Major.Minor.Build */
+ static ssize_t mxt_fw_version_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+@@ -1194,12 +1216,14 @@ static ssize_t mxt_update_fw_store(struct device *dev,
+ return count;
+ }
+
++static DEVICE_ATTR(calibrate, S_IWUSR, NULL, mxt_calibrate_store);
+ static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL);
+ static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL);
+ static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL);
+ static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);
+
+ static struct attribute *mxt_attrs[] = {
++ &dev_attr_calibrate.attr,
+ &dev_attr_fw_version.attr,
+ &dev_attr_hw_version.attr,
+ &dev_attr_object.attr,
diff --git a/patches/linux-3.8.13/0520-CHROMIUM-Input-atmel_mxt_ts-add-sysfs-entry-to-read-.patch b/patches/linux-3.8.13/0520-CHROMIUM-Input-atmel_mxt_ts-add-sysfs-entry-to-read-.patch
new file mode 100644
index 0000000..9f811f9
--- /dev/null
+++ b/patches/linux-3.8.13/0520-CHROMIUM-Input-atmel_mxt_ts-add-sysfs-entry-to-read-.patch
@@ -0,0 +1,82 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Mon, 23 Apr 2012 12:33:12 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - add sysfs entry to read
+ config checksum
+
+Config checksum is returned in the T6 message at every boot, and when
+the config changes. Cache its value and add sysfs entry for userspace to
+read it.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chrome-os-partner:9103
+TEST=cat /sys/bus/i2c/drivers/atmel_mxt_ts/2-004b/config_csum
+
+Change-Id: Ic546d1671e9f6a3da598f06a31f76a6ca96ce235
+Reviewed-on: https://gerrit.chromium.org/gerrit/20597
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Benson Leung <bleung@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 00968a1..a03a0c4 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -253,6 +253,8 @@ struct mxt_data {
+ unsigned int max_x;
+ unsigned int max_y;
+
++ u32 config_csum;
++
+ /* Cached parameters from object table */
+ u8 T6_reportid;
+ u8 T9_reportid_min;
+@@ -748,9 +750,9 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
+
+ if (reportid == data->T6_reportid) {
+ u8 status = payload[0];
+- unsigned csum = mxt_extract_T6_csum(&payload[1]);
++ data->config_csum = mxt_extract_T6_csum(&payload[1]);
+ dev_dbg(dev, "Status: %02x Config Checksum: %06x\n",
+- status, csum);
++ status, data->config_csum);
+ } else if (mxt_is_T9_message(data, &message)) {
+ int id = reportid - data->T9_reportid_min;
+ mxt_input_touchevent(data, &message, id);
+@@ -1055,6 +1057,13 @@ out:
+ return ret ?: count;
+ }
+
++static ssize_t mxt_config_csum_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct mxt_data *data = dev_get_drvdata(dev);
++ return scnprintf(buf, PAGE_SIZE, "%06x\n", data->config_csum);
++}
++
+ /* Firmware Version is returned as Major.Minor.Build */
+ static ssize_t mxt_fw_version_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+@@ -1217,6 +1226,7 @@ static ssize_t mxt_update_fw_store(struct device *dev,
+ }
+
+ static DEVICE_ATTR(calibrate, S_IWUSR, NULL, mxt_calibrate_store);
++static DEVICE_ATTR(config_csum, S_IRUGO, mxt_config_csum_show, NULL);
+ static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL);
+ static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL);
+ static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL);
+@@ -1224,6 +1234,7 @@ static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);
+
+ static struct attribute *mxt_attrs[] = {
+ &dev_attr_calibrate.attr,
++ &dev_attr_config_csum.attr,
+ &dev_attr_fw_version.attr,
+ &dev_attr_hw_version.attr,
+ &dev_attr_object.attr,
diff --git a/patches/linux-3.8.13/0521-CHROMIUM-Input-atmel_mxt_ts-add-sysfs-entry-to-read-.patch b/patches/linux-3.8.13/0521-CHROMIUM-Input-atmel_mxt_ts-add-sysfs-entry-to-read-.patch
new file mode 100644
index 0000000..9f0c2cb
--- /dev/null
+++ b/patches/linux-3.8.13/0521-CHROMIUM-Input-atmel_mxt_ts-add-sysfs-entry-to-read-.patch
@@ -0,0 +1,103 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Fri, 27 Apr 2012 21:44:58 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - add sysfs entry to read info
+ checksum
+
+The device stores the Information Block Checksum in the 3 bytes
+immediately following the Information Block.
+
+Read these three bytes, cache the value, and add a sysfs entry so
+userspace can read it.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chrome-os-partner:9103
+TEST=cat /sys/bus/i2c/drivers/atmel_mxt_ts/2-004b/info_csum
+
+Change-Id: I27512c624bad15674bc7c50c15717913595affe4
+Reviewed-on: https://gerrit.chromium.org/gerrit/20599
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index a03a0c4..e6a5422 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -253,6 +253,7 @@ struct mxt_data {
+ unsigned int max_x;
+ unsigned int max_y;
+
++ u32 info_csum;
+ u32 config_csum;
+
+ /* Cached parameters from object table */
+@@ -894,10 +895,12 @@ static int mxt_get_info(struct mxt_data *data)
+ static int mxt_get_object_table(struct mxt_data *data)
+ {
+ struct i2c_client *client = data->client;
++ struct device *dev = &data->client->dev;
+ size_t table_size;
+ int error;
+ int i;
+ u8 reportid;
++ u8 csum[3];
+
+ table_size = data->info.object_num * sizeof(struct mxt_object);
+ error = __mxt_read_reg(client, MXT_OBJECT_START, table_size,
+@@ -905,6 +908,18 @@ static int mxt_get_object_table(struct mxt_data *data)
+ if (error)
+ return error;
+
++ /*
++ * Read Information Block checksum from 3 bytes immediately following
++ * info block
++ */
++ error = __mxt_read_reg(client, MXT_OBJECT_START + table_size,
++ sizeof(csum), csum);
++ if (error)
++ return error;
++
++ data->info_csum = csum[0] | (csum[1] << 8) | (csum[2] << 16);
++ dev_info(dev, "Information Block Checksum = %06x\n", data->info_csum);
++
+ /* Valid Report IDs start counting from 1 */
+ reportid = 1;
+ for (i = 0; i < data->info.object_num; i++) {
+@@ -1084,6 +1099,13 @@ static ssize_t mxt_hw_version_show(struct device *dev,
+ info->family_id, info->variant_id);
+ }
+
++static ssize_t mxt_info_csum_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct mxt_data *data = dev_get_drvdata(dev);
++ return scnprintf(buf, PAGE_SIZE, "%06x\n", data->info_csum);
++}
++
+ static ssize_t mxt_show_instance(char *buf, int count,
+ struct mxt_object *object, int instance,
+ const u8 *val)
+@@ -1229,6 +1251,7 @@ static DEVICE_ATTR(calibrate, S_IWUSR, NULL, mxt_calibrate_store);
+ static DEVICE_ATTR(config_csum, S_IRUGO, mxt_config_csum_show, NULL);
+ static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL);
+ static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL);
++static DEVICE_ATTR(info_csum, S_IRUGO, mxt_info_csum_show, NULL);
+ static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL);
+ static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);
+
+@@ -1237,6 +1260,7 @@ static struct attribute *mxt_attrs[] = {
+ &dev_attr_config_csum.attr,
+ &dev_attr_fw_version.attr,
+ &dev_attr_hw_version.attr,
++ &dev_attr_info_csum.attr,
+ &dev_attr_object.attr,
+ &dev_attr_update_fw.attr,
+ NULL
diff --git a/patches/linux-3.8.13/0522-CHROMIUM-Input-atmel_mxt_ts-verify-info-block-checks.patch b/patches/linux-3.8.13/0522-CHROMIUM-Input-atmel_mxt_ts-verify-info-block-checks.patch
new file mode 100644
index 0000000..e3483bb
--- /dev/null
+++ b/patches/linux-3.8.13/0522-CHROMIUM-Input-atmel_mxt_ts-verify-info-block-checks.patch
@@ -0,0 +1,111 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Thu, 26 Apr 2012 00:57:41 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - verify info block checksum
+
+Compute 24 bit CRC over entire Information Block (ID info plus Object
+Table), and verify that it matches checksum read from the device.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chrome-os-partner:9103
+TEST=Verify atmel device is discovered and operates as before.
+
+Change-Id: Ic20f585abf6726e7ff5e2cc4afd7ae805180b81d
+Reviewed-on: https://gerrit.chromium.org/gerrit/20600
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 69 ++++++++++++++++++++++++++++++
+ 1 file changed, 69 insertions(+)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index e6a5422..9210a8a 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -878,6 +878,71 @@ static void mxt_handle_pdata(struct mxt_data *data)
+ }
+ }
+
++/* Update 24-bit CRC with two new bytes of data */
++static u32 crc24_step(u32 crc, u8 byte1, u8 byte2)
++{
++ const u32 crcpoly = 0x80001b;
++ u16 data = byte1 | (byte2 << 8);
++ u32 result = data ^ (crc << 1);
++
++ /* XOR result with crcpoly if bit 25 is set (overflow occurred) */
++ if (result & 0x01000000)
++ result ^= crcpoly;
++
++ return result & 0x00ffffff;
++}
++
++static u32 crc24(u32 crc, const u8 *data, size_t len)
++{
++ size_t i;
++
++ for (i = 0; i < len - 1; i += 2)
++ crc = crc24_step(crc, data[i], data[i + 1]);
++
++ /* If there were an odd number of bytes pad with 0 */
++ if (i < len)
++ crc = crc24_step(crc, data[i], 0);
++
++ return crc;
++}
++
++static int mxt_verify_info_block_csum(struct mxt_data *data)
++{
++ struct i2c_client *client = data->client;
++ struct device *dev = &client->dev;
++ size_t object_table_size, info_block_size;
++ u32 crc = 0;
++ u8 *info_block;
++ int ret = 0;
++
++ object_table_size = data->info.object_num * MXT_OBJECT_SIZE;
++ info_block_size = sizeof(data->info) + object_table_size;
++ info_block = kmalloc(info_block_size, GFP_KERNEL);
++ if (!info_block)
++ return -ENOMEM;
++
++ /*
++ * Information Block CRC is computed over both ID info and Object Table
++ * So concat them in a temporary buffer, before computing CRC.
++ * TODO: refactor how the info block is read from the device such
++ * that it ends up in a single buffer and this copy is not needed.
++ */
++ memcpy(info_block, &data->info, sizeof(data->info));
++ memcpy(&info_block[sizeof(data->info)], data->object_table,
++ object_table_size);
++
++ crc = crc24(crc, info_block, info_block_size);
++
++ if (crc != data->info_csum) {
++ dev_err(dev, "Information Block CRC mismatch: %06x != %06x\n",
++ data->info_csum, crc);
++ ret = -EINVAL;
++ }
++
++ kfree(info_block);
++ return ret;
++}
++
+ static int mxt_get_info(struct mxt_data *data)
+ {
+ struct i2c_client *client = data->client;
+@@ -920,6 +985,10 @@ static int mxt_get_object_table(struct mxt_data *data)
+ data->info_csum = csum[0] | (csum[1] << 8) | (csum[2] << 16);
+ dev_info(dev, "Information Block Checksum = %06x\n", data->info_csum);
+
++ error = mxt_verify_info_block_csum(data);
++ if (error)
++ return error;
++
+ /* Valid Report IDs start counting from 1 */
+ reportid = 1;
+ for (i = 0; i < data->info.object_num; i++) {
diff --git a/patches/linux-3.8.13/0523-CHROMIUM-Input-atmel_mxt_tx-add-matrix_size-sysfs-en.patch b/patches/linux-3.8.13/0523-CHROMIUM-Input-atmel_mxt_tx-add-matrix_size-sysfs-en.patch
new file mode 100644
index 0000000..41175c1
--- /dev/null
+++ b/patches/linux-3.8.13/0523-CHROMIUM-Input-atmel_mxt_tx-add-matrix_size-sysfs-en.patch
@@ -0,0 +1,63 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Mon, 30 Apr 2012 13:30:31 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_tx - add matrix_size sysfs entry
+
+Returns the number of X and Y sense lines.
+
+This entry will be used by userspace for determining the dimensions of
+the T37 arrays that will be returned by deltas and refs debugfs entries.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chromium-os:29899
+TEST=cat /sys/bus/i2c/drivers/atmel_mxt_ts/<dev>/matrix_size
+
+Change-Id: I3f6414a1eaa09f51d345256e7f1bb90bdbbc528f
+Reviewed-on: https://gerrit.chromium.org/gerrit/21458
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 9210a8a..b9a0de2 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -1175,6 +1175,16 @@ static ssize_t mxt_info_csum_show(struct device *dev,
+ return scnprintf(buf, PAGE_SIZE, "%06x\n", data->info_csum);
+ }
+
++/* Matrix Size is <MatrixSizeX> <MatrixSizeY> */
++static ssize_t mxt_matrix_size_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct mxt_data *data = dev_get_drvdata(dev);
++ struct mxt_info *info = &data->info;
++ return scnprintf(buf, PAGE_SIZE, "%u %u\n",
++ info->matrix_xsize, info->matrix_ysize);
++}
++
+ static ssize_t mxt_show_instance(char *buf, int count,
+ struct mxt_object *object, int instance,
+ const u8 *val)
+@@ -1321,6 +1331,7 @@ static DEVICE_ATTR(config_csum, S_IRUGO, mxt_config_csum_show, NULL);
+ static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL);
+ static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL);
+ static DEVICE_ATTR(info_csum, S_IRUGO, mxt_info_csum_show, NULL);
++static DEVICE_ATTR(matrix_size, S_IRUGO, mxt_matrix_size_show, NULL);
+ static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL);
+ static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);
+
+@@ -1330,6 +1341,7 @@ static struct attribute *mxt_attrs[] = {
+ &dev_attr_fw_version.attr,
+ &dev_attr_hw_version.attr,
+ &dev_attr_info_csum.attr,
++ &dev_attr_matrix_size.attr,
+ &dev_attr_object.attr,
+ &dev_attr_update_fw.attr,
+ NULL
diff --git a/patches/linux-3.8.13/0524-CHROMIUM-Input-atmel_mxt_ts-define-helper-functions-.patch b/patches/linux-3.8.13/0524-CHROMIUM-Input-atmel_mxt_ts-define-helper-functions-.patch
new file mode 100644
index 0000000..2800b7c
--- /dev/null
+++ b/patches/linux-3.8.13/0524-CHROMIUM-Input-atmel_mxt_ts-define-helper-functions-.patch
@@ -0,0 +1,117 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Mon, 17 Dec 2012 17:22:02 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - define helper functions for
+ size and instances
+
+These two object table entry fields are reported 1 less than their value.
+When used, however, we always want the actual size and instances.
+
+To keep the object size and instances 1-byte fields, and thus preserve
+the object-table struct's 6-byte packed alignment, add some convenient
+accessor functions that do the +1 every time these fields are accessed.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chromium-os:27713
+TEST=Confirm object table is read correctly:
+ cat /sys/bus/i2c/devices/<dev>/object
+
+Change-Id: If303428b09e8ad5516bae8f2eccb3fd1c386192d
+Reviewed-on: https://gerrit.chromium.org/gerrit/17946
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 31 ++++++++++++++++++++----------
+ 1 file changed, 21 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index b9a0de2..b53e839 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -270,6 +270,16 @@ static int mxt_initialize(struct mxt_data *data);
+ static int mxt_input_dev_create(struct mxt_data *data);
+ static int mxt_make_highchg(struct mxt_data *data);
+
++static inline size_t mxt_obj_size(const struct mxt_object *obj)
++{
++ return obj->size + 1;
++}
++
++static inline size_t mxt_obj_instances(const struct mxt_object *obj)
++{
++ return obj->instances + 1;
++}
++
+ static bool mxt_object_readable(unsigned int type)
+ {
+ switch (type) {
+@@ -575,7 +585,7 @@ static int mxt_write_object(struct mxt_data *data,
+ u16 reg;
+
+ object = mxt_get_object(data, type);
+- if (!object || offset >= object->size + 1)
++ if (!object || offset >= mxt_obj_size(object))
+ return -EINVAL;
+
+ reg = object->start_address;
+@@ -792,7 +802,7 @@ static int mxt_check_reg_init(struct mxt_data *data)
+ if (!mxt_object_writable(object->type))
+ continue;
+
+- size = (object->size + 1) * (object->instances + 1);
++ size = mxt_obj_size(object) * mxt_obj_instances(object);
+ if (index + size > pdata->config_length) {
+ dev_err(dev, "Not enough config data!\n");
+ return -EINVAL;
+@@ -1000,7 +1010,7 @@ static int mxt_get_object_table(struct mxt_data *data)
+ if (object->num_report_ids) {
+ min_id = reportid;
+ reportid += object->num_report_ids *
+- (object->instances + 1);
++ mxt_obj_instances(object);
+ max_id = reportid - 1;
+ } else {
+ min_id = 0;
+@@ -1008,9 +1018,10 @@ static int mxt_get_object_table(struct mxt_data *data)
+ }
+
+ dev_dbg(&data->client->dev,
+- "Type %2d Start %3d Size %3d Instances %2d ReportIDs %3u : %3u\n",
+- object->type, object->start_address, object->size + 1,
+- object->instances + 1, min_id, max_id);
++ "Type %2d Start %3d Size %3zu Instances %2zu ReportIDs %3u : %3u\n",
++ object->type, object->start_address,
++ mxt_obj_size(object), mxt_obj_instances(object),
++ min_id, max_id);
+
+ switch (object->type) {
+ case MXT_GEN_COMMAND_T6:
+@@ -1191,11 +1202,11 @@ static ssize_t mxt_show_instance(char *buf, int count,
+ {
+ int i;
+
+- if (object->instances > 0)
++ if (mxt_obj_instances(object) > 1)
+ count += scnprintf(buf + count, PAGE_SIZE - count,
+ "Instance %u\n", instance);
+
+- for (i = 0; i < object->size + 1; i++)
++ for (i = 0; i < mxt_obj_size(object); i++)
+ count += scnprintf(buf + count, PAGE_SIZE - count,
+ "\t[%2u]: %02x (%d)\n", i, val[i], val[i]);
+ count += scnprintf(buf + count, PAGE_SIZE - count, "\n");
+@@ -1228,8 +1239,8 @@ static ssize_t mxt_object_show(struct device *dev,
+ count += scnprintf(buf + count, PAGE_SIZE - count,
+ "T%u:\n", object->type);
+
+- for (j = 0; j < object->instances + 1; j++) {
+- u16 size = object->size + 1;
++ for (j = 0; j < mxt_obj_instances(object); j++) {
++ u16 size = mxt_obj_size(object);
+ u16 addr = object->start_address + j * size;
+
+ error = __mxt_read_reg(data->client, addr, size, obuf);
diff --git a/patches/linux-3.8.13/0525-CHROMIUM-Input-atmel_mxt_ts-add-debugfs-infrastructu.patch b/patches/linux-3.8.13/0525-CHROMIUM-Input-atmel_mxt_ts-add-debugfs-infrastructu.patch
new file mode 100644
index 0000000..aa3d35c
--- /dev/null
+++ b/patches/linux-3.8.13/0525-CHROMIUM-Input-atmel_mxt_ts-add-debugfs-infrastructu.patch
@@ -0,0 +1,127 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Wed, 9 May 2012 02:18:14 +0000
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - add debugfs infrastructure
+
+This patch just creates a per-device debugfs root directory.
+Actual debugfs entries will be added in subsequent patches.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+BUG=chromium-os:29899
+TEST=ls /sys/kernel/debug/atmel_mxt_ts
+ => Should show directories for each atmel_mxt_ts device on the system
+
+Change-Id: I82e5470f5d1658dae03ad8d66bf348cc4fb2edb2
+Reviewed-on: https://gerrit.chromium.org/gerrit/21051
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 55 +++++++++++++++++++++++++++++-
+ 1 file changed, 54 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index b53e839..311959d 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -14,6 +14,7 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/completion.h>
++#include <linux/debugfs.h>
+ #include <linux/delay.h>
+ #include <linux/firmware.h>
+ #include <linux/i2c.h>
+@@ -263,8 +264,14 @@ struct mxt_data {
+
+ /* for fw update in bootloader */
+ struct completion bl_completion;
++
++ /* per-instance debugfs root */
++ struct dentry *dentry_dev;
+ };
+
++/* global root node of the atmel_mxt_ts debugfs directory. */
++static struct dentry *mxt_debugfs_root;
++
+ static void mxt_free_object_table(struct mxt_data *data);
+ static int mxt_initialize(struct mxt_data *data);
+ static int mxt_input_dev_create(struct mxt_data *data);
+@@ -1362,6 +1369,27 @@ static const struct attribute_group mxt_attr_group = {
+ .attrs = mxt_attrs,
+ };
+
++/*
++ **************************************************************
++ * debugfs interface
++ **************************************************************
++*/
++static int mxt_debugfs_init(struct mxt_data *mxt)
++{
++ struct device *dev = &mxt->client->dev;
++
++ if (!mxt_debugfs_root)
++ return -ENODEV;
++
++ mxt->dentry_dev = debugfs_create_dir(kobject_name(&dev->kobj),
++ mxt_debugfs_root);
++
++ if (!mxt->dentry_dev)
++ return -ENODEV;
++
++ return 0;
++}
++
+ static void mxt_start(struct mxt_data *data)
+ {
+ /* Touch enable */
+@@ -1512,6 +1540,10 @@ static int __devinit mxt_probe(struct i2c_client *client,
+ if (error)
+ goto err_free_irq;
+
++ error = mxt_debugfs_init(data);
++ if (error)
++ dev_warn(&client->dev, "error creating debugfs entries.\n");
++
+ return 0;
+
+ err_free_irq:
+@@ -1529,6 +1561,8 @@ static int mxt_remove(struct i2c_client *client)
+ {
+ struct mxt_data *data = i2c_get_clientdata(client);
+
++ if (data->dentry_dev)
++ debugfs_remove_recursive(data->dentry_dev);
+ sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
+ free_irq(data->irq, data);
+ if (data->input_dev)
+@@ -1606,7 +1640,26 @@ static struct i2c_driver mxt_driver = {
+ .id_table = mxt_id,
+ };
+
+-module_i2c_driver(mxt_driver);
++static int __init mxt_init(void)
++{
++ /* Create a global debugfs root for all atmel_mxt_ts devices */
++ mxt_debugfs_root = debugfs_create_dir(mxt_driver.driver.name, NULL);
++ if (mxt_debugfs_root == ERR_PTR(-ENODEV))
++ mxt_debugfs_root = NULL;
++
++ return i2c_add_driver(&mxt_driver);
++}
++
++static void __exit mxt_exit(void)
++{
++ if (mxt_debugfs_root)
++ debugfs_remove_recursive(mxt_debugfs_root);
++
++ i2c_del_driver(&mxt_driver);
++}
++
++module_init(mxt_init);
++module_exit(mxt_exit);
+
+ /* Module information */
+ MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
diff --git a/patches/linux-3.8.13/0526-CHROMIUM-Input-atmel_mxt_ts-add-deltas-and-refs-debu.patch b/patches/linux-3.8.13/0526-CHROMIUM-Input-atmel_mxt_ts-add-deltas-and-refs-debu.patch
new file mode 100644
index 0000000..4f4bb2d
--- /dev/null
+++ b/patches/linux-3.8.13/0526-CHROMIUM-Input-atmel_mxt_ts-add-deltas-and-refs-debu.patch
@@ -0,0 +1,338 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Mon, 17 Dec 2012 17:32:59 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - add deltas and refs debugfs
+ entries
+
+Reading these two debugfs entries returns a binary blob containing the
+contents of all pages of the T37 object when the DELTAS and REFERENCES
+commands are requested, respectively.
+The values are written to the file as they are arranged in the device's
+T37 object, that is, as a 2D array with matrix_ysize columns and
+matrix_xsize rows of 2-byte (little endian) values.
+
+It is left to userspace to parse the 2-byte values.
+ * Deltas are signed 2's complement 2-byte little-endian values.
+ s32 delta = (b[0] + (b[1] << 8));
+
+ * Refs are signed 'offset binary' 2-byte little-endian values,
+ with offset 16384 (0x4000):
+ s32 ref = (b[0] + (b[1] << 8)) - 16384;
+
+Userspace should use the 'matrix_size' sysfs entry to determine the
+dimensions of the returned arrays.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chromium-os:29899
+TEST=hexdump -e '52/2 "%6d" "\n"' /sys/kernel/debug/atmel_mxt_ts/<dev>/deltas
+ => dumps 'delta' values in a 52-column wide grid
+TEST=hexdump -e '12/2 "%6d" "\n"' /sys/kernel/debug/atmel_mxt_ts/<dev>/deltas
+ => dumps the 'ref' values in a 12-column wide grid
+
+Change-Id: I9deb64074dd9947739961aa4323573f4544e9dc1
+Reviewed-on: https://gerrit.chromium.org/gerrit/21052
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 241 +++++++++++++++++++++++++++++-
+ 1 file changed, 240 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 311959d..9a8cfd2 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -22,6 +22,7 @@
+ #include <linux/input/mt.h>
+ #include <linux/interrupt.h>
+ #include <linux/slab.h>
++#include <linux/uaccess.h>
+
+ /* Version */
+ #define MXT_VER_20 20
+@@ -90,6 +91,13 @@
+ #define MXT_COMMAND_REPORTALL 3
+ #define MXT_COMMAND_DIAGNOSTIC 5
+
++#define MXT_T6_CMD_PAGE_UP 0x01
++#define MXT_T6_CMD_PAGE_DOWN 0x02
++#define MXT_T6_CMD_DELTAS 0x10
++#define MXT_T6_CMD_REFS 0x11
++#define MXT_T6_CMD_DEVICE_ID 0x80
++#define MXT_T6_CMD_TOUCH_THRESH 0xF4
++
+ /* MXT_GEN_POWER_T7 field */
+ #define MXT_POWER_IDLEACQINT 0
+ #define MXT_POWER_ACTVACQINT 1
+@@ -267,6 +275,13 @@ struct mxt_data {
+
+ /* per-instance debugfs root */
+ struct dentry *dentry_dev;
++ struct dentry *dentry_deltas;
++ struct dentry *dentry_refs;
++
++ /* Protect access to the T37 object buffer, used by debugfs */
++ struct mutex T37_buf_mutex;
++ u8 *T37_buf;
++ size_t T37_buf_size;
+ };
+
+ /* global root node of the atmel_mxt_ts debugfs directory. */
+@@ -1138,6 +1153,133 @@ static void mxt_calc_resolution(struct mxt_data *data)
+ }
+ }
+
++/*
++ * Helper function for performing a T6 diagnostic command
++ */
++static int mxt_T6_diag_cmd(struct mxt_data *data, struct mxt_object *T6,
++ u8 cmd)
++{
++ int ret;
++ u16 addr = T6->start_address + MXT_COMMAND_DIAGNOSTIC;
++
++ ret = mxt_write_reg(data->client, addr, cmd);
++ if (ret)
++ return ret;
++
++ /*
++ * Poll T6.diag until it returns 0x00, which indicates command has
++ * completed.
++ */
++ while (cmd != 0) {
++ ret = __mxt_read_reg(data->client, addr, 1, &cmd);
++ if (ret)
++ return ret;
++ }
++ return 0;
++}
++
++/*
++ * SysFS Helper function for reading DELTAS and REFERENCE values for T37 object
++ *
++ * For both modes, a T37_buf is allocated to stores matrix_xsize * matrix_ysize
++ * 2-byte (little-endian) values, which are returned to userspace unmodified.
++ *
++ * It is left to userspace to parse the 2-byte values.
++ * - deltas are signed 2's complement 2-byte little-endian values.
++ * s32 delta = (b[0] + (b[1] << 8));
++ * - refs are signed 'offset binary' 2-byte little-endian values, with offset
++ * value 0x4000:
++ * s32 ref = (b[0] + (b[1] << 8)) - 0x4000;
++ */
++static ssize_t mxt_T37_fetch(struct mxt_data *data, u8 mode)
++{
++ struct mxt_object *T6, *T37;
++ u8 *obuf;
++ ssize_t ret = 0;
++ size_t i;
++ size_t T37_buf_size, num_pages;
++ size_t pos;
++
++ if (!data || !data->object_table)
++ return -ENODEV;
++
++ T6 = mxt_get_object(data, MXT_GEN_COMMAND_T6);
++ T37 = mxt_get_object(data, MXT_DEBUG_DIAGNOSTIC_T37);
++ if (!T6 || mxt_obj_size(T6) < 6 || !T37 || mxt_obj_size(T37) < 3) {
++ dev_err(&data->client->dev, "Invalid T6 or T37 object\n");
++ return -ENODEV;
++ }
++
++ /* Something has gone wrong if T37_buf is already allocated */
++ if (data->T37_buf)
++ return -EINVAL;
++
++ T37_buf_size = data->info.matrix_xsize * data->info.matrix_ysize *
++ sizeof(__le16);
++ data->T37_buf_size = T37_buf_size;
++ data->T37_buf = kmalloc(data->T37_buf_size, GFP_KERNEL);
++ if (!data->T37_buf)
++ return -ENOMEM;
++
++ /* Temporary buffer used to fetch one T37 page */
++ obuf = kmalloc(mxt_obj_size(T37), GFP_KERNEL);
++ if (!obuf)
++ return -ENOMEM;
++
++ disable_irq(data->irq);
++ num_pages = DIV_ROUND_UP(T37_buf_size, mxt_obj_size(T37) - 2);
++ pos = 0;
++ for (i = 0; i < num_pages; i++) {
++ u8 cmd;
++ size_t chunk_len;
++
++ /* For first page, send mode as cmd, otherwise PageUp */
++ cmd = (i == 0) ? mode : MXT_T6_CMD_PAGE_UP;
++ ret = mxt_T6_diag_cmd(data, T6, cmd);
++ if (ret)
++ goto err_free_T37_buf;
++
++ ret = __mxt_read_reg(data->client, T37->start_address,
++ mxt_obj_size(T37), obuf);
++ if (ret)
++ goto err_free_T37_buf;
++
++ /* Verify first two bytes are current mode and page # */
++ if (obuf[0] != mode) {
++ dev_err(&data->client->dev,
++ "Unexpected mode (%u != %u)\n", obuf[0], mode);
++ ret = -EIO;
++ goto err_free_T37_buf;
++ }
++
++ if (obuf[1] != i) {
++ dev_err(&data->client->dev,
++ "Unexpected page (%u != %zu)\n", obuf[1], i);
++ ret = -EIO;
++ goto err_free_T37_buf;
++ }
++
++ /*
++ * Copy the data portion of the page, or however many bytes are
++ * left, whichever is less.
++ */
++ chunk_len = min(mxt_obj_size(T37) - 2, T37_buf_size - pos);
++ memcpy(&data->T37_buf[pos], &obuf[2], chunk_len);
++ pos += chunk_len;
++ }
++
++ goto out;
++
++err_free_T37_buf:
++ kfree(data->T37_buf);
++ data->T37_buf = NULL;
++ data->T37_buf_size = 0;
++out:
++ kfree(obuf);
++ enable_irq(data->irq);
++ return ret ?: 0;
++}
++
+ static ssize_t mxt_calibrate_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+@@ -1374,6 +1516,92 @@ static const struct attribute_group mxt_attr_group = {
+ * debugfs interface
+ **************************************************************
+ */
++static int mxt_debugfs_T37_open(struct inode *inode, struct file *file)
++{
++ struct mxt_data *mxt = inode->i_private;
++ int ret;
++ u8 cmd;
++
++ if (file->f_dentry == mxt->dentry_deltas)
++ cmd = MXT_T6_CMD_DELTAS;
++ else if (file->f_dentry == mxt->dentry_refs)
++ cmd = MXT_T6_CMD_REFS;
++ else
++ return -EINVAL;
++
++ /* Only allow one T37 debugfs file to be opened at a time */
++ ret = mutex_lock_interruptible(&mxt->T37_buf_mutex);
++ if (ret)
++ return ret;
++
++ if (!i2c_use_client(mxt->client)) {
++ ret = -ENODEV;
++ goto err_unlock;
++ }
++
++ /* Fetch all T37 pages into mxt->T37_buf */
++ ret = mxt_T37_fetch(mxt, cmd);
++ if (ret)
++ goto err_release;
++
++ file->private_data = mxt;
++
++ return 0;
++
++err_release:
++ i2c_release_client(mxt->client);
++err_unlock:
++ mutex_unlock(&mxt->T37_buf_mutex);
++ return ret;
++}
++
++static int mxt_debugfs_T37_release(struct inode *inode, struct file *file)
++{
++ struct mxt_data *mxt = file->private_data;
++
++ file->private_data = NULL;
++
++ kfree(mxt->T37_buf);
++ mxt->T37_buf = NULL;
++ mxt->T37_buf_size = 0;
++
++ i2c_release_client(mxt->client);
++ mutex_unlock(&mxt->T37_buf_mutex);
++
++ return 0;
++}
++
++
++/* Return some bytes from the buffered T37 object, starting from *ppos */
++static ssize_t mxt_debugfs_T37_read(struct file *file, char __user *buffer,
++ size_t count, loff_t *ppos)
++{
++ struct mxt_data *mxt = file->private_data;
++
++ if (!mxt->T37_buf)
++ return -ENODEV;
++
++ if (*ppos >= mxt->T37_buf_size)
++ return 0;
++
++ if (count + *ppos > mxt->T37_buf_size)
++ count = mxt->T37_buf_size - *ppos;
++
++ if (copy_to_user(buffer, &mxt->T37_buf[*ppos], count))
++ return -EFAULT;
++
++ *ppos += count;
++
++ return count;
++}
++
++static const struct file_operations mxt_debugfs_T37_fops = {
++ .owner = THIS_MODULE,
++ .open = mxt_debugfs_T37_open,
++ .release = mxt_debugfs_T37_release,
++ .read = mxt_debugfs_T37_read
++};
++
+ static int mxt_debugfs_init(struct mxt_data *mxt)
+ {
+ struct device *dev = &mxt->client->dev;
+@@ -1387,6 +1615,14 @@ static int mxt_debugfs_init(struct mxt_data *mxt)
+ if (!mxt->dentry_dev)
+ return -ENODEV;
+
++ mutex_init(&mxt->T37_buf_mutex);
++
++ mxt->dentry_deltas = debugfs_create_file("deltas", S_IRUSR,
++ mxt->dentry_dev, mxt,
++ &mxt_debugfs_T37_fops);
++ mxt->dentry_refs = debugfs_create_file("refs", S_IRUSR,
++ mxt->dentry_dev, mxt,
++ &mxt_debugfs_T37_fops);
+ return 0;
+ }
+
+@@ -1561,8 +1797,11 @@ static int mxt_remove(struct i2c_client *client)
+ {
+ struct mxt_data *data = i2c_get_clientdata(client);
+
+- if (data->dentry_dev)
++ if (data->dentry_dev) {
+ debugfs_remove_recursive(data->dentry_dev);
++ mutex_destroy(&data->T37_buf_mutex);
++ kfree(data->T37_buf);
++ }
+ sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
+ free_irq(data->irq, data);
+ if (data->input_dev)
diff --git a/patches/linux-3.8.13/0527-CHROMIUM-Input-atmel_mxt_ts-add-device-id-for-touchp.patch b/patches/linux-3.8.13/0527-CHROMIUM-Input-atmel_mxt_ts-add-device-id-for-touchp.patch
new file mode 100644
index 0000000..26075cd
--- /dev/null
+++ b/patches/linux-3.8.13/0527-CHROMIUM-Input-atmel_mxt_ts-add-device-id-for-touchp.patch
@@ -0,0 +1,180 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Wed, 12 Dec 2012 15:33:18 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - add device id for touchpad
+ variant
+
+This same driver can be used by atmel based touchscreens and touchpads
+(buttonpads) by instantiating the i2c device as a "atmel_mxt_tp".
+
+This will cause the driver to perform some touchpad specific
+initializations, such as:
+ * register input device name "Atmel maXTouch Touchpad" instead of
+ Touchscreen.
+ * register BTN_LEFT & BTN_TOOL_* event types.
+ * register axis resolution (as a fixed constant, for now)
+ * register BUTTONPAD property
+ * process GPIO buttons using reportid T19
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chromium-os:27714
+TEST=builds clean; atmel tp works using ddc lines and cmt
+
+Change-Id: Ifb5cff5667156ca48c1ca90e5e8eea0c434480df
+Reviewed-on: https://gerrit.chromium.org/gerrit/17959
+Commit-Ready: Benson Leung <bleung@chromium.org>
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Tested-by: Benson Leung <bleung@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 51 +++++++++++++++++++++++++++++-
+ 1 file changed, 50 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 9a8cfd2..3b9007c 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -196,6 +196,12 @@
+
+ #define MXT_FWRESET_TIME 500 /* msec */
+
++/* MXT_SPT_GPIOPWM_T19 field */
++#define MXT_GPIO0_MASK 0x04
++#define MXT_GPIO1_MASK 0x08
++#define MXT_GPIO2_MASK 0x10
++#define MXT_GPIO3_MASK 0x20
++
+ /* Command to unlock bootloader */
+ #define MXT_UNLOCK_CMD_MSB 0xaa
+ #define MXT_UNLOCK_CMD_LSB 0xdc
+@@ -227,6 +233,9 @@
+ /* Touchscreen absolute values */
+ #define MXT_MAX_AREA 0xff
+
++/* For CMT (must match XRANGE/YRANGE as defined in board config */
++#define MXT_PIXELS_PER_MM 20
++
+ struct mxt_info {
+ u8 family_id;
+ u8 variant_id;
+@@ -258,6 +267,8 @@ struct mxt_data {
+ const struct mxt_platform_data *pdata;
+ struct mxt_object *object_table;
+ struct mxt_info info;
++ bool is_tp;
++
+ unsigned int irq;
+ unsigned int max_x;
+ unsigned int max_y;
+@@ -269,6 +280,7 @@ struct mxt_data {
+ u8 T6_reportid;
+ u8 T9_reportid_min;
+ u8 T9_reportid_max;
++ u8 T19_reportid;
+
+ /* for fw update in bootloader */
+ struct completion bl_completion;
+@@ -614,6 +626,18 @@ static int mxt_write_object(struct mxt_data *data,
+ return mxt_write_reg(data->client, reg + offset, val);
+ }
+
++static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
++{
++ struct device *dev = &data->client->dev;
++ struct input_dev *input = data->input_dev;
++ bool button;
++
++ /* Active-low switch */
++ button = !(message->message[0] & MXT_GPIO3_MASK);
++ input_report_key(input, BTN_LEFT, button);
++ dev_dbg(dev, "Button state: %d\n", button);
++}
++
+ static void mxt_input_touchevent(struct mxt_data *data,
+ struct mxt_message *message, int id)
+ {
+@@ -790,6 +814,9 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
+ int id = reportid - data->T9_reportid_min;
+ mxt_input_touchevent(data, &message, id);
+ update_input = true;
++ } else if (message.reportid == data->T19_reportid) {
++ mxt_input_button(data, &message);
++ update_input = true;
+ } else {
+ mxt_dump_message(dev, &message);
+ }
+@@ -1053,6 +1080,9 @@ static int mxt_get_object_table(struct mxt_data *data)
+ data->T9_reportid_min = min_id;
+ data->T9_reportid_max = max_id;
+ break;
++ case MXT_SPT_GPIOPWM_T19:
++ data->T19_reportid = min_id;
++ break;
+ }
+ }
+
+@@ -1666,7 +1696,8 @@ static int mxt_input_dev_create(struct mxt_data *data)
+ if (!input_dev)
+ return -ENOMEM;
+
+- input_dev->name = "Atmel maXTouch Touchscreen";
++ input_dev->name = (data->is_tp) ? "Atmel maXTouch Touchpad" :
++ "Atmel maXTouch Touchscreen";
+ input_dev->phys = data->phys;
+ input_dev->id.bustype = BUS_I2C;
+ input_dev->dev.parent = &data->client->dev;
+@@ -1677,6 +1708,18 @@ static int mxt_input_dev_create(struct mxt_data *data)
+ __set_bit(EV_KEY, input_dev->evbit);
+ __set_bit(BTN_TOUCH, input_dev->keybit);
+
++ if (data->is_tp) {
++ __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
++ __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
++
++ __set_bit(BTN_LEFT, input_dev->keybit);
++ __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
++ __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
++ __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
++ __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
++ __set_bit(BTN_TOOL_QUINTTAP, input_dev->keybit);
++ }
++
+ /* For single touch */
+ input_set_abs_params(input_dev, ABS_X,
+ 0, data->max_x, 0, 0);
+@@ -1684,6 +1727,8 @@ static int mxt_input_dev_create(struct mxt_data *data)
+ 0, data->max_y, 0, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE,
+ 0, 255, 0, 0);
++ input_abs_set_res(input_dev, ABS_X, MXT_PIXELS_PER_MM);
++ input_abs_set_res(input_dev, ABS_Y, MXT_PIXELS_PER_MM);
+
+ /* For multi touch */
+ num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1;
+@@ -1699,6 +1744,8 @@ static int mxt_input_dev_create(struct mxt_data *data)
+ 0, data->max_y, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_PRESSURE,
+ 0, 255, 0, 0);
++ input_abs_set_res(input_dev, ABS_MT_POSITION_X, MXT_PIXELS_PER_MM);
++ input_abs_set_res(input_dev, ABS_MT_POSITION_Y, MXT_PIXELS_PER_MM);
+
+ input_set_drvdata(input_dev, data);
+
+@@ -1730,6 +1777,7 @@ static int __devinit mxt_probe(struct i2c_client *client,
+ return -ENOMEM;
+ }
+
++ data->is_tp = !strcmp(id->name, "atmel_mxt_tp");
+ snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
+ client->adapter->nr, client->addr);
+
+@@ -1863,6 +1911,7 @@ static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume);
+ static const struct i2c_device_id mxt_id[] = {
+ { "qt602240_ts", 0 },
+ { "atmel_mxt_ts", 0 },
++ { "atmel_mxt_tp", 0 },
+ { "mXT224", 0 },
+ { }
+ };
diff --git a/patches/linux-3.8.13/0528-CHROMIUM-Input-atmel_mxt_ts-Read-resolution-from-dev.patch b/patches/linux-3.8.13/0528-CHROMIUM-Input-atmel_mxt_ts-Read-resolution-from-dev.patch
new file mode 100644
index 0000000..878c608
--- /dev/null
+++ b/patches/linux-3.8.13/0528-CHROMIUM-Input-atmel_mxt_ts-Read-resolution-from-dev.patch
@@ -0,0 +1,130 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Tue, 1 May 2012 16:58:46 -0400
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Read resolution from device
+ memory
+
+Currently mxt_calc_resolution() computes device resolution from
+provided platform data. Since we are going to support loading
+configuration data from file instead of platform data, we rework
+mxt_calc_resolution() so it reads the actual resolution from the
+configured device memory.
+
+And also move mxt_calc_resolution() into mxt_initialize() after
+the device is configured.
+
+BUG=chrome-os-partner:9103
+TEST=Use evtest to check that the range of ABS_X/Y and
+ ABS_MT_POSITION_X/Y are correct.
+
+Change-Id: Ibf66af4c656b138b52ce5608d7357bf15ee423ac
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+Reviewed-on: https://gerrit.chromium.org/gerrit/21544
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 51 +++++++++++++++++++++++-------
+ 1 file changed, 40 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 3b9007c..95abf18 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -299,6 +299,7 @@ struct mxt_data {
+ /* global root node of the atmel_mxt_ts debugfs directory. */
+ static struct dentry *mxt_debugfs_root;
+
++static int mxt_calc_resolution(struct mxt_data *data);
+ static void mxt_free_object_table(struct mxt_data *data);
+ static int mxt_initialize(struct mxt_data *data);
+ static int mxt_input_dev_create(struct mxt_data *data);
+@@ -1131,14 +1132,17 @@ static int mxt_initialize(struct mxt_data *data)
+ mxt_handle_pdata(data);
+
+ /* Backup to memory */
+- mxt_write_object(data, MXT_GEN_COMMAND_T6,
+- MXT_COMMAND_BACKUPNV,
+- MXT_BACKUP_VALUE);
++ error = mxt_write_object(data, MXT_GEN_COMMAND_T6,
++ MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE);
++ if (error)
++ return error;
+ msleep(MXT_BACKUP_TIME);
+
+ /* Soft reset */
+- mxt_write_object(data, MXT_GEN_COMMAND_T6,
+- MXT_COMMAND_RESET, 1);
++ error = mxt_write_object(data, MXT_GEN_COMMAND_T6,
++ MXT_COMMAND_RESET, 1);
++ if (error)
++ return error;
+ msleep(MXT_RESET_TIME);
+
+ /* Update matrix size at info struct */
+@@ -1162,6 +1166,10 @@ static int mxt_initialize(struct mxt_data *data)
+ info->matrix_xsize, info->matrix_ysize,
+ info->object_num);
+
++ error = mxt_calc_resolution(data);
++ if (error)
++ return error;
++
+ return 0;
+
+ err_free_object_table:
+@@ -1169,18 +1177,41 @@ err_free_object_table:
+ return error;
+ }
+
+-static void mxt_calc_resolution(struct mxt_data *data)
++static int mxt_calc_resolution(struct mxt_data *data)
+ {
+- unsigned int max_x = data->pdata->x_size - 1;
+- unsigned int max_y = data->pdata->y_size - 1;
++ struct i2c_client *client = data->client;
++ u8 orient;
++ __le16 xyrange[2];
++ unsigned int max_x, max_y;
++ int ret;
+
+- if (data->pdata->orient & MXT_XY_SWITCH) {
++ struct mxt_object *T9 = mxt_get_object(data, MXT_TOUCH_MULTI_T9);
++ if (T9 == NULL)
++ return -EINVAL;
++
++ /* Get touchscreen resolution */
++ ret = __mxt_read_reg(client, T9->start_address + MXT_TOUCH_XRANGE_LSB,
++ 4, xyrange);
++ if (ret)
++ return ret;
++
++ ret = __mxt_read_reg(client, T9->start_address + MXT_TOUCH_ORIENT,
++ 1, &orient);
++ if (ret)
++ return ret;
++
++ max_x = le16_to_cpu(xyrange[0]);
++ max_y = le16_to_cpu(xyrange[1]);
++
++ if (orient & MXT_XY_SWITCH) {
+ data->max_x = max_y;
+ data->max_y = max_x;
+ } else {
+ data->max_x = max_x;
+ data->max_y = max_y;
+ }
++
++ return 0;
+ }
+
+ /*
+@@ -1789,8 +1820,6 @@ static int __devinit mxt_probe(struct i2c_client *client,
+
+ init_completion(&data->bl_completion);
+
+- mxt_calc_resolution(data);
+-
+ if (mxt_in_bootloader(data)) {
+ dev_info(&client->dev, "Device in bootloader at probe\n");
+ } else {
diff --git a/patches/linux-3.8.13/0529-CHROMIUM-Input-atmel_mxt_ts-Report-TOUCH-MAJOR-in-te.patch b/patches/linux-3.8.13/0529-CHROMIUM-Input-atmel_mxt_ts-Report-TOUCH-MAJOR-in-te.patch
new file mode 100644
index 0000000..7fce353
--- /dev/null
+++ b/patches/linux-3.8.13/0529-CHROMIUM-Input-atmel_mxt_ts-Report-TOUCH-MAJOR-in-te.patch
@@ -0,0 +1,147 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Fri, 25 May 2012 13:55:26 -0400
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Report TOUCH MAJOR in terms
+ of pixels
+
+The TCHAREA field reported from the device is in terms of channels
+covered by the touch, while ABS_MT_TOUCH_MAJOR is expected to be in
+the units the same as the configured device resolution. So we
+approximate the touch contact as a circle, convert the touch area
+from channel numbers to pixel numbers, and compute the diameter of
+the circle touch as the value of ABS_MT_TOUCH_MAJOR.
+
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chrome-os-partner:9968
+TEST=using evtest to check the range of ABS_MT_TOUCH_MAJOR is now
+ somewhat between 50 ~ 100, instead of 1 ~ 10 while making
+ normal touching.
+
+Change-Id: I9972a4989a18b9fbe4fdf1edd70330a4e9df3f85
+Reviewed-on: https://gerrit.chromium.org/gerrit/24530
+Commit-Ready: Yufeng Shen <miletus@chromium.org>
+Reviewed-by: Yufeng Shen <miletus@chromium.org>
+Tested-by: Yufeng Shen <miletus@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 40 ++++++++++++++++++++++++++++--
+ 1 file changed, 38 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 95abf18..66b6f70 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -273,6 +273,10 @@ struct mxt_data {
+ unsigned int max_x;
+ unsigned int max_y;
+
++ /* max touchscreen area in terms of pixels and channels */
++ unsigned int max_area_pixels;
++ unsigned int max_area_channels;
++
+ u32 info_csum;
+ u32 config_csum;
+
+@@ -639,6 +643,23 @@ static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
+ dev_dbg(dev, "Button state: %d\n", button);
+ }
+
++/*
++ * Assume a circle touch contact and use the diameter as the touch major.
++ * touch_pixels = touch_channels * (max_area_pixels / max_area_channels)
++ * touch_pixels = pi * (touch_major / 2) ^ 2;
++ */
++static int get_touch_major_pixels(struct mxt_data *data, int touch_channels)
++{
++ int touch_pixels;
++
++ if (data->max_area_channels == 0)
++ return 0;
++
++ touch_pixels = DIV_ROUND_CLOSEST(touch_channels * data->max_area_pixels,
++ data->max_area_channels);
++ return int_sqrt(DIV_ROUND_CLOSEST(touch_pixels * 100, 314)) * 2;
++}
++
+ static void mxt_input_touchevent(struct mxt_data *data,
+ struct mxt_message *message, int id)
+ {
+@@ -649,6 +670,7 @@ static void mxt_input_touchevent(struct mxt_data *data,
+ int y;
+ int area;
+ int pressure;
++ int touch_major;
+
+ x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf);
+ y = (message->message[2] << 4) | ((message->message[3] & 0xf));
+@@ -658,6 +680,7 @@ static void mxt_input_touchevent(struct mxt_data *data,
+ y = y >> 2;
+
+ area = message->message[4];
++ touch_major = get_touch_major_pixels(data, area);
+ pressure = message->message[5];
+
+ dev_dbg(dev,
+@@ -681,7 +704,7 @@ static void mxt_input_touchevent(struct mxt_data *data,
+ input_report_abs(input_dev, ABS_MT_POSITION_X, x);
+ input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
+ input_report_abs(input_dev, ABS_MT_PRESSURE, pressure);
+- input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area);
++ input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, touch_major);
+ }
+ }
+
+@@ -1183,6 +1206,7 @@ static int mxt_calc_resolution(struct mxt_data *data)
+ u8 orient;
+ __le16 xyrange[2];
+ unsigned int max_x, max_y;
++ u8 xylines[2];
+ int ret;
+
+ struct mxt_object *T9 = mxt_get_object(data, MXT_TOUCH_MULTI_T9);
+@@ -1200,6 +1224,11 @@ static int mxt_calc_resolution(struct mxt_data *data)
+ if (ret)
+ return ret;
+
++ ret = __mxt_read_reg(client, T9->start_address + MXT_TOUCH_XSIZE,
++ 2, xylines);
++ if (ret)
++ return ret;
++
+ max_x = le16_to_cpu(xyrange[0]);
+ max_y = le16_to_cpu(xyrange[1]);
+
+@@ -1211,6 +1240,9 @@ static int mxt_calc_resolution(struct mxt_data *data)
+ data->max_y = max_y;
+ }
+
++ data->max_area_pixels = max_x * max_y;
++ data->max_area_channels = xylines[0] * xylines[1];
++
+ return 0;
+ }
+
+@@ -1722,6 +1754,8 @@ static int mxt_input_dev_create(struct mxt_data *data)
+ struct input_dev *input_dev;
+ int error;
+ unsigned int num_mt_slots;
++ int max_area_channels;
++ int max_touch_major;
+
+ data->input_dev = input_dev = input_allocate_device();
+ if (!input_dev)
+@@ -1767,8 +1801,10 @@ static int mxt_input_dev_create(struct mxt_data *data)
+ if (error)
+ goto err_free_device;
+
++ max_area_channels = min(255U, data->max_area_channels);
++ max_touch_major = get_touch_major_pixels(data, max_area_channels);
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
+- 0, MXT_MAX_AREA, 0, 0);
++ 0, max_touch_major, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+ 0, data->max_x, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
diff --git a/patches/linux-3.8.13/0530-CHROMIUM-Input-atmel_mxt_ts-add-new-object-types.patch b/patches/linux-3.8.13/0530-CHROMIUM-Input-atmel_mxt_ts-add-new-object-types.patch
new file mode 100644
index 0000000..cb1823a
--- /dev/null
+++ b/patches/linux-3.8.13/0530-CHROMIUM-Input-atmel_mxt_ts-add-new-object-types.patch
@@ -0,0 +1,78 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Wed, 4 Apr 2012 17:19:55 -0700
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - add new object types
+
+Add new object types to support newer mxt devices.
+
+BUG=chrome-os-partner:8732
+TEST=None yet.
+
+Change-Id: I5b7c8987ec4d98fc678a939154b7a057338037bd
+Signed-off-by: Benson Leung <bleung@chromium.org>
+Reviewed-on: https://gerrit.chromium.org/gerrit/19638
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 66b6f70..4d67eeb 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -75,6 +75,10 @@
+ #define MXT_PROCI_TOUCHSUPPRESSION_T42 42
+ #define MXT_PROCI_STYLUS_T47 47
+ #define MXT_PROCG_NOISESUPPRESSION_T48 48
++#define MXT_PROCI_ADAPTIVETHRESHOLD_T55 55
++#define MXT_PROCI_SHIELDLESS_T56 56
++#define MXT_PROCI_EXTRATOUCHSCREENDATA_T57 57
++#define MXT_PROCG_NOISESUPPRESSION_T62 62
+ #define MXT_SPT_COMMSCONFIG_T18 18
+ #define MXT_SPT_GPIOPWM_T19 19
+ #define MXT_SPT_SELFTEST_T25 25
+@@ -83,6 +87,7 @@
+ #define MXT_SPT_DIGITIZER_T43 43
+ #define MXT_SPT_MESSAGECOUNT_T44 44
+ #define MXT_SPT_CTECONFIG_T46 46
++#define MXT_SPT_TIMER_T61 61
+
+ /* MXT_GEN_COMMAND_T6 field */
+ #define MXT_COMMAND_RESET 0
+@@ -339,6 +344,10 @@ static bool mxt_object_readable(unsigned int type)
+ case MXT_PROCI_TOUCHSUPPRESSION_T42:
+ case MXT_PROCI_STYLUS_T47:
+ case MXT_PROCG_NOISESUPPRESSION_T48:
++ case MXT_PROCI_ADAPTIVETHRESHOLD_T55:
++ case MXT_PROCI_SHIELDLESS_T56:
++ case MXT_PROCI_EXTRATOUCHSCREENDATA_T57:
++ case MXT_PROCG_NOISESUPPRESSION_T62:
+ case MXT_SPT_COMMSCONFIG_T18:
+ case MXT_SPT_GPIOPWM_T19:
+ case MXT_SPT_SELFTEST_T25:
+@@ -346,6 +355,7 @@ static bool mxt_object_readable(unsigned int type)
+ case MXT_SPT_USERDATA_T38:
+ case MXT_SPT_DIGITIZER_T43:
+ case MXT_SPT_CTECONFIG_T46:
++ case MXT_SPT_TIMER_T61:
+ return true;
+ default:
+ return false;
+@@ -371,12 +381,17 @@ static bool mxt_object_writable(unsigned int type)
+ case MXT_PROCI_TOUCHSUPPRESSION_T42:
+ case MXT_PROCI_STYLUS_T47:
+ case MXT_PROCG_NOISESUPPRESSION_T48:
++ case MXT_PROCI_ADAPTIVETHRESHOLD_T55:
++ case MXT_PROCI_SHIELDLESS_T56:
++ case MXT_PROCI_EXTRATOUCHSCREENDATA_T57:
++ case MXT_PROCG_NOISESUPPRESSION_T62:
+ case MXT_SPT_COMMSCONFIG_T18:
+ case MXT_SPT_GPIOPWM_T19:
+ case MXT_SPT_SELFTEST_T25:
+ case MXT_SPT_CTECONFIG_T28:
+ case MXT_SPT_DIGITIZER_T43:
+ case MXT_SPT_CTECONFIG_T46:
++ case MXT_SPT_TIMER_T61:
+ return true;
+ default:
+ return false;
diff --git a/patches/linux-3.8.13/0531-CHROMIUM-INPUT-atmel_mxt_ts-Increase-the-wait-times-.patch b/patches/linux-3.8.13/0531-CHROMIUM-INPUT-atmel_mxt_ts-Increase-the-wait-times-.patch
new file mode 100644
index 0000000..ca2e2b0
--- /dev/null
+++ b/patches/linux-3.8.13/0531-CHROMIUM-INPUT-atmel_mxt_ts-Increase-the-wait-times-.patch
@@ -0,0 +1,48 @@
+From: Iiro Valkonen <iiro.valkonen@atmel.com>
+Date: Fri, 29 Apr 2011 09:37:45 -0400
+Subject: [PATCH] CHROMIUM: INPUT: atmel_mxt_ts - Increase the wait times for
+ backup and reset
+
+Increase the sleep times after backup and reset, so that we can be sure they have been completed even when the mXT cycle time is set to maximum value (254ms).
+
+Signed-off-by: Iiro Valkonen <iiro.valkonen@atmel.com>
+Patch is in progress of being submitted at http://www.spinics.net/lists/linux-input/msg14593.html
+Signed-off-by: Jon Kliegman <kliegs@chromium.org>
+
+R=olofj@chromium.org, msb@chromium.org
+BUG=chromium-os:13514
+TEST=Built kernel
+ Validated kernel boots fine
+ Validated in conjunction with other CLs in bug that the driver works
+
+Cherrypicking forward to 3.0 branch from 2.6.38
+(cherry picked from commit 1ebffd5d7df2202b20eee3c906096ff7f1d6c56a)
+
+Cherrypicking forward to 2.6.38 branch from http://codereview.chromium.org/6711073
+(cherry picked from commit 4dc5fe662e1352e12181ba4cfeb0f8333486c882)
+
+Review URL: http://codereview.chromium.org/6893098
+Patch from Iiro Valkonen <iiro.valkonen@atmel.com>.
+
+Change-Id: I487c75fd05d5eb7b6223b5a3b79d34076d096726
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+Reviewed-on: http://gerrit.chromium.org/gerrit/8773
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 4d67eeb..2f22ae1 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -195,8 +195,8 @@
+ /* Define for MXT_GEN_COMMAND_T6 */
+ #define MXT_BOOT_VALUE 0xa5
+ #define MXT_BACKUP_VALUE 0x55
+-#define MXT_BACKUP_TIME 25 /* msec */
+-#define MXT_RESET_TIME 65 /* msec */
++#define MXT_BACKUP_TIME 270 /* msec */
++#define MXT_RESET_TIME 350 /* msec */
+ #define MXT_CAL_TIME 25 /* msec */
+
+ #define MXT_FWRESET_TIME 500 /* msec */
diff --git a/patches/linux-3.8.13/0532-CHROMIUM-Input-atmel_mxt_ts-dump-mxt_read-write_reg.patch b/patches/linux-3.8.13/0532-CHROMIUM-Input-atmel_mxt_ts-dump-mxt_read-write_reg.patch
new file mode 100644
index 0000000..ba3816a
--- /dev/null
+++ b/patches/linux-3.8.13/0532-CHROMIUM-Input-atmel_mxt_ts-dump-mxt_read-write_reg.patch
@@ -0,0 +1,91 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Wed, 15 Feb 2012 16:32:02 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - dump mxt_read/write_reg
+
+For verbose on-the-wire debugging.
+Prints DUMP_LEN bytes (in hex) per line.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chromium-os:27713
+TEST=builds clean w/ & w/out DEBUG defined.
+ If DEBUG defined, bytes read & written over i2c by atmel_mxt_ts should
+ appear in /var/log/messages
+
+Change-Id: Ib1b8301a25bb915fea47e4dd62ff261ae5284c3c
+Reviewed-on: https://gerrit.chromium.org/gerrit/17943
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 35 +++++++++++++++++++++++++++++-
+ 1 file changed, 34 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 2f22ae1..50fe84a 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -546,11 +546,39 @@ static int mxt_fw_write(struct i2c_client *client,
+ return mxt_i2c_send(client, data, frame_size);
+ }
+
++#ifdef DEBUG
++#define DUMP_LEN 16
++static void mxt_dump_xfer(struct device *dev, const char *func, u16 reg,
++ u16 len, const u8 *val)
++{
++ /* Rough guess for string size */
++ char str[DUMP_LEN * 3 + 2];
++ int i;
++ size_t n;
++
++ for (i = 0, n = 0; i < len; i++) {
++ n += snprintf(&str[n], sizeof(str) - n, "%02x ", val[i]);
++ if ((i + 1) % DUMP_LEN == 0 || (i + 1) == len) {
++ dev_dbg(dev,
++ "%s(reg: %d len: %d offset: 0x%02x): %s\n",
++ func, reg, len, (i / DUMP_LEN) * DUMP_LEN,
++ str);
++ n = 0;
++ }
++ }
++}
++#undef DUMP_LEN
++#else
++static void mxt_dump_xfer(struct device *dev, const char *func, u16 reg,
++ u16 len, const u8 *val) { }
++#endif
++
+ static int __mxt_read_reg(struct i2c_client *client,
+ u16 reg, u16 len, void *val)
+ {
+ struct i2c_msg xfer[2];
+ u8 buf[2];
++ int ret;
+
+ buf[0] = reg & 0xff;
+ buf[1] = (reg >> 8) & 0xff;
+@@ -567,7 +595,11 @@ static int __mxt_read_reg(struct i2c_client *client,
+ xfer[1].len = len;
+ xfer[1].buf = val;
+
+- return mxt_i2c_transfer(client, xfer, 2);
++ ret = mxt_i2c_transfer(client, xfer, 2);
++ if (ret == 0)
++ mxt_dump_xfer(&client->dev, __func__, reg, len, val);
++
++ return ret;
+ }
+
+ static int mxt_read_reg(struct i2c_client *client, u16 reg, u8 *val)
+@@ -591,6 +623,7 @@ static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len,
+ buf[1] = (reg >> 8) & 0xff;
+ memcpy(&buf[2], val, len);
+
++ mxt_dump_xfer(&client->dev, __func__, reg, len, val);
+ ret = mxt_i2c_send(client, buf, count);
+ kfree(buf);
+ return ret;
diff --git a/patches/linux-3.8.13/0533-CHROMIUM-Input-atmel_mxt_ts-take-an-instance-for-mxt.patch b/patches/linux-3.8.13/0533-CHROMIUM-Input-atmel_mxt_ts-take-an-instance-for-mxt.patch
new file mode 100644
index 0000000..1a93854
--- /dev/null
+++ b/patches/linux-3.8.13/0533-CHROMIUM-Input-atmel_mxt_ts-take-an-instance-for-mxt.patch
@@ -0,0 +1,59 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Wed, 12 Dec 2012 15:27:51 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - take an instance for
+ mxt_write_object
+
+Objects in the object table can have multiple instances.
+Force writes to specify a particular instance.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chromium-os:27713
+TEST=build clean; atmel touch device configured and enabled correctly.
+
+Change-Id: Ic7208b2b994b490528cce7b2d780bf5497e0d1db
+Reviewed-on: https://gerrit.chromium.org/gerrit/18432
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 50fe84a..d07732d 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -665,18 +665,24 @@ static int mxt_read_message(struct mxt_data *data,
+ sizeof(struct mxt_message), message);
+ }
+
+-static int mxt_write_object(struct mxt_data *data,
+- u8 type, u8 offset, u8 val)
++static int mxt_write_obj_instance(struct mxt_data *data, u8 type, u8 instance,
++ u8 offset, u8 val)
+ {
+ struct mxt_object *object;
+ u16 reg;
+
+ object = mxt_get_object(data, type);
+- if (!object || offset >= mxt_obj_size(object))
++ if (!object || offset >= mxt_obj_size(object) ||
++ instance >= mxt_obj_instances(object))
+ return -EINVAL;
+
+- reg = object->start_address;
+- return mxt_write_reg(data->client, reg + offset, val);
++ reg = object->start_address + instance * mxt_obj_size(object) + offset;
++ return mxt_write_reg(data->client, reg, val);
++}
++
++static int mxt_write_object(struct mxt_data *data, u8 type, u8 offset, u8 val)
++{
++ return mxt_write_obj_instance(data, type, 0, offset, val);
+ }
+
+ static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
diff --git a/patches/linux-3.8.13/0534-CHROMIUM-Input-atmel_mxt_ts-allow-writing-to-object-.patch b/patches/linux-3.8.13/0534-CHROMIUM-Input-atmel_mxt_ts-allow-writing-to-object-.patch
new file mode 100644
index 0000000..6558816
--- /dev/null
+++ b/patches/linux-3.8.13/0534-CHROMIUM-Input-atmel_mxt_ts-allow-writing-to-object-.patch
@@ -0,0 +1,108 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Mon, 19 Mar 2012 09:39:12 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - allow writing to object
+ sysfs entry
+
+Userspace can write a 32-bit value (encoded as a 8 character hex string)
+to the 'object' sysfs entry to modify a single byte of the object table.
+The hex string encodes 4 bytes, in the following format:
+
+ TTIIFFVV
+
+Where:
+ TT = object type (atmel 'T' number)
+ II = object instance (0-indexes, so 0 is the first instance)
+ FF = object offset
+ VV = byte value
+
+The object table is modified in device ram, which means the change is
+volatile, and will be overwritten on the next device reset. To make
+changes permanent, the new settings should be persisted in the device's
+Non-Voltatile Memory using the updatenv sysfs entry.
+
+Also, since the device driver initializes itself by reading some values
+from the object table, the entire driver may need to be unloaded and
+reloaded after writing the values for the driver to stay in sync. Whether
+this is required depends on exactly which values were updated.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chromium-os:27713
+TEST=ls -l /sys/.../object
+ --wr--r--r 1 root root 4096 Feb 14 20:54 update_fw
+
+ (0) confirm current number of fingers (look for (Type 9, Offset 14)):
+ $ cat /sys/.../object
+ (1) Change number of reported fingers (Type: 0x09, Offset: 0x0e) to 7:
+ $ echo -n "090e07" > /sys/.../object
+ (2) confirm current number of fingers (look for (Type 9, Offset 14)):
+ $ cat /sys/.../object
+ (3) using mtplot, notice that there now up to 7 fingers are reported.
+ (4) reboot, and verify that the old number of fingers is restored.
+TEST=Trying to write to a non-existant instance, or past the length of
+ an object, should fail. For example:
+ echo -n "070005ab" > /sys/bus/i2c/devices/<dev>/object
+ => -bash: echo: write error: Invalid argument
+
+Change-Id: I8149770f762a84ef457c7bf4aefdb310d07c52c5
+Reviewed-on: https://gerrit.chromium.org/gerrit/17944
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 32 +++++++++++++++++++++++++++++-
+ 1 file changed, 31 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index d07732d..120d766 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -1552,6 +1552,35 @@ done:
+ return error ?: count;
+ }
+
++static ssize_t mxt_object_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct mxt_data *data = dev_get_drvdata(dev);
++ int ret;
++ u32 param;
++ u8 type, instance, offset, val;
++
++ ret = kstrtou32(buf, 16, &param);
++ if (ret < 0)
++ return -EINVAL;
++
++ /*
++ * Byte Write Command is encoded in 32-bit word: TTIIOOVV:
++ * <Type> <Instance> <Offset> <Value>
++ */
++ type = (param & 0xff000000) >> 24;
++ instance = (param & 0x00ff0000) >> 16;
++ offset = (param & 0x0000ff00) >> 8;
++ val = param & 0x000000ff;
++
++ ret = mxt_write_obj_instance(data, type, instance, offset, val);
++ if (ret)
++ return ret;
++
++ return count;
++}
++
+ static int mxt_load_fw(struct device *dev, const char *fn)
+ {
+ struct mxt_data *data = dev_get_drvdata(dev);
+@@ -1639,7 +1668,8 @@ static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL);
+ static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL);
+ static DEVICE_ATTR(info_csum, S_IRUGO, mxt_info_csum_show, NULL);
+ static DEVICE_ATTR(matrix_size, S_IRUGO, mxt_matrix_size_show, NULL);
+-static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL);
++static DEVICE_ATTR(object, S_IRUGO | S_IWUSR, mxt_object_show,
++ mxt_object_store);
+ static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);
+
+ static struct attribute *mxt_attrs[] = {
diff --git a/patches/linux-3.8.13/0535-CHROMIUM-Input-atmel_mxt_ts-add-backupnv-sysfs-entry.patch b/patches/linux-3.8.13/0535-CHROMIUM-Input-atmel_mxt_ts-add-backupnv-sysfs-entry.patch
new file mode 100644
index 0000000..e34db9d
--- /dev/null
+++ b/patches/linux-3.8.13/0535-CHROMIUM-Input-atmel_mxt_ts-add-backupnv-sysfs-entry.patch
@@ -0,0 +1,72 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Mon, 19 Mar 2012 10:09:41 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - add backupnv sysfs entry
+
+Writing to the object sysfs entry permits individual object table entries
+to be modified in the device RAM at runtime. To permanently save
+the settings, they must be written to Non-Volatile memory (NVM).
+This patch adds a write-only sysfs entry to allow userspace to save
+current settings to NVM, but restricts access to root.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chromium-os:27713
+TEST=ls -al /sys/.../backupnv
+ -> --w------- 1 root root 4096 Feb 14 20:54 backupnv
+
+Change-Id: Id767e0b7ef7f882d6a45ebfe7e96e02800ef2cb8
+Reviewed-on: https://gerrit.chromium.org/gerrit/17945
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 120d766..c2891f2 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -1427,6 +1427,23 @@ out:
+ return ret ?: 0;
+ }
+
++static ssize_t mxt_backupnv_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct mxt_data *data = dev_get_drvdata(dev);
++ int ret;
++
++ /* Backup non-volatile memory */
++ ret = mxt_write_object(data, MXT_GEN_COMMAND_T6,
++ MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE);
++ if (ret)
++ return ret;
++ msleep(MXT_BACKUP_TIME);
++
++ return count;
++}
++
+ static ssize_t mxt_calibrate_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+@@ -1662,6 +1679,7 @@ static ssize_t mxt_update_fw_store(struct device *dev,
+ return count;
+ }
+
++static DEVICE_ATTR(backupnv, S_IWUSR, NULL, mxt_backupnv_store);
+ static DEVICE_ATTR(calibrate, S_IWUSR, NULL, mxt_calibrate_store);
+ static DEVICE_ATTR(config_csum, S_IRUGO, mxt_config_csum_show, NULL);
+ static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL);
+@@ -1673,6 +1691,7 @@ static DEVICE_ATTR(object, S_IRUGO | S_IWUSR, mxt_object_show,
+ static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);
+
+ static struct attribute *mxt_attrs[] = {
++ &dev_attr_backupnv.attr,
+ &dev_attr_calibrate.attr,
+ &dev_attr_config_csum.attr,
+ &dev_attr_fw_version.attr,
diff --git a/patches/linux-3.8.13/0536-CHROMIUM-Input-atmel_mxt_ts-read-num-messages-then-a.patch b/patches/linux-3.8.13/0536-CHROMIUM-Input-atmel_mxt_ts-read-num-messages-then-a.patch
new file mode 100644
index 0000000..e1c36fc
--- /dev/null
+++ b/patches/linux-3.8.13/0536-CHROMIUM-Input-atmel_mxt_ts-read-num-messages-then-a.patch
@@ -0,0 +1,237 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Mon, 19 Mar 2012 09:42:09 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - read num messages, then all
+ messages
+
+Implement the MXT DMA method of reading messages.
+On an interrupt, the T44 report always contains the number of messages
+pending to be read. So, read 1 byte from T44 in 1 i2c transaction, then
+read the N pending messages in a second transaction.
+
+The end result is a much much faster read time for all pending messages.
+Using 400kHz i2c, it is possible to read 10 pending messages (e.g. for 10
+moving contatcts) in less than 2.8ms, which is well less than the typical
+10-15ms update rate.
+
+Note: There is a possible optimization here. The T44 byte is guaranteed
+to always be right before the T5 address. Thus, it should be possible
+to always fetch the T44 message count and the first message in a single
+transaction. This would eliminate the overhead of a second complete read
+transaction for the case where there is only a single pending message.
+(This is actually the most common case, for instance with just 1-contact
+on the device touch surface). This optimization, however, is not done in
+this patch.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chromium-os:27713
+TEST=builds clean; all pending messages are processed for each interrupt.
+
+Change-Id: I9aa4627d2afdc6da14b7495e78c429d1c4ded7ae
+Reviewed-on: https://gerrit.chromium.org/gerrit/17956
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 138 +++++++++++++++++++-----------
+ 1 file changed, 90 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index c2891f2..8c29fb3 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -286,10 +286,12 @@ struct mxt_data {
+ u32 config_csum;
+
+ /* Cached parameters from object table */
++ u16 T5_address;
+ u8 T6_reportid;
+ u8 T9_reportid_min;
+ u8 T9_reportid_max;
+ u8 T19_reportid;
++ u16 T44_address;
+
+ /* for fw update in bootloader */
+ struct completion bl_completion;
+@@ -650,19 +652,23 @@ mxt_get_object(struct mxt_data *data, u8 type)
+ return NULL;
+ }
+
+-static int mxt_read_message(struct mxt_data *data,
+- struct mxt_message *message)
++static int mxt_read_num_messages(struct mxt_data *data, u8 *count)
+ {
+- struct mxt_object *object;
+- u16 reg;
++ /* TODO: Optimization: read first message along with message count */
++ return __mxt_read_reg(data->client, data->T44_address, 1, count);
++}
+
+- object = mxt_get_object(data, MXT_GEN_MESSAGE_T5);
+- if (!object)
+- return -EINVAL;
++static int mxt_read_messages(struct mxt_data *data, u8 count,
++ struct mxt_message *messages)
++{
++ return __mxt_read_reg(data->client, data->T5_address,
++ sizeof(struct mxt_message) * count, messages);
++}
+
+- reg = object->start_address;
+- return __mxt_read_reg(data->client, reg,
+- sizeof(struct mxt_message), message);
++static int mxt_read_message(struct mxt_data *data,
++ struct mxt_message *message)
++{
++ return mxt_read_messages(data, 1, message);
+ }
+
+ static int mxt_write_obj_instance(struct mxt_data *data, u8 type, u8 instance,
+@@ -773,6 +779,72 @@ static bool mxt_is_T9_message(struct mxt_data *data, struct mxt_message *msg)
+ return (id >= data->T9_reportid_min && id <= data->T9_reportid_max);
+ }
+
++static int mxt_proc_messages(struct mxt_data *data, u8 count)
++{
++ struct device *dev = &data->client->dev;
++ u8 reportid;
++ bool update_input = false;
++ struct mxt_message *messages, *msg;
++ int ret;
++
++ messages = kcalloc(count, sizeof(*messages), GFP_KERNEL);
++ if (!messages)
++ return -ENOMEM;
++
++ ret = mxt_read_messages(data, count, messages);
++ if (ret) {
++ dev_err(dev, "Failed to read %u messages (%d).\n", count, ret);
++ goto out;
++ }
++
++ for (msg = messages; msg < &messages[count]; msg++) {
++ mxt_dump_message(dev, msg);
++ reportid = msg->reportid;
++
++ if (reportid == data->T6_reportid) {
++ const u8 *payload = &msg->message[0];
++ u8 status = payload[0];
++ data->config_csum = mxt_extract_T6_csum(&payload[1]);
++ dev_dbg(dev, "Status: %02x Config Checksum: %06x\n",
++ status, data->config_csum);
++ } else if (mxt_is_T9_message(data, msg)) {
++ int id = reportid - data->T9_reportid_min;
++ mxt_input_touchevent(data, msg, id);
++ update_input = true;
++ } else if (msg->reportid == data->T19_reportid) {
++ mxt_input_button(data, msg);
++ update_input = true;
++ }
++ }
++
++ if (update_input) {
++ input_mt_report_pointer_emulation(data->input_dev, false);
++ input_sync(data->input_dev);
++ }
++
++out:
++ kfree(messages);
++ return ret;
++}
++
++static int mxt_handle_messages(struct mxt_data *data)
++{
++ struct device *dev = &data->client->dev;
++ int ret;
++ u8 count;
++
++ ret = mxt_read_num_messages(data, &count);
++ if (ret) {
++ dev_err(dev, "Failed to read message count (%d).\n", ret);
++ return ret;
++ }
++
++ if (count > 0)
++ ret = mxt_proc_messages(data, count);
++
++ return ret;
++}
++
+ static int mxt_enter_bl(struct mxt_data *data)
+ {
+ struct i2c_client *client = data->client;
+@@ -863,49 +935,13 @@ static void mxt_exit_bl(struct mxt_data *data)
+ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
+ {
+ struct mxt_data *data = dev_id;
+- struct mxt_message message;
+- const u8 *payload = &message.message[0];
+- struct device *dev = &data->client->dev;
+- u8 reportid;
+- bool update_input = false;
+
+ if (mxt_in_bootloader(data)) {
+ /* bootloader state transition completion */
+ complete(&data->bl_completion);
+- goto end;
+- }
+-
+- do {
+- if (mxt_read_message(data, &message)) {
+- dev_err(dev, "Failed to read message\n");
+- goto end;
+- }
+-
+- reportid = message.reportid;
+-
+- if (reportid == data->T6_reportid) {
+- u8 status = payload[0];
+- data->config_csum = mxt_extract_T6_csum(&payload[1]);
+- dev_dbg(dev, "Status: %02x Config Checksum: %06x\n",
+- status, data->config_csum);
+- } else if (mxt_is_T9_message(data, &message)) {
+- int id = reportid - data->T9_reportid_min;
+- mxt_input_touchevent(data, &message, id);
+- update_input = true;
+- } else if (message.reportid == data->T19_reportid) {
+- mxt_input_button(data, &message);
+- update_input = true;
+- } else {
+- mxt_dump_message(dev, &message);
+- }
+- } while (reportid != 0xff);
+-
+- if (update_input) {
+- input_mt_report_pointer_emulation(data->input_dev, false);
+- input_sync(data->input_dev);
++ } else {
++ mxt_handle_messages(data);
+ }
+-
+-end:
+ return IRQ_HANDLED;
+ }
+
+@@ -1151,6 +1187,9 @@ static int mxt_get_object_table(struct mxt_data *data)
+ min_id, max_id);
+
+ switch (object->type) {
++ case MXT_GEN_MESSAGE_T5:
++ data->T5_address = object->start_address;
++ break;
+ case MXT_GEN_COMMAND_T6:
+ data->T6_reportid = min_id;
+ break;
+@@ -1161,6 +1200,9 @@ static int mxt_get_object_table(struct mxt_data *data)
+ case MXT_SPT_GPIOPWM_T19:
+ data->T19_reportid = min_id;
+ break;
++ case MXT_SPT_MESSAGECOUNT_T44:
++ data->T44_address = object->start_address;
++ break;
+ }
+ }
+
diff --git a/patches/linux-3.8.13/0537-CHROMIUM-Input-atmel_mxt_ts-remove-mxt_make_highchg.patch b/patches/linux-3.8.13/0537-CHROMIUM-Input-atmel_mxt_ts-remove-mxt_make_highchg.patch
new file mode 100644
index 0000000..63c45ff
--- /dev/null
+++ b/patches/linux-3.8.13/0537-CHROMIUM-Input-atmel_mxt_ts-remove-mxt_make_highchg.patch
@@ -0,0 +1,104 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Wed, 19 Dec 2012 17:48:36 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - remove mxt_make_highchg
+
+This function attempts to make the CHG pin high by reading a messages
+until the device queue is empty.
+
+Instead of throwing away the message contents, let's actually process them.
+Also, instead of stopping after a fixed (10) number of messages, keep
+reading until the device reports that it has no more valid messages - at
+that point, the CHG line should truly be high.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chromium-os:27713
+TEST=builds clean; messages after boot are processed;
+ Config Checksum displayed in dmesg:
+ $ grep "Config Checksum" /var/log/messages
+
+Change-Id: I3d1e266d1ac53f5640e65c5acc3fe6672a0c1451
+Reviewed-on: https://gerrit.chromium.org/gerrit/17957
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Benson Leung <bleung@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 33 ++----------------------------
+ 1 file changed, 2 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 8c29fb3..8dfdba9 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -314,7 +314,6 @@ static int mxt_calc_resolution(struct mxt_data *data);
+ static void mxt_free_object_table(struct mxt_data *data);
+ static int mxt_initialize(struct mxt_data *data);
+ static int mxt_input_dev_create(struct mxt_data *data);
+-static int mxt_make_highchg(struct mxt_data *data);
+
+ static inline size_t mxt_obj_size(const struct mxt_object *obj)
+ {
+@@ -665,12 +664,6 @@ static int mxt_read_messages(struct mxt_data *data, u8 count,
+ sizeof(struct mxt_message) * count, messages);
+ }
+
+-static int mxt_read_message(struct mxt_data *data,
+- struct mxt_message *message)
+-{
+- return mxt_read_messages(data, 1, message);
+-}
+-
+ static int mxt_write_obj_instance(struct mxt_data *data, u8 type, u8 instance,
+ u8 offset, u8 val)
+ {
+@@ -925,7 +918,7 @@ static void mxt_exit_bl(struct mxt_data *data)
+ return;
+ }
+
+- error = mxt_make_highchg(data);
++ error = mxt_handle_messages(data);
+ if (error)
+ dev_err(dev, "Failed to clear CHG after init. error = %d\n",
+ error);
+@@ -981,28 +974,6 @@ static int mxt_check_reg_init(struct mxt_data *data)
+ return 0;
+ }
+
+-static int mxt_make_highchg(struct mxt_data *data)
+-{
+- struct device *dev = &data->client->dev;
+- struct mxt_message message;
+- int count = 10;
+- int error;
+-
+- /* Read dummy message to make high CHG pin */
+- do {
+- error = mxt_read_message(data, &message);
+- if (error)
+- return error;
+- } while (message.reportid != 0xff && --count);
+-
+- if (!count) {
+- dev_err(dev, "CHG pin isn't cleared\n");
+- return -EBUSY;
+- }
+-
+- return 0;
+-}
+-
+ static void mxt_handle_pdata(struct mxt_data *data)
+ {
+ const struct mxt_platform_data *pdata = data->pdata;
+@@ -2025,7 +1996,7 @@ static int __devinit mxt_probe(struct i2c_client *client,
+ }
+
+ if (!mxt_in_bootloader(data)) {
+- error = mxt_make_highchg(data);
++ error = mxt_handle_messages(data);
+ if (error)
+ goto err_free_irq;
+ }
diff --git a/patches/linux-3.8.13/0538-CHROMIUM-Input-atmel_mxt_ts-Remove-matrix-size-updat.patch b/patches/linux-3.8.13/0538-CHROMIUM-Input-atmel_mxt_ts-Remove-matrix-size-updat.patch
new file mode 100644
index 0000000..c1cdfc7
--- /dev/null
+++ b/patches/linux-3.8.13/0538-CHROMIUM-Input-atmel_mxt_ts-Remove-matrix-size-updat.patch
@@ -0,0 +1,64 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Tue, 1 May 2012 17:31:04 -0400
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Remove matrix size update
+
+The matrix x/y size in the Info Block represents the max x/y lines
+availble on the device and it will only be updated by the firmware
+but not the platform data configuration, which sets the x/y lines
+in T9 object.
+
+BUG=None
+TEST=None
+
+Change-Id: I18e4f9855fe2018c2b55256ce25821a6197b9f81
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+Reviewed-on: https://gerrit.chromium.org/gerrit/21547
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 17 -----------------
+ 1 file changed, 17 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 8dfdba9..71a5317 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -603,11 +603,6 @@ static int __mxt_read_reg(struct i2c_client *client,
+ return ret;
+ }
+
+-static int mxt_read_reg(struct i2c_client *client, u16 reg, u8 *val)
+-{
+- return __mxt_read_reg(client, reg, 1, val);
+-}
+-
+ static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len,
+ const void *val)
+ {
+@@ -1195,7 +1190,6 @@ static int mxt_initialize(struct mxt_data *data)
+ struct i2c_client *client = data->client;
+ struct mxt_info *info = &data->info;
+ int error;
+- u8 val;
+
+ error = mxt_get_info(data);
+ if (error)
+@@ -1235,17 +1229,6 @@ static int mxt_initialize(struct mxt_data *data)
+ return error;
+ msleep(MXT_RESET_TIME);
+
+- /* Update matrix size at info struct */
+- error = mxt_read_reg(client, MXT_MATRIX_X_SIZE, &val);
+- if (error)
+- goto err_free_object_table;
+- info->matrix_xsize = val;
+-
+- error = mxt_read_reg(client, MXT_MATRIX_Y_SIZE, &val);
+- if (error)
+- goto err_free_object_table;
+- info->matrix_ysize = val;
+-
+ dev_info(&client->dev,
+ "Family ID: %u Variant ID: %u Major.Minor.Build: %u.%u.%02X\n",
+ info->family_id, info->variant_id, info->version >> 4,
diff --git a/patches/linux-3.8.13/0539-CHROMIUM-Input-atmel_mxt_ts-parse-vector-field-of-da.patch b/patches/linux-3.8.13/0539-CHROMIUM-Input-atmel_mxt_ts-parse-vector-field-of-da.patch
new file mode 100644
index 0000000..53f60b1
--- /dev/null
+++ b/patches/linux-3.8.13/0539-CHROMIUM-Input-atmel_mxt_ts-parse-vector-field-of-da.patch
@@ -0,0 +1,69 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Mon, 20 Feb 2012 23:35:06 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - parse vector field of data
+ packets
+
+The atmel_mxt_ts T9 data contains information orientation in its 'vector'
+field. Parse and debug print its contents, although its value isn't
+actually used yet.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chromium-os:27713
+TEST=builds clean; vector values are reported when DEBUG is defined.
+
+Change-Id: Ida4d9aa167e5134c76d044599240a6c7e329a62c
+Reviewed-on: https://gerrit.chromium.org/gerrit/17951
+Commit-Ready: Daniel Kurtz <djkurtz@chromium.org>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Tested-by: Daniel Kurtz <djkurtz@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 71a5317..1882e14 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -719,6 +719,7 @@ static void mxt_input_touchevent(struct mxt_data *data,
+ int area;
+ int pressure;
+ int touch_major;
++ int vector1, vector2;
+
+ x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf);
+ y = (message->message[2] << 4) | ((message->message[3] & 0xf));
+@@ -731,8 +732,12 @@ static void mxt_input_touchevent(struct mxt_data *data,
+ touch_major = get_touch_major_pixels(data, area);
+ pressure = message->message[5];
+
++ /* The two vector components are 4-bit signed ints (2s complement) */
++ vector1 = (signed)((signed char)message->message[6]) >> 4;
++ vector2 = (signed)((signed char)(message->message[6] << 4)) >> 4;
++
+ dev_dbg(dev,
+- "[%u] %c%c%c%c%c%c%c%c x: %5u y: %5u area: %3u amp: %3u\n",
++ "[%u] %c%c%c%c%c%c%c%c x: %5u y: %5u area: %3u amp: %3u vector: [%d,%d]\n",
+ id,
+ (status & MXT_DETECT) ? 'D' : '.',
+ (status & MXT_PRESS) ? 'P' : '.',
+@@ -742,7 +747,7 @@ static void mxt_input_touchevent(struct mxt_data *data,
+ (status & MXT_AMP) ? 'A' : '.',
+ (status & MXT_SUPPRESS) ? 'S' : '.',
+ (status & MXT_UNGRIP) ? 'U' : '.',
+- x, y, area, pressure);
++ x, y, area, pressure, vector1, vector2);
+
+ input_mt_slot(input_dev, id);
+ input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
+@@ -753,6 +758,7 @@ static void mxt_input_touchevent(struct mxt_data *data,
+ input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
+ input_report_abs(input_dev, ABS_MT_PRESSURE, pressure);
+ input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, touch_major);
++ /* TODO: Use vector to report ORIENTATION & TOUCH_MINOR */
+ }
+ }
+
diff --git a/patches/linux-3.8.13/0540-CHROMIUM-Input-atmel_mxt_ts-Add-IDLE-DEEP-SLEEP-mode.patch b/patches/linux-3.8.13/0540-CHROMIUM-Input-atmel_mxt_ts-Add-IDLE-DEEP-SLEEP-mode.patch
new file mode 100644
index 0000000..639a5de
--- /dev/null
+++ b/patches/linux-3.8.13/0540-CHROMIUM-Input-atmel_mxt_ts-Add-IDLE-DEEP-SLEEP-mode.patch
@@ -0,0 +1,226 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Fri, 4 May 2012 20:47:32 -0400
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Add IDLE/DEEP-SLEEP modes
+ when suspend
+
+Currently when system enters/leaves sleep mode, the driver dis/enables
+T9 object. It has the limitation that 1) it does not allow the device
+to wakeup the system 2) the device is not in it's best power saving mode
+when the system is sleeping.
+
+This patch adds the support to put the device into 1) Idle mode, when the
+need of wakeup from sleep is needed 2) Deepsleep mode when wakeup from
+sleep is not needed.
+
+To achieve this, when the system enters sleep mode, the current T7 Power
+Config value is first saved and then it is re-configured to be Idle mode
+(with largest Idle Acquisition Interval and largest Active Acquisition
+Interval) or Deepsleep mode. Also if wakeup from sleep is needed, the
+current T9 Ctrl field is saved and a resonable value 0x03 is used to
+enable T9 so that we can be sure touch contact will generate IRQ to wake
+the system up.
+
+When resume, before-suspend T7 and T9 values are restored accordingly.
+
+BUG=chrome-os-partner:9413
+TEST=On system with atmel trackpad
+ cd /sys/bus/i2c/drivers/atmel_mxt_ts/2-004b/power
+ echo "enabled" > wakeup
+ powerd_suspend
+ touch trackpad should wakeup the system
+ echo "disabled" > wakeup
+ powerd_suspend
+ touch trackpad should not wakeup the system
+
+Change-Id: I85896691ddd69d854a923f548edf8b7d6caa9f8e
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+Reviewed-on: https://gerrit.chromium.org/gerrit/21919
+Reviewed-by: Benson Leung <bleung@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 134 ++++++++++++++++++++++++++++--
+ 1 file changed, 127 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 1882e14..0804795 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -305,6 +305,20 @@ struct mxt_data {
+ struct mutex T37_buf_mutex;
+ u8 *T37_buf;
+ size_t T37_buf_size;
++
++ /* Saved T7 configuration
++ * [0] = IDLEACQINT
++ * [1] = ACTVACQINT
++ * [2] = ACTV2IDLETO
++ */
++ u8 T7_config[3];
++ bool T7_config_valid;
++
++ /* Saved T9 Ctrl field */
++ u8 T9_ctrl;
++ bool T9_ctrl_valid;
++
++ bool irq_wake; /* irq wake is enabled */
+ };
+
+ /* global root node of the atmel_mxt_ts debugfs directory. */
+@@ -1824,6 +1838,44 @@ static int mxt_debugfs_init(struct mxt_data *mxt)
+ return 0;
+ }
+
++static int mxt_save_regs(struct mxt_data *data, u8 type, u8 instance,
++ u8 offset, u8 *val, u16 size)
++{
++ struct mxt_object *object;
++ u16 addr;
++ int ret;
++
++ object = mxt_get_object(data, type);
++ if (!object)
++ return -EINVAL;
++
++ addr = object->start_address + instance * mxt_obj_size(object) + offset;
++ ret = __mxt_read_reg(data->client, addr, size, val);
++ if (ret)
++ return -EINVAL;
++
++ return 0;
++}
++
++static int mxt_set_regs(struct mxt_data *data, u8 type, u8 instance,
++ u8 offset, const u8 *val, u16 size)
++{
++ struct mxt_object *object;
++ u16 addr;
++ int ret;
++
++ object = mxt_get_object(data, type);
++ if (!object)
++ return -EINVAL;
++
++ addr = object->start_address + instance * mxt_obj_size(object) + offset;
++ ret = __mxt_write_reg(data->client, addr, size, val);
++ if (ret)
++ return -EINVAL;
++
++ return 0;
++}
++
+ static void mxt_start(struct mxt_data *data)
+ {
+ /* Touch enable */
+@@ -2036,14 +2088,62 @@ static int mxt_suspend(struct device *dev)
+ struct i2c_client *client = to_i2c_client(dev);
+ struct mxt_data *data = i2c_get_clientdata(client);
+ struct input_dev *input_dev = data->input_dev;
++ static const u8 T7_config_idle[3] = { 0xfe, 0xfe, 0x00 };
++ static const u8 T7_config_deepsleep[3] = { 0x00, 0x00, 0x00 };
++ const u8 *power_config;
++ u8 T9_ctrl = 0x03;
++ int ret;
+
+ if (mxt_in_bootloader(data))
+ return 0;
+
+ mutex_lock(&input_dev->mutex);
+
+- if (input_dev->users)
++ /* Save 3 bytes T7 Power config */
++ ret = mxt_save_regs(data, MXT_GEN_POWER_T7, 0, 0,
++ data->T7_config, 3);
++ if (ret)
++ dev_err(dev, "Save T7 Power config failed, %d\n", ret);
++ data->T7_config_valid = (ret == 0);
++
++ /*
++ * Set T7 to idle mode if we allow wakeup from touch, otherwise
++ * put it into deepsleep mode.
++ */
++ power_config = device_may_wakeup(dev) ? T7_config_idle
++ : T7_config_deepsleep;
++
++ ret = mxt_set_regs(data, MXT_GEN_POWER_T7, 0, 0,
++ power_config, 3);
++ if (ret)
++ dev_err(dev, "Set T7 Power config failed, %d\n", ret);
++
++ if (device_may_wakeup(dev)) {
++ /*
++ * If we allow wakeup from touch, we have to enable T9 so
++ * that IRQ can be generated from touch
++ */
++
++ /* Save 1 byte T9 Ctrl config */
++ ret = mxt_save_regs(data, MXT_TOUCH_MULTI_T9, 0, 0,
++ &data->T9_ctrl, 1);
++ if (ret)
++ dev_err(dev, "Save T9 ctrl config failed, %d\n", ret);
++ data->T9_ctrl_valid = (ret == 0);
++
++ /* Enable T9 object */
++ ret = mxt_set_regs(data, MXT_TOUCH_MULTI_T9, 0, 0,
++ &T9_ctrl, 1);
++ if (ret)
++ dev_err(dev, "Set T9 ctrl config failed, %d\n", ret);
++
++ /* Enable wake from IRQ */
++ data->irq_wake = (enable_irq_wake(data->irq) == 0);
++ } else if (input_dev->users) {
+ mxt_stop(data);
++ }
++
++ disable_irq(data->irq);
+
+ mutex_unlock(&input_dev->mutex);
+
+@@ -2055,20 +2155,40 @@ static int mxt_resume(struct device *dev)
+ struct i2c_client *client = to_i2c_client(dev);
+ struct mxt_data *data = i2c_get_clientdata(client);
+ struct input_dev *input_dev = data->input_dev;
++ int ret;
+
+ if (mxt_in_bootloader(data))
+ return 0;
+
+- /* Soft reset */
+- mxt_write_object(data, MXT_GEN_COMMAND_T6,
+- MXT_COMMAND_RESET, 1);
+-
+- msleep(MXT_RESET_TIME);
++ /* Process any pending message so that CHG line can be de-asserted */
++ ret = mxt_handle_messages(data);
++ if (ret)
++ dev_err(dev, "Handling message fails upon resume, %d\n", ret);
+
+ mutex_lock(&input_dev->mutex);
+
+- if (input_dev->users)
++ enable_irq(data->irq);
++
++ if (device_may_wakeup(dev) && data->irq_wake)
++ disable_irq_wake(data->irq);
++
++ /* Restore the T9 Ctrl config to before-suspend value */
++ if (device_may_wakeup(dev) && data->T9_ctrl_valid) {
++ ret = mxt_set_regs(data, MXT_TOUCH_MULTI_T9, 0, 0,
++ &data->T9_ctrl, 1);
++ if (ret)
++ dev_err(dev, "Set T9 ctrl config failed, %d\n", ret);
++ } else if (input_dev->users) {
+ mxt_start(data);
++ }
++
++ /* Restore the T7 Power config to before-suspend value */
++ if (data->T7_config_valid) {
++ ret = mxt_set_regs(data, MXT_GEN_POWER_T7, 0, 0,
++ data->T7_config, 3);
++ if (ret)
++ dev_err(dev, "Set T7 power config failed, %d\n", ret);
++ }
+
+ mutex_unlock(&input_dev->mutex);
+
diff --git a/patches/linux-3.8.13/0541-CHROMIUM-Input-atmel_mxt_ts-Move-object-from-sysfs-t.patch b/patches/linux-3.8.13/0541-CHROMIUM-Input-atmel_mxt_ts-Move-object-from-sysfs-t.patch
new file mode 100644
index 0000000..bbb1d34
--- /dev/null
+++ b/patches/linux-3.8.13/0541-CHROMIUM-Input-atmel_mxt_ts-Move-object-from-sysfs-t.patch
@@ -0,0 +1,372 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Thu, 10 May 2012 16:19:04 -0400
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Move object from sysfs to
+ debugfs
+
+The object sysfs entry is used to read the current register value
+of all the objects. Each read on the sysfs entry can only return
+up to PAGE_SIZE (usually 4k) bytes, which is not enough for showing
+all the object values for some atmel chips. This CL moves the sysfs
+entry to debugfs which does not have this PAGE_SIZE limit on read.
+
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+
+BUG=chrome-os-partner:9253
+TEST=cd /sys/kernel/debug/atmel_mxt_ts/*DEVICE-I2C-ADDR*/
+ cat object
+ it should show the register value for all the objects
+
+Change-Id: Ic2f0df0c17655b5208ef5746f602fdb8af1c3467
+Reviewed-on: https://gerrit.chromium.org/gerrit/21812
+Commit-Ready: Yufeng Shen <miletus@chromium.org>
+Reviewed-by: Yufeng Shen <miletus@chromium.org>
+Tested-by: Yufeng Shen <miletus@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 279 +++++++++++++++++++++++-------
+ 1 file changed, 212 insertions(+), 67 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 0804795..3ea35d1 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -300,6 +300,7 @@ struct mxt_data {
+ struct dentry *dentry_dev;
+ struct dentry *dentry_deltas;
+ struct dentry *dentry_refs;
++ struct dentry *dentry_object;
+
+ /* Protect access to the T37 object buffer, used by debugfs */
+ struct mutex T37_buf_mutex;
+@@ -319,6 +320,11 @@ struct mxt_data {
+ bool T9_ctrl_valid;
+
+ bool irq_wake; /* irq wake is enabled */
++
++ /* Protect access to the object register buffer */
++ struct mutex object_str_mutex;
++ char *object_str;
++ size_t object_str_size;
+ };
+
+ /* global root node of the atmel_mxt_ts debugfs directory. */
+@@ -1525,66 +1531,6 @@ static ssize_t mxt_matrix_size_show(struct device *dev,
+ info->matrix_xsize, info->matrix_ysize);
+ }
+
+-static ssize_t mxt_show_instance(char *buf, int count,
+- struct mxt_object *object, int instance,
+- const u8 *val)
+-{
+- int i;
+-
+- if (mxt_obj_instances(object) > 1)
+- count += scnprintf(buf + count, PAGE_SIZE - count,
+- "Instance %u\n", instance);
+-
+- for (i = 0; i < mxt_obj_size(object); i++)
+- count += scnprintf(buf + count, PAGE_SIZE - count,
+- "\t[%2u]: %02x (%d)\n", i, val[i], val[i]);
+- count += scnprintf(buf + count, PAGE_SIZE - count, "\n");
+-
+- return count;
+-}
+-
+-static ssize_t mxt_object_show(struct device *dev,
+- struct device_attribute *attr, char *buf)
+-{
+- struct mxt_data *data = dev_get_drvdata(dev);
+- struct mxt_object *object;
+- int count = 0;
+- int i, j;
+- int error;
+- u8 *obuf;
+-
+- /* Pre-allocate buffer large enough to hold max sized object. */
+- obuf = kmalloc(256, GFP_KERNEL);
+- if (!obuf)
+- return -ENOMEM;
+-
+- error = 0;
+- for (i = 0; i < data->info.object_num; i++) {
+- object = data->object_table + i;
+-
+- if (!mxt_object_readable(object->type))
+- continue;
+-
+- count += scnprintf(buf + count, PAGE_SIZE - count,
+- "T%u:\n", object->type);
+-
+- for (j = 0; j < mxt_obj_instances(object); j++) {
+- u16 size = mxt_obj_size(object);
+- u16 addr = object->start_address + j * size;
+-
+- error = __mxt_read_reg(data->client, addr, size, obuf);
+- if (error)
+- goto done;
+-
+- count = mxt_show_instance(buf, count, object, j, obuf);
+- }
+- }
+-
+-done:
+- kfree(obuf);
+- return error ?: count;
+-}
+-
+ static ssize_t mxt_object_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+@@ -1702,8 +1648,7 @@ static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL);
+ static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL);
+ static DEVICE_ATTR(info_csum, S_IRUGO, mxt_info_csum_show, NULL);
+ static DEVICE_ATTR(matrix_size, S_IRUGO, mxt_matrix_size_show, NULL);
+-static DEVICE_ATTR(object, S_IRUGO | S_IWUSR, mxt_object_show,
+- mxt_object_store);
++static DEVICE_ATTR(object, S_IWUSR, NULL, mxt_object_store);
+ static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);
+
+ static struct attribute *mxt_attrs[] = {
+@@ -1725,6 +1670,122 @@ static const struct attribute_group mxt_attr_group = {
+
+ /*
+ **************************************************************
++ * debugfs helper functions
++ **************************************************************
++*/
++
++/*
++ * Print the formatted string into the end of string |*str| which has size
++ * |*str_size|. Extra space will be allocated to hold the formatted string
++ * and |*str_size| will be updated accordingly.
++ */
++static int mxt_asprintf(char **str, size_t *str_size, const char *fmt, ...)
++{
++ unsigned int len;
++ va_list ap, aq;
++ int ret;
++ char *str_tmp;
++
++ va_start(ap, fmt);
++ va_copy(aq, ap);
++ len = vsnprintf(NULL, 0, fmt, aq);
++ va_end(aq);
++
++ str_tmp = krealloc(*str, *str_size + len + 1, GFP_KERNEL);
++ if (str_tmp == NULL)
++ return -ENOMEM;
++
++ *str = str_tmp;
++
++ ret = vsnprintf(*str + *str_size, len + 1, fmt, ap);
++ va_end(ap);
++
++ if (ret != len)
++ return -EINVAL;
++
++ *str_size += len;
++
++ return 0;
++}
++
++static int mxt_instance_fetch(char **str, size_t *count,
++ struct mxt_object *object, int instance, const u8 *val)
++{
++ int i;
++ int ret;
++
++ if (mxt_obj_instances(object) > 1) {
++ ret = mxt_asprintf(str, count, "Instance: %zu\n", instance);
++ if (ret)
++ return ret;
++ }
++
++ for (i = 0; i < mxt_obj_size(object); i++) {
++ ret = mxt_asprintf(str, count,
++ "\t[%2zu]: %02x (%d)\n", i, val[i], val[i]);
++ if (ret)
++ return ret;
++ }
++
++ return 0;
++}
++
++static int mxt_object_fetch(struct mxt_data *data)
++{
++ struct mxt_object *object;
++ size_t count = 0;
++ size_t i, j;
++ int ret = 0;
++ char *str = NULL;
++ u8 *obuf;
++
++ if (data->object_str)
++ return -EINVAL;
++
++ /* Pre-allocate buffer large enough to hold max sized object. */
++ obuf = kmalloc(256, GFP_KERNEL);
++ if (!obuf)
++ return -ENOMEM;
++
++ for (i = 0; i < data->info.object_num; i++) {
++ object = data->object_table + i;
++
++ if (!mxt_object_readable(object->type))
++ continue;
++
++ ret = mxt_asprintf(&str, &count, "\nT%u\n", object->type);
++ if (ret)
++ goto err;
++
++ for (j = 0; j < mxt_obj_instances(object); j++) {
++ u16 size = mxt_obj_size(object);
++ u16 addr = object->start_address + j * size;
++
++ ret = __mxt_read_reg(data->client, addr, size, obuf);
++ if (ret)
++ goto done;
++
++ ret = mxt_instance_fetch(&str, &count, object, j, obuf);
++ if (ret)
++ goto err;
++ }
++ }
++
++ goto done;
++
++err:
++ kfree(str);
++ str = NULL;
++ count = 0;
++done:
++ data->object_str = str;
++ data->object_str_size = count;
++ kfree(obuf);
++ return ret;
++}
++
++/*
++ **************************************************************
+ * debugfs interface
+ **************************************************************
+ */
+@@ -1814,6 +1875,78 @@ static const struct file_operations mxt_debugfs_T37_fops = {
+ .read = mxt_debugfs_T37_read
+ };
+
++static int mxt_debugfs_object_open(struct inode *inode, struct file *file)
++{
++ struct mxt_data *mxt = inode->i_private;
++ int ret;
++
++ /* Only allow one object debugfs file to be opened at a time */
++ ret = mutex_lock_interruptible(&mxt->object_str_mutex);
++ if (ret)
++ return ret;
++
++ if (!i2c_use_client(mxt->client)) {
++ ret = -ENODEV;
++ goto err_object_unlock;
++ }
++
++ ret = mxt_object_fetch(mxt);
++ if (ret)
++ goto err_object_i2c_release;
++ file->private_data = mxt;
++
++ return 0;
++
++err_object_i2c_release:
++ i2c_release_client(mxt->client);
++err_object_unlock:
++ mutex_unlock(&mxt->object_str_mutex);
++ return ret;
++}
++
++static int mxt_debugfs_object_release(struct inode *inode, struct file *file)
++{
++ struct mxt_data *mxt = file->private_data;
++ file->private_data = NULL;
++
++ kfree(mxt->object_str);
++ mxt->object_str = NULL;
++ mxt->object_str_size = 0;
++
++ i2c_release_client(mxt->client);
++ mutex_unlock(&mxt->object_str_mutex);
++
++ return 0;
++}
++
++static ssize_t mxt_debugfs_object_read(struct file *file, char __user* buffer,
++ size_t count, loff_t *ppos)
++{
++ struct mxt_data *mxt = file->private_data;
++ if (!mxt->object_str)
++ return -ENODEV;
++
++ if (*ppos >= mxt->object_str_size)
++ return 0;
++
++ if (count + *ppos > mxt->object_str_size)
++ count = mxt->object_str_size - *ppos;
++
++ if (copy_to_user(buffer, &mxt->object_str[*ppos], count))
++ return -EFAULT;
++
++ *ppos += count;
++
++ return count;
++}
++
++static const struct file_operations mxt_debugfs_object_fops = {
++ .owner = THIS_MODULE,
++ .open = mxt_debugfs_object_open,
++ .release = mxt_debugfs_object_release,
++ .read = mxt_debugfs_object_read,
++};
++
+ static int mxt_debugfs_init(struct mxt_data *mxt)
+ {
+ struct device *dev = &mxt->client->dev;
+@@ -1835,9 +1968,25 @@ static int mxt_debugfs_init(struct mxt_data *mxt)
+ mxt->dentry_refs = debugfs_create_file("refs", S_IRUSR,
+ mxt->dentry_dev, mxt,
+ &mxt_debugfs_T37_fops);
++ mutex_init(&mxt->object_str_mutex);
++
++ mxt->dentry_object = debugfs_create_file("object", S_IRUGO,
++ mxt->dentry_dev, mxt,
++ &mxt_debugfs_object_fops);
+ return 0;
+ }
+
++static void mxt_debugfs_remove(struct mxt_data *mxt)
++{
++ if (mxt->dentry_dev) {
++ debugfs_remove_recursive(mxt->dentry_dev);
++ mutex_destroy(&mxt->object_str_mutex);
++ kfree(mxt->object_str);
++ mutex_destroy(&mxt->T37_buf_mutex);
++ kfree(mxt->T37_buf);
++ }
++}
++
+ static int mxt_save_regs(struct mxt_data *data, u8 type, u8 instance,
+ u8 offset, u8 *val, u16 size)
+ {
+@@ -2067,11 +2216,7 @@ static int mxt_remove(struct i2c_client *client)
+ {
+ struct mxt_data *data = i2c_get_clientdata(client);
+
+- if (data->dentry_dev) {
+- debugfs_remove_recursive(data->dentry_dev);
+- mutex_destroy(&data->T37_buf_mutex);
+- kfree(data->T37_buf);
+- }
++ mxt_debugfs_remove(data);
+ sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
+ free_irq(data->irq, data);
+ if (data->input_dev)
diff --git a/patches/linux-3.8.13/0542-CHROMIUM-Input-atmel_mxt_ts-Set-default-irqflags-whe.patch b/patches/linux-3.8.13/0542-CHROMIUM-Input-atmel_mxt_ts-Set-default-irqflags-whe.patch
new file mode 100644
index 0000000..7bb730e
--- /dev/null
+++ b/patches/linux-3.8.13/0542-CHROMIUM-Input-atmel_mxt_ts-Set-default-irqflags-whe.patch
@@ -0,0 +1,55 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Mon, 14 May 2012 12:06:29 -0400
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Set default irqflags when
+ there is no pdata
+
+This is the preparation for supporting the code path when there is
+platform data provided and still boot the device into a sane state
+with backup NVRAM config.
+
+This CL makes the irqflags default to be IRQF_TRIGGER_FALLING if no
+platform data is provided.
+
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+
+BUG=chrome-os-partner:9103
+TEST=The code path for no pdata is not supported yet, so no test can
+ be done at this point. And no funtional change along the normal
+ code path with platform data provided.
+
+Change-Id: Icea0fff544c77b38eb380851d7e7d8f857b76745
+Reviewed-on: https://gerrit.chromium.org/gerrit/22417
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Commit-Ready: Yufeng Shen <miletus@chromium.org>
+Tested-by: Yufeng Shen <miletus@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 3ea35d1..ec1077b 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -2139,6 +2139,7 @@ static int __devinit mxt_probe(struct i2c_client *client,
+ {
+ const struct mxt_platform_data *pdata = client->dev.platform_data;
+ struct mxt_data *data;
++ unsigned long irqflags;
+ int error;
+
+ if (!pdata)
+@@ -2174,8 +2175,10 @@ static int __devinit mxt_probe(struct i2c_client *client,
+ goto err_free_object;
+ }
+
++ /* Default to falling edge if no platform data provided */
++ irqflags = pdata ? pdata->irqflags : IRQF_TRIGGER_FALLING;
+ error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
+- pdata->irqflags | IRQF_ONESHOT,
++ irqflags | IRQF_ONESHOT,
+ client->name, data);
+ if (error) {
+ dev_err(&client->dev, "Failed to register interrupt\n");
diff --git a/patches/linux-3.8.13/0543-CHROMIUM-Input-atmel_mxt_ts-Support-the-case-with-no.patch b/patches/linux-3.8.13/0543-CHROMIUM-Input-atmel_mxt_ts-Support-the-case-with-no.patch
new file mode 100644
index 0000000..9fc8d2d
--- /dev/null
+++ b/patches/linux-3.8.13/0543-CHROMIUM-Input-atmel_mxt_ts-Support-the-case-with-no.patch
@@ -0,0 +1,110 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Mon, 14 May 2012 12:29:52 -0400
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Support the case with no
+ platform data
+
+Add the support that the device finishes initialization even when no
+platform data is provided. Most of the time the device needs configured
+only once and later on it can just use backed up config from NVRAM.
+So the code path with no platform saves on device initialization time.
+
+Rename mxt_check_reg_init() to be mxt_apply_pdata_config() and move it
+into mxt_handle_pdata() so that all the platform data processing is in
+one fucntion.
+
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+
+BUG=chrome-os-partner:9103
+TEST=Rebuild the kernel with no platform data provided, boot the device
+ with a previously working atmel chip, and make sure the atmel chip
+ still works.
+
+Change-Id: I2440c58ab9b9baa1160406827ba9d08aee52a554
+Reviewed-on: https://gerrit.chromium.org/gerrit/22587
+Commit-Ready: Yufeng Shen <miletus@chromium.org>
+Reviewed-by: Yufeng Shen <miletus@chromium.org>
+Tested-by: Yufeng Shen <miletus@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 28 ++++++++++++++++++----------
+ 1 file changed, 18 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index ec1077b..3dbaa3c 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -959,7 +959,7 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
+ return IRQ_HANDLED;
+ }
+
+-static int mxt_check_reg_init(struct mxt_data *data)
++static int mxt_apply_pdata_config(struct mxt_data *data)
+ {
+ const struct mxt_platform_data *pdata = data->pdata;
+ struct mxt_object *object;
+@@ -969,7 +969,7 @@ static int mxt_check_reg_init(struct mxt_data *data)
+ int ret;
+
+ if (!pdata->config) {
+- dev_dbg(dev, "No cfg data defined, skipping reg init\n");
++ dev_info(dev, "No cfg data defined, skipping reg init\n");
+ return 0;
+ }
+
+@@ -995,10 +995,21 @@ static int mxt_check_reg_init(struct mxt_data *data)
+ return 0;
+ }
+
+-static void mxt_handle_pdata(struct mxt_data *data)
++static int mxt_handle_pdata(struct mxt_data *data)
+ {
+ const struct mxt_platform_data *pdata = data->pdata;
++ struct device *dev = &data->client->dev;
+ u8 voltage;
++ int ret;
++
++ if (!pdata) {
++ dev_info(dev, "No platform data provided\n");
++ return 0;
++ }
++
++ ret = mxt_apply_pdata_config(data);
++ if (ret)
++ return ret;
+
+ /* Set touchscreen lines */
+ mxt_write_object(data, MXT_TOUCH_MULTI_T9, MXT_TOUCH_XSIZE,
+@@ -1041,6 +1052,8 @@ static void mxt_handle_pdata(struct mxt_data *data)
+ mxt_write_object(data, MXT_SPT_CTECONFIG_T28,
+ MXT_CTE_VOLTAGE, voltage);
+ }
++
++ return 0;
+ }
+
+ /* Update 24-bit CRC with two new bytes of data */
+@@ -1234,13 +1247,11 @@ static int mxt_initialize(struct mxt_data *data)
+ if (error)
+ goto err_free_object_table;
+
+- /* Check register init values */
+- error = mxt_check_reg_init(data);
++ /* Apply config from platform data */
++ error = mxt_handle_pdata(data);
+ if (error)
+ goto err_free_object_table;
+
+- mxt_handle_pdata(data);
+-
+ /* Backup to memory */
+ error = mxt_write_object(data, MXT_GEN_COMMAND_T6,
+ MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE);
+@@ -2142,9 +2153,6 @@ static int __devinit mxt_probe(struct i2c_client *client,
+ unsigned long irqflags;
+ int error;
+
+- if (!pdata)
+- return -EINVAL;
+-
+ data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL);
+ if (!data) {
+ dev_err(&client->dev, "Failed to allocate memory\n");
diff --git a/patches/linux-3.8.13/0544-CHROMIUM-Input-atmel_mxt_ts-Wait-on-auto-calibration.patch b/patches/linux-3.8.13/0544-CHROMIUM-Input-atmel_mxt_ts-Wait-on-auto-calibration.patch
new file mode 100644
index 0000000..5620224
--- /dev/null
+++ b/patches/linux-3.8.13/0544-CHROMIUM-Input-atmel_mxt_ts-Wait-on-auto-calibration.patch
@@ -0,0 +1,117 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Wed, 16 May 2012 14:52:02 -0400
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Wait on auto calibration msg
+ in suspend
+
+If the atmel chip enters suspend mode and wants to be able to
+wakeup from suspend, T9 object has to be enabled during suspend.
+If T9 is enalbed from a disabled state, the chip will perform an
+auto calibration and send back the status of the calibration.
+We have to wait for these messages to be read before entering
+suspend, otherwise these message will wakeup the system automatically.
+
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+
+BUG=chrome-os-partner:8722
+TEST=run powerd_suspend to put system into sleep and make sure it
+ does not wakeup automatically. And touch the TS/TP to wake the
+ system up
+
+Change-Id: Iaf8175c8e6d523edfd152172e1966303ac8fd65f
+Reviewed-on: https://gerrit.chromium.org/gerrit/22842
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
+Tested-by: Yufeng Shen <miletus@chromium.org>
+Commit-Ready: Yufeng Shen <miletus@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 39 +++++++++++++++++++++++++-----
+ 1 file changed, 33 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 3dbaa3c..bac30d1f 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -325,6 +325,9 @@ struct mxt_data {
+ struct mutex object_str_mutex;
+ char *object_str;
+ size_t object_str_size;
++
++ /* for auto-calibration in suspend */
++ struct completion auto_cal_completion;
+ };
+
+ /* global root node of the atmel_mxt_ts debugfs directory. */
+@@ -821,6 +824,8 @@ static int mxt_proc_messages(struct mxt_data *data, u8 count)
+ data->config_csum = mxt_extract_T6_csum(&payload[1]);
+ dev_dbg(dev, "Status: %02x Config Checksum: %06x\n",
+ status, data->config_csum);
++ if (status == 0x00)
++ complete(&data->auto_cal_completion);
+ } else if (mxt_is_T9_message(data, msg)) {
+ int id = reportid - data->T9_reportid_min;
+ mxt_input_touchevent(data, msg, id);
+@@ -2170,6 +2175,7 @@ static int __devinit mxt_probe(struct i2c_client *client,
+ data->irq = client->irq;
+
+ init_completion(&data->bl_completion);
++ init_completion(&data->auto_cal_completion);
+
+ if (mxt_in_bootloader(data)) {
+ dev_info(&client->dev, "Device in bootloader at probe\n");
+@@ -2239,6 +2245,30 @@ static int mxt_remove(struct i2c_client *client)
+ }
+
+ #ifdef CONFIG_PM_SLEEP
++
++static void mxt_suspend_enable_T9(struct mxt_data *data)
++{
++ struct device *dev = &data->client->dev;
++ u8 T9_ctrl = 0x03;
++ int ret;
++ unsigned long timeout = msecs_to_jiffies(350);
++
++ INIT_COMPLETION(data->auto_cal_completion);
++
++ /* Enable T9 object */
++ ret = mxt_set_regs(data, MXT_TOUCH_MULTI_T9, 0, 0,
++ &T9_ctrl, 1);
++ if (ret) {
++ dev_err(dev, "Set T9 ctrl config failed, %d\n", ret);
++ return;
++ }
++
++ ret = wait_for_completion_interruptible_timeout(
++ &data->auto_cal_completion, timeout);
++ if (ret <= 0)
++ dev_err(dev, "Wait for auto cal completion failed.\n");
++}
++
+ static int mxt_suspend(struct device *dev)
+ {
+ struct i2c_client *client = to_i2c_client(dev);
+@@ -2247,7 +2277,6 @@ static int mxt_suspend(struct device *dev)
+ static const u8 T7_config_idle[3] = { 0xfe, 0xfe, 0x00 };
+ static const u8 T7_config_deepsleep[3] = { 0x00, 0x00, 0x00 };
+ const u8 *power_config;
+- u8 T9_ctrl = 0x03;
+ int ret;
+
+ if (mxt_in_bootloader(data))
+@@ -2287,11 +2316,9 @@ static int mxt_suspend(struct device *dev)
+ dev_err(dev, "Save T9 ctrl config failed, %d\n", ret);
+ data->T9_ctrl_valid = (ret == 0);
+
+- /* Enable T9 object */
+- ret = mxt_set_regs(data, MXT_TOUCH_MULTI_T9, 0, 0,
+- &T9_ctrl, 1);
+- if (ret)
+- dev_err(dev, "Set T9 ctrl config failed, %d\n", ret);
++ /* Enable T9 only if it is not currently enabled */
++ if (data->T9_ctrl_valid && !(data->T9_ctrl & 0x01))
++ mxt_suspend_enable_T9(data);
+
+ /* Enable wake from IRQ */
+ data->irq_wake = (enable_irq_wake(data->irq) == 0);
diff --git a/patches/linux-3.8.13/0545-CHROMIUM-Input-atmel_mxt_ts-Add-sysfs-entry-for-r-w-.patch b/patches/linux-3.8.13/0545-CHROMIUM-Input-atmel_mxt_ts-Add-sysfs-entry-for-r-w-.patch
new file mode 100644
index 0000000..9e354b2
--- /dev/null
+++ b/patches/linux-3.8.13/0545-CHROMIUM-Input-atmel_mxt_ts-Add-sysfs-entry-for-r-w-.patch
@@ -0,0 +1,182 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Thu, 13 Dec 2012 11:36:59 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Add sysfs entry for r/w fw
+ file name
+
+On system with more than 1 Atmel chip, a fixed firmware file name
+"maxtouch.fw" does not work since different chips need different
+firmware files. This CL adds the sysfs entry that make it possible
+for userspace to specify the file name of the firmware to be loaded.
+If no file name is specified, the default "maxtouch.fw" is used for
+compatibility with existing code.
+
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+
+BUG=chrome-os-partner:9103
+TEST=cat path-to-atmel-sysfs/fw_file
+ and make sure "maxtouch.fw" is returned
+ echo XXX > path-to-atmel-sysfs/fw_file
+ cat path-to-atmel-sysfs/fw_file
+ and make sure XXX is returned
+ echo 1 > path-to-atmel-sysfs/update_fw
+ and make sure the driver tries to load XXX
+ if XXX exists in /lib/firmware, check that
+ firmware update succeeds
+ if XXX does not exist in /lib/firmware, check
+ that firmware update fails
+
+Change-Id: Icdff2851866b36de08c6fd75c29947a8d27f7dfe
+Reviewed-on: https://gerrit.chromium.org/gerrit/22867
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Tested-by: Yufeng Shen <miletus@chromium.org>
+Commit-Ready: Yufeng Shen <miletus@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 69 +++++++++++++++++++++++++++++-
+ 1 file changed, 67 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index bac30d1f..1659d91 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -328,6 +328,9 @@ struct mxt_data {
+
+ /* for auto-calibration in suspend */
+ struct completion auto_cal_completion;
++
++ /* firmware file name */
++ char *fw_file;
+ };
+
+ /* global root node of the atmel_mxt_ts debugfs directory. */
+@@ -1465,6 +1468,35 @@ out:
+ return ret ?: 0;
+ }
+
++static int mxt_update_file_name(struct device *dev, char** file_name,
++ const char *buf, size_t count)
++{
++ char *file_name_tmp;
++
++ /* Simple sanity check */
++ if (count > 64) {
++ dev_warn(dev, "File name too long\n");
++ return -EINVAL;
++ }
++
++ file_name_tmp = krealloc(*file_name, count + 1, GFP_KERNEL);
++ if (!file_name_tmp) {
++ dev_warn(dev, "no memory\n");
++ return -ENOMEM;
++ }
++
++ *file_name = file_name_tmp;
++ memcpy(*file_name, buf, count);
++
++ /* Echo into the sysfs entry may append newline at the end of buf */
++ if (buf[count - 1] == '\n')
++ (*file_name)[count - 1] = '\0';
++ else
++ (*file_name)[count] = '\0';
++
++ return 0;
++}
++
+ static ssize_t mxt_backupnv_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+@@ -1510,6 +1542,27 @@ static ssize_t mxt_config_csum_show(struct device *dev,
+ return scnprintf(buf, PAGE_SIZE, "%06x\n", data->config_csum);
+ }
+
++static ssize_t mxt_fw_file_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct mxt_data *data = dev_get_drvdata(dev);
++ return scnprintf(buf, PAGE_SIZE, "%s\n", data->fw_file);
++}
++
++static ssize_t mxt_fw_file_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct mxt_data *data = dev_get_drvdata(dev);
++ int ret;
++
++ ret = mxt_update_file_name(dev, &data->fw_file, buf, count);
++ if (ret)
++ return ret;
++
++ return count;
++}
++
+ /* Firmware Version is returned as Major.Minor.Build */
+ static ssize_t mxt_fw_version_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+@@ -1644,9 +1697,10 @@ static ssize_t mxt_update_fw_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
++ struct mxt_data *data = dev_get_drvdata(dev);
+ int error;
+
+- error = mxt_load_fw(dev, MXT_FW_NAME);
++ error = mxt_load_fw(dev, data->fw_file);
+ if (error) {
+ dev_err(dev, "The firmware update failed(%d)\n", error);
+ count = error;
+@@ -1660,6 +1714,8 @@ static ssize_t mxt_update_fw_store(struct device *dev,
+ static DEVICE_ATTR(backupnv, S_IWUSR, NULL, mxt_backupnv_store);
+ static DEVICE_ATTR(calibrate, S_IWUSR, NULL, mxt_calibrate_store);
+ static DEVICE_ATTR(config_csum, S_IRUGO, mxt_config_csum_show, NULL);
++static DEVICE_ATTR(fw_file, S_IRUGO | S_IWUSR, mxt_fw_file_show,
++ mxt_fw_file_store);
+ static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL);
+ static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL);
+ static DEVICE_ATTR(info_csum, S_IRUGO, mxt_info_csum_show, NULL);
+@@ -1671,6 +1727,7 @@ static struct attribute *mxt_attrs[] = {
+ &dev_attr_backupnv.attr,
+ &dev_attr_calibrate.attr,
+ &dev_attr_config_csum.attr,
++ &dev_attr_fw_file.attr,
+ &dev_attr_fw_version.attr,
+ &dev_attr_hw_version.attr,
+ &dev_attr_info_csum.attr,
+@@ -2177,12 +2234,17 @@ static int __devinit mxt_probe(struct i2c_client *client,
+ init_completion(&data->bl_completion);
+ init_completion(&data->auto_cal_completion);
+
++ error = mxt_update_file_name(&client->dev, &data->fw_file, MXT_FW_NAME,
++ strlen(MXT_FW_NAME));
++ if (error)
++ goto err_free_mem;
++
+ if (mxt_in_bootloader(data)) {
+ dev_info(&client->dev, "Device in bootloader at probe\n");
+ } else {
+ error = mxt_initialize(data);
+ if (error)
+- goto err_free_mem;
++ goto err_free_fw_file;
+
+ error = mxt_input_dev_create(data);
+ if (error)
+@@ -2224,6 +2286,8 @@ err_unregister_device:
+ input_unregister_device(data->input_dev);
+ err_free_object:
+ kfree(data->object_table);
++err_free_fw_file:
++ kfree(data->fw_file);
+ err_free_mem:
+ kfree(data);
+ return error;
+@@ -2239,6 +2303,7 @@ static int mxt_remove(struct i2c_client *client)
+ if (data->input_dev)
+ input_unregister_device(data->input_dev);
+ kfree(data->object_table);
++ kfree(data->fw_file);
+ kfree(data);
+
+ return 0;
diff --git a/patches/linux-3.8.13/0546-CHROMIUM-Input-atmel_mxt_ts-Add-sysfs-entry-for-r-w-.patch b/patches/linux-3.8.13/0546-CHROMIUM-Input-atmel_mxt_ts-Add-sysfs-entry-for-r-w-.patch
new file mode 100644
index 0000000..51411ec
--- /dev/null
+++ b/patches/linux-3.8.13/0546-CHROMIUM-Input-atmel_mxt_ts-Add-sysfs-entry-for-r-w-.patch
@@ -0,0 +1,137 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Wed, 16 May 2012 18:38:14 -0400
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Add sysfs entry for r/w
+ config file name
+
+In the preparation for adding support of loading atmel config data
+from file, this CL adds the sysfs entry config_file so that which
+config file to be used is configurable from userspace. The config
+file under /lib/firmware/ will be loaded through request_firmware()
+call. The default config file is "maxtouch.cfg".
+
+This support is necessary on system with more than 1 atmel chip and
+each needs a different configuration file.
+
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+
+BUG=chrome-os-partner:9103
+TEST=cat path-to-atmel-sysfs/config_file
+ and make sure "maxtouch.cfg" is returned
+ echo XXX > path-to-atmel-sysfs/config_file
+ cat path-to-atmel-sysfs/config_file
+ and make sure XXX is returned
+
+Change-Id: If87a4956c46b4a27e40f689be6304691b79cbf00
+Reviewed-on: https://gerrit.chromium.org/gerrit/21663
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Commit-Ready: Yufeng Shen <miletus@chromium.org>
+Tested-by: Yufeng Shen <miletus@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 37 +++++++++++++++++++++++++++++-
+ 1 file changed, 36 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 1659d91..dbabc89 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -42,6 +42,9 @@
+ /* Firmware */
+ #define MXT_FW_NAME "maxtouch.fw"
+
++/* Config file */
++#define MXT_CONFIG_NAME "maxtouch.cfg"
++
+ /* Registers */
+ #define MXT_INFO 0x00
+ #define MXT_FAMILY_ID 0x00
+@@ -331,6 +334,9 @@ struct mxt_data {
+
+ /* firmware file name */
+ char *fw_file;
++
++ /* config file name */
++ char *config_file;
+ };
+
+ /* global root node of the atmel_mxt_ts debugfs directory. */
+@@ -1542,6 +1548,24 @@ static ssize_t mxt_config_csum_show(struct device *dev,
+ return scnprintf(buf, PAGE_SIZE, "%06x\n", data->config_csum);
+ }
+
++static ssize_t mxt_config_file_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct mxt_data *data = dev_get_drvdata(dev);
++ return scnprintf(buf, PAGE_SIZE, "%s\n", data->config_file);
++}
++
++static ssize_t mxt_config_file_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct mxt_data *data = dev_get_drvdata(dev);
++ int ret;
++
++ ret = mxt_update_file_name(dev, &data->config_file, buf, count);
++ return ret ? ret : count;
++}
++
+ static ssize_t mxt_fw_file_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+ {
+@@ -1714,6 +1738,8 @@ static ssize_t mxt_update_fw_store(struct device *dev,
+ static DEVICE_ATTR(backupnv, S_IWUSR, NULL, mxt_backupnv_store);
+ static DEVICE_ATTR(calibrate, S_IWUSR, NULL, mxt_calibrate_store);
+ static DEVICE_ATTR(config_csum, S_IRUGO, mxt_config_csum_show, NULL);
++static DEVICE_ATTR(config_file, S_IRUGO | S_IWUSR, mxt_config_file_show,
++ mxt_config_file_store);
+ static DEVICE_ATTR(fw_file, S_IRUGO | S_IWUSR, mxt_fw_file_show,
+ mxt_fw_file_store);
+ static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL);
+@@ -1727,6 +1753,7 @@ static struct attribute *mxt_attrs[] = {
+ &dev_attr_backupnv.attr,
+ &dev_attr_calibrate.attr,
+ &dev_attr_config_csum.attr,
++ &dev_attr_config_file.attr,
+ &dev_attr_fw_file.attr,
+ &dev_attr_fw_version.attr,
+ &dev_attr_hw_version.attr,
+@@ -2239,12 +2266,17 @@ static int __devinit mxt_probe(struct i2c_client *client,
+ if (error)
+ goto err_free_mem;
+
++ error = mxt_update_file_name(&client->dev, &data->config_file,
++ MXT_CONFIG_NAME, strlen(MXT_CONFIG_NAME));
++ if (error)
++ goto err_free_fw_file;
++
+ if (mxt_in_bootloader(data)) {
+ dev_info(&client->dev, "Device in bootloader at probe\n");
+ } else {
+ error = mxt_initialize(data);
+ if (error)
+- goto err_free_fw_file;
++ goto err_free_cfg_file;
+
+ error = mxt_input_dev_create(data);
+ if (error)
+@@ -2286,6 +2318,8 @@ err_unregister_device:
+ input_unregister_device(data->input_dev);
+ err_free_object:
+ kfree(data->object_table);
++err_free_cfg_file:
++ kfree(data->config_file);
+ err_free_fw_file:
+ kfree(data->fw_file);
+ err_free_mem:
+@@ -2304,6 +2338,7 @@ static int mxt_remove(struct i2c_client *client)
+ input_unregister_device(data->input_dev);
+ kfree(data->object_table);
+ kfree(data->fw_file);
++ kfree(data->config_file);
+ kfree(data);
+
+ return 0;
diff --git a/patches/linux-3.8.13/0547-CHROMIUM-Input-atmel_mxt_ts-add-sysfs-entry-for-writ.patch b/patches/linux-3.8.13/0547-CHROMIUM-Input-atmel_mxt_ts-add-sysfs-entry-for-writ.patch
new file mode 100644
index 0000000..f14fd89
--- /dev/null
+++ b/patches/linux-3.8.13/0547-CHROMIUM-Input-atmel_mxt_ts-add-sysfs-entry-for-writ.patch
@@ -0,0 +1,408 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Fri, 18 May 2012 16:04:06 -0400
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - add sysfs entry for writing
+ a config file
+
+Adding a sysfs entry for loading .raw Atmel config file and write it to
+the device memory.
+
+The format spec of .raw Atmel config file can be found at
+E-9078 Object-Based Chip Config File Format
+
+The input device is unregistered while the configuration data is written
+to ensure there are no open/close calls to the driver which may write
+extraneous values to the T9 control register.
+The input device is recreated once the device has been reset following
+the configuration update.
+
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+
+BUG=chrome-os-partner:9103,chromium-os:33981
+
+TEST=Provide no platform to the atmel device
+ cd path-to-atmel-sysfs
+ 1. cat config_file
+ make sure maxtouch.cfg is returned.
+ echo 1 > update_config
+ and check the error msg in dmesg for
+ "Unable to open config file"
+ 2. copy maxtouch.cfg over to /lib/firmware/
+ echo 1 > update_config
+ check dmesg to see the device is reconfigured.
+
+Original-Change-Id: I439d86fcc0bf05b7922619e55af56ef79c1892ab
+Reviewed-on: https://gerrit.chromium.org/gerrit/24532
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Commit-Ready: Yufeng Shen <miletus@chromium.org>
+Tested-by: Yufeng Shen <miletus@chromium.org>
+Change-Id: If8f7ea2953f1a825cbcad4a548cf563345518c7d
+Reviewed-on: https://gerrit.chromium.org/gerrit/31638
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 315 ++++++++++++++++++++++++++++++
+ 1 file changed, 315 insertions(+)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index dbabc89..8f1a33f 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -45,6 +45,9 @@
+ /* Config file */
+ #define MXT_CONFIG_NAME "maxtouch.cfg"
+
++/* Configuration Data */
++#define MXT_CONFIG_VERSION "OBP_RAW V1"
++
+ /* Registers */
+ #define MXT_INFO 0x00
+ #define MXT_FAMILY_ID 0x00
+@@ -244,6 +247,19 @@
+ /* For CMT (must match XRANGE/YRANGE as defined in board config */
+ #define MXT_PIXELS_PER_MM 20
+
++struct mxt_cfg_file_hdr {
++ bool valid;
++ u32 info_crc;
++ u32 cfg_crc;
++};
++
++struct mxt_cfg_file_line {
++ struct list_head list;
++ u16 addr;
++ u8 size;
++ u8 *content;
++};
++
+ struct mxt_info {
+ u8 family_id;
+ u8 variant_id;
+@@ -1348,6 +1364,287 @@ static int mxt_calc_resolution(struct mxt_data *data)
+ }
+
+ /*
++ * Atmel Raw Config File Format
++ *
++ * The first four lines of the raw config file contain:
++ * 1) Version
++ * 2) Chip ID Information (first 7 bytes of device memory)
++ * 3) Chip Information Block 24-bit CRC Checksum
++ * 4) Chip Configuration 24-bit CRC Checksum
++ *
++ * The rest of the file consists of one line per object instance:
++ * <TYPE> <INSTANCE> <SIZE> <CONTENTS>
++ *
++ * <TYPE> - 2-byte object type as hex
++ * <INSTANCE> - 2-byte object instance number as hex
++ * <SIZE> - 2-byte object size as hex
++ * <CONTENTS> - array of <SIZE> 1-byte hex values
++ */
++static int mxt_cfg_verify_hdr(struct mxt_data *data, char **config)
++{
++ struct i2c_client *client = data->client;
++ struct device *dev = &client->dev;
++ struct mxt_info info;
++ char *token;
++ int ret = 0;
++ u32 crc;
++
++ /* Process the first four lines of the file*/
++ /* 1) Version */
++ token = strsep(config, "\n");
++ dev_info(dev, "Config File: Version = %s\n", token ?: "<null>");
++ if (!token ||
++ strncmp(token, MXT_CONFIG_VERSION, strlen(MXT_CONFIG_VERSION))) {
++ dev_err(dev, "Invalid config file: Bad Version\n");
++ return -EINVAL;
++ }
++
++ /* 2) Chip ID */
++ token = strsep(config, "\n");
++ if (!token) {
++ dev_err(dev, "Invalid config file: No Chip ID\n");
++ return -EINVAL;
++ }
++ ret = sscanf(token, "%hhx %hhx %hhx %hhx %hhx %hhx %hhx",
++ &info.family_id, &info.variant_id,
++ &info.version, &info.build, &info.matrix_xsize,
++ &info.matrix_ysize, &info.object_num);
++ dev_info(dev, "Config File: Chip ID = %02x %02x %02x %02x %02x %02x %02x\n",
++ info.family_id, info.variant_id, info.version, info.build,
++ info.matrix_xsize, info.matrix_ysize, info.object_num);
++ if (ret != 7 ||
++ info.family_id != data->info.family_id ||
++ info.variant_id != data->info.variant_id ||
++ info.version != data->info.version ||
++ info.build != data->info.build ||
++ info.matrix_xsize != data->info.matrix_xsize ||
++ info.matrix_ysize != data->info.matrix_ysize ||
++ info.object_num != data->info.object_num) {
++ dev_err(dev, "Invalid config file: Chip ID info mismatch\n");
++ dev_err(dev, "Chip Info: %02x %02x %02x %02x %02x %02x %02x\n",
++ data->info.family_id, data->info.variant_id,
++ data->info.version, data->info.build,
++ data->info.matrix_xsize, data->info.matrix_ysize,
++ data->info.object_num);
++ return -EINVAL;
++ }
++
++ /* 3) Info Block CRC */
++ token = strsep(config, "\n");
++ if (!token) {
++ dev_err(dev, "Invalid config file: No Info Block CRC\n");
++ return -EINVAL;
++ }
++ ret = sscanf(token, "%x", &crc);
++ dev_info(dev, "Config File: Info Block CRC = %06x\n", crc);
++ if (ret != 1 || crc != data->info_csum) {
++ dev_err(dev, "Invalid config file: Bad Info Block CRC\n");
++ return -EINVAL;
++ }
++
++ /* 4) Config CRC */
++ /*
++ * Parse but don't verify against current config;
++ * TODO: Verify against CRC of rest of file?
++ */
++ token = strsep(config, "\n");
++ if (!token) {
++ dev_err(dev, "Invalid config file: No Config CRC\n");
++ return -EINVAL;
++ }
++ ret = sscanf(token, "%x", &crc);
++ dev_info(dev, "Config File: Config CRC = %06x\n", crc);
++ if (ret != 1) {
++ dev_err(dev, "Invalid config file: Bad Config CRC\n");
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int mxt_cfg_proc_line(struct mxt_data *data, const char *line,
++ struct list_head *cfg_list)
++{
++ int ret;
++ u16 type, instance, size;
++ int len;
++ struct mxt_cfg_file_line *cfg_line;
++ struct mxt_object *object;
++ u8 *content;
++ size_t i;
++
++ ret = sscanf(line, "%hx %hx %hx%n", &type, &instance, &size, &len);
++ /* Skip unparseable lines */
++ if (ret < 3)
++ return 0;
++ /* Only support 1-byte types */
++ if (type > 0xff)
++ return -EINVAL;
++
++ /* Supplied object MUST be a valid instance and match object size */
++ object = mxt_get_object(data, type);
++ if (!object || instance > object->instances || size != object->size)
++ return -EINVAL;
++
++ content = kmalloc(size, GFP_KERNEL);
++ if (!content)
++ return -ENOMEM;
++
++ for (i = 0; i < size; i++) {
++ line += len;
++ ret = sscanf(line, "%hhx%n", &content[i], &len);
++ if (ret < 1) {
++ ret = -EINVAL;
++ goto free_content;
++ }
++ }
++
++ cfg_line = kzalloc(sizeof(*cfg_line), GFP_KERNEL);
++ if (!cfg_line) {
++ ret = -ENOMEM;
++ goto free_content;
++ }
++ INIT_LIST_HEAD(&cfg_line->list);
++ cfg_line->addr = object->start_address + instance * object->size;
++ cfg_line->size = object->size;
++ cfg_line->content = content;
++ list_add_tail(&cfg_line->list, cfg_list);
++
++ return 0;
++
++free_content:
++ kfree(content);
++ return ret;
++}
++
++static int mxt_cfg_proc_data(struct mxt_data *data, char **config)
++{
++ struct i2c_client *client = data->client;
++ struct device *dev = &client->dev;
++ char *line;
++ int ret = 0;
++ struct list_head cfg_lines;
++ struct mxt_cfg_file_line *cfg_line, *cfg_line_tmp;
++
++ INIT_LIST_HEAD(&cfg_lines);
++
++ while ((line = strsep(config, "\n"))) {
++ ret = mxt_cfg_proc_line(data, line, &cfg_lines);
++ if (ret < 0)
++ goto free_objects;
++ }
++
++ list_for_each_entry(cfg_line, &cfg_lines, list) {
++ dev_dbg(dev, "Addr = %u Size = %u\n",
++ cfg_line->addr, cfg_line->size);
++ print_hex_dump(KERN_DEBUG, "atmel_mxt_ts: ", DUMP_PREFIX_OFFSET,
++ 16, 1, cfg_line->content, cfg_line->size, false);
++
++ ret = __mxt_write_reg(client, cfg_line->addr, cfg_line->size,
++ cfg_line->content);
++ if (ret)
++ break;
++ }
++
++free_objects:
++ list_for_each_entry_safe(cfg_line, cfg_line_tmp, &cfg_lines, list) {
++ list_del(&cfg_line->list);
++ kfree(cfg_line->content);
++ kfree(cfg_line);
++ }
++ return ret;
++}
++
++static int mxt_load_config(struct mxt_data *data, const char *fn)
++{
++ struct i2c_client *client = data->client;
++ struct device *dev = &client->dev;
++ const struct firmware *fw = NULL;
++ int ret, ret2;
++ char *cfg_copy = NULL;
++ char *running;
++
++ ret = request_firmware(&fw, fn, dev);
++ if (ret) {
++ dev_err(dev, "Unable to open config file %s\n", fn);
++ return ret;
++ }
++
++ dev_info(dev, "Using config file %s (size = %zu)\n", fn, fw->size);
++
++ /* Make a mutable, '\0'-terminated copy of the config file */
++ cfg_copy = kmalloc(fw->size + 1, GFP_KERNEL);
++ if (!cfg_copy) {
++ ret = -ENOMEM;
++ goto err_alloc_copy;
++ }
++ memcpy(cfg_copy, fw->data, fw->size);
++ cfg_copy[fw->size] = '\0';
++
++ /* Verify config file header (after which running points to data) */
++ running = cfg_copy;
++ ret = mxt_cfg_verify_hdr(data, &running);
++ if (ret) {
++ dev_err(dev, "Error verifying config header (%d)\n", ret);
++ goto free_cfg_copy;
++ }
++
++ disable_irq(data->irq);
++
++ if (data->input_dev) {
++ input_unregister_device(data->input_dev);
++ data->input_dev = NULL;
++ }
++
++ /* Write configuration */
++ ret = mxt_cfg_proc_data(data, &running);
++ if (ret) {
++ dev_err(dev, "Error writing config file (%d)\n", ret);
++ goto register_input_dev;
++ }
++
++ /* Backup nvram */
++ ret = mxt_write_object(data, MXT_GEN_COMMAND_T6,
++ MXT_COMMAND_BACKUPNV,
++ MXT_BACKUP_VALUE);
++ if (ret) {
++ dev_err(dev, "Error backup to nvram (%d)\n", ret);
++ goto register_input_dev;
++ }
++ msleep(MXT_BACKUP_TIME);
++
++ /* Reset device */
++ ret = mxt_write_object(data, MXT_GEN_COMMAND_T6,
++ MXT_COMMAND_RESET, 1);
++ if (ret) {
++ dev_err(dev, "Error resetting device (%d)\n", ret);
++ goto register_input_dev;
++ }
++ msleep(MXT_RESET_TIME);
++
++register_input_dev:
++ ret2 = mxt_input_dev_create(data);
++ if (ret2) {
++ dev_err(dev, "Error creating input_dev (%d)\n", ret2);
++ ret = ret2;
++ }
++
++ /* Clear message buffer */
++ ret2 = mxt_handle_messages(data);
++ if (ret2) {
++ dev_err(dev, "Error clearing msg buffer (%d)\n", ret2);
++ ret = ret2;
++ }
++
++ enable_irq(data->irq);
++free_cfg_copy:
++ kfree(cfg_copy);
++err_alloc_copy:
++ release_firmware(fw);
++ return ret;
++}
++
++/*
+ * Helper function for performing a T6 diagnostic command
+ */
+ static int mxt_T6_diag_cmd(struct mxt_data *data, struct mxt_object *T6,
+@@ -1653,6 +1950,22 @@ static ssize_t mxt_object_store(struct device *dev,
+ return count;
+ }
+
++static ssize_t mxt_update_config_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct mxt_data *data = dev_get_drvdata(dev);
++ ssize_t ret;
++
++ ret = mxt_load_config(data, data->config_file);
++ if (ret)
++ dev_err(dev, "The config update failed (%zd)\n", ret);
++ else
++ dev_dbg(dev, "The config update succeeded\n");
++
++ return ret ?: count;
++}
++
+ static int mxt_load_fw(struct device *dev, const char *fn)
+ {
+ struct mxt_data *data = dev_get_drvdata(dev);
+@@ -1747,6 +2060,7 @@ static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL);
+ static DEVICE_ATTR(info_csum, S_IRUGO, mxt_info_csum_show, NULL);
+ static DEVICE_ATTR(matrix_size, S_IRUGO, mxt_matrix_size_show, NULL);
+ static DEVICE_ATTR(object, S_IWUSR, NULL, mxt_object_store);
++static DEVICE_ATTR(update_config, S_IWUSR, NULL, mxt_update_config_store);
+ static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);
+
+ static struct attribute *mxt_attrs[] = {
+@@ -1760,6 +2074,7 @@ static struct attribute *mxt_attrs[] = {
+ &dev_attr_info_csum.attr,
+ &dev_attr_matrix_size.attr,
+ &dev_attr_object.attr,
++ &dev_attr_update_config.attr,
+ &dev_attr_update_fw.attr,
+ NULL
+ };
diff --git a/patches/linux-3.8.13/0548-CHROMIUM-Input-atmel_mxt_ts-make-mxt_initialize-asyn.patch b/patches/linux-3.8.13/0548-CHROMIUM-Input-atmel_mxt_ts-make-mxt_initialize-asyn.patch
new file mode 100644
index 0000000..edbd0db
--- /dev/null
+++ b/patches/linux-3.8.13/0548-CHROMIUM-Input-atmel_mxt_ts-make-mxt_initialize-asyn.patch
@@ -0,0 +1,223 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Tue, 30 Oct 2012 16:06:51 -0400
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - make mxt_initialize async
+
+mxt_probe() calles mxt_initialize() to initialize the device, which includes
+a soft reset and then msleep for the reset to finish. This has big impact on
+the system boot time. This patch makes the mxt_initizlize() call async to
+reduce the system boot time.
+
+BUG=chrome-os-partner:15743
+TEST=Boot the device and check the kernel timestamp in dmesg to see that
+ the device initialization is parallelized.
+
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+
+Original-Change-Id: If106af37a52a0fa874cdc8255c91fdde36776e1f
+Reviewed-on: https://gerrit.chromium.org/gerrit/36964
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Tested-by: Simon Que <sque@chromium.org>
+Commit-Ready: Yufeng Shen <miletus@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+[sonnyrao: removed __devinit for 3.8 rebase]
+
+Change-Id: I81785546c6a0ff87486e7ee92cb8bab8aefe2594
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 123 ++++++++++++++++++------------
+ 1 file changed, 74 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 8f1a33f..315dcb9 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -13,6 +13,7 @@
+
+ #include <linux/module.h>
+ #include <linux/init.h>
++#include <linux/async.h>
+ #include <linux/completion.h>
+ #include <linux/debugfs.h>
+ #include <linux/delay.h>
+@@ -1286,14 +1287,14 @@ static int mxt_initialize(struct mxt_data *data)
+ error = mxt_write_object(data, MXT_GEN_COMMAND_T6,
+ MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE);
+ if (error)
+- return error;
++ goto err_free_object_table;
+ msleep(MXT_BACKUP_TIME);
+
+ /* Soft reset */
+ error = mxt_write_object(data, MXT_GEN_COMMAND_T6,
+ MXT_COMMAND_RESET, 1);
+ if (error)
+- return error;
++ goto err_free_object_table;
+ msleep(MXT_RESET_TIME);
+
+ dev_info(&client->dev,
+@@ -2549,92 +2550,116 @@ err_free_device:
+ return error;
+ }
+
+-static int __devinit mxt_probe(struct i2c_client *client,
+- const struct i2c_device_id *id)
++static void mxt_initialize_async(void *closure, async_cookie_t cookie)
+ {
+- const struct mxt_platform_data *pdata = client->dev.platform_data;
+- struct mxt_data *data;
++ struct mxt_data *data = closure;
++ struct i2c_client *client = data->client;
+ unsigned long irqflags;
+ int error;
+
+- data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL);
+- if (!data) {
+- dev_err(&client->dev, "Failed to allocate memory\n");
+- return -ENOMEM;
+- }
+-
+- data->is_tp = !strcmp(id->name, "atmel_mxt_tp");
+- snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
+- client->adapter->nr, client->addr);
+-
+- data->client = client;
+- i2c_set_clientdata(client, data);
+-
+- data->pdata = pdata;
+- data->irq = client->irq;
+-
+- init_completion(&data->bl_completion);
+- init_completion(&data->auto_cal_completion);
+-
+- error = mxt_update_file_name(&client->dev, &data->fw_file, MXT_FW_NAME,
+- strlen(MXT_FW_NAME));
+- if (error)
+- goto err_free_mem;
+-
+- error = mxt_update_file_name(&client->dev, &data->config_file,
+- MXT_CONFIG_NAME, strlen(MXT_CONFIG_NAME));
+- if (error)
+- goto err_free_fw_file;
+-
+ if (mxt_in_bootloader(data)) {
+- dev_info(&client->dev, "Device in bootloader at probe\n");
++ dev_info(&client->dev, "device in bootloader at probe\n");
+ } else {
+ error = mxt_initialize(data);
+ if (error)
+- goto err_free_cfg_file;
++ goto error_free_mem;
+
+ error = mxt_input_dev_create(data);
+ if (error)
+- goto err_free_object;
++ goto error_free_object;
+ }
+
+ /* Default to falling edge if no platform data provided */
+- irqflags = pdata ? pdata->irqflags : IRQF_TRIGGER_FALLING;
++ irqflags = data->pdata ? data->pdata->irqflags : IRQF_TRIGGER_FALLING;
+ error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
+ irqflags | IRQF_ONESHOT,
+ client->name, data);
+ if (error) {
+ dev_err(&client->dev, "Failed to register interrupt\n");
+ if (mxt_in_bootloader(data))
+- goto err_free_mem;
++ goto error_free_mem;
+ else
+- goto err_unregister_device;
++ goto error_unregister_device;
+ }
+
+ if (!mxt_in_bootloader(data)) {
+ error = mxt_handle_messages(data);
+ if (error)
+- goto err_free_irq;
++ goto error_free_irq;
+ }
+
+- error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group);
++ /* Force the device to report back status so we can cache the device
++ * config checksum
++ */
++ error = mxt_write_object(data, MXT_GEN_COMMAND_T6,
++ MXT_COMMAND_REPORTALL, 1);
+ if (error)
+- goto err_free_irq;
++ dev_warn(&client->dev, "error making device report status.\n");
++
++ error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group);
++ if (error) {
++ dev_err(&client->dev, "error creating sysfs entries.\n");
++ goto error_free_irq;
++ }
+
+ error = mxt_debugfs_init(data);
+ if (error)
+ dev_warn(&client->dev, "error creating debugfs entries.\n");
+
+- return 0;
++ return;
+
+-err_free_irq:
++error_free_irq:
+ free_irq(client->irq, data);
+-err_unregister_device:
++error_unregister_device:
+ input_unregister_device(data->input_dev);
+-err_free_object:
++error_free_object:
+ kfree(data->object_table);
+-err_free_cfg_file:
++error_free_mem:
++ kfree(data->fw_file);
+ kfree(data->config_file);
++ kfree(data);
++}
++
++static int mxt_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ const struct mxt_platform_data *pdata = client->dev.platform_data;
++ struct mxt_data *data;
++ int error;
++
++ data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL);
++ if (!data) {
++ dev_err(&client->dev, "Failed to allocate memory\n");
++ return -ENOMEM;
++ }
++
++ data->is_tp = !strcmp(id->name, "atmel_mxt_tp");
++ snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
++ client->adapter->nr, client->addr);
++
++ data->client = client;
++ i2c_set_clientdata(client, data);
++
++ data->pdata = pdata;
++ data->irq = client->irq;
++
++ init_completion(&data->bl_completion);
++ init_completion(&data->auto_cal_completion);
++
++ error = mxt_update_file_name(&client->dev, &data->fw_file, MXT_FW_NAME,
++ strlen(MXT_FW_NAME));
++ if (error)
++ goto err_free_mem;
++
++ error = mxt_update_file_name(&client->dev, &data->config_file,
++ MXT_CONFIG_NAME, strlen(MXT_CONFIG_NAME));
++ if (error)
++ goto err_free_fw_file;
++
++ async_schedule(mxt_initialize_async, data);
++
++ return 0;
++
+ err_free_fw_file:
+ kfree(data->fw_file);
+ err_free_mem:
diff --git a/patches/linux-3.8.13/0549-CHROMIUM-Input-atmel_mxt_ts-move-backup_nv-to-handle.patch b/patches/linux-3.8.13/0549-CHROMIUM-Input-atmel_mxt_ts-move-backup_nv-to-handle.patch
new file mode 100644
index 0000000..2608fe1
--- /dev/null
+++ b/patches/linux-3.8.13/0549-CHROMIUM-Input-atmel_mxt_ts-move-backup_nv-to-handle.patch
@@ -0,0 +1,62 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Tue, 7 Aug 2012 19:48:12 -0700
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - move backup_nv to
+ handle_pdata
+
+Now that we conditionally load configs from pdata only if pdata exists,
+we no longer need to backup_nv in mxt_initialize.
+Backup nv should only be done if config data
+was provided as a part of platform data. This will save 270ms for
+backup to nv wait.
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+
+BUG=chromium-os:33370
+TEST=Boot on a system with a touch device instantiated without
+pdata. Ensure that device is still functional, but that
+270ms has been saved until the input device is created.
+
+Change-Id: I44ecf9237db2f866787c72e03e8962ca285db865
+Reviewed-on: https://gerrit.chromium.org/gerrit/29571
+Commit-Ready: Benson Leung <bleung@chromium.org>
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Tested-by: Benson Leung <bleung@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 315dcb9..bdbcc60 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -1084,6 +1084,13 @@ static int mxt_handle_pdata(struct mxt_data *data)
+ MXT_CTE_VOLTAGE, voltage);
+ }
+
++ /* Backup to memory */
++ ret = mxt_write_object(data, MXT_GEN_COMMAND_T6,
++ MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE);
++ if (ret)
++ return ret;
++ msleep(MXT_BACKUP_TIME);
++
+ return 0;
+ }
+
+@@ -1283,13 +1290,6 @@ static int mxt_initialize(struct mxt_data *data)
+ if (error)
+ goto err_free_object_table;
+
+- /* Backup to memory */
+- error = mxt_write_object(data, MXT_GEN_COMMAND_T6,
+- MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE);
+- if (error)
+- goto err_free_object_table;
+- msleep(MXT_BACKUP_TIME);
+-
+ /* Soft reset */
+ error = mxt_write_object(data, MXT_GEN_COMMAND_T6,
+ MXT_COMMAND_RESET, 1);
diff --git a/patches/linux-3.8.13/0550-CHROMIUM-Input-atmel_mxt_ts-Add-defines-for-T9-Touch.patch b/patches/linux-3.8.13/0550-CHROMIUM-Input-atmel_mxt_ts-Add-defines-for-T9-Touch.patch
new file mode 100644
index 0000000..045aa55
--- /dev/null
+++ b/patches/linux-3.8.13/0550-CHROMIUM-Input-atmel_mxt_ts-Add-defines-for-T9-Touch.patch
@@ -0,0 +1,81 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Tue, 7 Aug 2012 16:20:18 -0700
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Add defines for T9 Touch
+ Control
+
+Fix the use of magic numbers (such as 0x83) to write to
+T9 Touch Control.
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+
+BUG=chromium-os:33368
+TEST=Builds clean.
+
+Change-Id: I28d650becaa103490541cd88b600fdb535b4196c
+Reviewed-on: https://gerrit.chromium.org/gerrit/29558
+Commit-Ready: Benson Leung <bleung@chromium.org>
+Tested-by: Benson Leung <bleung@chromium.org>
+Reviewed-by: Benson Leung <bleung@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index bdbcc60..f13ef67 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -154,6 +154,21 @@
+ #define MXT_TOUCH_YEDGEDIST 29
+ #define MXT_TOUCH_JUMPLIMIT 30
+
++/* MXT_TOUCH_CTRL bits */
++#define MXT_TOUCH_CTRL_ENABLE (1 << 0)
++#define MXT_TOUCH_CTRL_RPTEN (1 << 1)
++#define MXT_TOUCH_CTRL_DISAMP (1 << 2)
++#define MXT_TOUCH_CTRL_DISVECT (1 << 3)
++#define MXT_TOUCH_CTRL_DISMOVE (1 << 4)
++#define MXT_TOUCH_CTRL_DISREL (1 << 5)
++#define MXT_TOUCH_CTRL_DISPRESS (1 << 6)
++#define MXT_TOUCH_CTRL_SCANEN (1 << 7)
++#define MXT_TOUCH_CTRL_OPERATIONAL (MXT_TOUCH_CTRL_ENABLE | \
++ MXT_TOUCH_CTRL_SCANEN | \
++ MXT_TOUCH_CTRL_RPTEN)
++#define MXT_TOUCH_CTRL_SCANNING (MXT_TOUCH_CTRL_ENABLE | \
++ MXT_TOUCH_CTRL_SCANEN)
++
+ /* MXT_PROCI_GRIPFACE_T20 field */
+ #define MXT_GRIPFACE_CTRL 0
+ #define MXT_GRIPFACE_XLOGRIP 1
+@@ -2444,8 +2459,8 @@ static int mxt_set_regs(struct mxt_data *data, u8 type, u8 instance,
+ static void mxt_start(struct mxt_data *data)
+ {
+ /* Touch enable */
+- mxt_write_object(data,
+- MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0x83);
++ mxt_write_object(data, MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL,
++ MXT_TOUCH_CTRL_OPERATIONAL);
+ }
+
+ static void mxt_stop(struct mxt_data *data)
+@@ -2689,7 +2704,7 @@ static int mxt_remove(struct i2c_client *client)
+ static void mxt_suspend_enable_T9(struct mxt_data *data)
+ {
+ struct device *dev = &data->client->dev;
+- u8 T9_ctrl = 0x03;
++ u8 T9_ctrl = MXT_TOUCH_CTRL_ENABLE | MXT_TOUCH_CTRL_RPTEN;
+ int ret;
+ unsigned long timeout = msecs_to_jiffies(350);
+
+@@ -2757,7 +2772,8 @@ static int mxt_suspend(struct device *dev)
+ data->T9_ctrl_valid = (ret == 0);
+
+ /* Enable T9 only if it is not currently enabled */
+- if (data->T9_ctrl_valid && !(data->T9_ctrl & 0x01))
++ if (data->T9_ctrl_valid &&
++ !(data->T9_ctrl & MXT_TOUCH_CTRL_ENABLE))
+ mxt_suspend_enable_T9(data);
+
+ /* Enable wake from IRQ */
diff --git a/patches/linux-3.8.13/0551-CHROMIUM-Input-atmel_mxt_ts-disable-reporting-on-sto.patch b/patches/linux-3.8.13/0551-CHROMIUM-Input-atmel_mxt_ts-disable-reporting-on-sto.patch
new file mode 100644
index 0000000..ca1c752
--- /dev/null
+++ b/patches/linux-3.8.13/0551-CHROMIUM-Input-atmel_mxt_ts-disable-reporting-on-sto.patch
@@ -0,0 +1,48 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Fri, 10 Aug 2012 18:43:52 -0700
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - disable reporting on stop
+
+Leave the touch device scanning and enabled, but disable reporting
+on mxt_stop. This will prevent a needless recalibration due to the T9_ctrl
+register being set to 0 (disabling the object) and then set back to 0x83.
+
+BUG=chrome-os-partner:12042,chrome-os-partner:9717
+TEST=Log in to guest mode. Test the touch screen.
+Log out. Verify that in the next session (after X has restarted)
+touch performance is still good.
+
+Change-Id: If5556325d69390a329d1ed406b5bba9f0d494896
+Signed-off-by: Benson Leung <bleung@chromium.org>
+Reviewed-on: https://gerrit.chromium.org/gerrit/29951
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index f13ef67..33b564b 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -2458,16 +2458,16 @@ static int mxt_set_regs(struct mxt_data *data, u8 type, u8 instance,
+
+ static void mxt_start(struct mxt_data *data)
+ {
+- /* Touch enable */
++ /* Enable touch reporting */
+ mxt_write_object(data, MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL,
+ MXT_TOUCH_CTRL_OPERATIONAL);
+ }
+
+ static void mxt_stop(struct mxt_data *data)
+ {
+- /* Touch disable */
+- mxt_write_object(data,
+- MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0);
++ /* Disable touch reporting */
++ mxt_write_object(data, MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL,
++ MXT_TOUCH_CTRL_SCANNING);
+ }
+
+ static int mxt_input_open(struct input_dev *dev)
diff --git a/patches/linux-3.8.13/0552-CHROMIUM-Input-atmel_mxt_ts-Suppress-handle-messages.patch b/patches/linux-3.8.13/0552-CHROMIUM-Input-atmel_mxt_ts-Suppress-handle-messages.patch
new file mode 100644
index 0000000..25fb51d
--- /dev/null
+++ b/patches/linux-3.8.13/0552-CHROMIUM-Input-atmel_mxt_ts-Suppress-handle-messages.patch
@@ -0,0 +1,112 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Mon, 13 Aug 2012 18:10:29 -0700
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Suppress handle messages
+ used for resume
+
+The position information at resume time while the system is in a
+low power state may be garbage, so do not actually report this
+information up to the input layer. Just perform the reads to clear
+out the status on the device side.
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+
+BUG=chrome-os-partner:12318
+TEST=Suspend/resume using lid close. Check that on resume,
+the touch device doesn't show a bunch of garbage data
+from when the lid was just being opened.
+
+Change-Id: I4e60ab672d6191b9141e08e9b0bfdbf42649a95e
+Reviewed-on: https://gerrit.chromium.org/gerrit/31194
+Reviewed-by: Yufeng Shen <miletus@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 33b564b..af92d8d 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -837,7 +837,7 @@ static bool mxt_is_T9_message(struct mxt_data *data, struct mxt_message *msg)
+ return (id >= data->T9_reportid_min && id <= data->T9_reportid_max);
+ }
+
+-static int mxt_proc_messages(struct mxt_data *data, u8 count)
++static int mxt_proc_messages(struct mxt_data *data, u8 count, bool report)
+ {
+ struct device *dev = &data->client->dev;
+ u8 reportid;
+@@ -854,6 +854,8 @@ static int mxt_proc_messages(struct mxt_data *data, u8 count)
+ dev_err(dev, "Failed to read %u messages (%d).\n", count, ret);
+ goto out;
+ }
++ if (!report)
++ goto out;
+
+ for (msg = messages; msg < &messages[count]; msg++) {
+ mxt_dump_message(dev, msg);
+@@ -887,7 +889,7 @@ out:
+ return ret;
+ }
+
+-static int mxt_handle_messages(struct mxt_data *data)
++static int mxt_handle_messages(struct mxt_data *data, bool report)
+ {
+ struct device *dev = &data->client->dev;
+ int ret;
+@@ -900,7 +902,7 @@ static int mxt_handle_messages(struct mxt_data *data)
+ }
+
+ if (count > 0)
+- ret = mxt_proc_messages(data, count);
++ ret = mxt_proc_messages(data, count, report);
+
+ return ret;
+ }
+@@ -985,7 +987,7 @@ static void mxt_exit_bl(struct mxt_data *data)
+ return;
+ }
+
+- error = mxt_handle_messages(data);
++ error = mxt_handle_messages(data, false);
+ if (error)
+ dev_err(dev, "Failed to clear CHG after init. error = %d\n",
+ error);
+@@ -1000,7 +1002,7 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
+ /* bootloader state transition completion */
+ complete(&data->bl_completion);
+ } else {
+- mxt_handle_messages(data);
++ mxt_handle_messages(data, true);
+ }
+ return IRQ_HANDLED;
+ }
+@@ -1646,7 +1648,7 @@ register_input_dev:
+ }
+
+ /* Clear message buffer */
+- ret2 = mxt_handle_messages(data);
++ ret2 = mxt_handle_messages(data, true);
+ if (ret2) {
+ dev_err(dev, "Error clearing msg buffer (%d)\n", ret2);
+ ret = ret2;
+@@ -2598,7 +2600,7 @@ static void mxt_initialize_async(void *closure, async_cookie_t cookie)
+ }
+
+ if (!mxt_in_bootloader(data)) {
+- error = mxt_handle_messages(data);
++ error = mxt_handle_messages(data, true);
+ if (error)
+ goto error_free_irq;
+ }
+@@ -2800,7 +2802,7 @@ static int mxt_resume(struct device *dev)
+ return 0;
+
+ /* Process any pending message so that CHG line can be de-asserted */
+- ret = mxt_handle_messages(data);
++ ret = mxt_handle_messages(data, false);
+ if (ret)
+ dev_err(dev, "Handling message fails upon resume, %d\n", ret);
+
diff --git a/patches/linux-3.8.13/0553-CHROMIUM-Input-atmel_mxt_ts-save-and-restore-t9_ctrl.patch b/patches/linux-3.8.13/0553-CHROMIUM-Input-atmel_mxt_ts-save-and-restore-t9_ctrl.patch
new file mode 100644
index 0000000..d8b216e
--- /dev/null
+++ b/patches/linux-3.8.13/0553-CHROMIUM-Input-atmel_mxt_ts-save-and-restore-t9_ctrl.patch
@@ -0,0 +1,70 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Thu, 23 Aug 2012 15:43:55 -0700
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - save and restore t9_ctrl on
+ wakeup disabled
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+
+BUG=chrome-os-partner:12318
+TEST=Close and open the lid to suspend and resume the system.
+Make sure that the touchscreen does not generate a lot of
+stray events on resume.
+
+Change-Id: I57b34aab52149cc78cd55a79640b496239bbfa5e
+Reviewed-on: https://gerrit.chromium.org/gerrit/31270
+Reviewed-by: Yufeng Shen <miletus@chromium.org>
+Commit-Ready: Benson Leung <bleung@chromium.org>
+Tested-by: Benson Leung <bleung@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index af92d8d..ae8a6f3 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -2760,19 +2760,19 @@ static int mxt_suspend(struct device *dev)
+ if (ret)
+ dev_err(dev, "Set T7 Power config failed, %d\n", ret);
+
++ /* Save 1 byte T9 Ctrl config */
++ ret = mxt_save_regs(data, MXT_TOUCH_MULTI_T9, 0, 0,
++ &data->T9_ctrl, 1);
++ if (ret)
++ dev_err(dev, "Save T9 ctrl config failed, %d\n", ret);
++ data->T9_ctrl_valid = (ret == 0);
++
+ if (device_may_wakeup(dev)) {
+ /*
+ * If we allow wakeup from touch, we have to enable T9 so
+ * that IRQ can be generated from touch
+ */
+
+- /* Save 1 byte T9 Ctrl config */
+- ret = mxt_save_regs(data, MXT_TOUCH_MULTI_T9, 0, 0,
+- &data->T9_ctrl, 1);
+- if (ret)
+- dev_err(dev, "Save T9 ctrl config failed, %d\n", ret);
+- data->T9_ctrl_valid = (ret == 0);
+-
+ /* Enable T9 only if it is not currently enabled */
+ if (data->T9_ctrl_valid &&
+ !(data->T9_ctrl & MXT_TOUCH_CTRL_ENABLE))
+@@ -2814,13 +2814,11 @@ static int mxt_resume(struct device *dev)
+ disable_irq_wake(data->irq);
+
+ /* Restore the T9 Ctrl config to before-suspend value */
+- if (device_may_wakeup(dev) && data->T9_ctrl_valid) {
++ if (data->T9_ctrl_valid) {
+ ret = mxt_set_regs(data, MXT_TOUCH_MULTI_T9, 0, 0,
+ &data->T9_ctrl, 1);
+ if (ret)
+ dev_err(dev, "Set T9 ctrl config failed, %d\n", ret);
+- } else if (input_dev->users) {
+- mxt_start(data);
+ }
+
+ /* Restore the T7 Power config to before-suspend value */
diff --git a/patches/linux-3.8.13/0554-CHROMIUM-Input-atmel_mxt_ts-enable-RPTEN-if-can-wake.patch b/patches/linux-3.8.13/0554-CHROMIUM-Input-atmel_mxt_ts-enable-RPTEN-if-can-wake.patch
new file mode 100644
index 0000000..aad2a97
--- /dev/null
+++ b/patches/linux-3.8.13/0554-CHROMIUM-Input-atmel_mxt_ts-enable-RPTEN-if-can-wake.patch
@@ -0,0 +1,95 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Wed, 12 Sep 2012 12:42:16 -0400
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - enable RPTEN if can wakeup
+ from suspend
+
+Currently when going into suspend and if wakeup is enabled,
+the driver will check whether the T9_ctrl ENABLE bit is set and
+if not, it will toggle the bit so that T9 object is enabled
+to make wakeup possible during suspend.
+
+With recent change to T9_ctrl's default value to be 0x81, it
+is enabled (ENABLE bit set) but not reporting (RPTEN bit not
+set) which prevents touches reported back during suspend.
+
+To fix this, this patches adds checking that whether both ENABLE
+and RPTEN bits are set, and if not, set both of them.
+
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+
+BUG=chrome-os-partner:9192
+TEST=Use powerd_suspend to supend the device and then make sure
+ touching the touch device wakes up the system.
+
+Change-Id: I234531ae91627f7e1cccbef5810a18a5af6cbae9
+Reviewed-on: https://gerrit.chromium.org/gerrit/33088
+Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Commit-Ready: Yufeng Shen <miletus@chromium.org>
+Tested-by: Yufeng Shen <miletus@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 35 ++++++++++++++++++++++--------
+ 1 file changed, 26 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index ae8a6f3..d7cd1a5 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -2709,10 +2709,26 @@ static void mxt_suspend_enable_T9(struct mxt_data *data)
+ u8 T9_ctrl = MXT_TOUCH_CTRL_ENABLE | MXT_TOUCH_CTRL_RPTEN;
+ int ret;
+ unsigned long timeout = msecs_to_jiffies(350);
++ bool need_enable = false;
++ bool need_report = false;
+
+- INIT_COMPLETION(data->auto_cal_completion);
++ dev_dbg(dev, "Current T9_Ctrl is %x\n", data->T9_ctrl);
+
+- /* Enable T9 object */
++ need_enable = !(data->T9_ctrl & MXT_TOUCH_CTRL_ENABLE);
++ need_report = !(data->T9_ctrl & MXT_TOUCH_CTRL_RPTEN);
++
++ /* If already enabled and reporting, do nothing */
++ if (!need_enable && !need_report)
++ return;
++
++ /* If the ENABLE bit is toggled, there will be auto-calibration msg.
++ * We will have to clear this msg before going into suspend otherwise
++ * it will wake up the device immediately
++ */
++ if (need_enable)
++ INIT_COMPLETION(data->auto_cal_completion);
++
++ /* Enable T9 object (ENABLE and REPORT) */
+ ret = mxt_set_regs(data, MXT_TOUCH_MULTI_T9, 0, 0,
+ &T9_ctrl, 1);
+ if (ret) {
+@@ -2720,10 +2736,12 @@ static void mxt_suspend_enable_T9(struct mxt_data *data)
+ return;
+ }
+
+- ret = wait_for_completion_interruptible_timeout(
+- &data->auto_cal_completion, timeout);
+- if (ret <= 0)
+- dev_err(dev, "Wait for auto cal completion failed.\n");
++ if (need_enable) {
++ ret = wait_for_completion_interruptible_timeout(
++ &data->auto_cal_completion, timeout);
++ if (ret <= 0)
++ dev_err(dev, "Wait for auto cal completion failed.\n");
++ }
+ }
+
+ static int mxt_suspend(struct device *dev)
+@@ -2773,9 +2791,8 @@ static int mxt_suspend(struct device *dev)
+ * that IRQ can be generated from touch
+ */
+
+- /* Enable T9 only if it is not currently enabled */
+- if (data->T9_ctrl_valid &&
+- !(data->T9_ctrl & MXT_TOUCH_CTRL_ENABLE))
++ /* Set proper T9 ENABLE & REPTN bits */
++ if (data->T9_ctrl_valid)
+ mxt_suspend_enable_T9(data);
+
+ /* Enable wake from IRQ */
diff --git a/patches/linux-3.8.13/0555-CHROMIUM-Input-atmel_mxt_ts-release-all-fingers-on-r.patch b/patches/linux-3.8.13/0555-CHROMIUM-Input-atmel_mxt_ts-release-all-fingers-on-r.patch
new file mode 100644
index 0000000..e8fa618
--- /dev/null
+++ b/patches/linux-3.8.13/0555-CHROMIUM-Input-atmel_mxt_ts-release-all-fingers-on-r.patch
@@ -0,0 +1,126 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Tue, 9 Oct 2012 16:51:52 -0400
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - release all fingers on
+ resume
+
+Currently lid close/open can generate noise touch events on system
+suspend and resume. One case is that touch down is generated before
+suspend, and touch liftoff is processed on resume. The driver will
+discard any pending messages on resume which might make the system
+enter ghost finger state (touch down without ever liftoff).
+
+To workaround the ghost finger case, this patch forces release of
+all possible fingers on resume. And to avoid the unwanted click
+resulted from the forced release, move these fingers first to (0,0)
+and assign them with maximal PRESSURE and TOUCH_MAJOR value so to
+make them look like palms.
+
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+
+BUG=chromium:154383
+TEST=use evtest to monitor the touch device; put fingers on the
+ touch device; close the lid; remove fingers after making
+ sure the system enters suspend; Open the lid;
+ Make sure to see finger move events with pressue and
+ touch_major = 255 and the release events.
+
+Change-Id: Ic9f0659a2e731c2db03255eb2107be88b333541a
+Reviewed-on: https://gerrit.chromium.org/gerrit/35046
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Commit-Ready: Yufeng Shen <miletus@chromium.org>
+Tested-by: Yufeng Shen <miletus@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 49 ++++++++++++++++++++++++++++++
+ 1 file changed, 49 insertions(+)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index d7cd1a5..b964430 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -260,6 +260,8 @@
+ /* Touchscreen absolute values */
+ #define MXT_MAX_AREA 0xff
+
++#define MXT_MAX_FINGER 10
++
+ /* For CMT (must match XRANGE/YRANGE as defined in board config */
+ #define MXT_PIXELS_PER_MM 20
+
+@@ -369,6 +371,9 @@ struct mxt_data {
+
+ /* config file name */
+ char *config_file;
++
++ /* map for the tracking id currently being used */
++ bool current_id[MXT_MAX_FINGER];
+ };
+
+ /* global root node of the atmel_mxt_ts debugfs directory. */
+@@ -470,6 +475,47 @@ static void mxt_dump_message(struct device *dev,
+ message->reportid, 7, message->message);
+ }
+
++/*
++ * Release all the fingers that are being tracked. To avoid unwanted gestures,
++ * move all the fingers to (0,0) with largest PRESSURE and TOUCH_MAJOR.
++ * Userspace apps can use these info to filter out these events and/or cancel
++ * existing gestures.
++ */
++static void mxt_release_all_fingers(struct mxt_data *data)
++{
++ struct device *dev = &data->client->dev;
++ struct input_dev *input_dev = data->input_dev;
++ int id;
++ bool need_update = false;
++ for (id = 0; id < MXT_MAX_FINGER; id++) {
++ if (data->current_id[id]) {
++ dev_warn(dev, "Move touch %d to (0,0)\n", id);
++ input_mt_slot(input_dev, id);
++ input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
++ true);
++ input_report_abs(input_dev, ABS_MT_POSITION_X, 0);
++ input_report_abs(input_dev, ABS_MT_POSITION_Y, 0);
++ input_report_abs(input_dev, ABS_MT_PRESSURE, 255);
++ input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, 255);
++ need_update = true;
++ }
++ }
++ if (need_update)
++ input_sync(data->input_dev);
++
++ for (id = 0; id < MXT_MAX_FINGER; id++) {
++ if (data->current_id[id]) {
++ dev_warn(dev, "Release touch contact %d\n", id);
++ input_mt_slot(input_dev, id);
++ input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
++ false);
++ data->current_id[id] = false;
++ }
++ }
++ if (need_update)
++ input_sync(data->input_dev);
++}
++
+ static bool mxt_in_bootloader(struct mxt_data *data)
+ {
+ struct i2c_client *client = data->client;
+@@ -816,6 +862,7 @@ static void mxt_input_touchevent(struct mxt_data *data,
+ input_mt_slot(input_dev, id);
+ input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
+ status & MXT_DETECT);
++ data->current_id[id] = status & MXT_DETECT;
+
+ if (status & MXT_DETECT) {
+ input_report_abs(input_dev, ABS_MT_POSITION_X, x);
+@@ -2823,6 +2870,8 @@ static int mxt_resume(struct device *dev)
+ if (ret)
+ dev_err(dev, "Handling message fails upon resume, %d\n", ret);
+
++ mxt_release_all_fingers(data);
++
+ mutex_lock(&input_dev->mutex);
+
+ enable_irq(data->irq);
diff --git a/patches/linux-3.8.13/0556-CHROMIUM-Input-atmel_mxt_ts-make-suspend-power-acqui.patch b/patches/linux-3.8.13/0556-CHROMIUM-Input-atmel_mxt_ts-make-suspend-power-acqui.patch
new file mode 100644
index 0000000..6c4fa6e
--- /dev/null
+++ b/patches/linux-3.8.13/0556-CHROMIUM-Input-atmel_mxt_ts-make-suspend-power-acqui.patch
@@ -0,0 +1,167 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Mon, 12 Nov 2012 14:21:10 -0500
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - make suspend power
+ acquisition interval configurable
+
+Create sysfs for T7 IDLE/ACTV-ACQINT settings to have a configurable power
+acquisition setting during system suspend.
+
+Also change the default T7 IDLE/ACTV-ACQINT values during system suspend to be
+32ms to have a sensitive wakeup-from-touch response.
+
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+
+BUG=chrome-os-partner:15968
+TEST=1. go to touch device sysfs directory
+ echo 254 > power/suspend_acq_interval_ms
+ Try powerd_suspend and use very quick, gentle touch to wake up the system
+ and notice that sometimes the system does not wake up from touch.
+ 2. go to touch device sysfs directory
+ echo 32 > power/suspend_acq_interval_ms
+ Try powerd_suspend and use very quick, gentle touch to wake up the system
+ and make sure the system always wakes up.
+
+Change-Id: Ib7ad7a6b81699b71bcb165df06f275e55a68e7c6
+Reviewed-on: https://gerrit.chromium.org/gerrit/37836
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Commit-Ready: Yufeng Shen <miletus@chromium.org>
+Tested-by: Yufeng Shen <miletus@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 64 +++++++++++++++++++++++++++++-
+ 1 file changed, 63 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index b964430..8ca5288 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -223,6 +223,9 @@
+
+ #define MXT_FWRESET_TIME 500 /* msec */
+
++/* Default value for acquisition interval when in suspend mode*/
++#define MXT_SUSPEND_ACQINT_VALUE 32 /* msec */
++
+ /* MXT_SPT_GPIOPWM_T19 field */
+ #define MXT_GPIO0_MASK 0x04
+ #define MXT_GPIO1_MASK 0x08
+@@ -352,6 +355,9 @@ struct mxt_data {
+ u8 T7_config[3];
+ bool T7_config_valid;
+
++ /* T7 IDLEACQINT & ACTVACQINT setting when in suspend mode*/
++ u8 suspend_acq_interval;
++
+ /* Saved T9 Ctrl field */
+ u8 T9_ctrl;
+ bool T9_ctrl_valid;
+@@ -2113,6 +2119,39 @@ static ssize_t mxt_update_fw_store(struct device *dev,
+ return count;
+ }
+
++static ssize_t mxt_suspend_acq_interval_ms_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct mxt_data *data = dev_get_drvdata(dev);
++ u8 interval_reg = data->suspend_acq_interval;
++ u8 interval_ms = (interval_reg == 255) ? 0 : interval_reg;
++ return scnprintf(buf, PAGE_SIZE, "%u\n", interval_ms);
++}
++
++static ssize_t mxt_suspend_acq_interval_ms_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct mxt_data *data = dev_get_drvdata(dev);
++ int ret;
++ u32 param;
++
++ ret = kstrtou32(buf, 10, &param);
++ if (ret < 0)
++ return -EINVAL;
++
++ /* 0 ms inteval means "free run" */
++ if (param == 0)
++ param = 255;
++ /* 254 ms is the largest interval */
++ else if (param > 254)
++ param = 254;
++
++ data->suspend_acq_interval = param;
++ return count;
++}
++
+ static DEVICE_ATTR(backupnv, S_IWUSR, NULL, mxt_backupnv_store);
+ static DEVICE_ATTR(calibrate, S_IWUSR, NULL, mxt_calibrate_store);
+ static DEVICE_ATTR(config_csum, S_IRUGO, mxt_config_csum_show, NULL);
+@@ -2127,6 +2166,9 @@ static DEVICE_ATTR(matrix_size, S_IRUGO, mxt_matrix_size_show, NULL);
+ static DEVICE_ATTR(object, S_IWUSR, NULL, mxt_object_store);
+ static DEVICE_ATTR(update_config, S_IWUSR, NULL, mxt_update_config_store);
+ static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);
++static DEVICE_ATTR(suspend_acq_interval_ms, S_IRUGO | S_IWUSR,
++ mxt_suspend_acq_interval_ms_show,
++ mxt_suspend_acq_interval_ms_store);
+
+ static struct attribute *mxt_attrs[] = {
+ &dev_attr_backupnv.attr,
+@@ -2148,6 +2190,16 @@ static const struct attribute_group mxt_attr_group = {
+ .attrs = mxt_attrs,
+ };
+
++static struct attribute *mxt_power_attrs[] = {
++ &dev_attr_suspend_acq_interval_ms.attr,
++ NULL
++};
++
++static const struct attribute_group mxt_power_attr_group = {
++ .name = power_group_name,
++ .attrs = mxt_power_attrs,
++};
++
+ /*
+ **************************************************************
+ * debugfs helper functions
+@@ -2666,6 +2718,10 @@ static void mxt_initialize_async(void *closure, async_cookie_t cookie)
+ goto error_free_irq;
+ }
+
++ error = sysfs_merge_group(&client->dev.kobj, &mxt_power_attr_group);
++ if (error)
++ dev_warn(&client->dev, "error merging power sysfs entries.\n");
++
+ error = mxt_debugfs_init(data);
+ if (error)
+ dev_warn(&client->dev, "error creating debugfs entries.\n");
+@@ -2710,6 +2766,8 @@ static int mxt_probe(struct i2c_client *client,
+ init_completion(&data->bl_completion);
+ init_completion(&data->auto_cal_completion);
+
++ data->suspend_acq_interval = MXT_SUSPEND_ACQINT_VALUE;
++
+ error = mxt_update_file_name(&client->dev, &data->fw_file, MXT_FW_NAME,
+ strlen(MXT_FW_NAME));
+ if (error)
+@@ -2736,6 +2794,7 @@ static int mxt_remove(struct i2c_client *client)
+ struct mxt_data *data = i2c_get_clientdata(client);
+
+ mxt_debugfs_remove(data);
++ sysfs_unmerge_group(&client->dev.kobj, &mxt_power_attr_group);
+ sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
+ free_irq(data->irq, data);
+ if (data->input_dev)
+@@ -2796,7 +2855,10 @@ static int mxt_suspend(struct device *dev)
+ struct i2c_client *client = to_i2c_client(dev);
+ struct mxt_data *data = i2c_get_clientdata(client);
+ struct input_dev *input_dev = data->input_dev;
+- static const u8 T7_config_idle[3] = { 0xfe, 0xfe, 0x00 };
++ const u8 T7_config_idle[3] = {
++ data->suspend_acq_interval,
++ data->suspend_acq_interval,
++ 0x00 };
+ static const u8 T7_config_deepsleep[3] = { 0x00, 0x00, 0x00 };
+ const u8 *power_config;
+ int ret;
diff --git a/patches/linux-3.8.13/0557-CHROMIUM-Input-atmel_mxt_ts-recalibrate-on-system-re.patch b/patches/linux-3.8.13/0557-CHROMIUM-Input-atmel_mxt_ts-recalibrate-on-system-re.patch
new file mode 100644
index 0000000..9d473e4
--- /dev/null
+++ b/patches/linux-3.8.13/0557-CHROMIUM-Input-atmel_mxt_ts-recalibrate-on-system-re.patch
@@ -0,0 +1,80 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Wed, 14 Nov 2012 16:13:59 -0500
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - recalibrate on system resume
+
+In the suspend path, if we don't allow device wakeup, we put the
+chip into deepsleep mode and the chip stops scanning during suspen.
+On resume if the environment changes, the calibrated baseline before
+suspend will no longer be valid.
+
+In this patch we force a recalibration on resume if device wakeup is
+disabled during suspend to handle the environment change.
+
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+
+BUG=chrome-os-partner:16171
+TEST=I don't have a controlled environment to test this. So I only test
+ normal suspend/resume to make sure no noise touches happen on resume
+ and touch devices work as expected.
+ 1. With lid open, using powerd_suspend to suspend the system. Wakeup
+ the system and make sure the touch device still works.
+ Run "demsg | grep atmel" to make sure no calibration message reported.
+ 2. Use lid close to suspend the system. Wakeup the system and make
+ sure touch device still works.
+ Run "demsg | grep atmel" to make sure calibration message are reported.
+ 3. Also notice the case of lid open caused system resume, if something is
+ on the touch surface (like opening the lid and quickly put the palm on the
+ touch surface for a while), the system will get calibrated into a wrong
+ baseline and touch device then won't work.
+
+Change-Id: I62cb47fa1c97917a2c0f968e41ee4cd13f12187c
+Reviewed-on: https://gerrit.chromium.org/gerrit/38051
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Commit-Ready: Yufeng Shen <miletus@chromium.org>
+Tested-by: Yufeng Shen <miletus@chromium.org>
+
+v3.7 rebase:
+Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 8ca5288..9196e94 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -2936,11 +2936,6 @@ static int mxt_resume(struct device *dev)
+
+ mutex_lock(&input_dev->mutex);
+
+- enable_irq(data->irq);
+-
+- if (device_may_wakeup(dev) && data->irq_wake)
+- disable_irq_wake(data->irq);
+-
+ /* Restore the T9 Ctrl config to before-suspend value */
+ if (data->T9_ctrl_valid) {
+ ret = mxt_set_regs(data, MXT_TOUCH_MULTI_T9, 0, 0,
+@@ -2957,8 +2952,22 @@ static int mxt_resume(struct device *dev)
+ dev_err(dev, "Set T7 power config failed, %d\n", ret);
+ }
+
++ if (!device_may_wakeup(dev)) {
++ /* Recalibration in case of environment change */
++ ret = mxt_write_object(data, MXT_GEN_COMMAND_T6,
++ MXT_COMMAND_CALIBRATE, 1);
++ if (ret)
++ dev_err(dev, "Resume recalibration failed %d\n", ret);
++ msleep(MXT_CAL_TIME);
++ }
++
+ mutex_unlock(&input_dev->mutex);
+
++ enable_irq(data->irq);
++
++ if (device_may_wakeup(dev) && data->irq_wake)
++ disable_irq_wake(data->irq);
++
+ return 0;
+ }
+ #endif
diff --git a/patches/linux-3.8.13/0558-CHROMIUM-Input-atmel_mxt_ts-Use-correct-max-touch_ma.patch b/patches/linux-3.8.13/0558-CHROMIUM-Input-atmel_mxt_ts-Use-correct-max-touch_ma.patch
new file mode 100644
index 0000000..6877389
--- /dev/null
+++ b/patches/linux-3.8.13/0558-CHROMIUM-Input-atmel_mxt_ts-Use-correct-max-touch_ma.patch
@@ -0,0 +1,59 @@
+From: Yufeng Shen <miletus@chromium.org>
+Date: Thu, 10 Jan 2013 15:00:42 -0500
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts: Use correct max touch_major
+ in mxt_release_all_fingers()
+
+We hard-coded the maximal touch_major value to be 255 in mxt_release_all_fingers().
+Fixing this by using the queried actual maximal touch_major value.
+
+Signed-off-by: Yufeng Shen <miletus@chromium.org>
+
+BUG=chrome-os-partner:17176
+TEST=1. Run evtest on the touch device
+ 2. Keep touching the device while closing the lid.
+ 3. Release the touch after the system suspends.
+ 4. Open the lid to resume the system
+ 5. Check evtest result and see that there is release events with correct
+ touch major value.
+
+Change-Id: I4c3bbb37c25c0df67c752a8b6943f6c127f01aa7
+Reviewed-on: https://gerrit.chromium.org/gerrit/41031
+Reviewed-by: Benson Leung <bleung@chromium.org>
+Commit-Queue: Yufeng Shen <miletus@chromium.org>
+Tested-by: Yufeng Shen <miletus@chromium.org>
+(cherry picked from commit 0a962d62165755547e4802da837ca9004f5d246b)
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 9196e94..893d59d 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -389,6 +389,7 @@ static int mxt_calc_resolution(struct mxt_data *data);
+ static void mxt_free_object_table(struct mxt_data *data);
+ static int mxt_initialize(struct mxt_data *data);
+ static int mxt_input_dev_create(struct mxt_data *data);
++static int get_touch_major_pixels(struct mxt_data *data, int touch_channels);
+
+ static inline size_t mxt_obj_size(const struct mxt_object *obj)
+ {
+@@ -492,6 +493,8 @@ static void mxt_release_all_fingers(struct mxt_data *data)
+ struct device *dev = &data->client->dev;
+ struct input_dev *input_dev = data->input_dev;
+ int id;
++ int max_area_channels = min(255U, data->max_area_channels);
++ int max_touch_major = get_touch_major_pixels(data, max_area_channels);
+ bool need_update = false;
+ for (id = 0; id < MXT_MAX_FINGER; id++) {
+ if (data->current_id[id]) {
+@@ -502,7 +505,8 @@ static void mxt_release_all_fingers(struct mxt_data *data)
+ input_report_abs(input_dev, ABS_MT_POSITION_X, 0);
+ input_report_abs(input_dev, ABS_MT_POSITION_Y, 0);
+ input_report_abs(input_dev, ABS_MT_PRESSURE, 255);
+- input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, 255);
++ input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR,
++ max_touch_major);
+ need_update = true;
+ }
+ }
diff --git a/patches/linux-3.8.13/0559-CHROMIUM-Input-atmel_mxt_ts-Add-support-for-T65-Lens.patch b/patches/linux-3.8.13/0559-CHROMIUM-Input-atmel_mxt_ts-Add-support-for-T65-Lens.patch
new file mode 100644
index 0000000..d8df62f
--- /dev/null
+++ b/patches/linux-3.8.13/0559-CHROMIUM-Input-atmel_mxt_ts-Add-support-for-T65-Lens.patch
@@ -0,0 +1,70 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Wed, 9 Jan 2013 17:30:44 -0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Add support for T65,
+ Lensbending Correction
+
+Add T65 object to list of supported objects, and mark it readable
+and writable.
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+
+BUG=chrome-os-partner:17253
+TEST=cat /sys/kernel/debug/atmel_mxt_ts/2-004a/object
+Check that the following object appears:
+Type: 65
+ [ 0]: 00 (0)
+ [ 1]: 00 (0)
+ [ 2]: 00 (0)
+ [ 3]: 00 (0)
+ [ 4]: 00 (0)
+ [ 5]: 00 (0)
+ [ 6]: 00 (0)
+ [ 7]: 00 (0)
+ [ 8]: 00 (0)
+ [ 9]: 00 (0)
+ [10]: 00 (0)
+ [11]: 00 (0)
+ [12]: 00 (0)
+ [13]: 00 (0)
+ [14]: 00 (0)
+ [15]: 00 (0)
+ [16]: 00 (0)
+
+Change-Id: I8400bd53d619ff0e4af4c4d5ae7f54bb5dc6e9b8
+Reviewed-on: https://gerrit.chromium.org/gerrit/41310
+Reviewed-by: Yufeng Shen <miletus@chromium.org>
+Commit-Queue: Benson Leung <bleung@chromium.org>
+Tested-by: Benson Leung <bleung@chromium.org>
+(cherry picked from commit 5fd7e4778bd22252de5611a894d061a3bb64c4a2)
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 893d59d..fdf61b8 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -86,6 +86,7 @@
+ #define MXT_PROCI_SHIELDLESS_T56 56
+ #define MXT_PROCI_EXTRATOUCHSCREENDATA_T57 57
+ #define MXT_PROCG_NOISESUPPRESSION_T62 62
++#define MXT_PROCI_LENSBENDING_T65 65
+ #define MXT_SPT_COMMSCONFIG_T18 18
+ #define MXT_SPT_GPIOPWM_T19 19
+ #define MXT_SPT_SELFTEST_T25 25
+@@ -425,6 +426,7 @@ static bool mxt_object_readable(unsigned int type)
+ case MXT_PROCI_SHIELDLESS_T56:
+ case MXT_PROCI_EXTRATOUCHSCREENDATA_T57:
+ case MXT_PROCG_NOISESUPPRESSION_T62:
++ case MXT_PROCI_LENSBENDING_T65:
+ case MXT_SPT_COMMSCONFIG_T18:
+ case MXT_SPT_GPIOPWM_T19:
+ case MXT_SPT_SELFTEST_T25:
+@@ -462,6 +464,7 @@ static bool mxt_object_writable(unsigned int type)
+ case MXT_PROCI_SHIELDLESS_T56:
+ case MXT_PROCI_EXTRATOUCHSCREENDATA_T57:
+ case MXT_PROCG_NOISESUPPRESSION_T62:
++ case MXT_PROCI_LENSBENDING_T65:
+ case MXT_SPT_COMMSCONFIG_T18:
+ case MXT_SPT_GPIOPWM_T19:
+ case MXT_SPT_SELFTEST_T25:
diff --git a/patches/linux-3.8.13/0560-CHROMIUM-Input-atmel_mxt_ts-On-Tpads-enable-T42-disa.patch b/patches/linux-3.8.13/0560-CHROMIUM-Input-atmel_mxt_ts-On-Tpads-enable-T42-disa.patch
new file mode 100644
index 0000000..d40b812
--- /dev/null
+++ b/patches/linux-3.8.13/0560-CHROMIUM-Input-atmel_mxt_ts-On-Tpads-enable-T42-disa.patch
@@ -0,0 +1,118 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Fri, 18 Jan 2013 17:35:19 -0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts : On Tpads, enable T42,
+ disable T19 on suspend
+
+To work around an issue where an idle-suspended system may wake
+unnecessarily when the lid is closed because the B panel comes close to
+the trackpad, enable touch suppression (t42) when suspending. Also
+disable T19, for the button, to allow the button to be pressed if
+the case is flexed without the system waking.
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+
+BUG=chrome-os-partner:17336
+TEST=1. Suspend the system with powerd_suspend with lid open.
+2. Touch the touchpad. Make sure the system still wakes.
+3. Suspend again with powerd_suspend
+4. Close the lid. Ensure the system does not wake by observing the system
+status light.
+
+Change-Id: I858af27e65ce491c8eb99f5b8db13ea91f789f3e
+Reviewed-on: https://gerrit.chromium.org/gerrit/41678
+Reviewed-by: Puneet Kumar <puneetster@chromium.org>
+Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
+Commit-Queue: Benson Leung <bleung@chromium.org>
+Tested-by: Benson Leung <bleung@chromium.org>
+(cherry picked from commit 6988c8d813d863007df2ba3f418172d07b63ece6)
+[djkurtz: v3.6: merge]
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 61 ++++++++++++++++++++++++++++++
+ 1 file changed, 61 insertions(+)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index fdf61b8..8077000 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -364,6 +364,13 @@ struct mxt_data {
+ bool T9_ctrl_valid;
+
+ bool irq_wake; /* irq wake is enabled */
++ /* Saved T42 Touch Suppression field */
++ u8 T42_ctrl;
++ bool T42_ctrl_valid;
++
++ /* Saved T19 GPIO config */
++ u8 T19_ctrl;
++ bool T19_ctrl_valid;
+
+ /* Protect access to the object register buffer */
+ struct mutex object_str_mutex;
+@@ -2901,6 +2908,44 @@ static int mxt_suspend(struct device *dev)
+ dev_err(dev, "Save T9 ctrl config failed, %d\n", ret);
+ data->T9_ctrl_valid = (ret == 0);
+
++ /*
++ * For tpads, save T42 and T19 ctrl registers if may wakeup,
++ * enable large object suppression, and disable button wake.
++ * This will prevent a lid close from acting as a wake source.
++ */
++ if (data->is_tp && device_may_wakeup(dev)) {
++ u8 T42_sleep = 0x01;
++ u8 T19_sleep = 0x00;
++
++ ret = mxt_save_regs(data, MXT_PROCI_TOUCHSUPPRESSION_T42, 0, 0,
++ &data->T42_ctrl, 1);
++ if (ret)
++ dev_err(dev, "Save T42 ctrl config failed, %d\n", ret);
++ data->T42_ctrl_valid = (ret == 0);
++
++ ret = mxt_save_regs(data, MXT_SPT_GPIOPWM_T19, 0, 0,
++ &data->T19_ctrl, 1);
++ if (ret)
++ dev_err(dev, "Save T19 ctrl config failed, %d\n", ret);
++ data->T19_ctrl_valid = (ret == 0);
++
++
++ /* Enable Large Object Suppression */
++ ret = mxt_set_regs(data, MXT_PROCI_TOUCHSUPPRESSION_T42, 0, 0,
++ &T42_sleep, 1);
++ if (ret)
++ dev_err(dev, "Set T42 ctrl failed, %d\n", ret);
++
++ /* Disable Touchpad Button via GPIO */
++ ret = mxt_set_regs(data, MXT_SPT_GPIOPWM_T19, 0, 0,
++ &T19_sleep, 1);
++ if (ret)
++ dev_err(dev, "Set T19 ctrl failed, %d\n", ret);
++
++ } else {
++ data->T42_ctrl_valid = data->T19_ctrl_valid = false;
++ }
++
+ if (device_may_wakeup(dev)) {
+ /*
+ * If we allow wakeup from touch, we have to enable T9 so
+@@ -2959,6 +3004,22 @@ static int mxt_resume(struct device *dev)
+ dev_err(dev, "Set T7 power config failed, %d\n", ret);
+ }
+
++ /* Restore the T42 ctrl to before-suspend value */
++ if (data->T42_ctrl_valid) {
++ ret = mxt_set_regs(data, MXT_PROCI_TOUCHSUPPRESSION_T42, 0, 0,
++ &data->T42_ctrl, 1);
++ if (ret)
++ dev_err(dev, "Set T42 ctrl failed, %d\n", ret);
++ }
++
++ /* Restore the T19 ctrl to before-suspend value */
++ if (data->T19_ctrl_valid) {
++ ret = mxt_set_regs(data, MXT_SPT_GPIOPWM_T19, 0, 0,
++ &data->T19_ctrl, 1);
++ if (ret)
++ dev_err(dev, "Set T19 ctrl failed, %d\n", ret);
++ }
++
+ if (!device_may_wakeup(dev)) {
+ /* Recalibration in case of environment change */
+ ret = mxt_write_object(data, MXT_GEN_COMMAND_T6,
diff --git a/patches/linux-3.8.13/0561-CHROMIUM-Input-atmel_mxt_ts-Set-power-wakeup-to-disa.patch b/patches/linux-3.8.13/0561-CHROMIUM-Input-atmel_mxt_ts-Set-power-wakeup-to-disa.patch
new file mode 100644
index 0000000..33b6996
--- /dev/null
+++ b/patches/linux-3.8.13/0561-CHROMIUM-Input-atmel_mxt_ts-Set-power-wakeup-to-disa.patch
@@ -0,0 +1,39 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Fri, 18 Jan 2013 17:35:52 -0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts : Set power/wakeup to disabled
+ by default.
+
+Userspace will change it to enabled if needed.
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+
+BUG=chrome-os-partner:17336
+TEST=cat /sys/bus/i2c/devices/2-004a/power/wakeup
+Check that it returns "disabled"
+Suspend the system using powerd_suspend.
+Check that the touch device 2-004a does not wake the system.
+
+Change-Id: If5ac3b30c137d16e5592d4a2ee555fd2533b0caa
+Reviewed-on: https://gerrit.chromium.org/gerrit/41679
+Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
+Reviewed-by: Puneet Kumar <puneetster@chromium.org>
+Commit-Queue: Benson Leung <bleung@chromium.org>
+Tested-by: Benson Leung <bleung@chromium.org>
+(cherry picked from commit 6625e780bacf270b6da346751819d2825f09c20a)
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 8077000..3f14d3b 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -2792,6 +2792,8 @@ static int mxt_probe(struct i2c_client *client,
+ if (error)
+ goto err_free_fw_file;
+
++ device_set_wakeup_enable(&client->dev, false);
++
+ async_schedule(mxt_initialize_async, data);
+
+ return 0;
diff --git a/patches/linux-3.8.13/0562-CHROMIUM-Input-atmel_mxt_ts-mxt_stop-on-lid-close.patch b/patches/linux-3.8.13/0562-CHROMIUM-Input-atmel_mxt_ts-mxt_stop-on-lid-close.patch
new file mode 100644
index 0000000..c71b1f3
--- /dev/null
+++ b/patches/linux-3.8.13/0562-CHROMIUM-Input-atmel_mxt_ts-mxt_stop-on-lid-close.patch
@@ -0,0 +1,121 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Fri, 25 Jan 2013 17:45:56 -0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - mxt_stop on lid close
+
+This is an x86 specific change for the short term.
+When the lid is closed, issue an mxt_stop to turn off scanning
+to prevent the lid from affecting the touch device and causing
+stray touches.
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+
+BUG=chrome-os-partner:17465
+TEST=From test mode, run evtest, and watch the atmel_mxt device.
+Close and open the lid. Make sure there are no touch data comes
+from the atmel driver when the lid is being closed.
+
+Change-Id: I2163384fc7cbd45c63d05983c50d2a869975a3c9
+Reviewed-on: https://gerrit.chromium.org/gerrit/42080
+Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
+Commit-Queue: Benson Leung <bleung@chromium.org>
+Tested-by: Benson Leung <bleung@chromium.org>
+(cherry picked from commit 5391ebafb8f9b72475795445ca71b02815a2a229)
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 49 ++++++++++++++++++++++++++++++
+ 1 file changed, 49 insertions(+)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 3f14d3b..cd900ee 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -25,6 +25,11 @@
+ #include <linux/slab.h>
+ #include <linux/uaccess.h>
+
++#if defined(CONFIG_ACPI_BUTTON)
++#include <acpi/button.h>
++#endif
++
++
+ /* Version */
+ #define MXT_VER_20 20
+ #define MXT_VER_21 21
+@@ -388,6 +393,11 @@ struct mxt_data {
+
+ /* map for the tracking id currently being used */
+ bool current_id[MXT_MAX_FINGER];
++
++#if defined(CONFIG_ACPI_BUTTON)
++ /* notifier block for acpi_lid_notifier */
++ struct notifier_block lid_notifier;
++#endif
+ };
+
+ /* global root node of the atmel_mxt_ts debugfs directory. */
+@@ -2601,6 +2611,24 @@ static void mxt_input_close(struct input_dev *dev)
+ mxt_stop(data);
+ }
+
++#if defined(CONFIG_ACPI_BUTTON)
++static int mxt_lid_notify(struct notifier_block *nb, unsigned long val,
++ void *unused)
++{
++ struct mxt_data *data = container_of(nb, struct mxt_data, lid_notifier);
++
++ if (mxt_in_bootloader(data))
++ return NOTIFY_OK;
++
++ if (val == 0)
++ mxt_stop(data);
++ else
++ mxt_start(data);
++
++ return NOTIFY_OK;
++}
++#endif
++
+ static int mxt_input_dev_create(struct mxt_data *data)
+ {
+ struct input_dev *input_dev;
+@@ -2796,6 +2824,14 @@ static int mxt_probe(struct i2c_client *client,
+
+ async_schedule(mxt_initialize_async, data);
+
++#if defined(CONFIG_ACPI_BUTTON)
++ data->lid_notifier.notifier_call = mxt_lid_notify;
++ if (acpi_lid_notifier_register(&data->lid_notifier)) {
++ pr_info("lid notifier registration failed\n");
++ data->lid_notifier.notifier_call = NULL;
++ }
++#endif
++
+ return 0;
+
+ err_free_fw_file:
+@@ -2815,6 +2851,10 @@ static int mxt_remove(struct i2c_client *client)
+ free_irq(data->irq, data);
+ if (data->input_dev)
+ input_unregister_device(data->input_dev);
++#if defined(CONFIG_ACPI_BUTTON)
++ if (data->lid_notifier.notifier_call)
++ acpi_lid_notifier_unregister(&data->lid_notifier);
++#endif
+ kfree(data->object_table);
+ kfree(data->fw_file);
+ kfree(data->config_file);
+@@ -2910,6 +2950,15 @@ static int mxt_suspend(struct device *dev)
+ dev_err(dev, "Save T9 ctrl config failed, %d\n", ret);
+ data->T9_ctrl_valid = (ret == 0);
+
++#if defined(CONFIG_ACPI_BUTTON)
++ ret = acpi_lid_open();
++ if (ret == 0) {
++ /* lid is closed. set T9_ctrl to operational on resume */
++ data->T9_ctrl = MXT_TOUCH_CTRL_OPERATIONAL;
++ data->T9_ctrl_valid = true;
++ }
++#endif
++
+ /*
+ * For tpads, save T42 and T19 ctrl registers if may wakeup,
+ * enable large object suppression, and disable button wake.
diff --git a/patches/linux-3.8.13/0563-CHROMIUM-Input-atmel_mxt_ts-Disable-T9-on-mxt_stop.patch b/patches/linux-3.8.13/0563-CHROMIUM-Input-atmel_mxt_ts-Disable-T9-on-mxt_stop.patch
new file mode 100644
index 0000000..df01c74
--- /dev/null
+++ b/patches/linux-3.8.13/0563-CHROMIUM-Input-atmel_mxt_ts-Disable-T9-on-mxt_stop.patch
@@ -0,0 +1,49 @@
+From: Daniel Kurtz <djkurtz@chromium.org>
+Date: Thu, 31 Jan 2013 17:43:07 +0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Disable T9 on mxt_stop
+
+Instead of using 0x81 to keep the object enabled,
+disable T9 on mxt_stop by writing 0x00 to it.
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+
+BUG=chrome-os-partner:17465
+TEST=stop powerd (on R25 also stop powerm)
+close the lid, or use a magnet to trigger the lid sensor.
+cat /sys/kernel/debug/atmel_mxt_ts/2-004a/object
+Look for Type: 9, byte 0. Check that this is 0x00
+when lid is closed. When opened, this should return
+to 0x83.
+
+Change-Id: If794e121d1b61186fee9e5b9f97b922549d7beb8
+Reviewed-on: https://gerrit.chromium.org/gerrit/42183
+Reviewed-by: Puneet Kumar <puneetster@chromium.org>
+Commit-Queue: Benson Leung <bleung@chromium.org>
+Tested-by: Benson Leung <bleung@chromium.org>
+(cherry picked from commit 65caaf9e0697899cd5e21eb643e018298adc781a)
+[djkurtz: v3.6 merge]
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index cd900ee..0865842 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -174,6 +174,7 @@
+ MXT_TOUCH_CTRL_RPTEN)
+ #define MXT_TOUCH_CTRL_SCANNING (MXT_TOUCH_CTRL_ENABLE | \
+ MXT_TOUCH_CTRL_SCANEN)
++#define MXT_TOUCH_CTRL_OFF 0x0
+
+ /* MXT_PROCI_GRIPFACE_T20 field */
+ #define MXT_GRIPFACE_CTRL 0
+@@ -2592,7 +2593,7 @@ static void mxt_stop(struct mxt_data *data)
+ {
+ /* Disable touch reporting */
+ mxt_write_object(data, MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL,
+- MXT_TOUCH_CTRL_SCANNING);
++ MXT_TOUCH_CTRL_OFF);
+ }
+
+ static int mxt_input_open(struct input_dev *dev)
diff --git a/patches/linux-3.8.13/0564-CHROMIUM-Input-atmel_mxt_ts-Set-T9-in-mxt_resume-bas.patch b/patches/linux-3.8.13/0564-CHROMIUM-Input-atmel_mxt_ts-Set-T9-in-mxt_resume-bas.patch
new file mode 100644
index 0000000..c8f70cf
--- /dev/null
+++ b/patches/linux-3.8.13/0564-CHROMIUM-Input-atmel_mxt_ts-Set-T9-in-mxt_resume-bas.patch
@@ -0,0 +1,73 @@
+From: Benson Leung <bleung@chromium.org>
+Date: Mon, 28 Jan 2013 15:26:25 -0800
+Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Set T9 in mxt_resume based
+ on lid state
+
+This is an x86 specific change for the short term.
+When the lid is closed on resume, make sure T9 is disabled.
+to prevent the lid from affecting the touch device and causing
+stray touches. If lid is open, restore operational settings for T9.
+
+Signed-off-by: Benson Leung <bleung@chromium.org>
+
+BUG=chrome-os-partner:17465
+TEST=Close the lid to suspend in guest mode.
+Open the lid slowly, until you see the lights indicating resuming.
+Close the lid immediately upon seeing the system resume from
+the status light.
+The system should stay in S0. Check via ssh:
+cat /sys/kernel/debug/atmel_mxt_ts/2-004a/object
+Check that T9 is 0x00.
+On a normal suspend/resume, where the lid is opened,
+check that touch device is functional.
+
+Change-Id: Ibce1c8c000e4bd2a8f360bea2b116051eee35be7
+Reviewed-on: https://gerrit.chromium.org/gerrit/42184
+Reviewed-by: Puneet Kumar <puneetster@chromium.org>
+Commit-Queue: Benson Leung <bleung@chromium.org>
+Tested-by: Benson Leung <bleung@chromium.org>
+(cherry picked from commit 4201ff9f7a9e114c453932662d49e34047dee59c)
+---
+ drivers/input/touchscreen/atmel_mxt_ts.c | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
+index 0865842..ca94635 100644
+--- a/drivers/input/touchscreen/atmel_mxt_ts.c
++++ b/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -2951,15 +2951,6 @@ static int mxt_suspend(struct device *dev)
+ dev_err(dev, "Save T9 ctrl config failed, %d\n", ret);
+ data->T9_ctrl_valid = (ret == 0);
+
+-#if defined(CONFIG_ACPI_BUTTON)
+- ret = acpi_lid_open();
+- if (ret == 0) {
+- /* lid is closed. set T9_ctrl to operational on resume */
+- data->T9_ctrl = MXT_TOUCH_CTRL_OPERATIONAL;
+- data->T9_ctrl_valid = true;
+- }
+-#endif
+-
+ /*
+ * For tpads, save T42 and T19 ctrl registers if may wakeup,
+ * enable large object suppression, and disable button wake.
+@@ -3040,6 +3031,19 @@ static int mxt_resume(struct device *dev)
+
+ mutex_lock(&input_dev->mutex);
+
++#if defined(CONFIG_ACPI_BUTTON)
++ ret = acpi_lid_open();
++ if (ret == 0) {
++ /* lid is closed. set T9_ctrl to non operational resume */
++ data->T9_ctrl = MXT_TOUCH_CTRL_OFF;
++ data->T9_ctrl_valid = true;
++ } else if (ret == 1) {
++ /* lid is open. Set to operational */
++ data->T9_ctrl = MXT_TOUCH_CTRL_OPERATIONAL;
++ data->T9_ctrl_valid = true;
++ }
++#endif
++
+ /* Restore the T9 Ctrl config to before-suspend value */
+ if (data->T9_ctrl_valid) {
+ ret = mxt_set_regs(data, MXT_TOUCH_MULTI_T9, 0, 0,
diff --git a/patches/linux-3.8.13/0565-video-ssd1307fb-Add-support-for-SSD1306-OLED-control.patch b/patches/linux-3.8.13/0565-video-ssd1307fb-Add-support-for-SSD1306-OLED-control.patch
new file mode 100644
index 0000000..ef175ab
--- /dev/null
+++ b/patches/linux-3.8.13/0565-video-ssd1307fb-Add-support-for-SSD1306-OLED-control.patch
@@ -0,0 +1,431 @@
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Fri, 7 Dec 2012 17:20:04 +0100
+Subject: [PATCH] video: ssd1307fb: Add support for SSD1306 OLED controller
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ .../devicetree/bindings/video/ssd1307fb.txt | 10 +-
+ drivers/video/ssd1307fb.c | 267 ++++++++++++++------
+ 2 files changed, 203 insertions(+), 74 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/video/ssd1307fb.txt b/Documentation/devicetree/bindings/video/ssd1307fb.txt
+index 3d0060c..7a12542 100644
+--- a/Documentation/devicetree/bindings/video/ssd1307fb.txt
++++ b/Documentation/devicetree/bindings/video/ssd1307fb.txt
+@@ -1,13 +1,17 @@
+ * Solomon SSD1307 Framebuffer Driver
+
+ Required properties:
+- - compatible: Should be "solomon,ssd1307fb-<bus>". The only supported bus for
+- now is i2c.
++ - compatible: Should be "solomon,<chip>fb-<bus>". The only supported bus for
++ now is i2c, and the supported chips are ssd1306 and ssd1307.
+ - reg: Should contain address of the controller on the I2C bus. Most likely
+ 0x3c or 0x3d
+ - pwm: Should contain the pwm to use according to the OF device tree PWM
+- specification [0]
++ specification [0]. Only required for the ssd1307.
+ - reset-gpios: Should contain the GPIO used to reset the OLED display
++ - solomon,height: Height in pixel of the screen driven by the controller
++ - solomon,width: Width in pixel of the screen driven by the controller
++ - solomon,page-offset: Offset of pages (band of 8 pixels) that the screen is
++ mapped to.
+
+ Optional properties:
+ - reset-active-low: Is the reset gpio is active on physical low?
+diff --git a/drivers/video/ssd1307fb.c b/drivers/video/ssd1307fb.c
+index 395cb6a..95f76e2 100644
+--- a/drivers/video/ssd1307fb.c
++++ b/drivers/video/ssd1307fb.c
+@@ -16,24 +16,39 @@
+ #include <linux/pwm.h>
+ #include <linux/delay.h>
+
+-#define SSD1307FB_WIDTH 96
+-#define SSD1307FB_HEIGHT 16
+-
+ #define SSD1307FB_DATA 0x40
+ #define SSD1307FB_COMMAND 0x80
+
+ #define SSD1307FB_CONTRAST 0x81
++#define SSD1307FB_CHARGE_PUMP 0x8d
+ #define SSD1307FB_SEG_REMAP_ON 0xa1
+ #define SSD1307FB_DISPLAY_OFF 0xae
++#define SSD1307FB_SET_MULTIPLEX_RATIO 0xa8
+ #define SSD1307FB_DISPLAY_ON 0xaf
+ #define SSD1307FB_START_PAGE_ADDRESS 0xb0
++#define SSD1307FB_SET_DISPLAY_OFFSET 0xd3
++#define SSD1307FB_SET_CLOCK_FREQ 0xd5
++#define SSD1307FB_SET_PRECHARGE_PERIOD 0xd9
++#define SSD1307FB_SET_COM_PINS_CONFIG 0xda
++#define SSD1307FB_SET_VCOMH 0xdb
++
++struct ssd1307fb_par;
++
++struct ssd1307fb_ops {
++ int (*init)(struct ssd1307fb_par *);
++ int (*remove)(struct ssd1307fb_par *);
++};
+
+ struct ssd1307fb_par {
+ struct i2c_client *client;
++ u32 height;
+ struct fb_info *info;
++ struct ssd1307fb_ops *ops;
++ u32 page_offset;
+ struct pwm_device *pwm;
+ u32 pwm_period;
+ int reset;
++ u32 width;
+ };
+
+ static struct fb_fix_screeninfo ssd1307fb_fix = {
+@@ -43,15 +58,10 @@ static struct fb_fix_screeninfo ssd1307fb_fix = {
+ .xpanstep = 0,
+ .ypanstep = 0,
+ .ywrapstep = 0,
+- .line_length = SSD1307FB_WIDTH / 8,
+ .accel = FB_ACCEL_NONE,
+ };
+
+ static struct fb_var_screeninfo ssd1307fb_var = {
+- .xres = SSD1307FB_WIDTH,
+- .yres = SSD1307FB_HEIGHT,
+- .xres_virtual = SSD1307FB_WIDTH,
+- .yres_virtual = SSD1307FB_HEIGHT,
+ .bits_per_pixel = 1,
+ };
+
+@@ -134,16 +144,16 @@ static void ssd1307fb_update_display(struct ssd1307fb_par *par)
+ * (5) A4 B4 C4 D4 E4 F4 G4 H4
+ */
+
+- for (i = 0; i < (SSD1307FB_HEIGHT / 8); i++) {
+- ssd1307fb_write_cmd(par->client, SSD1307FB_START_PAGE_ADDRESS + (i + 1));
++ for (i = 0; i < (par->height / 8); i++) {
++ ssd1307fb_write_cmd(par->client, SSD1307FB_START_PAGE_ADDRESS + i + par->page_offset);
+ ssd1307fb_write_cmd(par->client, 0x00);
+ ssd1307fb_write_cmd(par->client, 0x10);
+
+- for (j = 0; j < SSD1307FB_WIDTH; j++) {
++ for (j = 0; j < par->width; j++) {
+ u8 buf = 0;
+ for (k = 0; k < 8; k++) {
+- u32 page_length = SSD1307FB_WIDTH * i;
+- u32 index = page_length + (SSD1307FB_WIDTH * k + j) / 8;
++ u32 page_length = par->width * i;
++ u32 index = page_length + (par->width * k + j) / 8;
+ u8 byte = *(vmem + index);
+ u8 bit = byte & (1 << (j % 8));
+ bit = bit >> (j % 8);
+@@ -227,16 +237,137 @@ static struct fb_deferred_io ssd1307fb_defio = {
+ .deferred_io = ssd1307fb_deferred_io,
+ };
+
++static int ssd1307fb_ssd1307_init(struct ssd1307fb_par *par) {
++ int ret;
++
++ par->pwm = pwm_get(&par->client->dev, NULL);
++ if (IS_ERR(par->pwm)) {
++ dev_err(&par->client->dev, "Could not get PWM from device tree!\n");
++ return PTR_ERR(par->pwm);
++ }
++
++ par->pwm_period = pwm_get_period(par->pwm);
++ /* Enable the PWM */
++ pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period);
++ pwm_enable(par->pwm);
++
++ dev_dbg(&par->client->dev, "Using PWM%d with a %dns period.\n", par->pwm->pwm, par->pwm_period);
++
++ /* Map column 127 of the OLED to segment 0 */
++ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SEG_REMAP_ON);
++ if (ret < 0)
++ return ret;
++
++ /* Turn on the display */
++ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_ON);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++static int ssd1307fb_ssd1307_remove(struct ssd1307fb_par *par) {
++ pwm_disable(par->pwm);
++ pwm_put(par->pwm);
++ return 0;
++}
++
++static struct ssd1307fb_ops ssd1307fb_ssd1307_ops = {
++ .init = ssd1307fb_ssd1307_init,
++ .remove = ssd1307fb_ssd1307_remove,
++};
++
++static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par) {
++ int ret;
++
++ /* Set initial contrast */
++ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_CONTRAST);
++ ret = ret & ssd1307fb_write_cmd(par->client, 0x7f);
++ if (ret < 0)
++ return ret;
++
++ /* Set COM direction */
++ ret = ssd1307fb_write_cmd(par->client, 0xc8);
++ if (ret < 0)
++ return ret;
++
++ /* Set segment re-map */
++ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SEG_REMAP_ON);
++ if (ret < 0)
++ return ret;
++
++ /* Set multiplex ratio value */
++ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_MULTIPLEX_RATIO);
++ ret = ret & ssd1307fb_write_cmd(par->client, par->height - 1);
++ if (ret < 0)
++ return ret;
++
++ /* set display offset value */
++ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_DISPLAY_OFFSET);
++ ret = ssd1307fb_write_cmd(par->client, 0x20);
++ if (ret < 0)
++ return ret;
++
++ /* Set clock frequency */
++ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_CLOCK_FREQ);
++ ret = ret & ssd1307fb_write_cmd(par->client, 0xf0);
++ if (ret < 0)
++ return ret;
++
++ /* Set precharge period in number of ticks from the internal clock */
++ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_PRECHARGE_PERIOD);
++ ret = ret & ssd1307fb_write_cmd(par->client, 0x22);
++ if (ret < 0)
++ return ret;
++
++ /* Set COM pins configuration */
++ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COM_PINS_CONFIG);
++ ret = ret & ssd1307fb_write_cmd(par->client, 0x22);
++ if (ret < 0)
++ return ret;
++
++ /* Set VCOMH */
++ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_VCOMH);
++ ret = ret & ssd1307fb_write_cmd(par->client, 0x49);
++ if (ret < 0)
++ return ret;
++
++ /* Turn on the DC-DC Charge Pump */
++ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_CHARGE_PUMP);
++ ret = ret & ssd1307fb_write_cmd(par->client, 0x14);
++ if (ret < 0)
++ return ret;
++
++ /* Turn on the display */
++ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_ON);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++static struct ssd1307fb_ops ssd1307fb_ssd1306_ops = {
++ .init = ssd1307fb_ssd1306_init,
++};
++
++static const struct of_device_id ssd1307fb_of_match[] = {
++ { .compatible = "solomon,ssd1306fb-i2c", .data = (void*)&ssd1307fb_ssd1306_ops },
++ { .compatible = "solomon,ssd1307fb-i2c", .data = (void*)&ssd1307fb_ssd1307_ops },
++ {},
++};
++MODULE_DEVICE_TABLE(of, ssd1307fb_of_match);
++
+ static int ssd1307fb_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+ {
+ struct fb_info *info;
+- u32 vmem_size = SSD1307FB_WIDTH * SSD1307FB_HEIGHT / 8;
++ struct device_node *node = client->dev.of_node;
++ u32 vmem_size;
+ struct ssd1307fb_par *par;
+ u8 *vmem;
+ int ret;
+
+- if (!client->dev.of_node) {
++ if (!node) {
+ dev_err(&client->dev, "No device tree data found!\n");
+ return -EINVAL;
+ }
+@@ -247,6 +378,36 @@ static int ssd1307fb_probe(struct i2c_client *client,
+ return -ENOMEM;
+ }
+
++ par = info->par;
++ par->info = info;
++ par->client = client;
++
++ par->ops = (struct ssd1307fb_ops*)of_match_device(ssd1307fb_of_match, &client->dev)->data;
++
++ par->reset = of_get_named_gpio(client->dev.of_node,
++ "reset-gpios", 0);
++ if (!gpio_is_valid(par->reset)) {
++ ret = -EINVAL;
++ goto fb_alloc_error;
++ }
++
++ if (of_property_read_u32(node, "solomon,width", &par->width))
++ par->width = 96;
++
++ printk("Width\t%u\n", par->width);
++
++ if (of_property_read_u32(node, "solomon,height", &par->height))
++ par->width = 16;
++
++ printk("Height\t%u\n", par->height);
++
++ if (of_property_read_u32(node, "solomon,page-offset", &par->page_offset))
++ par->page_offset = 1;
++
++ printk("Offset\t%u\n", par->page_offset);
++
++ vmem_size = par->width * par->height / 8;
++
+ vmem = devm_kzalloc(&client->dev, vmem_size, GFP_KERNEL);
+ if (!vmem) {
+ dev_err(&client->dev, "Couldn't allocate graphical memory.\n");
+@@ -256,9 +417,15 @@ static int ssd1307fb_probe(struct i2c_client *client,
+
+ info->fbops = &ssd1307fb_ops;
+ info->fix = ssd1307fb_fix;
++ info->fix.line_length = par->width / 8;
+ info->fbdefio = &ssd1307fb_defio;
+
+ info->var = ssd1307fb_var;
++ info->var.xres = par->width;
++ info->var.xres_virtual = par->width;
++ info->var.yres = par->height;
++ info->var.yres_virtual = par->height;
++
+ info->var.red.length = 1;
+ info->var.red.offset = 0;
+ info->var.green.length = 1;
+@@ -272,17 +439,6 @@ static int ssd1307fb_probe(struct i2c_client *client,
+
+ fb_deferred_io_init(info);
+
+- par = info->par;
+- par->info = info;
+- par->client = client;
+-
+- par->reset = of_get_named_gpio(client->dev.of_node,
+- "reset-gpios", 0);
+- if (!gpio_is_valid(par->reset)) {
+- ret = -EINVAL;
+- goto reset_oled_error;
+- }
+-
+ ret = devm_gpio_request_one(&client->dev, par->reset,
+ GPIOF_OUT_INIT_HIGH,
+ "oled-reset");
+@@ -293,23 +449,6 @@ static int ssd1307fb_probe(struct i2c_client *client,
+ goto reset_oled_error;
+ }
+
+- par->pwm = pwm_get(&client->dev, NULL);
+- if (IS_ERR(par->pwm)) {
+- dev_err(&client->dev, "Could not get PWM from device tree!\n");
+- ret = PTR_ERR(par->pwm);
+- goto pwm_error;
+- }
+-
+- par->pwm_period = pwm_get_period(par->pwm);
+-
+- dev_dbg(&client->dev, "Using PWM%d with a %dns period.\n", par->pwm->pwm, par->pwm_period);
+-
+- ret = register_framebuffer(info);
+- if (ret) {
+- dev_err(&client->dev, "Couldn't register the framebuffer\n");
+- goto fbreg_error;
+- }
+-
+ i2c_set_clientdata(client, info);
+
+ /* Reset the screen */
+@@ -318,34 +457,25 @@ static int ssd1307fb_probe(struct i2c_client *client,
+ gpio_set_value(par->reset, 1);
+ udelay(4);
+
+- /* Enable the PWM */
+- pwm_config(par->pwm, par->pwm_period / 2, par->pwm_period);
+- pwm_enable(par->pwm);
+-
+- /* Map column 127 of the OLED to segment 0 */
+- ret = ssd1307fb_write_cmd(client, SSD1307FB_SEG_REMAP_ON);
+- if (ret < 0) {
+- dev_err(&client->dev, "Couldn't remap the screen.\n");
+- goto remap_error;
++ if (par->ops->init) {
++ ret = par->ops->init(par);
++ if (ret)
++ goto reset_oled_error;
+ }
+
+- /* Turn on the display */
+- ret = ssd1307fb_write_cmd(client, SSD1307FB_DISPLAY_ON);
+- if (ret < 0) {
+- dev_err(&client->dev, "Couldn't turn the display on.\n");
+- goto remap_error;
++ ret = register_framebuffer(info);
++ if (ret) {
++ dev_err(&client->dev, "Couldn't register the framebuffer\n");
++ goto panel_init_error;
+ }
+
+ dev_info(&client->dev, "fb%d: %s framebuffer device registered, using %d bytes of video memory\n", info->node, info->fix.id, vmem_size);
+
+ return 0;
+
+-remap_error:
+- unregister_framebuffer(info);
+- pwm_disable(par->pwm);
+-fbreg_error:
+- pwm_put(par->pwm);
+-pwm_error:
++panel_init_error:
++ if (par->ops->remove)
++ par->ops->remove(par);
+ reset_oled_error:
+ fb_deferred_io_cleanup(info);
+ fb_alloc_error:
+@@ -359,8 +489,8 @@ static int ssd1307fb_remove(struct i2c_client *client)
+ struct ssd1307fb_par *par = info->par;
+
+ unregister_framebuffer(info);
+- pwm_disable(par->pwm);
+- pwm_put(par->pwm);
++ if (par->ops->remove)
++ par->ops->remove(par);
+ fb_deferred_io_cleanup(info);
+ framebuffer_release(info);
+
+@@ -368,17 +498,12 @@ static int ssd1307fb_remove(struct i2c_client *client)
+ }
+
+ static const struct i2c_device_id ssd1307fb_i2c_id[] = {
++ { "ssd1306fb", 0 },
+ { "ssd1307fb", 0 },
+ { }
+ };
+ MODULE_DEVICE_TABLE(i2c, ssd1307fb_i2c_id);
+
+-static const struct of_device_id ssd1307fb_of_match[] = {
+- { .compatible = "solomon,ssd1307fb-i2c" },
+- {},
+-};
+-MODULE_DEVICE_TABLE(of, ssd1307fb_of_match);
+-
+ static struct i2c_driver ssd1307fb_driver = {
+ .probe = ssd1307fb_probe,
+ .remove = ssd1307fb_remove,
diff --git a/patches/linux-3.8.13/0566-ssd1307fb-Rework-the-communication-functions.patch b/patches/linux-3.8.13/0566-ssd1307fb-Rework-the-communication-functions.patch
new file mode 100644
index 0000000..b963a37
--- /dev/null
+++ b/patches/linux-3.8.13/0566-ssd1307fb-Rework-the-communication-functions.patch
@@ -0,0 +1,111 @@
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Tue, 26 Feb 2013 11:39:52 +0100
+Subject: [PATCH] ssd1307fb: Rework the communication functions
+
+To efficiently send a whole page to the display, we need to be able to
+manipulate more easily the data arrays that has to be sent to the OLED
+controller. As such, this patch introduces a ssd1307fb_array structure
+that handles both the small header to be sent over i2c, which contains
+the type of information sent, and the raw bytes after that.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ drivers/video/ssd1307fb.c | 62 +++++++++++++++++++++++++--------------------
+ 1 file changed, 35 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/video/ssd1307fb.c b/drivers/video/ssd1307fb.c
+index 95f76e2..85e0860 100644
+--- a/drivers/video/ssd1307fb.c
++++ b/drivers/video/ssd1307fb.c
+@@ -51,6 +51,11 @@ struct ssd1307fb_par {
+ u32 width;
+ };
+
++struct ssd1307fb_array {
++ u8 type;
++ u8 data[0];
++};
++
+ static struct fb_fix_screeninfo ssd1307fb_fix = {
+ .id = "Solomon SSD1307",
+ .type = FB_TYPE_PACKED_PIXELS,
+@@ -65,49 +70,52 @@ static struct fb_var_screeninfo ssd1307fb_var = {
+ .bits_per_pixel = 1,
+ };
+
+-static int ssd1307fb_write_array(struct i2c_client *client, u8 type, u8 *cmd, u32 len)
++static struct ssd1307fb_array *ssd1307fb_alloc_array(u32 len, u8 type)
+ {
+- u8 *buf;
+- int ret = 0;
++ struct ssd1307fb_array *array = kzalloc(sizeof(struct ssd1307fb_array) + len, GFP_KERNEL);
++ if (!array)
++ return NULL;
+
+- buf = kzalloc(len + 1, GFP_KERNEL);
+- if (!buf) {
+- dev_err(&client->dev, "Couldn't allocate sending buffer.\n");
+- return -ENOMEM;
+- }
++ array->type = type;
+
+- buf[0] = type;
+- memcpy(buf + 1, cmd, len);
++ return array;
++}
+
+- ret = i2c_master_send(client, buf, len + 1);
+- if (ret != len + 1) {
++static int ssd1307fb_write_array(struct i2c_client *client, struct ssd1307fb_array *array, u32 len)
++{
++ int ret;
++
++ len += sizeof(struct ssd1307fb_array);
++
++ ret = i2c_master_send(client, (u8*)array, len);
++ if (ret != len) {
+ dev_err(&client->dev, "Couldn't send I2C command.\n");
+- goto error;
++ return ret;
+ }
+
+-error:
+- kfree(buf);
+- return ret;
+-}
+-
+-static inline int ssd1307fb_write_cmd_array(struct i2c_client *client, u8 *cmd, u32 len)
+-{
+- return ssd1307fb_write_array(client, SSD1307FB_COMMAND, cmd, len);
++ return 0;
+ }
+
+ static inline int ssd1307fb_write_cmd(struct i2c_client *client, u8 cmd)
+ {
+- return ssd1307fb_write_cmd_array(client, &cmd, 1);
+-}
++ struct ssd1307fb_array *array = ssd1307fb_alloc_array(1, SSD1307FB_COMMAND);
++ if (!array)
++ return -ENOMEM;
+
+-static inline int ssd1307fb_write_data_array(struct i2c_client *client, u8 *cmd, u32 len)
+-{
+- return ssd1307fb_write_array(client, SSD1307FB_DATA, cmd, len);
++ array->data[0] = cmd;
++
++ return ssd1307fb_write_array(client, array, 1);
+ }
+
+ static inline int ssd1307fb_write_data(struct i2c_client *client, u8 data)
+ {
+- return ssd1307fb_write_data_array(client, &data, 1);
++ struct ssd1307fb_array *array = ssd1307fb_alloc_array(1, SSD1307FB_DATA);
++ if (!array)
++ return -ENOMEM;
++
++ array->data[0] = data;
++
++ return ssd1307fb_write_array(client, array, 1);
+ }
+
+ static void ssd1307fb_update_display(struct ssd1307fb_par *par)
diff --git a/patches/linux-3.8.13/0567-ssd1307fb-Speed-up-the-communication-with-the-contro.patch b/patches/linux-3.8.13/0567-ssd1307fb-Speed-up-the-communication-with-the-contro.patch
new file mode 100644
index 0000000..ab176ad
--- /dev/null
+++ b/patches/linux-3.8.13/0567-ssd1307fb-Speed-up-the-communication-with-the-contro.patch
@@ -0,0 +1,53 @@
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Tue, 26 Feb 2013 11:46:40 +0100
+Subject: [PATCH] ssd1307fb: Speed up the communication with the controller
+
+The code until now was sending only 1pixel-wide page segment at once,
+and started a new transfer every time. It has proven very inefficient,
+because for one byte to display on the screen, we had to actually send 3
+bytes over I2C: the address, the type of data that was going to the
+controller, and then the actual data.
+
+This patches changes that by sending a whole page at once, avoiding most
+of this expensive overhead.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ drivers/video/ssd1307fb.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/video/ssd1307fb.c b/drivers/video/ssd1307fb.c
+index 85e0860..676241b 100644
+--- a/drivers/video/ssd1307fb.c
++++ b/drivers/video/ssd1307fb.c
+@@ -153,22 +153,27 @@ static void ssd1307fb_update_display(struct ssd1307fb_par *par)
+ */
+
+ for (i = 0; i < (par->height / 8); i++) {
++ struct ssd1307fb_array *array;
++
+ ssd1307fb_write_cmd(par->client, SSD1307FB_START_PAGE_ADDRESS + i + par->page_offset);
+ ssd1307fb_write_cmd(par->client, 0x00);
+ ssd1307fb_write_cmd(par->client, 0x10);
+
++ array = ssd1307fb_alloc_array(par->width, SSD1307FB_DATA);
++
+ for (j = 0; j < par->width; j++) {
+- u8 buf = 0;
++ array->data[j] = 0;
+ for (k = 0; k < 8; k++) {
+ u32 page_length = par->width * i;
+ u32 index = page_length + (par->width * k + j) / 8;
+ u8 byte = *(vmem + index);
+ u8 bit = byte & (1 << (j % 8));
+ bit = bit >> (j % 8);
+- buf |= bit << k;
++ array->data[j] |= bit << k;
+ }
+- ssd1307fb_write_data(par->client, buf);
+ }
++
++ ssd1307fb_write_array(par->client, array, par->width);
+ }
+ }
+
diff --git a/patches/linux-3.8.13/0568-ssd1307fb-Make-use-of-horizontal-addressing-mode.patch b/patches/linux-3.8.13/0568-ssd1307fb-Make-use-of-horizontal-addressing-mode.patch
new file mode 100644
index 0000000..484cff5
--- /dev/null
+++ b/patches/linux-3.8.13/0568-ssd1307fb-Make-use-of-horizontal-addressing-mode.patch
@@ -0,0 +1,105 @@
+From: Maxime Ripard <maxime.ripard@free-electrons.com>
+Date: Fri, 13 Jul 2012 15:16:12 +0200
+Subject: [PATCH] ssd1307fb: Make use of horizontal addressing mode
+
+By default, the ssd1307 controller uses an addressing mode called page
+addressing. This mode only increments the column cursor in memory when
+writing data but will not increments the page cursor when we are at the
+end of the page.
+
+However, the controller supports another addressing mode, called
+horizontal addressing, that will maintain both the page and column
+cursors when writing data to the controller.
+
+That means that we can just remove the code that increments the current
+page address and reset the column cursor when reaching the end of the
+line, allowing to have a lower data overhead, and a simpler driver.
+
+Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
+---
+ drivers/video/ssd1307fb.c | 41 +++++++++++++++++++++++++++++------------
+ 1 file changed, 29 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/video/ssd1307fb.c b/drivers/video/ssd1307fb.c
+index 676241b..6594458 100644
+--- a/drivers/video/ssd1307fb.c
++++ b/drivers/video/ssd1307fb.c
+@@ -19,6 +19,12 @@
+ #define SSD1307FB_DATA 0x40
+ #define SSD1307FB_COMMAND 0x80
+
++#define SSD1307FB_SET_ADDRESS_MODE 0x20
++#define SSD1307FB_SET_ADDRESS_MODE_HORIZONTAL (0x00)
++#define SSD1307FB_SET_ADDRESS_MODE_VERTICAL (0x01)
++#define SSD1307FB_SET_ADDRESS_MODE_PAGE (0x02)
++#define SSD1307FB_SET_COL_RANGE 0x21
++#define SSD1307FB_SET_PAGE_RANGE 0x22
+ #define SSD1307FB_CONTRAST 0x81
+ #define SSD1307FB_CHARGE_PUMP 0x8d
+ #define SSD1307FB_SEG_REMAP_ON 0xa1
+@@ -120,6 +126,7 @@ static inline int ssd1307fb_write_data(struct i2c_client *client, u8 data)
+
+ static void ssd1307fb_update_display(struct ssd1307fb_par *par)
+ {
++ struct ssd1307fb_array *array = ssd1307fb_alloc_array(par->width * par->height / 8, SSD1307FB_DATA);
+ u8 *vmem = par->info->screen_base;
+ int i, j, k;
+
+@@ -153,28 +160,20 @@ static void ssd1307fb_update_display(struct ssd1307fb_par *par)
+ */
+
+ for (i = 0; i < (par->height / 8); i++) {
+- struct ssd1307fb_array *array;
+-
+- ssd1307fb_write_cmd(par->client, SSD1307FB_START_PAGE_ADDRESS + i + par->page_offset);
+- ssd1307fb_write_cmd(par->client, 0x00);
+- ssd1307fb_write_cmd(par->client, 0x10);
+-
+- array = ssd1307fb_alloc_array(par->width, SSD1307FB_DATA);
+-
+ for (j = 0; j < par->width; j++) {
+- array->data[j] = 0;
++ u32 array_idx = i * par->width + j;
++ array->data[array_idx] = 0;
+ for (k = 0; k < 8; k++) {
+ u32 page_length = par->width * i;
+ u32 index = page_length + (par->width * k + j) / 8;
+ u8 byte = *(vmem + index);
+ u8 bit = byte & (1 << (j % 8));
+ bit = bit >> (j % 8);
+- array->data[j] |= bit << k;
++ array->data[array_idx] |= bit << k;
+ }
+ }
+-
+- ssd1307fb_write_array(par->client, array, par->width);
+ }
++ ssd1307fb_write_array(par->client, array, par->width * par->height / 8);
+ }
+
+
+@@ -351,6 +350,24 @@ static int ssd1307fb_ssd1306_init(struct ssd1307fb_par *par) {
+ if (ret < 0)
+ return ret;
+
++ /* Switch to horizontal addressing mode */
++ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_ADDRESS_MODE);
++ ret = ret & ssd1307fb_write_cmd(par->client, SSD1307FB_SET_ADDRESS_MODE_HORIZONTAL);
++ if (ret < 0)
++ return ret;
++
++ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_COL_RANGE);
++ ret = ret & ssd1307fb_write_cmd(par->client, 0x0);
++ ret = ret & ssd1307fb_write_cmd(par->client, par->width - 1);
++ if (ret < 0)
++ return ret;
++
++ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_SET_PAGE_RANGE);
++ ret = ret & ssd1307fb_write_cmd(par->client, 0x0);
++ ret = ret & ssd1307fb_write_cmd(par->client, par->page_offset + (par->height / 8) - 1);
++ if (ret < 0)
++ return ret;
++
+ /* Turn on the display */
+ ret = ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_ON);
+ if (ret < 0)
diff --git a/patches/linux-3.8.13/0569-SSD1307fb-1Hz-8Hz-defio-updates.patch b/patches/linux-3.8.13/0569-SSD1307fb-1Hz-8Hz-defio-updates.patch
new file mode 100644
index 0000000..88c4f56
--- /dev/null
+++ b/patches/linux-3.8.13/0569-SSD1307fb-1Hz-8Hz-defio-updates.patch
@@ -0,0 +1,22 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Sat, 13 Apr 2013 20:10:05 +0200
+Subject: [PATCH] SSD1307fb: 1Hz -> 8Hz defio updates
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ drivers/video/ssd1307fb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/video/ssd1307fb.c b/drivers/video/ssd1307fb.c
+index 6594458..f47b59b 100644
+--- a/drivers/video/ssd1307fb.c
++++ b/drivers/video/ssd1307fb.c
+@@ -245,7 +245,7 @@ static void ssd1307fb_deferred_io(struct fb_info *info,
+ }
+
+ static struct fb_deferred_io ssd1307fb_defio = {
+- .delay = HZ,
++ .delay = HZ/8,
+ .deferred_io = ssd1307fb_deferred_io,
+ };
+
diff --git a/patches/linux-3.8.13/0570-ARM-force-march-armv7a-for-thumb2-builds-http-lists..patch b/patches/linux-3.8.13/0570-ARM-force-march-armv7a-for-thumb2-builds-http-lists..patch
new file mode 100644
index 0000000..21032a1
--- /dev/null
+++ b/patches/linux-3.8.13/0570-ARM-force-march-armv7a-for-thumb2-builds-http-lists..patch
@@ -0,0 +1,23 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Wed, 3 Apr 2013 09:36:21 +0200
+Subject: [PATCH] ARM: force -march=armv7a for thumb2 builds -
+ http://lists.linaro.org/pipermail/linaro-dev/2011-August/006752.html
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/boot/compressed/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
+index 5cad8a6..12edc8c 100644
+--- a/arch/arm/boot/compressed/Makefile
++++ b/arch/arm/boot/compressed/Makefile
+@@ -121,7 +121,7 @@ KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
+ endif
+
+ ccflags-y := -fpic -fno-builtin -I$(obj)
+-asflags-y := -Wa,-march=all -DZIMAGE
++asflags-y := -Wa,-march=armv7a -DZIMAGE
+
+ # Supply kernel BSS size to the decompressor via a linker symbol.
+ KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \
diff --git a/patches/linux-3.8.13/0571-headers_install-Fix-build-failures-on-deep-directory.patch b/patches/linux-3.8.13/0571-headers_install-Fix-build-failures-on-deep-directory.patch
new file mode 100644
index 0000000..790519d
--- /dev/null
+++ b/patches/linux-3.8.13/0571-headers_install-Fix-build-failures-on-deep-directory.patch
@@ -0,0 +1,56 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 8 Apr 2013 19:45:48 +0000
+Subject: [PATCH] headers_install: Fix build failures on deep directory
+ hierarchy
+
+Make headers_install croaks when we're on a deep directory hierarchy
+Fix using intermediate file lists in /tmp + xargs (but crud is left in /tmp)
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ scripts/Makefile.headersinst | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst
+index e253917..c399133 100644
+--- a/scripts/Makefile.headersinst
++++ b/scripts/Makefile.headersinst
+@@ -60,6 +60,13 @@ input-files := $(foreach hdr, $(header-y), \
+ $(error Missing generated UAPI file $(gendir)/$(hdr)) \
+ ))
+
++# these will leave a file in /tmp - but they work...
++input-files-temp := $(shell mktemp)
++$(foreach f, $(input-files), $(shell echo "$(f)" >> $(input-files-temp)))
++
++all-files-temp := $(shell mktemp)
++$(foreach f, $(all-files), $(shell echo "$(installdir)/$(f)" >> $(all-files-temp)))
++
+ # Work out what needs to be removed
+ oldheaders := $(patsubst $(installdir)/%,%,$(wildcard $(installdir)/*.h))
+ unwanted := $(filter-out $(all-files),$(oldheaders))
+@@ -72,7 +79,7 @@ printdir = $(patsubst $(INSTALL_HDR_PATH)/%/,%,$(dir $@))
+ quiet_cmd_install = INSTALL $(printdir) ($(words $(all-files))\
+ file$(if $(word 2, $(all-files)),s))
+ cmd_install = \
+- $(PERL) $< $(installdir) $(SRCARCH) $(input-files); \
++ cat $(input-files-temp) | xargs -d '\n' | $(PERL) $< $(installdir) $(SRCARCH); \
+ for F in $(wrapper-files); do \
+ echo "\#include <asm-generic/$$F>" > $(installdir)/$$F; \
+ done; \
+@@ -84,11 +91,10 @@ quiet_cmd_remove = REMOVE $(unwanted)
+ quiet_cmd_check = CHECK $(printdir) ($(words $(all-files)) files)
+ # Headers list can be pretty long, xargs helps to avoid
+ # the "Argument list too long" error.
+- cmd_check = for f in $(all-files); do \
+- echo "$(installdir)/$${f}"; done \
+- | xargs \
+- $(PERL) $< $(INSTALL_HDR_PATH)/include $(SRCARCH); \
+- touch $@
++ cmd_check = \
++ cat $(all-files-temp) | xargs -d '\n' | \
++ $(PERL) $< $(INSTALL_HDR_PATH)/include $(SRCARCH); \
++ touch $@
+
+ PHONY += __headersinst __headerscheck
+
diff --git a/patches/linux-3.8.13/0572-libtraceevent-Remove-hard-coded-include-to-usr-local.patch b/patches/linux-3.8.13/0572-libtraceevent-Remove-hard-coded-include-to-usr-local.patch
new file mode 100644
index 0000000..86036de
--- /dev/null
+++ b/patches/linux-3.8.13/0572-libtraceevent-Remove-hard-coded-include-to-usr-local.patch
@@ -0,0 +1,33 @@
+From: Jack Mitchell <jack.mitchell@dbbroadcast.co.uk>
+Date: Fri, 8 Mar 2013 11:21:52 +0000
+Subject: [PATCH] libtraceevent: Remove hard coded include to
+ /usr/local/include in Makefile
+
+having /usr/local/include hardcoded into the makefile is not necessary
+as this is automatically included by GCC. It also infects cross-compile
+builds with the host systems includes.
+
+Signed-off-by: Jack Mitchell <jack.mitchell@dbbroadcast.co.uk>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Link: http://lkml.kernel.org/r/1362741712-21308-1-git-send-email-ml@communistcode.co.uk
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/lib/traceevent/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
+index a20e320..0b0a907 100644
+--- a/tools/lib/traceevent/Makefile
++++ b/tools/lib/traceevent/Makefile
+@@ -122,7 +122,7 @@ export Q VERBOSE
+
+ EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION)
+
+-INCLUDES = -I. -I/usr/local/include $(CONFIG_INCLUDES)
++INCLUDES = -I. $(CONFIG_INCLUDES)
+
+ # Set compile option CFLAGS if not set elsewhere
+ CFLAGS ?= -g -Wall
diff --git a/patches/linux-3.8.13/0573-Make-single-.dtb-targets-also-with-DTC_FLAGS.patch b/patches/linux-3.8.13/0573-Make-single-.dtb-targets-also-with-DTC_FLAGS.patch
new file mode 100644
index 0000000..f233308
--- /dev/null
+++ b/patches/linux-3.8.13/0573-Make-single-.dtb-targets-also-with-DTC_FLAGS.patch
@@ -0,0 +1,21 @@
+From: Phil Eichinger <phil@zankapfel.net>
+Date: Wed, 5 Jun 2013 15:32:04 +0200
+Subject: [PATCH] Make single .dtb targets also with DTC_FLAGS
+
+---
+ arch/arm/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/Makefile b/arch/arm/Makefile
+index e9729a4..d5935c0 100644
+--- a/arch/arm/Makefile
++++ b/arch/arm/Makefile
+@@ -299,7 +299,7 @@ uImage-dtb.%: scripts
+ $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+
+ %.dtb: scripts
+- $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@
++ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) DTC_FLAGS=$(DTC_FLAGS) $(boot)/dts/$@
+
+ dtbs: scripts
+ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) DTC_FLAGS=$(DTC_FLAGS) dtbs
diff --git a/patches/linux-3.8.13/0574-video-Add-generic-HDMI-infoframe-helpers.patch b/patches/linux-3.8.13/0574-video-Add-generic-HDMI-infoframe-helpers.patch
new file mode 100644
index 0000000..05ccb04
--- /dev/null
+++ b/patches/linux-3.8.13/0574-video-Add-generic-HDMI-infoframe-helpers.patch
@@ -0,0 +1,593 @@
+From: Thierry Reding <thierry.reding@avionic-design.de>
+Date: Fri, 22 Feb 2013 07:03:26 +0000
+Subject: [PATCH] video: Add generic HDMI infoframe helpers
+
+Add generic helpers to pack HDMI infoframes into binary buffers.
+
+Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
+---
+ drivers/video/Kconfig | 3 +
+ drivers/video/Makefile | 1 +
+ drivers/video/hdmi.c | 308 ++++++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/hdmi.h | 231 ++++++++++++++++++++++++++++++++++++
+ 4 files changed, 543 insertions(+)
+ create mode 100644 drivers/video/hdmi.c
+ create mode 100644 include/linux/hdmi.h
+
+diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
+index f8f0a41..a0c757a 100644
+--- a/drivers/video/Kconfig
++++ b/drivers/video/Kconfig
+@@ -54,6 +54,9 @@ config OF_VIDEOMODE
+ help
+ helper to get videomodes from the devicetree
+
++config HDMI
++ bool
++
+ menuconfig FB
+ tristate "Support for frame buffer devices"
+ ---help---
+diff --git a/drivers/video/Makefile b/drivers/video/Makefile
+index a3ab28c..28bfbca 100644
+--- a/drivers/video/Makefile
++++ b/drivers/video/Makefile
+@@ -5,6 +5,7 @@
+ # Each configuration option enables a list of files.
+
+ obj-$(CONFIG_VGASTATE) += vgastate.o
++obj-$(CONFIG_HDMI) += hdmi.o
+ obj-y += fb_notify.o
+ obj-$(CONFIG_FB) += fb.o
+ fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
+diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
+new file mode 100644
+index 0000000..ab23c9b
+--- /dev/null
++++ b/drivers/video/hdmi.c
+@@ -0,0 +1,308 @@
++/*
++ * Copyright (C) 2012 Avionic Design GmbH
++ *
++ * 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/bitops.h>
++#include <linux/errno.h>
++#include <linux/export.h>
++#include <linux/hdmi.h>
++#include <linux/string.h>
++
++static void hdmi_infoframe_checksum(void *buffer, size_t size)
++{
++ u8 *ptr = buffer;
++ u8 csum = 0;
++ size_t i;
++
++ /* compute checksum */
++ for (i = 0; i < size; i++)
++ csum += ptr[i];
++
++ ptr[3] = 256 - csum;
++}
++
++/**
++ * hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe
++ * @frame: HDMI AVI infoframe
++ *
++ * Returns 0 on success or a negative error code on failure.
++ */
++int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
++{
++ memset(frame, 0, sizeof(*frame));
++
++ frame->type = HDMI_INFOFRAME_TYPE_AVI;
++ frame->version = 2;
++ frame->length = 13;
++
++ return 0;
++}
++EXPORT_SYMBOL(hdmi_avi_infoframe_init);
++
++/**
++ * hdmi_avi_infoframe_pack() - write HDMI AVI infoframe to binary buffer
++ * @frame: HDMI AVI infoframe
++ * @buffer: destination buffer
++ * @size: size of buffer
++ *
++ * Packs the information contained in the @frame structure into a binary
++ * representation that can be written into the corresponding controller
++ * registers. Also computes the checksum as required by section 5.3.5 of
++ * the HDMI 1.4 specification.
++ *
++ * Returns the number of bytes packed into the binary buffer or a negative
++ * error code on failure.
++ */
++ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
++ size_t size)
++{
++ u8 *ptr = buffer;
++ size_t length;
++
++ length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
++
++ if (size < length)
++ return -ENOSPC;
++
++ memset(buffer, 0, length);
++
++ ptr[0] = frame->type;
++ ptr[1] = frame->version;
++ ptr[2] = frame->length;
++ ptr[3] = 0; /* checksum */
++
++ /* start infoframe payload */
++ ptr += HDMI_INFOFRAME_HEADER_SIZE;
++
++ ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3);
++
++ if (frame->active_info_valid)
++ ptr[0] |= BIT(4);
++
++ if (frame->horizontal_bar_valid)
++ ptr[0] |= BIT(3);
++
++ if (frame->vertical_bar_valid)
++ ptr[0] |= BIT(2);
++
++ ptr[1] = ((frame->colorimetry & 0x3) << 6) |
++ ((frame->picture_aspect & 0x3) << 4) |
++ (frame->active_aspect & 0xf);
++
++ ptr[2] = ((frame->extended_colorimetry & 0x7) << 4) |
++ ((frame->quantization_range & 0x3) << 2) |
++ (frame->nups & 0x3);
++
++ if (frame->itc)
++ ptr[2] |= BIT(7);
++
++ ptr[3] = frame->video_code & 0x7f;
++
++ ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) |
++ ((frame->content_type & 0x3) << 4) |
++ (frame->pixel_repeat & 0xf);
++
++ ptr[5] = frame->top_bar & 0xff;
++ ptr[6] = (frame->top_bar >> 8) & 0xff;
++ ptr[7] = frame->bottom_bar & 0xff;
++ ptr[8] = (frame->bottom_bar >> 8) & 0xff;
++ ptr[9] = frame->left_bar & 0xff;
++ ptr[10] = (frame->left_bar >> 8) & 0xff;
++ ptr[11] = frame->right_bar & 0xff;
++ ptr[12] = (frame->right_bar >> 8) & 0xff;
++
++ hdmi_infoframe_checksum(buffer, length);
++
++ return length;
++}
++EXPORT_SYMBOL(hdmi_avi_infoframe_pack);
++
++/**
++ * hdmi_spd_infoframe_init() - initialize an HDMI SPD infoframe
++ * @frame: HDMI SPD infoframe
++ * @vendor: vendor string
++ * @product: product string
++ *
++ * Returns 0 on success or a negative error code on failure.
++ */
++int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
++ const char *vendor, const char *product)
++{
++ memset(frame, 0, sizeof(*frame));
++
++ frame->type = HDMI_INFOFRAME_TYPE_SPD;
++ frame->version = 1;
++ frame->length = 25;
++
++ strncpy(frame->vendor, vendor, sizeof(frame->vendor));
++ strncpy(frame->product, product, sizeof(frame->product));
++
++ return 0;
++}
++EXPORT_SYMBOL(hdmi_spd_infoframe_init);
++
++/**
++ * hdmi_spd_infoframe_pack() - write HDMI SPD infoframe to binary buffer
++ * @frame: HDMI SPD infoframe
++ * @buffer: destination buffer
++ * @size: size of buffer
++ *
++ * Packs the information contained in the @frame structure into a binary
++ * representation that can be written into the corresponding controller
++ * registers. Also computes the checksum as required by section 5.3.5 of
++ * the HDMI 1.4 specification.
++ *
++ * Returns the number of bytes packed into the binary buffer or a negative
++ * error code on failure.
++ */
++ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
++ size_t size)
++{
++ u8 *ptr = buffer;
++ size_t length;
++
++ length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
++
++ if (size < length)
++ return -ENOSPC;
++
++ memset(buffer, 0, length);
++
++ ptr[0] = frame->type;
++ ptr[1] = frame->version;
++ ptr[2] = frame->length;
++ ptr[3] = 0; /* checksum */
++
++ /* start infoframe payload */
++ ptr += HDMI_INFOFRAME_HEADER_SIZE;
++
++ memcpy(ptr, frame->vendor, sizeof(frame->vendor));
++ memcpy(ptr + 8, frame->product, sizeof(frame->product));
++
++ ptr[24] = frame->sdi;
++
++ hdmi_infoframe_checksum(buffer, length);
++
++ return length;
++}
++EXPORT_SYMBOL(hdmi_spd_infoframe_pack);
++
++/**
++ * hdmi_audio_infoframe_init() - initialize an HDMI audio infoframe
++ * @frame: HDMI audio infoframe
++ *
++ * Returns 0 on success or a negative error code on failure.
++ */
++int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)
++{
++ memset(frame, 0, sizeof(*frame));
++
++ frame->type = HDMI_INFOFRAME_TYPE_AUDIO;
++ frame->version = 1;
++ frame->length = 10;
++
++ return 0;
++}
++EXPORT_SYMBOL(hdmi_audio_infoframe_init);
++
++/**
++ * hdmi_audio_infoframe_pack() - write HDMI audio infoframe to binary buffer
++ * @frame: HDMI audio infoframe
++ * @buffer: destination buffer
++ * @size: size of buffer
++ *
++ * Packs the information contained in the @frame structure into a binary
++ * representation that can be written into the corresponding controller
++ * registers. Also computes the checksum as required by section 5.3.5 of
++ * the HDMI 1.4 specification.
++ *
++ * Returns the number of bytes packed into the binary buffer or a negative
++ * error code on failure.
++ */
++ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
++ void *buffer, size_t size)
++{
++ unsigned char channels;
++ u8 *ptr = buffer;
++ size_t length;
++
++ length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
++
++ if (size < length)
++ return -ENOSPC;
++
++ memset(buffer, 0, length);
++
++ if (frame->channels >= 2)
++ channels = frame->channels - 1;
++ else
++ channels = 0;
++
++ ptr[0] = frame->type;
++ ptr[1] = frame->version;
++ ptr[2] = frame->length;
++ ptr[3] = 0; /* checksum */
++
++ /* start infoframe payload */
++ ptr += HDMI_INFOFRAME_HEADER_SIZE;
++
++ ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
++ ptr[1] = ((frame->sample_frequency & 0x7) << 2) |
++ (frame->sample_size & 0x3);
++ ptr[2] = frame->coding_type_ext & 0x1f;
++ ptr[3] = frame->channel_allocation;
++ ptr[4] = (frame->level_shift_value & 0xf) << 3;
++
++ if (frame->downmix_inhibit)
++ ptr[4] |= BIT(7);
++
++ hdmi_infoframe_checksum(buffer, length);
++
++ return length;
++}
++EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
++
++/**
++ * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary
++ * buffer
++ * @frame: HDMI vendor infoframe
++ * @buffer: destination buffer
++ * @size: size of buffer
++ *
++ * Packs the information contained in the @frame structure into a binary
++ * representation that can be written into the corresponding controller
++ * registers. Also computes the checksum as required by section 5.3.5 of
++ * the HDMI 1.4 specification.
++ *
++ * Returns the number of bytes packed into the binary buffer or a negative
++ * error code on failure.
++ */
++ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
++ void *buffer, size_t size)
++{
++ u8 *ptr = buffer;
++ size_t length;
++
++ length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
++
++ if (size < length)
++ return -ENOSPC;
++
++ memset(buffer, 0, length);
++
++ ptr[0] = frame->type;
++ ptr[1] = frame->version;
++ ptr[2] = frame->length;
++ ptr[3] = 0; /* checksum */
++
++ memcpy(&ptr[HDMI_INFOFRAME_HEADER_SIZE], frame->data, frame->length);
++
++ hdmi_infoframe_checksum(buffer, length);
++
++ return length;
++}
++EXPORT_SYMBOL(hdmi_vendor_infoframe_pack);
+diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
+new file mode 100644
+index 0000000..3b58944
+--- /dev/null
++++ b/include/linux/hdmi.h
+@@ -0,0 +1,231 @@
++/*
++ * Copyright (C) 2012 Avionic Design GmbH
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __LINUX_HDMI_H_
++#define __LINUX_HDMI_H_
++
++#include <linux/types.h>
++
++enum hdmi_infoframe_type {
++ HDMI_INFOFRAME_TYPE_VENDOR = 0x81,
++ HDMI_INFOFRAME_TYPE_AVI = 0x82,
++ HDMI_INFOFRAME_TYPE_SPD = 0x83,
++ HDMI_INFOFRAME_TYPE_AUDIO = 0x84,
++};
++
++#define HDMI_INFOFRAME_HEADER_SIZE 4
++#define HDMI_AVI_INFOFRAME_SIZE 13
++#define HDMI_SPD_INFOFRAME_SIZE 25
++#define HDMI_AUDIO_INFOFRAME_SIZE 10
++
++enum hdmi_colorspace {
++ HDMI_COLORSPACE_RGB,
++ HDMI_COLORSPACE_YUV422,
++ HDMI_COLORSPACE_YUV444,
++};
++
++enum hdmi_scan_mode {
++ HDMI_SCAN_MODE_NONE,
++ HDMI_SCAN_MODE_OVERSCAN,
++ HDMI_SCAN_MODE_UNDERSCAN,
++};
++
++enum hdmi_colorimetry {
++ HDMI_COLORIMETRY_NONE,
++ HDMI_COLORIMETRY_ITU_601,
++ HDMI_COLORIMETRY_ITU_709,
++ HDMI_COLORIMETRY_EXTENDED,
++};
++
++enum hdmi_picture_aspect {
++ HDMI_PICTURE_ASPECT_NONE,
++ HDMI_PICTURE_ASPECT_4_3,
++ HDMI_PICTURE_ASPECT_16_9,
++};
++
++enum hdmi_active_aspect {
++ HDMI_ACTIVE_ASPECT_16_9_TOP = 2,
++ HDMI_ACTIVE_ASPECT_14_9_TOP = 3,
++ HDMI_ACTIVE_ASPECT_16_9_CENTER = 4,
++ HDMI_ACTIVE_ASPECT_PICTURE = 8,
++ HDMI_ACTIVE_ASPECT_4_3 = 9,
++ HDMI_ACTIVE_ASPECT_16_9 = 10,
++ HDMI_ACTIVE_ASPECT_14_9 = 11,
++ HDMI_ACTIVE_ASPECT_4_3_SP_14_9 = 13,
++ HDMI_ACTIVE_ASPECT_16_9_SP_14_9 = 14,
++ HDMI_ACTIVE_ASPECT_16_9_SP_4_3 = 15,
++};
++
++enum hdmi_extended_colorimetry {
++ HDMI_EXTENDED_COLORIMETRY_XV_YCC_601,
++ HDMI_EXTENDED_COLORIMETRY_XV_YCC_709,
++ HDMI_EXTENDED_COLORIMETRY_S_YCC_601,
++ HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601,
++ HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB,
++};
++
++enum hdmi_quantization_range {
++ HDMI_QUANTIZATION_RANGE_DEFAULT,
++ HDMI_QUANTIZATION_RANGE_LIMITED,
++ HDMI_QUANTIZATION_RANGE_FULL,
++};
++
++/* non-uniform picture scaling */
++enum hdmi_nups {
++ HDMI_NUPS_UNKNOWN,
++ HDMI_NUPS_HORIZONTAL,
++ HDMI_NUPS_VERTICAL,
++ HDMI_NUPS_BOTH,
++};
++
++enum hdmi_ycc_quantization_range {
++ HDMI_YCC_QUANTIZATION_RANGE_LIMITED,
++ HDMI_YCC_QUANTIZATION_RANGE_FULL,
++};
++
++enum hdmi_content_type {
++ HDMI_CONTENT_TYPE_NONE,
++ HDMI_CONTENT_TYPE_PHOTO,
++ HDMI_CONTENT_TYPE_CINEMA,
++ HDMI_CONTENT_TYPE_GAME,
++};
++
++struct hdmi_avi_infoframe {
++ enum hdmi_infoframe_type type;
++ unsigned char version;
++ unsigned char length;
++ enum hdmi_colorspace colorspace;
++ bool active_info_valid;
++ bool horizontal_bar_valid;
++ bool vertical_bar_valid;
++ enum hdmi_scan_mode scan_mode;
++ enum hdmi_colorimetry colorimetry;
++ enum hdmi_picture_aspect picture_aspect;
++ enum hdmi_active_aspect active_aspect;
++ bool itc;
++ enum hdmi_extended_colorimetry extended_colorimetry;
++ enum hdmi_quantization_range quantization_range;
++ enum hdmi_nups nups;
++ unsigned char video_code;
++ enum hdmi_ycc_quantization_range ycc_quantization_range;
++ enum hdmi_content_type content_type;
++ unsigned char pixel_repeat;
++ unsigned short top_bar;
++ unsigned short bottom_bar;
++ unsigned short left_bar;
++ unsigned short right_bar;
++};
++
++int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame);
++ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
++ size_t size);
++
++enum hdmi_spd_sdi {
++ HDMI_SPD_SDI_UNKNOWN,
++ HDMI_SPD_SDI_DSTB,
++ HDMI_SPD_SDI_DVDP,
++ HDMI_SPD_SDI_DVHS,
++ HDMI_SPD_SDI_HDDVR,
++ HDMI_SPD_SDI_DVC,
++ HDMI_SPD_SDI_DSC,
++ HDMI_SPD_SDI_VCD,
++ HDMI_SPD_SDI_GAME,
++ HDMI_SPD_SDI_PC,
++ HDMI_SPD_SDI_BD,
++ HDMI_SPD_SDI_SACD,
++ HDMI_SPD_SDI_HDDVD,
++ HDMI_SPD_SDI_PMP,
++};
++
++struct hdmi_spd_infoframe {
++ enum hdmi_infoframe_type type;
++ unsigned char version;
++ unsigned char length;
++ char vendor[8];
++ char product[16];
++ enum hdmi_spd_sdi sdi;
++};
++
++int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
++ const char *vendor, const char *product);
++ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer,
++ size_t size);
++
++enum hdmi_audio_coding_type {
++ HDMI_AUDIO_CODING_TYPE_STREAM,
++ HDMI_AUDIO_CODING_TYPE_PCM,
++ HDMI_AUDIO_CODING_TYPE_AC3,
++ HDMI_AUDIO_CODING_TYPE_MPEG1,
++ HDMI_AUDIO_CODING_TYPE_MP3,
++ HDMI_AUDIO_CODING_TYPE_MPEG2,
++ HDMI_AUDIO_CODING_TYPE_AAC_LC,
++ HDMI_AUDIO_CODING_TYPE_DTS,
++ HDMI_AUDIO_CODING_TYPE_ATRAC,
++ HDMI_AUDIO_CODING_TYPE_DSD,
++ HDMI_AUDIO_CODING_TYPE_EAC3,
++ HDMI_AUDIO_CODING_TYPE_DTS_HD,
++ HDMI_AUDIO_CODING_TYPE_MLP,
++ HDMI_AUDIO_CODING_TYPE_DST,
++ HDMI_AUDIO_CODING_TYPE_WMA_PRO,
++};
++
++enum hdmi_audio_sample_size {
++ HDMI_AUDIO_SAMPLE_SIZE_STREAM,
++ HDMI_AUDIO_SAMPLE_SIZE_16,
++ HDMI_AUDIO_SAMPLE_SIZE_20,
++ HDMI_AUDIO_SAMPLE_SIZE_24,
++};
++
++enum hdmi_audio_sample_frequency {
++ HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM,
++ HDMI_AUDIO_SAMPLE_FREQUENCY_32000,
++ HDMI_AUDIO_SAMPLE_FREQUENCY_44100,
++ HDMI_AUDIO_SAMPLE_FREQUENCY_48000,
++ HDMI_AUDIO_SAMPLE_FREQUENCY_88200,
++ HDMI_AUDIO_SAMPLE_FREQUENCY_96000,
++ HDMI_AUDIO_SAMPLE_FREQUENCY_176400,
++ HDMI_AUDIO_SAMPLE_FREQUENCY_192000,
++};
++
++enum hdmi_audio_coding_type_ext {
++ HDMI_AUDIO_CODING_TYPE_EXT_STREAM,
++ HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC,
++ HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC_V2,
++ HDMI_AUDIO_CODING_TYPE_EXT_MPEG_SURROUND,
++};
++
++struct hdmi_audio_infoframe {
++ enum hdmi_infoframe_type type;
++ unsigned char version;
++ unsigned char length;
++ unsigned char channels;
++ enum hdmi_audio_coding_type coding_type;
++ enum hdmi_audio_sample_size sample_size;
++ enum hdmi_audio_sample_frequency sample_frequency;
++ enum hdmi_audio_coding_type_ext coding_type_ext;
++ unsigned char channel_allocation;
++ unsigned char level_shift_value;
++ bool downmix_inhibit;
++
++};
++
++int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame);
++ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
++ void *buffer, size_t size);
++
++struct hdmi_vendor_infoframe {
++ enum hdmi_infoframe_type type;
++ unsigned char version;
++ unsigned char length;
++ u8 data[27];
++};
++
++ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
++ void *buffer, size_t size);
++
++#endif /* _DRM_HDMI_H */
diff --git a/patches/linux-3.8.13/0575-BeagleBone-Black-TDA998x-Initial-HDMI-Audio-support.patch b/patches/linux-3.8.13/0575-BeagleBone-Black-TDA998x-Initial-HDMI-Audio-support.patch
new file mode 100644
index 0000000..9eddf81
--- /dev/null
+++ b/patches/linux-3.8.13/0575-BeagleBone-Black-TDA998x-Initial-HDMI-Audio-support.patch
@@ -0,0 +1,784 @@
+From: Darren Etheridge <detheridge@ti.com>
+Date: Fri, 19 Apr 2013 12:37:37 -0500
+Subject: [PATCH] BeagleBone Black TDA998x Initial HDMI Audio support
+
+commit 5e166deffcfe438f57ec334e288e068e42fb05bb
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Fri Apr 19 11:34:44 2013 -0500
+
+ tda998x - select the correct i2s format for BBB
+
+commit 27ce11f74e084c2d49bd9d50db7eaf8fe3386bf9
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Thu Apr 18 15:42:57 2013 -0500
+
+ TDA998x initial attempt at adding HDMI/audio
+ This now supports HDMI with correct CEA timings and Audio output (fixed at 48KHz)
+
+commit a25d22ec97a60611ba8f3579a015fa05ee4f96fa
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Wed Apr 17 17:06:40 2013 -0500
+
+ TILCDC enable pulling in HDMI infoframe helper functions
+
+commit 90cd4a836a4d60232d70f84f56a854c794917422
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Wed Apr 17 14:11:59 2013 -0500
+
+ Adding new audio driver-combined with DRM driver for NXP TDA 998x
+
+commit df7d51d3aebcb2222be60acfd3408e67d83d9383
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Wed Apr 17 13:52:29 2013 -0500
+
+ Remove debug, changing codec name to dedicated NXP
+
+commit 566687c6bb1c80a1d8e8cb66b469152bf69ae67b
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Wed Apr 17 12:14:08 2013 -0500
+
+ Remove NXP supplied driver from the build
+ Replace with custom DRM driver.
+
+commit c150fef5971088705fc155163a3a5a4f805b321e
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Wed Apr 17 12:07:25 2013 -0500
+
+ AM335x audio back to original setup, with new NXP hdmi driver moved to DRM
+
+commit 19c2249b7e4ad600f28bfdb67106abe0c8509701
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Wed Apr 17 11:55:50 2013 -0500
+
+ Reverting file back to original form and replacing with custom NXP driver
+ that will be part of the DRM driver.
+
+commit da88657d82d52ad212f34429b7b349dbea093bc0
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Wed Apr 17 11:50:02 2013 -0500
+
+ Cleaning up for NXP codec support on BeagleBone Black
+
+commit bda7bcce6f54c8108bd8dc9efb5e0f4c375f112d
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Wed Apr 17 11:48:44 2013 -0500
+
+ Added a new build target for NXP audio driver
+
+commit 38b5a020fa895a6da2b495a5b46b7f5e4cb5a0a4
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Wed Apr 17 11:47:40 2013 -0500
+
+ Changing to put the NXP into HDMI mode by default
+ Much more work is needed to make this into a real driver
+ with audio support.
+
+commit 0bdff4a28649d1c17bff1d74ca41bf9ce28f7743
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Wed Apr 17 11:46:15 2013 -0500
+
+ Initial version of dummy codec driver for NXP HDMI encoder
+
+commit e15d0879137b6cb15c1ff57d9f32d60f4ba9e232
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Fri Apr 12 16:45:43 2013 -0500
+
+ Fixing typo in Bone Cape DTS file
+
+commit 8a2693c254cc56227f9b8ae180df64963ec944dd
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Fri Apr 5 16:15:45 2013 -0500
+
+ Fixing the default audio format from the mcasp for nxp hdmi driver.
+
+commit 1e66174fbe31672e3fb8776fe6146d4445916021
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Fri Apr 5 13:09:24 2013 -0500
+
+ Create an hdmi device and fix setting in mcasp
+ this is very much a temporary commit and needs to be cleaned up and
+ done the right way before it is rolled out further.
+
+commit e48b28929abdfa635d69fca38009bea1422745e7
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Fri Apr 5 13:07:51 2013 -0500
+
+ Set the right format for HDMI Codec
+
+commit 465924ca1fd1a27c252f47fe6f501444f624319d
+Author: Darren Etheridge <detheridge@ti.com>
+Date: Fri Apr 5 10:44:03 2013 -0500
+
+ Add the necessary device tree nodes to enable HDMI audio. Add code to enable the McASP clock
+ that is enabled by setting gpio1_27 high. Create a new machine in Davinci audio driver for
+ BeagleBone Black.
+---
+ drivers/gpu/drm/i2c/Kconfig | 1 +
+ drivers/gpu/drm/i2c/Makefile | 2 +-
+ drivers/gpu/drm/i2c/tda998x_audio_drv.c | 76 ++++++++++
+ drivers/gpu/drm/i2c/tda998x_drv.c | 205 ++++++++++++++++++++++++++-
+ firmware/capes/cape-boneblack-hdmi-00A0.dts | 52 +++++++
+ sound/soc/davinci/davinci-evm.c | 50 ++++++-
+ sound/soc/davinci/davinci-mcasp.c | 15 +-
+ 7 files changed, 385 insertions(+), 16 deletions(-)
+ create mode 100644 drivers/gpu/drm/i2c/tda998x_audio_drv.c
+
+diff --git a/drivers/gpu/drm/i2c/Kconfig b/drivers/gpu/drm/i2c/Kconfig
+index 4d341db..2342005 100644
+--- a/drivers/gpu/drm/i2c/Kconfig
++++ b/drivers/gpu/drm/i2c/Kconfig
+@@ -22,6 +22,7 @@ config DRM_I2C_SIL164
+ config DRM_I2C_NXP_TDA998X
+ tristate "NXP Semiconductors TDA998X HDMI encoder"
+ default m if DRM_TILCDC
++ select HDMI
+ help
+ Support for NXP Semiconductors TDA998X HDMI encoders.
+
+diff --git a/drivers/gpu/drm/i2c/Makefile b/drivers/gpu/drm/i2c/Makefile
+index 43aa33b..0ba6bd3 100644
+--- a/drivers/gpu/drm/i2c/Makefile
++++ b/drivers/gpu/drm/i2c/Makefile
+@@ -6,5 +6,5 @@ obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o
+ sil164-y := sil164_drv.o
+ obj-$(CONFIG_DRM_I2C_SIL164) += sil164.o
+
+-tda998x-y := tda998x_drv.o
++tda998x-y := tda998x_drv.o tda998x_audio_drv.o
+ obj-$(CONFIG_DRM_I2C_NXP_TDA998X) += tda998x.o
+diff --git a/drivers/gpu/drm/i2c/tda998x_audio_drv.c b/drivers/gpu/drm/i2c/tda998x_audio_drv.c
+new file mode 100644
+index 0000000..c13e25b
+--- /dev/null
++++ b/drivers/gpu/drm/i2c/tda998x_audio_drv.c
+@@ -0,0 +1,76 @@
++/*
++ * ALSA SoC codec driver for HDMI audio on NXP TDA998x series.
++ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
++ * Author: Darren Etheridge <detheridge@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * version 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
++ * 02110-1301 USA
++ *
++ */
++#include <linux/module.h>
++#include <sound/soc.h>
++#include <linux/of_device.h>
++
++#define DRV_NAME "nxp-hdmi-audio-codec"
++
++static struct snd_soc_codec_driver nxp_hdmi_codec;
++
++static struct snd_soc_dai_driver nxp_hdmi_codec_dai = {
++ .name = "nxp-hdmi-hifi",
++ .playback = {
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = SNDRV_PCM_RATE_48000,
++ .formats = SNDRV_PCM_FMTBIT_S32_LE,
++ },
++};
++
++#ifdef CONFIG_OF
++static const struct of_device_id nxptda_dt_ids[] = {
++ { .compatible = "nxp,nxptda", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, nxptda_dt_ids);
++#endif
++
++
++static int nxp_hdmi_codec_probe(struct platform_device *pdev)
++{
++ return snd_soc_register_codec(&pdev->dev, &nxp_hdmi_codec,
++ &nxp_hdmi_codec_dai, 1);
++}
++
++static int nxp_hdmi_codec_remove(struct platform_device *pdev)
++{
++ snd_soc_unregister_codec(&pdev->dev);
++ return 0;
++}
++
++static struct platform_driver nxp_hdmi_codec_driver = {
++ .driver = {
++ .name = DRV_NAME,
++ .owner = THIS_MODULE,
++ .of_match_table = of_match_ptr(nxptda_dt_ids)
++ },
++
++ .probe = nxp_hdmi_codec_probe,
++ .remove = nxp_hdmi_codec_remove,
++};
++
++module_platform_driver(nxp_hdmi_codec_driver);
++
++MODULE_AUTHOR("Darren Etheridge <detheridge@ti.com>");
++MODULE_DESCRIPTION("ASoC NXP Dummy HDMI codec driver");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:" DRV_NAME);
+diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
+index e68b58a..e3e9101 100644
+--- a/drivers/gpu/drm/i2c/tda998x_drv.c
++++ b/drivers/gpu/drm/i2c/tda998x_drv.c
+@@ -23,7 +23,7 @@
+ #include <drm/drm_crtc_helper.h>
+ #include <drm/drm_encoder_slave.h>
+ #include <drm/drm_edid.h>
+-
++#include <linux/hdmi.h>
+
+ #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
+
+@@ -110,6 +110,9 @@ struct tda998x_priv {
+ #define REG_VIP_CNTRL_5 REG(0x00, 0x25) /* write */
+ # define VIP_CNTRL_5_CKCASE (1 << 0)
+ # define VIP_CNTRL_5_SP_CNT(x) (((x) & 3) << 1)
++
++#define REG_MUX_AP REG(0x00, 0x26)
++# define MUX_AP_SELECT_I2S (0x64)
+ #define REG_MAT_CONTRL REG(0x00, 0x80) /* write */
+ # define MAT_CONTRL_MAT_SC(x) (((x) & 3) << 0)
+ # define MAT_CONTRL_MAT_BP (1 << 2)
+@@ -171,7 +174,10 @@ struct tda998x_priv {
+ # define HVF_CNTRL_1_PAD(x) (((x) & 3) << 4)
+ # define HVF_CNTRL_1_SEMI_PLANAR (1 << 6)
+ #define REG_RPT_CNTRL REG(0x00, 0xf0) /* write */
++#define REG_I2S_FORMAT REG(0x00, 0xfc)
+
++#define REG_AIP_CLKSEL REG(0x00, 0xfd)
++# define SEL_AIP_I2S (1 << 3) /* I2S Clk */
+
+ /* Page 02h: PLL settings */
+ #define REG_PLL_SERIAL_1 REG(0x02, 0x00) /* read/write */
+@@ -212,7 +218,8 @@ struct tda998x_priv {
+
+
+ /* Page 10h: information frames and packets */
+-
++#define REG_AVI_IF REG(0x10, 0x40) /* AVI Infoframe packet */
++#define REG_AUDIO_IF REG(0x10, 0x80) /* AVI Infoframe packet */
+
+ /* Page 11h: audio settings and content info packets */
+ #define REG_AIP_CNTRL_0 REG(0x11, 0x00) /* read/write */
+@@ -221,11 +228,28 @@ struct tda998x_priv {
+ # define AIP_CNTRL_0_LAYOUT (1 << 2)
+ # define AIP_CNTRL_0_ACR_MAN (1 << 5)
+ # define AIP_CNTRL_0_RST_CTS (1 << 6)
++#define REG_ACR_CTS_0 REG(0x11, 0x05)
++#define REG_ACR_CTS_1 REG(0x11, 0x06)
++#define REG_ACR_CTS_2 REG(0x11, 0x07)
++#define REG_ACR_N_0 REG(0x11, 0x08)
++#define REG_ACR_N_1 REG(0x11, 0x09)
++#define REG_ACR_N_2 REG(0x11, 0x0a)
++#define REG_GC_AVMUTE REG(0x11, 0x0b)
++# define GC_AVMUTE_CLRMUTE (1 << 0)
++# define GC_AVMUTE_SETMUTE (1 << 1)
++#define REG_CTS_N REG(0x11, 0x0c)
+ #define REG_ENC_CNTRL REG(0x11, 0x0d) /* read/write */
+ # define ENC_CNTRL_RST_ENC (1 << 0)
+ # define ENC_CNTRL_RST_SEL (1 << 1)
+ # define ENC_CNTRL_CTL_CODE(x) (((x) & 3) << 2)
+-
++#define REG_DIP_FLAGS REG(0x11, 0x0e)
++# define DIP_FLAGS_ACR (1 << 0)
++#define REG_DIP_IF_FLAGS REG(0x11, 0x0f) /* read/write */
++#define DIP_IF_FLAGS_IF1 (1 << 1)
++#define DIP_IF_FLAGS_IF2 (1 << 2)
++#define DIP_IF_FLAGS_IF3 (1 << 3)
++#define DIP_IF_FLAGS_IF4 (1 << 4)
++#define DIP_IF_FLAGS_IF5 (1 << 5)
+
+ /* Page 12h: HDCP and OTP */
+ #define REG_TX3 REG(0x12, 0x9a) /* read/write */
+@@ -262,6 +286,9 @@ struct tda998x_priv {
+ #define TDA19989N2 0x0202
+ #define TDA19988 0x0301
+
++static uint8_t *
++do_get_edid(struct drm_encoder *encoder);
++
+ static void
+ cec_write(struct drm_encoder *encoder, uint16_t addr, uint8_t val)
+ {
+@@ -338,6 +365,35 @@ fail:
+ return ret;
+ }
+
++static int
++reg_write_range(struct drm_encoder *encoder, uint16_t reg, char *buf, int cnt)
++{
++ struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
++ int ret = 0;
++ uint8_t *i2cpacket;
++
++ i2cpacket = (uint8_t *)kmalloc(cnt + 1, GFP_KERNEL);
++ if(!i2cpacket) {
++ goto fail;
++ }
++ i2cpacket[0] = REG2ADDR(reg);
++ memcpy(&i2cpacket[1], buf, cnt);
++
++ set_page(encoder, reg);
++
++ ret = i2c_master_send(client, i2cpacket, cnt+1);
++ kfree(i2cpacket);
++ if (ret < 0)
++ goto fail;
++
++ return ret;
++
++fail:
++ dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg);
++ return ret;
++}
++
++
+ static uint8_t
+ reg_read(struct drm_encoder *encoder, uint16_t reg)
+ {
+@@ -437,7 +493,7 @@ tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
+ switch (mode) {
+ case DRM_MODE_DPMS_ON:
+ /* enable audio and video ports */
+- reg_write(encoder, REG_ENA_AP, 0xff);
++ reg_write(encoder, REG_ENA_AP, 0x03);
+ reg_write(encoder, REG_ENA_VP_0, 0xff);
+ reg_write(encoder, REG_ENA_VP_1, 0xff);
+ reg_write(encoder, REG_ENA_VP_2, 0xff);
+@@ -488,6 +544,87 @@ tda998x_encoder_mode_valid(struct drm_encoder *encoder,
+ return MODE_OK;
+ }
+
++
++static void
++tda998x_audio_infoframe_enable(struct drm_encoder *encoder)
++{
++ uint8_t buffer[20];
++ struct hdmi_audio_infoframe audio_frame;
++ size_t len;
++
++ hdmi_audio_infoframe_init(&audio_frame);
++
++ /* NXP audio is fixed at these values for the time being */
++ audio_frame.channels = 2;
++ audio_frame.coding_type = HDMI_AUDIO_CODING_TYPE_PCM;
++ audio_frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_24;
++ audio_frame.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_48000;
++
++ len = hdmi_audio_infoframe_pack(&audio_frame, buffer, sizeof(buffer));
++ WARN(len < 0, "hdmi_avi_infoframe_pack failed\n");
++
++ reg_write_range(encoder, REG_AUDIO_IF, buffer, len);
++
++ /* enable Audio Infoframe output in DIP_IF Register */
++ reg_clear(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF4);
++ udelay(5);
++ reg_set(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF4);
++}
++
++static void
++tda998x_avi_infoframe_enable(struct drm_encoder *encoder,
++ struct drm_display_mode *mode)
++{
++ uint8_t buffer[20];
++ struct hdmi_avi_infoframe avi_frame;
++ size_t len;
++
++ hdmi_avi_infoframe_init(&avi_frame);
++ avi_frame.video_code = drm_match_cea_mode(mode);
++ avi_frame.picture_aspect = HDMI_PICTURE_ASPECT_NONE;
++ avi_frame.active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
++ len = hdmi_avi_infoframe_pack(&avi_frame, buffer, sizeof(buffer));
++ WARN(len < 0, "hdmi_avi_infoframe_pack failed\n");
++
++ reg_write_range(encoder, REG_AVI_IF, buffer, len);
++
++ /*
++ * enable AVI Infoframe output in DIP_IF Register, but toggle it
++ * so that the hardware acknowledges that the packet data might have
++ * changed
++ */
++ reg_clear(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF3);
++ udelay(5);
++ reg_set(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF3);
++}
++
++/* loopup table for CEA values to VIDFORMAT values taken from NXP datasheet */
++static char cea_to_nxp_mode[32] = {-1, 0, 1, 1, 2, 3, 4, 4, 5, 5, -1, -1,
++ -1, -1, -1, -1, 6, 7, 7, 8, 9, 10, 10,
++ 11, 11, -1, -1, -1, -1, -1, -1, 12};
++
++static char tda998x_cea_to_vidformat(unsigned char cea_mode)
++{
++ if(cea_mode > 31) {
++ return -1;
++ }
++ return cea_to_nxp_mode[cea_mode];
++}
++
++static char tda998x_is_monitor_hdmi(struct drm_encoder *encoder)
++{
++ struct edid *edid = (struct edid *)do_get_edid(encoder);
++ char hdmi = 0;
++ if(edid) {
++ hdmi = drm_detect_hdmi_monitor(edid);
++ kfree(edid);
++ } else {
++ return -1;
++ }
++ return hdmi;
++}
++
++
+ static void
+ tda998x_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+@@ -534,7 +671,7 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder,
+ /* mute the audio FIFO: */
+ reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO);
+
+- /* set HDMI HDCP mode off: */
++ /* HDMI/HDCP mode off... for now...: */
+ reg_set(encoder, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS);
+ reg_clear(encoder, REG_TX33, TX33_HDMI);
+
+@@ -605,14 +742,69 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder,
+ reg = TBG_CNTRL_1_VHX_EXT_DE |
+ TBG_CNTRL_1_VHX_EXT_HS |
+ TBG_CNTRL_1_VHX_EXT_VS |
+- TBG_CNTRL_1_DWIN_DIS | /* HDCP off */
++ TBG_CNTRL_1_DWIN_DIS | /* HDCP off */
+ TBG_CNTRL_1_VH_TGL_2;
+ if (mode->flags & (DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC))
+ reg |= TBG_CNTRL_1_VH_TGL_0;
+ reg_set(encoder, REG_TBG_CNTRL_1, reg);
+
++
++
++
++ if(tda998x_is_monitor_hdmi(encoder) == 1) {
++ char vidformat;
++ vidformat = tda998x_cea_to_vidformat(drm_match_cea_mode(mode));
++ if(vidformat == (char)-1) {
++ dev_err(encoder->dev->dev, "Not sure which CEA mode to set, leaving as DVI");
++ goto out;
++ }
++ dev_info(encoder->dev->dev, "Connected to an HDMI monitor with cea mode %d", vidformat);
++
++ /* this is an HDMI monitor, so set things up a bit differently */
++ reg_write(encoder, REG_TBG_CNTRL_1, 0);
++ reg_write(encoder, REG_VIDFORMAT, vidformat);
++ /* get the infoframes pumping */
++ tda998x_avi_infoframe_enable(encoder, mode);
++ tda998x_audio_infoframe_enable(encoder);
++ reg_set(encoder, REG_TX33, TX33_HDMI);
++
++ /* set up audio registers */
++ reg_write(encoder, REG_ACR_CTS_0, 0x0);
++ reg_write(encoder, REG_ACR_CTS_1, 0x0);
++ reg_write(encoder, REG_ACR_CTS_2, 0x0);
++
++ reg_write(encoder, REG_ACR_N_0, 0x0);
++ reg_write(encoder, REG_ACR_N_1, 0x18);
++ reg_write(encoder, REG_ACR_N_2, 0x0);
++
++ reg_set(encoder, REG_DIP_FLAGS, DIP_FLAGS_ACR);
++
++ reg_write(encoder, REG_ENC_CNTRL, 0x04);
++ reg_write(encoder, REG_CTS_N, 0x33);
++ /* Set 2 channel I2S mode */
++ reg_write(encoder, REG_ENA_AP, 0x3);
++
++ /* set audio divider in pll settings */
++ reg_write(encoder, REG_AUDIO_DIV, 0x2);
++
++ /* select the audio input port clock */
++ reg_write(encoder, REG_AIP_CLKSEL, SEL_AIP_I2S);
++ reg_write(encoder, REG_MUX_AP, MUX_AP_SELECT_I2S);
++
++ /* select I2S format, and datasize */
++ reg_write(encoder, REG_I2S_FORMAT, 0x0a);
++
++ /* enable the audio FIFO: */
++ reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO);
++
++ /* mute and then unmute, to get audio going */
++ reg_write(encoder, REG_GC_AVMUTE, GC_AVMUTE_SETMUTE);
++ reg_write(encoder, REG_GC_AVMUTE, GC_AVMUTE_CLRMUTE);
++ }
++out:
+ /* must be last register set: */
+ reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_ONCE);
++
+ }
+
+ static enum drm_connector_status
+@@ -904,3 +1096,4 @@ MODULE_LICENSE("GPL");
+
+ module_init(tda998x_init);
+ module_exit(tda998x_exit);
++
+diff --git a/firmware/capes/cape-boneblack-hdmi-00A0.dts b/firmware/capes/cape-boneblack-hdmi-00A0.dts
+index ee36d0e..e5f714a 100644
+--- a/firmware/capes/cape-boneblack-hdmi-00A0.dts
++++ b/firmware/capes/cape-boneblack-hdmi-00A0.dts
+@@ -46,6 +46,16 @@
+ 0x1b0 0x03 /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */
+ >;
+ };
++
++ mcasp0_pins: mcasp0_pins {
++ pinctrl-single,pins = <
++ 0x1ac 0x30 /* mcasp0_ahclkx, MODE0 | INPUT */
++ 0x19c 0x02 /* mcasp0_ahclkr, */
++ 0x194 0x10 /* mcasp0_fsx, MODE0 | OUTPUT */
++ 0x190 0x00 /* mcasp0_aclkr.mcasp0_aclkx, MODE0 | OUTPUT_PULLDOWN */
++ 0x1a8 0x1f /* mcasp0_axr1 GPIO1_27 | OUTPUT | PULLUP */
++ >;
++ };
+ };
+ };
+
+@@ -57,6 +67,11 @@
+ #address-cells = <1>;
+ #size-cells = <1>;
+
++ nxptda: nxptda@0 {
++ compatible = "nxp,nxptda";
++ status = "okay";
++ };
++
+ hdmi {
+ compatible = "tilcdc,slave";
+ i2c = <&i2c0>;
+@@ -77,4 +92,41 @@
+ };
+ };
+
++ fragment@3 {
++ target = <&mcasp0>;
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&mcasp0_pins>;
++
++ status = "okay";
++
++ op-mode = <0>; /* MCASP_IIS_MODE */
++ tdm-slots = <2>;
++ num-serializer = <16>;
++ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
++ 0 0 1 0
++ 0 0 0 0
++ 0 0 0 0
++ 0 0 0 0
++ >;
++ tx-num-evt = <1>;
++ rx-num-evt = <1>;
++ };
++ };
++
++ fragment@4 {
++ target = <&ocp>;
++ __overlay__ {
++ sound {
++ compatible = "ti,am33xx-beaglebone-black";
++ ti,model = "TI BeagleBone Black";
++ ti,audio-codec = <&nxptda>;
++ ti,mcasp-controller = <&mcasp0>;
++ ti,codec-clock-rate = <2457600>;
++ mcasp_clock_enable = <&gpio2 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */
++ };
++ };
++
++ };
++
+ };
+diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
+index 349db80..7a7fc47 100644
+--- a/sound/soc/davinci/davinci-evm.c
++++ b/sound/soc/davinci/davinci-evm.c
+@@ -30,6 +30,9 @@
+ #include "davinci-i2s.h"
+ #include "davinci-mcasp.h"
+
++#include <linux/of_gpio.h>
++
++
+ #define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
+ SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
+ static int evm_hw_params(struct snd_pcm_substream *substream,
+@@ -311,11 +314,13 @@ static struct snd_soc_card da850_snd_soc_card = {
+ .num_links = 1,
+ };
+
++
+ #if defined(CONFIG_OF)
+
+ enum {
+ MACHINE_VERSION_1 = 0, /* DM365 with Voice Codec */
+ MACHINE_VERSION_2, /* DM365/DA8xx/OMAPL1x/AM33xx */
++ MACHINE_VERSION_3, /* AM33xx BeagleBone Black */
+ };
+
+ static const struct of_device_id davinci_evm_dt_ids[] = {
+@@ -327,6 +332,10 @@ static const struct of_device_id davinci_evm_dt_ids[] = {
+ .compatible = "ti,da830-evm-audio",
+ .data = (void *)MACHINE_VERSION_2,
+ },
++ {
++ .compatible = "ti,am33xx-beaglebone-black",
++ .data = (void *)MACHINE_VERSION_3,
++ },
+ { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, davinci_mcasp_dt_ids);
+@@ -353,7 +362,7 @@ static int davinci_evm_probe(struct platform_device *pdev)
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *match =
+ of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev);
+- u32 machine_ver;
++ u32 machine_ver, clk_gpio;
+ int ret = 0;
+
+ machine_ver = (u32)match->data;
+@@ -363,12 +372,37 @@ static int davinci_evm_probe(struct platform_device *pdev)
+ evm_dai.stream_name = "CQ93";
+ evm_dai.codec_dai_name = "cq93vc-hifi";
+ break;
+-
+ case MACHINE_VERSION_2:
+ evm_dai.ops = &evm_ops;
+ evm_dai.init = evm_aic3x_init;
+ break;
++ case MACHINE_VERSION_3:
++ evm_dai.name = "NXP TDA HDMI Chip";
++ evm_dai.stream_name = "HDMI";
++ evm_dai.codec_dai_name = "nxp-hdmi-hifi";
++
++ /*
++ * Move GPIO handling out of the probe, if probe gets
++ * deferred, the gpio will have been claimed on previous
++ * probe and will fail on the second and susequent probes
++ */
++ clk_gpio = of_get_named_gpio(np, "mcasp_clock_enable", 0);
++ if (clk_gpio < 0) {
++ dev_err(&pdev->dev, "failed to find mcasp_clock enable GPIO!\n");
++ return -EINVAL;
++ }
++ ret = gpio_request_one(clk_gpio, GPIOF_OUT_INIT_HIGH,
++ "McASP Clock Enable Pin");
++ if (ret < 0) {
++ dev_err(&pdev->dev, "Failed to claim McASP Clock Enable pin\n");
++ return -EINVAL;
++ }
++ gpio_set_value(clk_gpio, 1);
++ evm_dai.dai_fmt = SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF;
++ break;
++
+ }
++
+
+ evm_dai.codec_of_node = of_parse_phandle(np, "ti,audio-codec", 0);
+ if (!evm_dai.codec_of_node)
+@@ -387,9 +421,9 @@ static int davinci_evm_probe(struct platform_device *pdev)
+ return ret;
+
+ ret = snd_soc_register_card(&evm_soc_card);
+- if (ret)
++ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+-
++ }
+ return ret;
+ }
+
+@@ -426,8 +460,9 @@ static int __init evm_init(void)
+ * If dtb is there, the devices will be created dynamically.
+ * Only register platfrom driver structure.
+ */
+- if (of_have_populated_dt())
+- return platform_driver_register(&davinci_evm_driver);
++ if (of_have_populated_dt()) {
++ return platform_driver_register(&davinci_evm_driver);
++ }
+ #endif
+
+ if (machine_is_davinci_evm()) {
+@@ -448,8 +483,9 @@ static int __init evm_init(void)
+ } else if (machine_is_davinci_da850_evm()) {
+ evm_snd_dev_data = &da850_snd_soc_card;
+ index = 0;
+- } else
++ } else {
+ return -EINVAL;
++ }
+
+ evm_snd_device = platform_device_alloc("soc-audio", index);
+ if (!evm_snd_device)
+diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
+index ea292f6..4c700df 100644
+--- a/sound/soc/davinci/davinci-mcasp.c
++++ b/sound/soc/davinci/davinci-mcasp.c
+@@ -497,16 +497,22 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+- /* codec is clock and frame slave */
+- mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
++ /* codec is clock and frame slave */
++ printk("SND_SOC_DAIFMT_CBS_CFS entered\n");
++ mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE | ACLKXDIV(7));
++ mcasp_set_bits(base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXDIV(0));
++ mcasp_clr_bits(base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);
+ mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
+
+ mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
+ mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
+
+ mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, ACLKX | AFSX);
++ mcasp_clr_bits(base + DAVINCI_MCASP_PDIR_REG, AHCLKX);
+ break;
+ case SND_SOC_DAIFMT_CBM_CFS:
++ printk("SND_SOC_DAIFMT_CBM_CFS entered\n");
++
+ /* codec is clock master and frame slave */
+ mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
+ mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
+@@ -520,6 +526,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
+ AFSX | AFSR);
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
++ printk("SND_SOC_DAIFMT_CBM_CFM entered\n");
+ /* codec is clock and frame master */
+ mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
+ mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
+@@ -746,6 +753,8 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ /* bit stream is MSB first with no delay */
+ /* DSP_B mode */
++ printk("davinci hw_params _ PLAYBACK modified\n");
++ mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);
+ mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask);
+ mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD);
+
+@@ -755,6 +764,8 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
+ else
+ printk(KERN_ERR "playback tdm slot %d not supported\n",
+ dev->tdm_slots);
++ mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
++ mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
+ } else {
+ /* bit stream is MSB first with no delay */
+ /* DSP_B mode */
diff --git a/patches/linux-3.8.13/0576-Clean-up-some-formating-and-debug-in-Davinci-MCASP-d.patch b/patches/linux-3.8.13/0576-Clean-up-some-formating-and-debug-in-Davinci-MCASP-d.patch
new file mode 100644
index 0000000..3dda5bc
--- /dev/null
+++ b/patches/linux-3.8.13/0576-Clean-up-some-formating-and-debug-in-Davinci-MCASP-d.patch
@@ -0,0 +1,55 @@
+From: Darren Etheridge <detheridge@ti.com>
+Date: Fri, 19 Apr 2013 13:18:14 -0500
+Subject: [PATCH] Clean up some formating and debug in Davinci MCASP driver
+
+---
+ sound/soc/davinci/davinci-mcasp.c | 15 +++++----------
+ 1 file changed, 5 insertions(+), 10 deletions(-)
+
+diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
+index 4c700df..bef4e72 100644
+--- a/sound/soc/davinci/davinci-mcasp.c
++++ b/sound/soc/davinci/davinci-mcasp.c
+@@ -497,11 +497,10 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+- /* codec is clock and frame slave */
+- printk("SND_SOC_DAIFMT_CBS_CFS entered\n");
+- mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE | ACLKXDIV(7));
+- mcasp_set_bits(base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXDIV(0));
+- mcasp_clr_bits(base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);
++ /* codec is clock and frame slave */
++ mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE | ACLKXDIV(7));
++ mcasp_set_bits(base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXDIV(0));
++ mcasp_clr_bits(base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);
+ mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
+
+ mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
+@@ -511,8 +510,6 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
+ mcasp_clr_bits(base + DAVINCI_MCASP_PDIR_REG, AHCLKX);
+ break;
+ case SND_SOC_DAIFMT_CBM_CFS:
+- printk("SND_SOC_DAIFMT_CBM_CFS entered\n");
+-
+ /* codec is clock master and frame slave */
+ mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
+ mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
+@@ -526,7 +523,6 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
+ AFSX | AFSR);
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+- printk("SND_SOC_DAIFMT_CBM_CFM entered\n");
+ /* codec is clock and frame master */
+ mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
+ mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
+@@ -753,8 +749,7 @@ static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ /* bit stream is MSB first with no delay */
+ /* DSP_B mode */
+- printk("davinci hw_params _ PLAYBACK modified\n");
+- mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);
++ mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);
+ mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask);
+ mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD);
+
diff --git a/patches/linux-3.8.13/0577-tilcdc-Prune-modes-that-can-t-support-audio.patch b/patches/linux-3.8.13/0577-tilcdc-Prune-modes-that-can-t-support-audio.patch
new file mode 100644
index 0000000..339d422
--- /dev/null
+++ b/patches/linux-3.8.13/0577-tilcdc-Prune-modes-that-can-t-support-audio.patch
@@ -0,0 +1,240 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Fri, 3 May 2013 16:11:53 +0300
+Subject: [PATCH] tilcdc: Prune modes that can't support audio.
+
+If the connector supports audio, prune all the display modes that
+don't support it.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 73 +++++++++++++++++++-------------
+ drivers/gpu/drm/tilcdc/tilcdc_drv.c | 9 +++-
+ drivers/gpu/drm/tilcdc/tilcdc_drv.h | 3 +-
+ drivers/gpu/drm/tilcdc/tilcdc_panel.c | 2 +-
+ drivers/gpu/drm/tilcdc/tilcdc_slave.c | 6 ++-
+ drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 2 +-
+ 6 files changed, 59 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+index 69675e6..afbaa6f 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+@@ -241,7 +241,7 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
+ uint32_t reg, hbp, hfp, hsw, vbp, vfp, vsw;
+ int ret;
+
+- ret = tilcdc_crtc_mode_valid(crtc, mode, 0);
++ ret = tilcdc_crtc_mode_valid(crtc, mode, 0, 0, NULL);
+ if (WARN_ON(ret))
+ return ret;
+
+@@ -430,11 +430,12 @@ int tilcdc_crtc_max_width(struct drm_crtc *crtc)
+ }
+
+ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+- int rb_check)
++ int rb_check, int audio, struct edid *edid)
+ {
+ struct tilcdc_drm_private *priv = crtc->dev->dev_private;
+ unsigned int bandwidth;
+ uint32_t hbp, hfp, hsw, vbp, vfp, vsw;
++ int has_audio, is_cea_mode;
+
+ int rb;
+
+@@ -450,10 +451,22 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ if (mode->vdisplay > 2048)
+ return MODE_VIRTUAL_Y;
+
++ /* set if there's audio capability */
++ has_audio = edid && drm_detect_monitor_audio(edid);
+
+- DBG("Processing mode %dx%d@%d with pixel clock %d",
+- mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode), mode->clock);
++ /* set if it's a cea mode */
++ is_cea_mode = drm_match_cea_mode(mode) > 0;
+
++ DBG("mode %dx%d@%d pixel-clock %d audio %s cea %s",
++ mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode),
++ mode->clock,
++ has_audio ? "true" : "false",
++ is_cea_mode ? "true" : "false");
++
++ if (audio && has_audio && !is_cea_mode) {
++ DBG("Pruning mode : Does not support audio\n");
++ return MODE_BAD;
++ }
+
+ hbp = mode->htotal - mode->hsync_end;
+ hfp = mode->hsync_start - mode->hdisplay;
+@@ -462,56 +475,56 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ vfp = mode->vsync_start - mode->vdisplay;
+ vsw = mode->vsync_end - mode->vsync_start;
+
+- if(hbp & ~0x3ff) {
+- DBG("Pruning mode : Horizontal Back Porch out of range\n");
+- return MODE_BAD;
++ if (hbp & ~0x3ff) {
++ DBG("Pruning mode : Horizontal Back Porch out of range\n");
++ return MODE_BAD;
+ }
+
+- if(hfp & ~0x3ff) {
+- DBG("Pruning mode : Horizontal Front Porch out of range\n");
+- return MODE_BAD;
++ if (hfp & ~0x3ff) {
++ DBG("Pruning mode : Horizontal Front Porch out of range\n");
++ return MODE_BAD;
+ }
+
+- if(hsw & ~0x3ff) {
+- DBG("Pruning mode : Horizontal Sync Width out of range\n");
+- return MODE_BAD;
++ if (hsw & ~0x3ff) {
++ DBG("Pruning mode : Horizontal Sync Width out of range\n");
++ return MODE_BAD;
+ }
+
+- if(vbp & ~0xff) {
+- DBG("Pruning mode : Vertical Back Porch out of range\n");
+- return MODE_BAD;
++ if (vbp & ~0xff) {
++ DBG("Pruning mode : Vertical Back Porch out of range\n");
++ return MODE_BAD;
+ }
+
+- if(vfp & ~0xff) {
+- DBG("Pruning mode : Vertical Front Porch out of range\n");
+- return MODE_BAD;
++ if (vfp & ~0xff) {
++ DBG("Pruning mode : Vertical Front Porch out of range\n");
++ return MODE_BAD;
+ }
+
+- if(vsw & ~0x3f) {
+- DBG("Pruning mode : Vertical Sync Width out of range\n");
+- return MODE_BAD;
++ if (vsw & ~0x3f) {
++ DBG("Pruning mode : Vertical Sync Width out of range\n");
++ return MODE_BAD;
+ }
+
+ /* some devices have a maximum allowed pixel clock */
+ /* configured from the DT */
+- if(mode->clock > priv->max_pixelclock) {
+- DBG("Pruning mode, pixel clock too high");
+- return MODE_BAD;
++ if (mode->clock > priv->max_pixelclock) {
++ DBG("Pruning mode, pixel clock too high");
++ return MODE_BAD;
+ }
+
+ /* some devices further limit the max horizontal resolution */
+ /* configured from the DT */
+- if(mode->hdisplay > priv->max_width) {
+- DBG("Pruning mode, above max width of %d supported by device", priv->max_width);
+- return MODE_BAD;
++ if (mode->hdisplay > priv->max_width) {
++ DBG("Pruning mode, above max width of %d supported by device", priv->max_width);
++ return MODE_BAD;
+ }
+
+ /* filter out modes that would require too much memory bandwidth: */
+ /* configured from the DT */
+ bandwidth = mode->hdisplay * mode->vdisplay * drm_mode_vrefresh(mode);
+ if (bandwidth > priv->max_bandwidth) {
+- DBG("Pruning mode, exceeds defined bandwidth limit");
+- return MODE_BAD;
++ DBG("Pruning mode, exceeds defined bandwidth limit");
++ return MODE_BAD;
+ }
+
+ if (rb_check) {
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+index fca4f16..31e039e 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+@@ -250,12 +250,17 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
+
+ DBG("Maximum Pixel Clock Value %dKHz", priv->max_pixelclock);
+
+-
+ priv->allow_non_rblank = of_property_read_bool(node,
+ "ti,allow-non-reduced-blanking-modes");
+
++ DBG("Allowing Standard Monitor Modes: %s",
++ priv->allow_non_rblank ? "true" : "false");
++
++ priv->allow_non_audio = of_property_read_bool(node,
++ "ti,allow-non-audio-modes");
+
+- DBG("Allowing Standard Monitor Modes: %s", priv->allow_non_rblank?"true":"false");
++ DBG("Allowing Non Audio Monitor Modes: %s",
++ priv->allow_non_audio ? "true" : "false");
+
+ pm_runtime_enable(dev->dev);
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+index 48d744c..db3c468 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
++++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+@@ -58,6 +58,7 @@ struct tilcdc_drm_private {
+ uint32_t max_width;
+
+ int allow_non_rblank; /* ATM we don't support non reduced blank modes */
++ int allow_non_audio; /* allow modes that don't have working audio */
+
+ /* register contents saved across suspend/resume: */
+ u32 saved_register[12];
+@@ -160,7 +161,7 @@ void tilcdc_crtc_update_clk(struct drm_crtc *crtc);
+ void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc,
+ const struct tilcdc_panel_info *info);
+ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+- int rb_check);
++ int rb_check, int audio, struct edid *edid);
+ int tilcdc_crtc_max_width(struct drm_crtc *crtc);
+
+ #endif /* __TILCDC_DRV_H__ */
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+index 361c569..90bc0e3 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+@@ -199,7 +199,7 @@ static int panel_connector_mode_valid(struct drm_connector *connector,
+ {
+ struct tilcdc_drm_private *priv = connector->dev->dev_private;
+ /* our only constraints are what the crtc can generate: */
+- return tilcdc_crtc_mode_valid(priv->crtc, mode, 0);
++ return tilcdc_crtc_mode_valid(priv->crtc, mode, 0, 0, NULL);
+ }
+
+ static struct drm_encoder *panel_connector_best_encoder(
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave.c b/drivers/gpu/drm/tilcdc/tilcdc_slave.c
+index 17252ef..e454874 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_slave.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_slave.c
+@@ -170,7 +170,11 @@ static int slave_connector_mode_valid(struct drm_connector *connector,
+ int ret;
+
+ ret = tilcdc_crtc_mode_valid(priv->crtc, mode,
+- priv->allow_non_rblank ? 0 : 1);
++ priv->allow_non_rblank ? 0 : 1,
++ priv->allow_non_audio ? 0 : 1,
++ connector->edid_blob_ptr ?
++ (struct edid *)connector->edid_blob_ptr->data :
++ NULL);
+ if (ret != MODE_OK)
+ return ret;
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
+index 9d9796f..c71f955 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
+@@ -216,7 +216,7 @@ static int tfp410_connector_mode_valid(struct drm_connector *connector,
+ struct tilcdc_drm_private *priv = connector->dev->dev_private;
+ /* our only constraints are what the crtc can generate: */
+ return tilcdc_crtc_mode_valid(priv->crtc, mode,
+- priv->allow_non_rblank ? 0 : 1);
++ priv->allow_non_rblank ? 0 : 1, 0, NULL);
+ }
+
+ static struct drm_encoder *tfp410_connector_best_encoder(
diff --git a/patches/linux-3.8.13/0578-Enable-output-of-correct-AVI-Infoframe-type-hdmi.patch b/patches/linux-3.8.13/0578-Enable-output-of-correct-AVI-Infoframe-type-hdmi.patch
new file mode 100644
index 0000000..af9c935
--- /dev/null
+++ b/patches/linux-3.8.13/0578-Enable-output-of-correct-AVI-Infoframe-type-hdmi.patch
@@ -0,0 +1,24 @@
+From: Darren Etheridge <detheridge@ti.com>
+Date: Tue, 7 May 2013 21:22:27 -0500
+Subject: [PATCH] Enable output of correct AVI Infoframe type hdmi
+
+---
+ drivers/gpu/drm/i2c/tda998x_drv.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
+index e3e9101..7c64696 100644
+--- a/drivers/gpu/drm/i2c/tda998x_drv.c
++++ b/drivers/gpu/drm/i2c/tda998x_drv.c
+@@ -593,9 +593,9 @@ tda998x_avi_infoframe_enable(struct drm_encoder *encoder,
+ * so that the hardware acknowledges that the packet data might have
+ * changed
+ */
+- reg_clear(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF3);
++ reg_clear(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF2);
+ udelay(5);
+- reg_set(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF3);
++ reg_set(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF2);
+ }
+
+ /* loopup table for CEA values to VIDFORMAT values taken from NXP datasheet */
diff --git a/patches/linux-3.8.13/0579-drm-am335x-add-support-for-2048-lines-vertical.patch b/patches/linux-3.8.13/0579-drm-am335x-add-support-for-2048-lines-vertical.patch
new file mode 100644
index 0000000..d5003a0
--- /dev/null
+++ b/patches/linux-3.8.13/0579-drm-am335x-add-support-for-2048-lines-vertical.patch
@@ -0,0 +1,86 @@
+From: Darren Etheridge <detheridge@ti.com>
+Date: Wed, 8 May 2013 16:15:40 -0500
+Subject: [PATCH] drm: am335x: add support for 2048 lines vertical
+
+Add extra mode that enables 1920x1080@24, this now works
+with 2048 lines vertical support and EMIF setting of
+INT_CONFIG optimized.
+---
+ drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 15 ++++++++++++---
+ drivers/gpu/drm/tilcdc/tilcdc_drv.h | 10 +++++++---
+ drivers/gpu/drm/tilcdc/tilcdc_regs.h | 1 +
+ 3 files changed, 20 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+index afbaa6f..1dbd927 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+@@ -308,6 +308,7 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
+ (((hsw-1) & 0x3f) << 10);
+ if (priv->rev == 2)
+ reg |= (((mode->hdisplay >> 4) - 1) & 0x40) >> 3;
++
+ tilcdc_write(dev, LCDC_RASTER_TIMING_0_REG, reg);
+
+ /* only the vertical sync width maps 0 as 1 so only subtract 1 from vsw */
+@@ -317,6 +318,14 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
+ (((vsw-1) & 0x3f) << 10);
+ tilcdc_write(dev, LCDC_RASTER_TIMING_1_REG, reg);
+
++ if (priv->rev == 2) {
++ if((mode->vdisplay - 1) & 0x400) {
++ tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_LPP_B10);
++ } else {
++ tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_LPP_B10);
++ }
++ }
++
+ /* Configure display type: */
+ reg = tilcdc_read(dev, LCDC_RASTER_CTRL_REG) &
+ ~(LCDC_TFT_MODE | LCDC_MONO_8BIT_MODE | LCDC_MONOCHROME_MODE |
+@@ -530,9 +539,9 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ if (rb_check) {
+ /* we only support reduced blanking modes */
+ rb = (mode->htotal - mode->hdisplay == 160) &&
+- (mode->hsync_end - mode->hdisplay == 80) &&
+- (mode->hsync_end - mode->hsync_start == 32) &&
+- (mode->vsync_start - mode->vdisplay == 3);
++ (mode->hsync_end - mode->hdisplay == 80) &&
++ (mode->hsync_end - mode->hsync_start == 32) &&
++ (mode->vsync_start - mode->vdisplay == 3);
+ if (!rb) {
+ DBG("Pruning mode, only support reduced blanking modes");
+ return MODE_BAD;
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+index db3c468..6b2c7ea 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
++++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+@@ -37,9 +37,13 @@
+ /* Defaulting to pixel clock defined on AM335x */
+ #define TILCDC_DEFAULT_MAX_PIXELCLOCK 126000
+ /* Defaulting to max width as defined on AM335x */
+-#define TILCDC_DEFAULT_MAX_WIDTH 1366
+-/* This may need some tweaking, but want to allow at least 1280x1024@60 */
+-#define TILCDC_DEFAULT_MAX_BANDWIDTH (1366*1024*60)
++#define TILCDC_DEFAULT_MAX_WIDTH 2048
++/*
++ * This may need some tweaking, but want to allow at least 1280x1024@60
++ * with optimized DDR & EMIF settings tweaked 1920x1080@24 appears to
++ * be supportable
++ */
++#define TILCDC_DEFAULT_MAX_BANDWIDTH (1920*1080*25)
+
+ struct tilcdc_drm_private {
+ void __iomem *mmio;
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_regs.h b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
+index 17fd1b4..1bf5e25 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_regs.h
++++ b/drivers/gpu/drm/tilcdc/tilcdc_regs.h
+@@ -80,6 +80,7 @@
+ #define LCDC_INVERT_PIXEL_CLOCK BIT(22)
+ #define LCDC_INVERT_HSYNC BIT(21)
+ #define LCDC_INVERT_VSYNC BIT(20)
++#define LCDC_LPP_B10 BIT(26)
+
+ /* LCDC Block */
+ #define LCDC_PID_REG 0x0
diff --git a/patches/linux-3.8.13/0580-drm-tda998x-Adding-extra-CEA-mode-for-1920x1080-24.patch b/patches/linux-3.8.13/0580-drm-tda998x-Adding-extra-CEA-mode-for-1920x1080-24.patch
new file mode 100644
index 0000000..492c2f1
--- /dev/null
+++ b/patches/linux-3.8.13/0580-drm-tda998x-Adding-extra-CEA-mode-for-1920x1080-24.patch
@@ -0,0 +1,31 @@
+From: Darren Etheridge <detheridge@ti.com>
+Date: Wed, 8 May 2013 16:39:28 -0500
+Subject: [PATCH] drm: tda998x Adding extra CEA mode for 1920x1080@24
+
+---
+ drivers/gpu/drm/i2c/tda998x_drv.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
+index 7c64696..412ba4f 100644
+--- a/drivers/gpu/drm/i2c/tda998x_drv.c
++++ b/drivers/gpu/drm/i2c/tda998x_drv.c
+@@ -598,14 +598,14 @@ tda998x_avi_infoframe_enable(struct drm_encoder *encoder,
+ reg_set(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF2);
+ }
+
+-/* loopup table for CEA values to VIDFORMAT values taken from NXP datasheet */
+-static char cea_to_nxp_mode[32] = {-1, 0, 1, 1, 2, 3, 4, 4, 5, 5, -1, -1,
++/* lookup table for CEA values to VIDFORMAT values taken from NXP datasheet */
++static char cea_to_nxp_mode[34] = {-1, 0, 1, 1, 2, 3, 4, 4, 5, 5, -1, -1,
+ -1, -1, -1, -1, 6, 7, 7, 8, 9, 10, 10,
+- 11, 11, -1, -1, -1, -1, -1, -1, 12};
++ 11, 11, -1, -1, -1, -1, -1, -1, 12, 13};
+
+ static char tda998x_cea_to_vidformat(unsigned char cea_mode)
+ {
+- if(cea_mode > 31) {
++ if(cea_mode > (sizeof(cea_to_nxp_mode) -1) ) {
+ return -1;
+ }
+ return cea_to_nxp_mode[cea_mode];
diff --git a/patches/linux-3.8.13/0581-tilcdc-Remove-superfluous-newlines-from-DBG-messages.patch b/patches/linux-3.8.13/0581-tilcdc-Remove-superfluous-newlines-from-DBG-messages.patch
new file mode 100644
index 0000000..e889122
--- /dev/null
+++ b/patches/linux-3.8.13/0581-tilcdc-Remove-superfluous-newlines-from-DBG-messages.patch
@@ -0,0 +1,63 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 20 May 2013 13:54:21 +0300
+Subject: [PATCH] tilcdc: Remove superfluous newlines from DBG messages
+
+DBGs supply their own newlines, don't add them.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+index 1dbd927..c39503b 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+@@ -473,7 +473,7 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ is_cea_mode ? "true" : "false");
+
+ if (audio && has_audio && !is_cea_mode) {
+- DBG("Pruning mode : Does not support audio\n");
++ DBG("Pruning mode : Does not support audio");
+ return MODE_BAD;
+ }
+
+@@ -485,32 +485,32 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ vsw = mode->vsync_end - mode->vsync_start;
+
+ if (hbp & ~0x3ff) {
+- DBG("Pruning mode : Horizontal Back Porch out of range\n");
++ DBG("Pruning mode : Horizontal Back Porch out of range");
+ return MODE_BAD;
+ }
+
+ if (hfp & ~0x3ff) {
+- DBG("Pruning mode : Horizontal Front Porch out of range\n");
++ DBG("Pruning mode : Horizontal Front Porch out of range");
+ return MODE_BAD;
+ }
+
+ if (hsw & ~0x3ff) {
+- DBG("Pruning mode : Horizontal Sync Width out of range\n");
++ DBG("Pruning mode : Horizontal Sync Width out of range");
+ return MODE_BAD;
+ }
+
+ if (vbp & ~0xff) {
+- DBG("Pruning mode : Vertical Back Porch out of range\n");
++ DBG("Pruning mode : Vertical Back Porch out of range");
+ return MODE_BAD;
+ }
+
+ if (vfp & ~0xff) {
+- DBG("Pruning mode : Vertical Front Porch out of range\n");
++ DBG("Pruning mode : Vertical Front Porch out of range");
+ return MODE_BAD;
+ }
+
+ if (vsw & ~0x3f) {
+- DBG("Pruning mode : Vertical Sync Width out of range\n");
++ DBG("Pruning mode : Vertical Sync Width out of range");
+ return MODE_BAD;
+ }
+
diff --git a/patches/linux-3.8.13/0582-tilcdc-1280x1024x60-bw-1920x1080x24-bw.patch b/patches/linux-3.8.13/0582-tilcdc-1280x1024x60-bw-1920x1080x24-bw.patch
new file mode 100644
index 0000000..f236e24
--- /dev/null
+++ b/patches/linux-3.8.13/0582-tilcdc-1280x1024x60-bw-1920x1080x24-bw.patch
@@ -0,0 +1,43 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 20 May 2013 15:16:55 +0300
+Subject: [PATCH] tilcdc: 1280x1024x60 bw > 1920x1080x24 bw
+
+The lower resolution modes do infact need more bandwidth.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 2 +-
+ drivers/gpu/drm/tilcdc/tilcdc_drv.h | 5 +++--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+index c39503b..7ba2048 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+@@ -472,7 +472,7 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ has_audio ? "true" : "false",
+ is_cea_mode ? "true" : "false");
+
+- if (audio && has_audio && !is_cea_mode) {
++ if (edid && audio && has_audio && !is_cea_mode) {
+ DBG("Pruning mode : Does not support audio");
+ return MODE_BAD;
+ }
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+index 6b2c7ea..f3861e4 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
++++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+@@ -40,10 +40,11 @@
+ #define TILCDC_DEFAULT_MAX_WIDTH 2048
+ /*
+ * This may need some tweaking, but want to allow at least 1280x1024@60
+- * with optimized DDR & EMIF settings tweaked 1920x1080@24 appears to
++ * with optimized DDR & EMIF settings tweaked 1920x1080@25 appears to
+ * be supportable
++ * Note: 1920x1080x25=49766400 < 1280x1024x60=78643200
+ */
+-#define TILCDC_DEFAULT_MAX_BANDWIDTH (1920*1080*25)
++#define TILCDC_DEFAULT_MAX_BANDWIDTH (1280*1024*60)
+
+ struct tilcdc_drm_private {
+ void __iomem *mmio;
diff --git a/patches/linux-3.8.13/0583-tilcdc-Only-support-Audio-on-50-60-Hz-modes.patch b/patches/linux-3.8.13/0583-tilcdc-Only-support-Audio-on-50-60-Hz-modes.patch
new file mode 100644
index 0000000..d2c42a9
--- /dev/null
+++ b/patches/linux-3.8.13/0583-tilcdc-Only-support-Audio-on-50-60-Hz-modes.patch
@@ -0,0 +1,62 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 20 May 2013 16:01:07 +0300
+Subject: [PATCH] tilcdc: Only support Audio on 50 & 60 Hz modes
+
+Apparently anything other fails to work (at least for me).
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+index 7ba2048..14cee74 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+@@ -310,7 +310,7 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
+ reg |= (((mode->hdisplay >> 4) - 1) & 0x40) >> 3;
+
+ tilcdc_write(dev, LCDC_RASTER_TIMING_0_REG, reg);
+-
++
+ /* only the vertical sync width maps 0 as 1 so only subtract 1 from vsw */
+ reg = ((mode->vdisplay - 1) & 0x3ff) |
+ ((vbp & 0xff) << 24) |
+@@ -444,7 +444,7 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ struct tilcdc_drm_private *priv = crtc->dev->dev_private;
+ unsigned int bandwidth;
+ uint32_t hbp, hfp, hsw, vbp, vfp, vsw;
+- int has_audio, is_cea_mode;
++ int has_audio, is_cea_mode, can_output_audio, refresh;
+
+ int rb;
+
+@@ -463,16 +463,24 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ /* set if there's audio capability */
+ has_audio = edid && drm_detect_monitor_audio(edid);
+
++ /* only 50 & 60Hz modes reliably support audio */
++ refresh = drm_mode_vrefresh(mode);
++
+ /* set if it's a cea mode */
+ is_cea_mode = drm_match_cea_mode(mode) > 0;
+
+- DBG("mode %dx%d@%d pixel-clock %d audio %s cea %s",
+- mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode),
++ /* set if we can output audio */
++ can_output_audio = edid && has_audio && is_cea_mode &&
++ (refresh == 50 || refresh == 60);
++
++ DBG("mode %dx%d@%d pixel-clock %d audio %s cea %s can_output %s",
++ mode->hdisplay, mode->vdisplay,refresh,
+ mode->clock,
+ has_audio ? "true" : "false",
+- is_cea_mode ? "true" : "false");
++ is_cea_mode ? "true" : "false",
++ can_output_audio ? "true" : "false" );
+
+- if (edid && audio && has_audio && !is_cea_mode) {
++ if (edid && has_audio && !can_output_audio) {
+ DBG("Pruning mode : Does not support audio");
+ return MODE_BAD;
+ }
diff --git a/patches/linux-3.8.13/0584-drm-i2c-nxp-tda998x-fix-EDID-reading-on-TDA19988-dev.patch b/patches/linux-3.8.13/0584-drm-i2c-nxp-tda998x-fix-EDID-reading-on-TDA19988-dev.patch
new file mode 100644
index 0000000..1976f1e
--- /dev/null
+++ b/patches/linux-3.8.13/0584-drm-i2c-nxp-tda998x-fix-EDID-reading-on-TDA19988-dev.patch
@@ -0,0 +1,68 @@
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Thu, 16 May 2013 19:25:58 +0000
+Subject: [PATCH] drm/i2c: nxp-tda998x: fix EDID reading on TDA19988 devices
+
+TDA19988 devices need their RAM enabled in order to read EDID
+information. Add support for this.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+ drivers/gpu/drm/i2c/tda998x_drv.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
+index 412ba4f..9ac4ed9 100644
+--- a/drivers/gpu/drm/i2c/tda998x_drv.c
++++ b/drivers/gpu/drm/i2c/tda998x_drv.c
+@@ -253,6 +253,8 @@ struct tda998x_priv {
+
+ /* Page 12h: HDCP and OTP */
+ #define REG_TX3 REG(0x12, 0x9a) /* read/write */
++#define REG_TX4 REG(0x12, 0x9b) /* read/write */
++# define TX4_PD_RAM (1 << 1)
+ #define REG_TX33 REG(0x12, 0xb8) /* read/write */
+ # define TX33_HDMI (1 << 1)
+
+@@ -865,6 +867,7 @@ read_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk)
+ static uint8_t *
+ do_get_edid(struct drm_encoder *encoder)
+ {
++ struct tda998x_priv *priv = to_tda998x_priv(encoder);
+ int j = 0, valid_extensions = 0;
+ uint8_t *block, *new;
+ bool print_bad_edid = drm_debug & DRM_UT_KMS;
+@@ -872,6 +875,9 @@ do_get_edid(struct drm_encoder *encoder)
+ if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
+ return NULL;
+
++ if (priv->rev == TDA19988)
++ reg_clear(encoder, REG_TX4, TX4_PD_RAM);
++
+ /* base block fetch */
+ if (read_edid_block(encoder, block, 0))
+ goto fail;
+@@ -881,7 +887,7 @@ do_get_edid(struct drm_encoder *encoder)
+
+ /* if there's no extensions, we're done */
+ if (block[0x7e] == 0)
+- return block;
++ goto done;
+
+ new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL);
+ if (!new)
+@@ -908,9 +914,15 @@ do_get_edid(struct drm_encoder *encoder)
+ block = new;
+ }
+
++done:
++ if (priv->rev == TDA19988)
++ reg_set(encoder, REG_TX4, TX4_PD_RAM);
++
+ return block;
+
+ fail:
++ if (priv->rev == TDA19988)
++ reg_set(encoder, REG_TX4, TX4_PD_RAM);
+ dev_warn(encoder->dev->dev, "failed to read EDID\n");
+ kfree(block);
+ return NULL;
diff --git a/patches/linux-3.8.13/0585-tilcdc-Allow-non-audio-modes-when-we-don-t-support-t.patch b/patches/linux-3.8.13/0585-tilcdc-Allow-non-audio-modes-when-we-don-t-support-t.patch
new file mode 100644
index 0000000..6c902a6
--- /dev/null
+++ b/patches/linux-3.8.13/0585-tilcdc-Allow-non-audio-modes-when-we-don-t-support-t.patch
@@ -0,0 +1,26 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Tue, 4 Jun 2013 17:53:07 +0300
+Subject: [PATCH] tilcdc: Allow non-audio modes when we don't support them.
+
+Allow non-audio modes on an audio capable monitor if we explicitly
+disable audio.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+index 14cee74..5f5f464 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+@@ -480,7 +480,8 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ is_cea_mode ? "true" : "false",
+ can_output_audio ? "true" : "false" );
+
+- if (edid && has_audio && !can_output_audio) {
++ /* we only prune the mode if we ask for it */
++ if (audio && edid && has_audio && !can_output_audio) {
+ DBG("Pruning mode : Does not support audio");
+ return MODE_BAD;
+ }
diff --git a/patches/linux-3.8.13/0586-drm-i2c-nxp-tda998x-ensure-VIP-output-mux-is-properl.patch b/patches/linux-3.8.13/0586-drm-i2c-nxp-tda998x-ensure-VIP-output-mux-is-properl.patch
new file mode 100644
index 0000000..8c79a03
--- /dev/null
+++ b/patches/linux-3.8.13/0586-drm-i2c-nxp-tda998x-ensure-VIP-output-mux-is-properl.patch
@@ -0,0 +1,39 @@
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Thu, 16 May 2013 19:26:18 +0000
+Subject: [PATCH] drm/i2c: nxp-tda998x: ensure VIP output mux is properly set
+
+When switching between various drivers for this device, it's possible
+that some critical registers are left containing values which affect
+the device operation. One such case encountered is the VIP output
+mux register. This defaults to 0x24 on powerup, but other drivers may
+set this to 0x12. This results in incorrect colours.
+
+Fix this by ensuring that the register is always set to the power on
+default setting.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+ drivers/gpu/drm/i2c/tda998x_drv.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
+index 9ac4ed9..37094fd 100644
+--- a/drivers/gpu/drm/i2c/tda998x_drv.c
++++ b/drivers/gpu/drm/i2c/tda998x_drv.c
+@@ -110,6 +110,7 @@ struct tda998x_priv {
+ #define REG_VIP_CNTRL_5 REG(0x00, 0x25) /* write */
+ # define VIP_CNTRL_5_CKCASE (1 << 0)
+ # define VIP_CNTRL_5_SP_CNT(x) (((x) & 3) << 1)
++#define REG_MUX_VP_VIP_OUT REG(0x00, 0x27) /* read/write */
+
+ #define REG_MUX_AP REG(0x00, 0x26)
+ # define MUX_AP_SELECT_I2S (0x64)
+@@ -494,6 +495,8 @@ tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
+
+ switch (mode) {
+ case DRM_MODE_DPMS_ON:
++ /* Write the default value MUX register */
++ reg_write(encoder, REG_MUX_VP_VIP_OUT, 0x24);
+ /* enable audio and video ports */
+ reg_write(encoder, REG_ENA_AP, 0x03);
+ reg_write(encoder, REG_ENA_VP_0, 0xff);
diff --git a/patches/linux-3.8.13/0587-drm-i2c-nxp-tda998x-fix-npix-nline-programming.patch b/patches/linux-3.8.13/0587-drm-i2c-nxp-tda998x-fix-npix-nline-programming.patch
new file mode 100644
index 0000000..a547cd5
--- /dev/null
+++ b/patches/linux-3.8.13/0587-drm-i2c-nxp-tda998x-fix-npix-nline-programming.patch
@@ -0,0 +1,28 @@
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Thu, 16 May 2013 19:26:38 +0000
+Subject: [PATCH] drm/i2c: nxp-tda998x: fix npix/nline programming
+
+The npix/nline registers are supposed to be programmed with the total
+number of pixels/lines, not the displayed pixels/lines, and not minus
+one either.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+ drivers/gpu/drm/i2c/tda998x_drv.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
+index 37094fd..17db51b 100644
+--- a/drivers/gpu/drm/i2c/tda998x_drv.c
++++ b/drivers/gpu/drm/i2c/tda998x_drv.c
+@@ -723,8 +723,8 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder,
+ reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_H_TGL);
+
+ reg_write(encoder, REG_VIDFORMAT, 0x00);
+- reg_write16(encoder, REG_NPIX_MSB, mode->hdisplay - 1);
+- reg_write16(encoder, REG_NLINE_MSB, mode->vdisplay - 1);
++ reg_write16(encoder, REG_NPIX_MSB, mode->htotal);
++ reg_write16(encoder, REG_NLINE_MSB, mode->vtotal);
+ reg_write16(encoder, REG_VS_LINE_STRT_1_MSB, line_start);
+ reg_write16(encoder, REG_VS_LINE_END_1_MSB, line_end);
+ reg_write16(encoder, REG_VS_PIX_STRT_1_MSB, hs_start);
diff --git a/patches/linux-3.8.13/0588-drm-tilcdc-Clear-bits-of-register-we-re-going-to-set.patch b/patches/linux-3.8.13/0588-drm-tilcdc-Clear-bits-of-register-we-re-going-to-set.patch
new file mode 100644
index 0000000..66d60ae
--- /dev/null
+++ b/patches/linux-3.8.13/0588-drm-tilcdc-Clear-bits-of-register-we-re-going-to-set.patch
@@ -0,0 +1,63 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 5 Jun 2013 19:48:59 +0300
+Subject: [PATCH] drm: tilcdc: Clear bits of register we're going to set.
+
+Bits weren't cleared so resolution changes didn't work.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+index 5f5f464..8ce18ca 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+@@ -286,15 +286,18 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
+ mode->hdisplay, mode->vdisplay, hbp, hfp, hsw, vbp, vfp, vsw);
+
+ /* Configure the AC Bias Period and Number of Transitions per Interrupt: */
+- reg = tilcdc_read(dev, LCDC_RASTER_TIMING_2_REG) & ~0x000fff00;
++ reg = tilcdc_read(dev, LCDC_RASTER_TIMING_2_REG);
++ reg &= ~0x000fff00;
+ reg |= LCDC_AC_BIAS_FREQUENCY(info->ac_bias) |
+ LCDC_AC_BIAS_TRANSITIONS_PER_INT(info->ac_bias_intrpt);
+
+ /* subtract one from hfp, hbp, hsw because the hardware uses a value of 0 as 1 */
+ if (priv->rev == 2) {
+- reg |= ((hfp-1) & 0x300) >> 8;
+- reg |= ((hbp-1) & 0x300) >> 4;
+- reg |= ((hsw-1) & 0x3c0) << 21;
++ /* clear bits we're going to set */
++ reg &= ~0x78000033;
++ reg |= ((hfp-1) & 0x300) >> 8;
++ reg |= ((hbp-1) & 0x300) >> 4;
++ reg |= ((hsw-1) & 0x3c0) << 21;
+ }
+ tilcdc_write(dev, LCDC_RASTER_TIMING_2_REG, reg);
+
+@@ -307,7 +310,7 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
+ (((hfp-1) & 0xff) << 16) |
+ (((hsw-1) & 0x3f) << 10);
+ if (priv->rev == 2)
+- reg |= (((mode->hdisplay >> 4) - 1) & 0x40) >> 3;
++ reg |= (((mode->hdisplay >> 4) - 1) & 0x40) >> 3;
+
+ tilcdc_write(dev, LCDC_RASTER_TIMING_0_REG, reg);
+
+@@ -319,11 +322,10 @@ static int tilcdc_crtc_mode_set(struct drm_crtc *crtc,
+ tilcdc_write(dev, LCDC_RASTER_TIMING_1_REG, reg);
+
+ if (priv->rev == 2) {
+- if((mode->vdisplay - 1) & 0x400) {
+- tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_LPP_B10);
+- } else {
+- tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_LPP_B10);
+- }
++ if ((mode->vdisplay - 1) & 0x400)
++ tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_LPP_B10);
++ else
++ tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_LPP_B10);
+ }
+
+ /* Configure display type: */
diff --git a/patches/linux-3.8.13/0589-DRM-tda998x-add-missing-include.patch b/patches/linux-3.8.13/0589-DRM-tda998x-add-missing-include.patch
new file mode 100644
index 0000000..0de2566
--- /dev/null
+++ b/patches/linux-3.8.13/0589-DRM-tda998x-add-missing-include.patch
@@ -0,0 +1,42 @@
+From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+Date: Sat, 18 May 2013 17:12:19 +0000
+Subject: [PATCH] DRM: tda998x: add missing include
+
+The RFC sent by Russell King was missing an include for tda998x. This
+is just a compatible clone to remember Russell to add that later.
+
+Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+---
+ include/drm/i2c/tda998x.h | 23 +++++++++++++++++++++++
+ 1 file changed, 23 insertions(+)
+ create mode 100644 include/drm/i2c/tda998x.h
+
+diff --git a/include/drm/i2c/tda998x.h b/include/drm/i2c/tda998x.h
+new file mode 100644
+index 0000000..41f799f
+--- /dev/null
++++ b/include/drm/i2c/tda998x.h
+@@ -0,0 +1,23 @@
++#ifndef __TDA998X_H__
++#define __TDA998X_H__
++
++enum tda998x_audio_format {
++ AFMT_I2S,
++ AFMT_SPDIF,
++};
++
++struct tda998x_encoder_params {
++ int audio_cfg;
++ int audio_clk_cfg;
++ enum tda998x_audio_format audio_format;
++ int audio_sample_rate;
++ char audio_frame[6];
++ int swap_a, mirr_a;
++ int swap_b, mirr_b;
++ int swap_c, mirr_c;
++ int swap_d, mirr_d;
++ int swap_e, mirr_e;
++ int swap_f, mirr_f;
++};
++
++#endif
diff --git a/patches/linux-3.8.13/0590-drm-i2c-nxp-tda998x-prepare-for-video-input-configur.patch b/patches/linux-3.8.13/0590-drm-i2c-nxp-tda998x-prepare-for-video-input-configur.patch
new file mode 100644
index 0000000..f3a45fa
--- /dev/null
+++ b/patches/linux-3.8.13/0590-drm-i2c-nxp-tda998x-prepare-for-video-input-configur.patch
@@ -0,0 +1,50 @@
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Thu, 16 May 2013 19:26:58 +0000
+Subject: [PATCH] drm/i2c: nxp-tda998x: prepare for video input configuration
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+ drivers/gpu/drm/i2c/tda998x_drv.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
+index 17db51b..49e5d98 100644
+--- a/drivers/gpu/drm/i2c/tda998x_drv.c
++++ b/drivers/gpu/drm/i2c/tda998x_drv.c
+@@ -32,6 +32,9 @@ struct tda998x_priv {
+ uint16_t rev;
+ uint8_t current_page;
+ int dpms;
++ u8 vip_cntrl_0;
++ u8 vip_cntrl_1;
++ u8 vip_cntrl_2;
+ };
+
+ #define to_tda998x_priv(x) ((struct tda998x_priv *)to_encoder_slave(x)->slave_priv)
+@@ -503,12 +506,9 @@ tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
+ reg_write(encoder, REG_ENA_VP_1, 0xff);
+ reg_write(encoder, REG_ENA_VP_2, 0xff);
+ /* set muxing after enabling ports: */
+- reg_write(encoder, REG_VIP_CNTRL_0,
+- VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3));
+- reg_write(encoder, REG_VIP_CNTRL_1,
+- VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1));
+- reg_write(encoder, REG_VIP_CNTRL_2,
+- VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5));
++ reg_write(encoder, REG_VIP_CNTRL_0, priv->vip_cntrl_0);
++ reg_write(encoder, REG_VIP_CNTRL_1, priv->vip_cntrl_1);
++ reg_write(encoder, REG_VIP_CNTRL_2, priv->vip_cntrl_2);
+ break;
+ case DRM_MODE_DPMS_OFF:
+ /* disable audio and video ports */
+@@ -1014,6 +1014,10 @@ tda998x_encoder_init(struct i2c_client *client,
+ if (!priv)
+ return -ENOMEM;
+
++ priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3);
++ priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1);
++ priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5);
++
+ priv->current_page = 0;
+ priv->cec = i2c_new_dummy(client->adapter, 0x34);
+ priv->dpms = DRM_MODE_DPMS_OFF;
diff --git a/patches/linux-3.8.13/0591-WIP-of-new-tda998x-patches.patch b/patches/linux-3.8.13/0591-WIP-of-new-tda998x-patches.patch
new file mode 100644
index 0000000..990f0b0
--- /dev/null
+++ b/patches/linux-3.8.13/0591-WIP-of-new-tda998x-patches.patch
@@ -0,0 +1,808 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 5 Jun 2013 19:52:25 +0300
+Subject: [PATCH] WIP of new tda998x patches.
+
+Video works, but no audio. RMK uses SPDIF so I2S is missing various bits.
+With the tilcdc driver the some non CEC modes are shifted too.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/gpu/drm/i2c/tda998x_drv.c | 574 ++++++++++++++++++++++++++-----------
+ include/drm/i2c/tda998x.h | 21 +-
+ 2 files changed, 419 insertions(+), 176 deletions(-)
+
+diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
+index 49e5d98..2049898 100644
+--- a/drivers/gpu/drm/i2c/tda998x_drv.c
++++ b/drivers/gpu/drm/i2c/tda998x_drv.c
+@@ -25,6 +25,8 @@
+ #include <drm/drm_edid.h>
+ #include <linux/hdmi.h>
+
++#include <drm/i2c/tda998x.h>
++
+ #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
+
+ struct tda998x_priv {
+@@ -32,9 +34,11 @@ struct tda998x_priv {
+ uint16_t rev;
+ uint8_t current_page;
+ int dpms;
++ bool is_hdmi_sink;
+ u8 vip_cntrl_0;
+ u8 vip_cntrl_1;
+ u8 vip_cntrl_2;
++ struct tda998x_encoder_params params;
+ };
+
+ #define to_tda998x_priv(x) ((struct tda998x_priv *)to_encoder_slave(x)->slave_priv)
+@@ -71,10 +75,13 @@ struct tda998x_priv {
+ # define I2C_MASTER_DIS_MM (1 << 0)
+ # define I2C_MASTER_DIS_FILT (1 << 1)
+ # define I2C_MASTER_APP_STRT_LAT (1 << 2)
++#define REG_FEAT_POWERDOWN REG(0x00, 0x0e) /* read/write */
++# define FEAT_POWERDOWN_SPDIF (1 << 3)
+ #define REG_INT_FLAGS_0 REG(0x00, 0x0f) /* read/write */
+ #define REG_INT_FLAGS_1 REG(0x00, 0x10) /* read/write */
+ #define REG_INT_FLAGS_2 REG(0x00, 0x11) /* read/write */
+ # define INT_FLAGS_2_EDID_BLK_RD (1 << 1)
++#define REG_ENA_ACLK REG(0x00, 0x16) /* read/write */
+ #define REG_ENA_VP_0 REG(0x00, 0x18) /* read/write */
+ #define REG_ENA_VP_1 REG(0x00, 0x19) /* read/write */
+ #define REG_ENA_VP_2 REG(0x00, 0x1a) /* read/write */
+@@ -113,10 +120,8 @@ struct tda998x_priv {
+ #define REG_VIP_CNTRL_5 REG(0x00, 0x25) /* write */
+ # define VIP_CNTRL_5_CKCASE (1 << 0)
+ # define VIP_CNTRL_5_SP_CNT(x) (((x) & 3) << 1)
++#define REG_MUX_AP REG(0x00, 0x26) /* read/write */
+ #define REG_MUX_VP_VIP_OUT REG(0x00, 0x27) /* read/write */
+-
+-#define REG_MUX_AP REG(0x00, 0x26)
+-# define MUX_AP_SELECT_I2S (0x64)
+ #define REG_MAT_CONTRL REG(0x00, 0x80) /* write */
+ # define MAT_CONTRL_MAT_SC(x) (((x) & 3) << 0)
+ # define MAT_CONTRL_MAT_BP (1 << 2)
+@@ -178,10 +183,13 @@ struct tda998x_priv {
+ # define HVF_CNTRL_1_PAD(x) (((x) & 3) << 4)
+ # define HVF_CNTRL_1_SEMI_PLANAR (1 << 6)
+ #define REG_RPT_CNTRL REG(0x00, 0xf0) /* write */
+-#define REG_I2S_FORMAT REG(0x00, 0xfc)
++#define REG_I2S_FORMAT REG(0x00, 0xfc) /* read/write */
++# define I2S_FORMAT(x) (((x) & 3) << 0)
++#define REG_AIP_CLKSEL REG(0x00, 0xfd) /* write */
++# define AIP_CLKSEL_FS(x) (((x) & 3) << 0)
++# define AIP_CLKSEL_CLK_POL(x) (((x) & 1) << 2)
++# define AIP_CLKSEL_AIP(x) (((x) & 7) << 3)
+
+-#define REG_AIP_CLKSEL REG(0x00, 0xfd)
+-# define SEL_AIP_I2S (1 << 3) /* I2S Clk */
+
+ /* Page 02h: PLL settings */
+ #define REG_PLL_SERIAL_1 REG(0x02, 0x00) /* read/write */
+@@ -222,8 +230,12 @@ struct tda998x_priv {
+
+
+ /* Page 10h: information frames and packets */
+-#define REG_AVI_IF REG(0x10, 0x40) /* AVI Infoframe packet */
+-#define REG_AUDIO_IF REG(0x10, 0x80) /* AVI Infoframe packet */
++#define REG_IF1_HB0 REG(0x10, 0x20) /* read/write */
++#define REG_IF2_HB0 REG(0x10, 0x40) /* read/write */
++#define REG_IF3_HB0 REG(0x10, 0x60) /* read/write */
++#define REG_IF4_HB0 REG(0x10, 0x80) /* read/write */
++#define REG_IF5_HB0 REG(0x10, 0xa0) /* read/write */
++
+
+ /* Page 11h: audio settings and content info packets */
+ #define REG_AIP_CNTRL_0 REG(0x11, 0x00) /* read/write */
+@@ -232,28 +244,34 @@ struct tda998x_priv {
+ # define AIP_CNTRL_0_LAYOUT (1 << 2)
+ # define AIP_CNTRL_0_ACR_MAN (1 << 5)
+ # define AIP_CNTRL_0_RST_CTS (1 << 6)
+-#define REG_ACR_CTS_0 REG(0x11, 0x05)
+-#define REG_ACR_CTS_1 REG(0x11, 0x06)
+-#define REG_ACR_CTS_2 REG(0x11, 0x07)
+-#define REG_ACR_N_0 REG(0x11, 0x08)
+-#define REG_ACR_N_1 REG(0x11, 0x09)
+-#define REG_ACR_N_2 REG(0x11, 0x0a)
+-#define REG_GC_AVMUTE REG(0x11, 0x0b)
+-# define GC_AVMUTE_CLRMUTE (1 << 0)
+-# define GC_AVMUTE_SETMUTE (1 << 1)
+-#define REG_CTS_N REG(0x11, 0x0c)
++#define REG_CA_I2S REG(0x11, 0x01) /* read/write */
++# define CA_I2S_CA_I2S(x) (((x) & 31) << 0)
++# define CA_I2S_HBR_CHSTAT (1 << 6)
++#define REG_LATENCY_RD REG(0x11, 0x04) /* read/write */
++#define REG_ACR_CTS_0 REG(0x11, 0x05) /* read/write */
++#define REG_ACR_CTS_1 REG(0x11, 0x06) /* read/write */
++#define REG_ACR_CTS_2 REG(0x11, 0x07) /* read/write */
++#define REG_ACR_N_0 REG(0x11, 0x08) /* read/write */
++#define REG_ACR_N_1 REG(0x11, 0x09) /* read/write */
++#define REG_ACR_N_2 REG(0x11, 0x0a) /* read/write */
++#define REG_CTS_N REG(0x11, 0x0c) /* read/write */
++# define CTS_N_K(x) (((x) & 7) << 0)
++# define CTS_N_M(x) (((x) & 3) << 4)
+ #define REG_ENC_CNTRL REG(0x11, 0x0d) /* read/write */
+ # define ENC_CNTRL_RST_ENC (1 << 0)
+ # define ENC_CNTRL_RST_SEL (1 << 1)
+ # define ENC_CNTRL_CTL_CODE(x) (((x) & 3) << 2)
+-#define REG_DIP_FLAGS REG(0x11, 0x0e)
++#define REG_DIP_FLAGS REG(0x11, 0x0e) /* read/write */
+ # define DIP_FLAGS_ACR (1 << 0)
++# define DIP_FLAGS_GC (1 << 1)
+ #define REG_DIP_IF_FLAGS REG(0x11, 0x0f) /* read/write */
+-#define DIP_IF_FLAGS_IF1 (1 << 1)
+-#define DIP_IF_FLAGS_IF2 (1 << 2)
+-#define DIP_IF_FLAGS_IF3 (1 << 3)
+-#define DIP_IF_FLAGS_IF4 (1 << 4)
+-#define DIP_IF_FLAGS_IF5 (1 << 5)
++# define DIP_IF_FLAGS_IF1 (1 << 1)
++# define DIP_IF_FLAGS_IF2 (1 << 2)
++# define DIP_IF_FLAGS_IF3 (1 << 3)
++# define DIP_IF_FLAGS_IF4 (1 << 4)
++# define DIP_IF_FLAGS_IF5 (1 << 5)
++#define REG_CH_STAT_B(x) REG(0x11, 0x14 + (x)) /* read/write */
++
+
+ /* Page 12h: HDCP and OTP */
+ #define REG_TX3 REG(0x12, 0x9a) /* read/write */
+@@ -292,9 +310,6 @@ struct tda998x_priv {
+ #define TDA19989N2 0x0202
+ #define TDA19988 0x0301
+
+-static uint8_t *
+-do_get_edid(struct drm_encoder *encoder);
+-
+ static void
+ cec_write(struct drm_encoder *encoder, uint16_t addr, uint8_t val)
+ {
+@@ -477,11 +492,257 @@ tda998x_reset(struct drm_encoder *encoder)
+ reg_write(encoder, REG_PLL_SCG2, 0x10);
+ }
+
++static uint8_t tda998x_cksum(uint8_t *buf, size_t bytes)
++{
++ uint8_t sum = 0;
++
++ while (bytes--)
++ sum += *buf++;
++ return (255 - sum) + 1;
++}
++
++#define HB(x) (x)
++#define PB(x) (HB(2) + 1 + (x))
++
++static void
++tda998x_write_if(struct drm_encoder *encoder, uint8_t bit, uint16_t addr,
++ uint8_t *buf, size_t size)
++{
++ buf[PB(0)] = tda998x_cksum(buf, size);
++
++ reg_clear(encoder, REG_DIP_IF_FLAGS, bit);
++ reg_write_range(encoder, addr, buf, size);
++ reg_set(encoder, REG_DIP_IF_FLAGS, bit);
++}
++
++static void
++tda998x_write_aif(struct drm_encoder *encoder, struct tda998x_encoder_params *p)
++{
++ uint8_t buf[PB(5) + 1];
++
++ buf[HB(0)] = 0x84;
++ buf[HB(1)] = 0x01;
++ buf[HB(2)] = 10;
++ buf[PB(0)] = 0;
++ buf[PB(1)] = p->audio_frame[1] & 0x07; /* CC */
++ buf[PB(2)] = p->audio_frame[2] & 0x1c; /* SF */
++ buf[PB(4)] = p->audio_frame[4];
++ buf[PB(5)] = p->audio_frame[5] & 0xf8; /* DM_INH + LSV */
++
++ tda998x_write_if(encoder, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf,
++ sizeof(buf));
++}
++
++static void
++tda998x_write_avi(struct drm_encoder *encoder, struct drm_display_mode *mode)
++{
++ uint8_t buf[PB(13) + 1];
++
++ memset(buf, 0, sizeof(buf));
++ buf[HB(0)] = 0x82;
++ buf[HB(1)] = 0x02;
++ buf[HB(2)] = 13;
++ buf[PB(4)] = drm_match_cea_mode(mode);
++
++ tda998x_write_if(encoder, DIP_IF_FLAGS_IF2, REG_IF2_HB0, buf,
++ sizeof(buf));
++}
++
++static void tda998x_audio_mute(struct drm_encoder *encoder, bool on)
++{
++ if (on) {
++ reg_set(encoder, REG_SOFTRESET, SOFTRESET_AUDIO);
++ reg_clear(encoder, REG_SOFTRESET, SOFTRESET_AUDIO);
++ reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO);
++ } else {
++ reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO);
++ }
++}
++
++static void
++tda998x_configure_audio(struct drm_encoder *encoder, struct tda998x_encoder_params *p)
++{
++ uint8_t buf[6], clksel_aip = 0, clksel_fs = 0, ca_i2s, cts_n;
++ uint32_t n;
++
++ /* SetAudioPortConfig */
++ reg_write(encoder, REG_ENA_AP, p->audio_cfg);
++ /* SetAudioClockPortConfig */
++ reg_write(encoder, REG_ENA_ACLK, p->audio_clk_cfg);
++
++ /*
++ * layout = channelAllocation ? 1 : 0;
++ * AudioInSetConfig(format, i2sFormat, channelAllocation,
++ * HDMITX_CHAN_NO_CHANGE, HDMITX_CLKPOLDSD_NO_CHANGE,
++ * HDMITX_SWAPDSD_NO_CHANGE, layout, HDMITX_LATENCY_CURRENT,
++ * dstRate)
++ */
++ switch (p->audio_format) {
++ case AFMT_SPDIF:
++ reg_write(encoder, REG_MUX_AP, 0x40);
++ clksel_aip = AIP_CLKSEL_AIP(0);
++ /* FS64SPDIF */
++ clksel_fs = AIP_CLKSEL_FS(2);
++ cts_n = CTS_N_M(3) | CTS_N_K(3);
++ ca_i2s = 0;
++ break;
++
++ case AFMT_I2S:
++ reg_write(encoder, REG_MUX_AP, 0x64);
++ clksel_aip = AIP_CLKSEL_AIP(1);
++ /* ACLK */
++ clksel_fs = AIP_CLKSEL_FS(0);
++ cts_n = CTS_N_M(3) | CTS_N_K(3);
++ ca_i2s = CA_I2S_CA_I2S(0 /* channel allocation */);
++ break;
++ }
++
++ reg_write(encoder, REG_AIP_CLKSEL, clksel_aip);
++ if (p->audio_format == AFMT_I2S) {
++ reg_write(encoder, REG_CA_I2S, ca_i2s);
++ reg_write(encoder, REG_I2S_FORMAT, p->i2s_fmt);
++ }
++ reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_LAYOUT);
++ /* latency? */
++
++ /* get video format */
++
++ /*
++ * ctsRef = HDMITX_CTSREF_FS64SPDIF, uCtsX = HDMITX_CTSX_64
++ * AudioInSetCts(ctsRef, rate, VidFmt, vOutFreq,
++ * HDMITX_CTS_AUTO, uCtsX, HDMITX_CTSK_USE_CTSX,
++ * HDMITX_CTSMTS_USE_CTSX, dstRate)
++ */
++ /* Auto CTS */
++ reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_ACR_MAN);
++ reg_write(encoder, REG_CTS_N, cts_n);
++ // reg_write(encoder, REG_AUDIO_DIV, 3);
++ reg_write(encoder, REG_AUDIO_DIV, 2);
++
++ /*
++ * This is the approximate value of N, which happens to be
++ * the recommended values for non-coherent clocks.
++ */
++ n = 128 * p->audio_sample_rate / 1000;
++
++ /* Write the CTS and N values */
++ buf[0] = 0x44;
++ buf[1] = 0x42;
++ buf[2] = 0x01;
++ buf[3] = n;
++ buf[4] = n >> 8;
++ buf[5] = n >> 16;
++ reg_write_range(encoder, REG_ACR_CTS_0, buf, 6);
++
++ /* Set CTS clock reference */
++ reg_write(encoder, REG_AIP_CLKSEL, clksel_aip | clksel_fs);
++
++ /* Reset CTS generator */
++ reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS);
++ reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS);
++
++ /* Write the channel status */
++ buf[0] = 0x04;
++ buf[1] = 0x00;
++ buf[2] = 0x00;
++ buf[3] = 0xf1;
++ reg_write_range(encoder, REG_CH_STAT_B(0), buf, 4);
++
++ tda998x_audio_mute(encoder, true);
++ mdelay(20);
++ tda998x_audio_mute(encoder, false);
++
++ /* Write the audio information packet */
++ tda998x_write_aif(encoder, p);
++}
++
++#if 0
++static struct tda998x_encoder_params default_params = {
++#if 0
++ /* This is with a post mux value of 0x12, which is what the nxp driver uses
++ VIP_MUX_G_B | VIP_MUX_B_R | VIP_MUX_R_G = 0x00 | 0x02 | 0x10
++ LCD out Pins VIP Int VP
++ R:7:0 VPC7:0 23:16 7:0[R]
++ G:15:8 VPB7:0 15:8 23:16[G]
++ B:23:16 VPA7:0 7:0 15:8[B]
++ */
++ .swap_a = 0,
++ .swap_b = 1,
++ .swap_c = 2,
++ .swap_d = 3,
++ .swap_e = 4,
++ .swap_f = 5,
++#else
++ /* With 0x24, there is no translation between vp_out and int_vp
++ FB LCD out Pins VIP Int Vp
++ R:23:16 R:7:0 VPC7:0 7:0 7:0[R]
++ G:15:8 G:15:8 VPB7:0 23:16 23:16[G]
++ B:7:0 B:23:16 VPA7:0 15:8 15:8[B]
++ */
++ .swap_a = 2,
++ .swap_b = 3,
++ .swap_c = 4,
++ .swap_d = 5,
++ .swap_e = 0,
++ .swap_f = 1,
++#endif
++ .audio_cfg = BIT(2),
++ .audio_frame[1] = 1,
++ .audio_format = AFMT_SPDIF,
++ .audio_sample_rate = 44100,
++};
++#else
++static struct tda998x_encoder_params default_params = {
++ .swap_a = 2,
++ .mirr_a = 0,
++ .swap_b = 3,
++ .mirr_b = 0,
++ .swap_c = 0,
++ .mirr_c = 0,
++ .swap_d = 1,
++ .mirr_d = 0,
++ .swap_e = 4,
++ .mirr_e = 0,
++ .swap_f = 5,
++ .mirr_f = 0,
++
++ .audio_cfg = 3, /* 2 channels i2s mode */
++ .audio_frame[1] = 1,
++ .audio_format = AFMT_I2S,
++ .audio_sample_rate = 44100,
++ .i2s_fmt = 0x0a,
++};
++#endif
++
+ /* DRM encoder functions */
+
+ static void
+ tda998x_encoder_set_config(struct drm_encoder *encoder, void *params)
+ {
++ struct tda998x_priv *priv = to_tda998x_priv(encoder);
++ struct tda998x_encoder_params *p = params;
++
++ dev_info(encoder->dev->dev, "%s\n", __func__);
++
++ p = &default_params;
++
++ priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(p->swap_a) |
++ (p->mirr_a ? VIP_CNTRL_0_MIRR_A : 0) |
++ VIP_CNTRL_0_SWAP_B(p->swap_b) |
++ (p->mirr_b ? VIP_CNTRL_0_MIRR_B : 0);
++ priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(p->swap_c) |
++ (p->mirr_c ? VIP_CNTRL_1_MIRR_C : 0) |
++ VIP_CNTRL_1_SWAP_D(p->swap_d) |
++ (p->mirr_d ? VIP_CNTRL_1_MIRR_D : 0);
++ priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(p->swap_e) |
++ (p->mirr_e ? VIP_CNTRL_2_MIRR_E : 0) |
++ VIP_CNTRL_2_SWAP_F(p->swap_f) |
++ (p->mirr_f ? VIP_CNTRL_2_MIRR_F : 0);
++
++ priv->params = *p;
++
++ if (p->audio_cfg)
++ tda998x_configure_audio(encoder, p);
+ }
+
+ static void
+@@ -501,7 +762,8 @@ tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
+ /* Write the default value MUX register */
+ reg_write(encoder, REG_MUX_VP_VIP_OUT, 0x24);
+ /* enable audio and video ports */
+- reg_write(encoder, REG_ENA_AP, 0x03);
++// reg_write(encoder, REG_ENA_AP, priv->ena_ap);
++// reg_write(encoder, REG_ENA_ACLK, priv->ena_aclk);
+ reg_write(encoder, REG_ENA_VP_0, 0xff);
+ reg_write(encoder, REG_ENA_VP_1, 0xff);
+ reg_write(encoder, REG_ENA_VP_2, 0xff);
+@@ -512,7 +774,7 @@ tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
+ break;
+ case DRM_MODE_DPMS_OFF:
+ /* disable audio and video ports */
+- reg_write(encoder, REG_ENA_AP, 0x00);
++// reg_write(encoder, REG_ENA_AP, 0x00);
+ reg_write(encoder, REG_ENA_VP_0, 0x00);
+ reg_write(encoder, REG_ENA_VP_1, 0x00);
+ reg_write(encoder, REG_ENA_VP_2, 0x00);
+@@ -537,99 +799,36 @@ tda998x_encoder_restore(struct drm_encoder *encoder)
+ static bool
+ tda998x_encoder_mode_fixup(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode,
+- struct drm_display_mode *adjusted_mode)
+-{
+- return true;
+-}
+-
+-static int
+-tda998x_encoder_mode_valid(struct drm_encoder *encoder,
+- struct drm_display_mode *mode)
+-{
+- return MODE_OK;
+-}
+-
+-
+-static void
+-tda998x_audio_infoframe_enable(struct drm_encoder *encoder)
++ struct drm_display_mode *adjusted)
+ {
+- uint8_t buffer[20];
+- struct hdmi_audio_infoframe audio_frame;
+- size_t len;
+-
+- hdmi_audio_infoframe_init(&audio_frame);
+-
+- /* NXP audio is fixed at these values for the time being */
+- audio_frame.channels = 2;
+- audio_frame.coding_type = HDMI_AUDIO_CODING_TYPE_PCM;
+- audio_frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_24;
+- audio_frame.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_48000;
++ DBG("");
+
+- len = hdmi_audio_infoframe_pack(&audio_frame, buffer, sizeof(buffer));
+- WARN(len < 0, "hdmi_avi_infoframe_pack failed\n");
++ adjusted->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC |
++ DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC |
++ DRM_MODE_FLAG_PCSYNC | DRM_MODE_FLAG_NCSYNC);
+
+- reg_write_range(encoder, REG_AUDIO_IF, buffer, len);
++ /* The TDA19988 always requires negative VSYNC? */
++ adjusted->flags |= DRM_MODE_FLAG_NVSYNC;
+
+- /* enable Audio Infoframe output in DIP_IF Register */
+- reg_clear(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF4);
+- udelay(5);
+- reg_set(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF4);
+-}
++ /* The TDA19988 requires positive HSYNC on 1080p or 720p */
++ if ((adjusted->hdisplay == 1920 && adjusted->vdisplay == 1080) ||
++ (adjusted->hdisplay == 1280 && adjusted->vdisplay == 720))
++ adjusted->flags |= DRM_MODE_FLAG_PHSYNC;
++ else
++ adjusted->flags |= DRM_MODE_FLAG_NHSYNC;
+
+-static void
+-tda998x_avi_infoframe_enable(struct drm_encoder *encoder,
+- struct drm_display_mode *mode)
+-{
+- uint8_t buffer[20];
+- struct hdmi_avi_infoframe avi_frame;
+- size_t len;
+-
+- hdmi_avi_infoframe_init(&avi_frame);
+- avi_frame.video_code = drm_match_cea_mode(mode);
+- avi_frame.picture_aspect = HDMI_PICTURE_ASPECT_NONE;
+- avi_frame.active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
+- len = hdmi_avi_infoframe_pack(&avi_frame, buffer, sizeof(buffer));
+- WARN(len < 0, "hdmi_avi_infoframe_pack failed\n");
+-
+- reg_write_range(encoder, REG_AVI_IF, buffer, len);
+-
+- /*
+- * enable AVI Infoframe output in DIP_IF Register, but toggle it
+- * so that the hardware acknowledges that the packet data might have
+- * changed
+- */
+- reg_clear(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF2);
+- udelay(5);
+- reg_set(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF2);
++ return true;
+ }
+
+-/* lookup table for CEA values to VIDFORMAT values taken from NXP datasheet */
+-static char cea_to_nxp_mode[34] = {-1, 0, 1, 1, 2, 3, 4, 4, 5, 5, -1, -1,
+- -1, -1, -1, -1, 6, 7, 7, 8, 9, 10, 10,
+- 11, 11, -1, -1, -1, -1, -1, -1, 12, 13};
+-
+-static char tda998x_cea_to_vidformat(unsigned char cea_mode)
++static int
++tda998x_encoder_mode_valid(struct drm_encoder *encoder,
++ struct drm_display_mode *mode)
+ {
+- if(cea_mode > (sizeof(cea_to_nxp_mode) -1) ) {
+- return -1;
+- }
+- return cea_to_nxp_mode[cea_mode];
+-}
++ DBG("");
+
+-static char tda998x_is_monitor_hdmi(struct drm_encoder *encoder)
+-{
+- struct edid *edid = (struct edid *)do_get_edid(encoder);
+- char hdmi = 0;
+- if(edid) {
+- hdmi = drm_detect_hdmi_monitor(edid);
+- kfree(edid);
+- } else {
+- return -1;
+- }
+- return hdmi;
++ return MODE_OK;
+ }
+
+-
+ static void
+ tda998x_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+@@ -676,7 +875,7 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder,
+ /* mute the audio FIFO: */
+ reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO);
+
+- /* HDMI/HDCP mode off... for now...: */
++ /* set HDMI HDCP mode off: */
+ reg_set(encoder, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS);
+ reg_clear(encoder, REG_TX33, TX33_HDMI);
+
+@@ -744,69 +943,29 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder,
+ reg_write16(encoder, REG_REFPIX_MSB, ref_pix);
+ reg_write16(encoder, REG_REFLINE_MSB, ref_line);
+
+- reg = TBG_CNTRL_1_VHX_EXT_DE |
+- TBG_CNTRL_1_VHX_EXT_HS |
+- TBG_CNTRL_1_VHX_EXT_VS |
+- TBG_CNTRL_1_DWIN_DIS | /* HDCP off */
++ reg = TBG_CNTRL_1_DWIN_DIS | /* HDCP off */
+ TBG_CNTRL_1_VH_TGL_2;
++ /*
++ * It is questionable whether this is correct - the nxp driver
++ * does not set VH_TGL_2 and the below for all display modes.
++ */
+ if (mode->flags & (DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC))
+ reg |= TBG_CNTRL_1_VH_TGL_0;
+ reg_set(encoder, REG_TBG_CNTRL_1, reg);
+
+-
+-
+-
+- if(tda998x_is_monitor_hdmi(encoder) == 1) {
+- char vidformat;
+- vidformat = tda998x_cea_to_vidformat(drm_match_cea_mode(mode));
+- if(vidformat == (char)-1) {
+- dev_err(encoder->dev->dev, "Not sure which CEA mode to set, leaving as DVI");
+- goto out;
+- }
+- dev_info(encoder->dev->dev, "Connected to an HDMI monitor with cea mode %d", vidformat);
+-
+- /* this is an HDMI monitor, so set things up a bit differently */
+- reg_write(encoder, REG_TBG_CNTRL_1, 0);
+- reg_write(encoder, REG_VIDFORMAT, vidformat);
+- /* get the infoframes pumping */
+- tda998x_avi_infoframe_enable(encoder, mode);
+- tda998x_audio_infoframe_enable(encoder);
++ /* Only setup the info frames if the sink is HDMI */
++ if (priv->is_hdmi_sink) {
++ /* We need to turn HDMI HDCP stuff on to get audio through */
++ reg_clear(encoder, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS);
++ reg_write(encoder, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(1));
+ reg_set(encoder, REG_TX33, TX33_HDMI);
+
+- /* set up audio registers */
+- reg_write(encoder, REG_ACR_CTS_0, 0x0);
+- reg_write(encoder, REG_ACR_CTS_1, 0x0);
+- reg_write(encoder, REG_ACR_CTS_2, 0x0);
+-
+- reg_write(encoder, REG_ACR_N_0, 0x0);
+- reg_write(encoder, REG_ACR_N_1, 0x18);
+- reg_write(encoder, REG_ACR_N_2, 0x0);
++ tda998x_write_avi(encoder, adjusted_mode);
+
+- reg_set(encoder, REG_DIP_FLAGS, DIP_FLAGS_ACR);
+-
+- reg_write(encoder, REG_ENC_CNTRL, 0x04);
+- reg_write(encoder, REG_CTS_N, 0x33);
+- /* Set 2 channel I2S mode */
+- reg_write(encoder, REG_ENA_AP, 0x3);
+-
+- /* set audio divider in pll settings */
+- reg_write(encoder, REG_AUDIO_DIV, 0x2);
+-
+- /* select the audio input port clock */
+- reg_write(encoder, REG_AIP_CLKSEL, SEL_AIP_I2S);
+- reg_write(encoder, REG_MUX_AP, MUX_AP_SELECT_I2S);
+-
+- /* select I2S format, and datasize */
+- reg_write(encoder, REG_I2S_FORMAT, 0x0a);
+-
+- /* enable the audio FIFO: */
+- reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO);
+-
+- /* mute and then unmute, to get audio going */
+- reg_write(encoder, REG_GC_AVMUTE, GC_AVMUTE_SETMUTE);
+- reg_write(encoder, REG_GC_AVMUTE, GC_AVMUTE_CLRMUTE);
++ if (priv->params.audio_cfg)
++ tda998x_configure_audio(encoder, &priv->params);
+ }
+-out:
++
+ /* must be last register set: */
+ reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_ONCE);
+
+@@ -935,12 +1094,14 @@ static int
+ tda998x_encoder_get_modes(struct drm_encoder *encoder,
+ struct drm_connector *connector)
+ {
++ struct tda998x_priv *priv = to_tda998x_priv(encoder);
+ struct edid *edid = (struct edid *)do_get_edid(encoder);
+ int n = 0;
+
+ if (edid) {
+ drm_mode_connector_update_edid_property(connector, edid);
+ n = drm_add_edid_modes(connector, edid);
++ priv->is_hdmi_sink = drm_detect_hdmi_monitor(edid);
+ kfree(edid);
+ }
+
+@@ -1002,6 +1163,59 @@ tda998x_remove(struct i2c_client *client)
+ return 0;
+ }
+
++static ssize_t i2c_read_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
++{
++ struct drm_encoder *encoder = dev_get_drvdata(dev);
++ unsigned int page, addr;
++ unsigned char val;
++
++ sscanf(buf, "%x %x", &page, &addr);
++
++ val = reg_read(encoder, REG(page, addr));
++
++ printk("i2c read %02x @ page:%02x address:%02x\n", val, page, addr);
++ return size;
++}
++
++static ssize_t i2c_write_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
++{
++ struct drm_encoder *encoder = dev_get_drvdata(dev);
++ unsigned int page, addr, mask, val;
++ unsigned char rval;
++
++ sscanf(buf, "%x %x %x %x", &page, &addr, &mask, &val);
++
++ rval = reg_read(encoder, REG(page, addr));
++ rval &= ~mask;
++ rval |= val & mask;
++ reg_write(encoder, REG(page, addr), rval);
++
++ printk("i2c write %02x @ page:%02x address:%02x\n", rval, page, addr);
++ return size;
++}
++
++static ssize_t i2c_dump_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
++{
++ struct drm_encoder *encoder = dev_get_drvdata(dev);
++ unsigned int page;
++ char prefix[16];
++ uint8_t tmp[255];
++
++ sscanf(buf, "%x", &page);
++
++ reg_read_range(encoder, REG(page, 0), tmp, 254);
++
++ snprintf(prefix, sizeof(prefix) - 1, "PG-%02x ", page);
++
++ print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET, 16, 1, tmp, 254, false);
++
++ return size;
++}
++
++static DEVICE_ATTR(i2c_read, S_IWUSR, NULL, i2c_read_store);
++static DEVICE_ATTR(i2c_write, S_IWUSR, NULL, i2c_write_store);
++static DEVICE_ATTR(i2c_dump, S_IWUSR, NULL, i2c_dump_store);
++
+ static int
+ tda998x_encoder_init(struct i2c_client *client,
+ struct drm_device *dev,
+@@ -1009,14 +1223,41 @@ tda998x_encoder_init(struct i2c_client *client,
+ {
+ struct drm_encoder *encoder = &encoder_slave->base;
+ struct tda998x_priv *priv;
++ struct tda998x_encoder_params *p;
++
++/* debug */
++ device_create_file(&client->dev, &dev_attr_i2c_read);
++ device_create_file(&client->dev, &dev_attr_i2c_write);
++ device_create_file(&client->dev, &dev_attr_i2c_dump);
++ dev_set_drvdata(&client->dev, encoder);
++/* debug end */
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
++ p = &priv->params;
++#if 0
+ priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3);
+ priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1);
+ priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5);
++#else
++
++ *p = default_params;
++
++ priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(p->swap_a) |
++ (p->mirr_a ? VIP_CNTRL_0_MIRR_A : 0) |
++ VIP_CNTRL_0_SWAP_B(p->swap_b) |
++ (p->mirr_b ? VIP_CNTRL_0_MIRR_B : 0);
++ priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(p->swap_c) |
++ (p->mirr_c ? VIP_CNTRL_1_MIRR_C : 0) |
++ VIP_CNTRL_1_SWAP_D(p->swap_d) |
++ (p->mirr_d ? VIP_CNTRL_1_MIRR_D : 0);
++ priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(p->swap_e) |
++ (p->mirr_e ? VIP_CNTRL_2_MIRR_E : 0) |
++ VIP_CNTRL_2_SWAP_F(p->swap_f) |
++ (p->mirr_f ? VIP_CNTRL_2_MIRR_F : 0);
++#endif
+
+ priv->current_page = 0;
+ priv->cec = i2c_new_dummy(client->adapter, 0x34);
+@@ -1115,4 +1356,3 @@ MODULE_LICENSE("GPL");
+
+ module_init(tda998x_init);
+ module_exit(tda998x_exit);
+-
+diff --git a/include/drm/i2c/tda998x.h b/include/drm/i2c/tda998x.h
+index 41f799f..23736f1 100644
+--- a/include/drm/i2c/tda998x.h
++++ b/include/drm/i2c/tda998x.h
+@@ -1,23 +1,26 @@
+ #ifndef __TDA998X_H__
+ #define __TDA998X_H__
+
++#include <linux/types.h>
++
+ enum tda998x_audio_format {
+ AFMT_I2S,
+ AFMT_SPDIF,
+ };
+
+ struct tda998x_encoder_params {
+- int audio_cfg;
+- int audio_clk_cfg;
++ uint8_t audio_cfg;
++ uint8_t audio_clk_cfg;
+ enum tda998x_audio_format audio_format;
+ int audio_sample_rate;
+- char audio_frame[6];
+- int swap_a, mirr_a;
+- int swap_b, mirr_b;
+- int swap_c, mirr_c;
+- int swap_d, mirr_d;
+- int swap_e, mirr_e;
+- int swap_f, mirr_f;
++ uint8_t audio_frame[6];
++ uint8_t swap_a, mirr_a;
++ uint8_t swap_b, mirr_b;
++ uint8_t swap_c, mirr_c;
++ uint8_t swap_d, mirr_d;
++ uint8_t swap_e, mirr_e;
++ uint8_t swap_f, mirr_f;
++ uint8_t i2s_fmt;
+ };
+
+ #endif
diff --git a/patches/linux-3.8.13/0592-tilcdc-Slave-panel-settings-read-from-DT-now.patch b/patches/linux-3.8.13/0592-tilcdc-Slave-panel-settings-read-from-DT-now.patch
new file mode 100644
index 0000000..75110ff
--- /dev/null
+++ b/patches/linux-3.8.13/0592-tilcdc-Slave-panel-settings-read-from-DT-now.patch
@@ -0,0 +1,221 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 6 Jun 2013 11:45:28 +0300
+Subject: [PATCH] tilcdc: Slave panel settings read from DT now
+
+Turns out that we really need those panel settings.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 56 +++++++++++++++++++++++++++++++++
+ drivers/gpu/drm/tilcdc/tilcdc_drv.h | 3 ++
+ drivers/gpu/drm/tilcdc/tilcdc_panel.c | 49 +----------------------------
+ drivers/gpu/drm/tilcdc/tilcdc_slave.c | 25 +++++++--------
+ 4 files changed, 71 insertions(+), 62 deletions(-)
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+index 8ce18ca..023092f 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+@@ -721,3 +721,59 @@ fail:
+ tilcdc_crtc_destroy(crtc);
+ return NULL;
+ }
++
++struct tilcdc_panel_info *tilcdc_of_get_panel_info(struct device_node *np)
++{
++ struct device_node *info_np;
++ struct tilcdc_panel_info *info;
++ int ret = 0;
++
++ if (!np)
++ return NULL;
++
++ info_np = of_get_child_by_name(np, "panel-info");
++ if (!info_np) {
++ pr_err("%s: could not find panel-info node\n",
++ of_node_full_name(np));
++ return NULL;
++ }
++
++ info = kzalloc(sizeof(*info), GFP_KERNEL);
++ if (!info) {
++ pr_err("%s: allocation failed\n",
++ of_node_full_name(np));
++ goto err_no_mem;
++ }
++
++ ret |= of_property_read_u32(info_np, "ac-bias", &info->ac_bias);
++ ret |= of_property_read_u32(info_np, "ac-bias-intrpt", &info->ac_bias_intrpt);
++ ret |= of_property_read_u32(info_np, "dma-burst-sz", &info->dma_burst_sz);
++ ret |= of_property_read_u32(info_np, "bpp", &info->bpp);
++ ret |= of_property_read_u32(info_np, "fdd", &info->fdd);
++ ret |= of_property_read_u32(info_np, "sync-edge", &info->sync_edge);
++ ret |= of_property_read_u32(info_np, "sync-ctrl", &info->sync_ctrl);
++ ret |= of_property_read_u32(info_np, "raster-order", &info->raster_order);
++ ret |= of_property_read_u32(info_np, "fifo-th", &info->fifo_th);
++
++ /* optional: */
++ info->tft_alt_mode = of_property_read_bool(info_np, "tft-alt-mode");
++ info->invert_pxl_clk = of_property_read_bool(info_np, "invert-pxl-clk");
++
++ if (ret) {
++ pr_err("%s: error reading panel-info properties\n",
++ of_node_full_name(info_np));
++ goto err_bad_prop;
++ }
++
++ /* release ref */
++ of_node_put(info_np);
++
++ return info;
++
++err_bad_prop:
++ kfree(info);
++err_no_mem:
++ of_node_put(info_np);
++ return NULL;
++}
++
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+index f3861e4..40ff5d4 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
++++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+@@ -169,4 +169,7 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ int rb_check, int audio, struct edid *edid);
+ int tilcdc_crtc_max_width(struct drm_crtc *crtc);
+
++/* OF helper for reading panel info */
++struct tilcdc_panel_info *tilcdc_of_get_panel_info(struct device_node *np);
++
+ #endif /* __TILCDC_DRV_H__ */
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+index 90bc0e3..2aa4a2e 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+@@ -308,53 +308,6 @@ static const struct tilcdc_module_ops panel_module_ops = {
+ * Device:
+ */
+
+-/* maybe move this somewhere common if it is needed by other outputs? */
+-static struct tilcdc_panel_info * of_get_panel_info(struct device_node *np)
+-{
+- struct device_node *info_np;
+- struct tilcdc_panel_info *info;
+- int ret = 0;
+-
+- if (!np) {
+- pr_err("%s: no devicenode given\n", __func__);
+- return NULL;
+- }
+-
+- info_np = of_get_child_by_name(np, "panel-info");
+- if (!info_np) {
+- pr_err("%s: could not find panel-info node\n", __func__);
+- return NULL;
+- }
+-
+- info = kzalloc(sizeof(*info), GFP_KERNEL);
+- if (!info) {
+- pr_err("%s: allocation failed\n", __func__);
+- return NULL;
+- }
+-
+- ret |= of_property_read_u32(info_np, "ac-bias", &info->ac_bias);
+- ret |= of_property_read_u32(info_np, "ac-bias-intrpt", &info->ac_bias_intrpt);
+- ret |= of_property_read_u32(info_np, "dma-burst-sz", &info->dma_burst_sz);
+- ret |= of_property_read_u32(info_np, "bpp", &info->bpp);
+- ret |= of_property_read_u32(info_np, "fdd", &info->fdd);
+- ret |= of_property_read_u32(info_np, "sync-edge", &info->sync_edge);
+- ret |= of_property_read_u32(info_np, "sync-ctrl", &info->sync_ctrl);
+- ret |= of_property_read_u32(info_np, "raster-order", &info->raster_order);
+- ret |= of_property_read_u32(info_np, "fifo-th", &info->fifo_th);
+-
+- /* optional: */
+- info->tft_alt_mode = of_property_read_bool(info_np, "tft-alt-mode");
+- info->invert_pxl_clk = of_property_read_bool(info_np, "invert-pxl-clk");
+-
+- if (ret) {
+- pr_err("%s: error reading panel-info properties\n", __func__);
+- kfree(info);
+- return NULL;
+- }
+-
+- return info;
+-}
+-
+ static struct of_device_id panel_of_match[];
+
+ static ssize_t pinmux_show_state(struct device *dev,
+@@ -495,7 +448,7 @@ static int panel_probe(struct platform_device *pdev)
+ goto fail;
+ }
+
+- panel_mod->info = of_get_panel_info(node);
++ panel_mod->info = tilcdc_of_get_panel_info(node);
+ if (!panel_mod->info) {
+ dev_err(&pdev->dev, "could not get panel info\n");
+ goto fail;
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave.c b/drivers/gpu/drm/tilcdc/tilcdc_slave.c
+index e454874..440de4e 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_slave.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_slave.c
+@@ -25,25 +25,13 @@
+
+ struct slave_module {
+ struct tilcdc_module base;
++ struct tilcdc_panel_info *info;
+ struct i2c_adapter *i2c;
+ struct pinctrl *pinctrl;
+ char *selected_state_name;
+ };
+ #define to_slave_module(x) container_of(x, struct slave_module, base)
+
+-static const struct tilcdc_panel_info slave_info = {
+- .bpp = 16,
+- .ac_bias = 255,
+- .ac_bias_intrpt = 0,
+- .dma_burst_sz = 16,
+- .fdd = 0x80,
+- .tft_alt_mode = 0,
+- .sync_edge = 0,
+- .sync_ctrl = 1,
+- .raster_order = 0,
+-};
+-
+-
+ /*
+ * Encoder:
+ */
+@@ -71,8 +59,10 @@ static void slave_encoder_destroy(struct drm_encoder *encoder)
+
+ static void slave_encoder_prepare(struct drm_encoder *encoder)
+ {
++ struct slave_encoder *slave_encoder = to_slave_encoder(encoder);
++
+ drm_i2c_encoder_prepare(encoder);
+- tilcdc_crtc_set_panel_info(encoder->crtc, &slave_info);
++ tilcdc_crtc_set_panel_info(encoder->crtc, slave_encoder->mod->info);
+ }
+
+ static const struct drm_encoder_funcs slave_encoder_funcs = {
+@@ -283,6 +273,7 @@ static void slave_destroy(struct tilcdc_module *mod)
+ struct slave_module *slave_mod = to_slave_module(mod);
+
+ tilcdc_module_cleanup(mod);
++ kfree(slave_mod->info);
+ kfree(slave_mod);
+ }
+
+@@ -446,6 +437,12 @@ static int slave_probe(struct platform_device *pdev)
+ goto fail;
+ }
+
++ slave_mod->info = tilcdc_of_get_panel_info(node);
++ if (!slave_mod->info) {
++ dev_err(&pdev->dev, "could not get panel info\n");
++ goto fail;
++ }
++
+ of_node_put(i2c_node);
+
+ return 0;
diff --git a/patches/linux-3.8.13/0593-drm-tda998x-Revert-WIP-to-previous-state.patch b/patches/linux-3.8.13/0593-drm-tda998x-Revert-WIP-to-previous-state.patch
new file mode 100644
index 0000000..e6d7285
--- /dev/null
+++ b/patches/linux-3.8.13/0593-drm-tda998x-Revert-WIP-to-previous-state.patch
@@ -0,0 +1,838 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 6 Jun 2013 22:25:45 +0300
+Subject: [PATCH] drm: tda998x: Revert WIP to previous state
+
+Revert all the changes of the WIP so that audio continues to work.
+We do it with an explicit patch so that we can revisit at a later
+time when things settled down.
+---
+ drivers/gpu/drm/i2c/tda998x_drv.c | 611 +++++++++++--------------------------
+ 1 file changed, 176 insertions(+), 435 deletions(-)
+
+diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
+index 2049898..412ba4f 100644
+--- a/drivers/gpu/drm/i2c/tda998x_drv.c
++++ b/drivers/gpu/drm/i2c/tda998x_drv.c
+@@ -25,8 +25,6 @@
+ #include <drm/drm_edid.h>
+ #include <linux/hdmi.h>
+
+-#include <drm/i2c/tda998x.h>
+-
+ #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
+
+ struct tda998x_priv {
+@@ -34,11 +32,6 @@ struct tda998x_priv {
+ uint16_t rev;
+ uint8_t current_page;
+ int dpms;
+- bool is_hdmi_sink;
+- u8 vip_cntrl_0;
+- u8 vip_cntrl_1;
+- u8 vip_cntrl_2;
+- struct tda998x_encoder_params params;
+ };
+
+ #define to_tda998x_priv(x) ((struct tda998x_priv *)to_encoder_slave(x)->slave_priv)
+@@ -75,13 +68,10 @@ struct tda998x_priv {
+ # define I2C_MASTER_DIS_MM (1 << 0)
+ # define I2C_MASTER_DIS_FILT (1 << 1)
+ # define I2C_MASTER_APP_STRT_LAT (1 << 2)
+-#define REG_FEAT_POWERDOWN REG(0x00, 0x0e) /* read/write */
+-# define FEAT_POWERDOWN_SPDIF (1 << 3)
+ #define REG_INT_FLAGS_0 REG(0x00, 0x0f) /* read/write */
+ #define REG_INT_FLAGS_1 REG(0x00, 0x10) /* read/write */
+ #define REG_INT_FLAGS_2 REG(0x00, 0x11) /* read/write */
+ # define INT_FLAGS_2_EDID_BLK_RD (1 << 1)
+-#define REG_ENA_ACLK REG(0x00, 0x16) /* read/write */
+ #define REG_ENA_VP_0 REG(0x00, 0x18) /* read/write */
+ #define REG_ENA_VP_1 REG(0x00, 0x19) /* read/write */
+ #define REG_ENA_VP_2 REG(0x00, 0x1a) /* read/write */
+@@ -120,8 +110,9 @@ struct tda998x_priv {
+ #define REG_VIP_CNTRL_5 REG(0x00, 0x25) /* write */
+ # define VIP_CNTRL_5_CKCASE (1 << 0)
+ # define VIP_CNTRL_5_SP_CNT(x) (((x) & 3) << 1)
+-#define REG_MUX_AP REG(0x00, 0x26) /* read/write */
+-#define REG_MUX_VP_VIP_OUT REG(0x00, 0x27) /* read/write */
++
++#define REG_MUX_AP REG(0x00, 0x26)
++# define MUX_AP_SELECT_I2S (0x64)
+ #define REG_MAT_CONTRL REG(0x00, 0x80) /* write */
+ # define MAT_CONTRL_MAT_SC(x) (((x) & 3) << 0)
+ # define MAT_CONTRL_MAT_BP (1 << 2)
+@@ -183,13 +174,10 @@ struct tda998x_priv {
+ # define HVF_CNTRL_1_PAD(x) (((x) & 3) << 4)
+ # define HVF_CNTRL_1_SEMI_PLANAR (1 << 6)
+ #define REG_RPT_CNTRL REG(0x00, 0xf0) /* write */
+-#define REG_I2S_FORMAT REG(0x00, 0xfc) /* read/write */
+-# define I2S_FORMAT(x) (((x) & 3) << 0)
+-#define REG_AIP_CLKSEL REG(0x00, 0xfd) /* write */
+-# define AIP_CLKSEL_FS(x) (((x) & 3) << 0)
+-# define AIP_CLKSEL_CLK_POL(x) (((x) & 1) << 2)
+-# define AIP_CLKSEL_AIP(x) (((x) & 7) << 3)
++#define REG_I2S_FORMAT REG(0x00, 0xfc)
+
++#define REG_AIP_CLKSEL REG(0x00, 0xfd)
++# define SEL_AIP_I2S (1 << 3) /* I2S Clk */
+
+ /* Page 02h: PLL settings */
+ #define REG_PLL_SERIAL_1 REG(0x02, 0x00) /* read/write */
+@@ -230,12 +218,8 @@ struct tda998x_priv {
+
+
+ /* Page 10h: information frames and packets */
+-#define REG_IF1_HB0 REG(0x10, 0x20) /* read/write */
+-#define REG_IF2_HB0 REG(0x10, 0x40) /* read/write */
+-#define REG_IF3_HB0 REG(0x10, 0x60) /* read/write */
+-#define REG_IF4_HB0 REG(0x10, 0x80) /* read/write */
+-#define REG_IF5_HB0 REG(0x10, 0xa0) /* read/write */
+-
++#define REG_AVI_IF REG(0x10, 0x40) /* AVI Infoframe packet */
++#define REG_AUDIO_IF REG(0x10, 0x80) /* AVI Infoframe packet */
+
+ /* Page 11h: audio settings and content info packets */
+ #define REG_AIP_CNTRL_0 REG(0x11, 0x00) /* read/write */
+@@ -244,39 +228,31 @@ struct tda998x_priv {
+ # define AIP_CNTRL_0_LAYOUT (1 << 2)
+ # define AIP_CNTRL_0_ACR_MAN (1 << 5)
+ # define AIP_CNTRL_0_RST_CTS (1 << 6)
+-#define REG_CA_I2S REG(0x11, 0x01) /* read/write */
+-# define CA_I2S_CA_I2S(x) (((x) & 31) << 0)
+-# define CA_I2S_HBR_CHSTAT (1 << 6)
+-#define REG_LATENCY_RD REG(0x11, 0x04) /* read/write */
+-#define REG_ACR_CTS_0 REG(0x11, 0x05) /* read/write */
+-#define REG_ACR_CTS_1 REG(0x11, 0x06) /* read/write */
+-#define REG_ACR_CTS_2 REG(0x11, 0x07) /* read/write */
+-#define REG_ACR_N_0 REG(0x11, 0x08) /* read/write */
+-#define REG_ACR_N_1 REG(0x11, 0x09) /* read/write */
+-#define REG_ACR_N_2 REG(0x11, 0x0a) /* read/write */
+-#define REG_CTS_N REG(0x11, 0x0c) /* read/write */
+-# define CTS_N_K(x) (((x) & 7) << 0)
+-# define CTS_N_M(x) (((x) & 3) << 4)
++#define REG_ACR_CTS_0 REG(0x11, 0x05)
++#define REG_ACR_CTS_1 REG(0x11, 0x06)
++#define REG_ACR_CTS_2 REG(0x11, 0x07)
++#define REG_ACR_N_0 REG(0x11, 0x08)
++#define REG_ACR_N_1 REG(0x11, 0x09)
++#define REG_ACR_N_2 REG(0x11, 0x0a)
++#define REG_GC_AVMUTE REG(0x11, 0x0b)
++# define GC_AVMUTE_CLRMUTE (1 << 0)
++# define GC_AVMUTE_SETMUTE (1 << 1)
++#define REG_CTS_N REG(0x11, 0x0c)
+ #define REG_ENC_CNTRL REG(0x11, 0x0d) /* read/write */
+ # define ENC_CNTRL_RST_ENC (1 << 0)
+ # define ENC_CNTRL_RST_SEL (1 << 1)
+ # define ENC_CNTRL_CTL_CODE(x) (((x) & 3) << 2)
+-#define REG_DIP_FLAGS REG(0x11, 0x0e) /* read/write */
++#define REG_DIP_FLAGS REG(0x11, 0x0e)
+ # define DIP_FLAGS_ACR (1 << 0)
+-# define DIP_FLAGS_GC (1 << 1)
+ #define REG_DIP_IF_FLAGS REG(0x11, 0x0f) /* read/write */
+-# define DIP_IF_FLAGS_IF1 (1 << 1)
+-# define DIP_IF_FLAGS_IF2 (1 << 2)
+-# define DIP_IF_FLAGS_IF3 (1 << 3)
+-# define DIP_IF_FLAGS_IF4 (1 << 4)
+-# define DIP_IF_FLAGS_IF5 (1 << 5)
+-#define REG_CH_STAT_B(x) REG(0x11, 0x14 + (x)) /* read/write */
+-
++#define DIP_IF_FLAGS_IF1 (1 << 1)
++#define DIP_IF_FLAGS_IF2 (1 << 2)
++#define DIP_IF_FLAGS_IF3 (1 << 3)
++#define DIP_IF_FLAGS_IF4 (1 << 4)
++#define DIP_IF_FLAGS_IF5 (1 << 5)
+
+ /* Page 12h: HDCP and OTP */
+ #define REG_TX3 REG(0x12, 0x9a) /* read/write */
+-#define REG_TX4 REG(0x12, 0x9b) /* read/write */
+-# define TX4_PD_RAM (1 << 1)
+ #define REG_TX33 REG(0x12, 0xb8) /* read/write */
+ # define TX33_HDMI (1 << 1)
+
+@@ -310,6 +286,9 @@ struct tda998x_priv {
+ #define TDA19989N2 0x0202
+ #define TDA19988 0x0301
+
++static uint8_t *
++do_get_edid(struct drm_encoder *encoder);
++
+ static void
+ cec_write(struct drm_encoder *encoder, uint16_t addr, uint8_t val)
+ {
+@@ -492,257 +471,11 @@ tda998x_reset(struct drm_encoder *encoder)
+ reg_write(encoder, REG_PLL_SCG2, 0x10);
+ }
+
+-static uint8_t tda998x_cksum(uint8_t *buf, size_t bytes)
+-{
+- uint8_t sum = 0;
+-
+- while (bytes--)
+- sum += *buf++;
+- return (255 - sum) + 1;
+-}
+-
+-#define HB(x) (x)
+-#define PB(x) (HB(2) + 1 + (x))
+-
+-static void
+-tda998x_write_if(struct drm_encoder *encoder, uint8_t bit, uint16_t addr,
+- uint8_t *buf, size_t size)
+-{
+- buf[PB(0)] = tda998x_cksum(buf, size);
+-
+- reg_clear(encoder, REG_DIP_IF_FLAGS, bit);
+- reg_write_range(encoder, addr, buf, size);
+- reg_set(encoder, REG_DIP_IF_FLAGS, bit);
+-}
+-
+-static void
+-tda998x_write_aif(struct drm_encoder *encoder, struct tda998x_encoder_params *p)
+-{
+- uint8_t buf[PB(5) + 1];
+-
+- buf[HB(0)] = 0x84;
+- buf[HB(1)] = 0x01;
+- buf[HB(2)] = 10;
+- buf[PB(0)] = 0;
+- buf[PB(1)] = p->audio_frame[1] & 0x07; /* CC */
+- buf[PB(2)] = p->audio_frame[2] & 0x1c; /* SF */
+- buf[PB(4)] = p->audio_frame[4];
+- buf[PB(5)] = p->audio_frame[5] & 0xf8; /* DM_INH + LSV */
+-
+- tda998x_write_if(encoder, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf,
+- sizeof(buf));
+-}
+-
+-static void
+-tda998x_write_avi(struct drm_encoder *encoder, struct drm_display_mode *mode)
+-{
+- uint8_t buf[PB(13) + 1];
+-
+- memset(buf, 0, sizeof(buf));
+- buf[HB(0)] = 0x82;
+- buf[HB(1)] = 0x02;
+- buf[HB(2)] = 13;
+- buf[PB(4)] = drm_match_cea_mode(mode);
+-
+- tda998x_write_if(encoder, DIP_IF_FLAGS_IF2, REG_IF2_HB0, buf,
+- sizeof(buf));
+-}
+-
+-static void tda998x_audio_mute(struct drm_encoder *encoder, bool on)
+-{
+- if (on) {
+- reg_set(encoder, REG_SOFTRESET, SOFTRESET_AUDIO);
+- reg_clear(encoder, REG_SOFTRESET, SOFTRESET_AUDIO);
+- reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO);
+- } else {
+- reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO);
+- }
+-}
+-
+-static void
+-tda998x_configure_audio(struct drm_encoder *encoder, struct tda998x_encoder_params *p)
+-{
+- uint8_t buf[6], clksel_aip = 0, clksel_fs = 0, ca_i2s, cts_n;
+- uint32_t n;
+-
+- /* SetAudioPortConfig */
+- reg_write(encoder, REG_ENA_AP, p->audio_cfg);
+- /* SetAudioClockPortConfig */
+- reg_write(encoder, REG_ENA_ACLK, p->audio_clk_cfg);
+-
+- /*
+- * layout = channelAllocation ? 1 : 0;
+- * AudioInSetConfig(format, i2sFormat, channelAllocation,
+- * HDMITX_CHAN_NO_CHANGE, HDMITX_CLKPOLDSD_NO_CHANGE,
+- * HDMITX_SWAPDSD_NO_CHANGE, layout, HDMITX_LATENCY_CURRENT,
+- * dstRate)
+- */
+- switch (p->audio_format) {
+- case AFMT_SPDIF:
+- reg_write(encoder, REG_MUX_AP, 0x40);
+- clksel_aip = AIP_CLKSEL_AIP(0);
+- /* FS64SPDIF */
+- clksel_fs = AIP_CLKSEL_FS(2);
+- cts_n = CTS_N_M(3) | CTS_N_K(3);
+- ca_i2s = 0;
+- break;
+-
+- case AFMT_I2S:
+- reg_write(encoder, REG_MUX_AP, 0x64);
+- clksel_aip = AIP_CLKSEL_AIP(1);
+- /* ACLK */
+- clksel_fs = AIP_CLKSEL_FS(0);
+- cts_n = CTS_N_M(3) | CTS_N_K(3);
+- ca_i2s = CA_I2S_CA_I2S(0 /* channel allocation */);
+- break;
+- }
+-
+- reg_write(encoder, REG_AIP_CLKSEL, clksel_aip);
+- if (p->audio_format == AFMT_I2S) {
+- reg_write(encoder, REG_CA_I2S, ca_i2s);
+- reg_write(encoder, REG_I2S_FORMAT, p->i2s_fmt);
+- }
+- reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_LAYOUT);
+- /* latency? */
+-
+- /* get video format */
+-
+- /*
+- * ctsRef = HDMITX_CTSREF_FS64SPDIF, uCtsX = HDMITX_CTSX_64
+- * AudioInSetCts(ctsRef, rate, VidFmt, vOutFreq,
+- * HDMITX_CTS_AUTO, uCtsX, HDMITX_CTSK_USE_CTSX,
+- * HDMITX_CTSMTS_USE_CTSX, dstRate)
+- */
+- /* Auto CTS */
+- reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_ACR_MAN);
+- reg_write(encoder, REG_CTS_N, cts_n);
+- // reg_write(encoder, REG_AUDIO_DIV, 3);
+- reg_write(encoder, REG_AUDIO_DIV, 2);
+-
+- /*
+- * This is the approximate value of N, which happens to be
+- * the recommended values for non-coherent clocks.
+- */
+- n = 128 * p->audio_sample_rate / 1000;
+-
+- /* Write the CTS and N values */
+- buf[0] = 0x44;
+- buf[1] = 0x42;
+- buf[2] = 0x01;
+- buf[3] = n;
+- buf[4] = n >> 8;
+- buf[5] = n >> 16;
+- reg_write_range(encoder, REG_ACR_CTS_0, buf, 6);
+-
+- /* Set CTS clock reference */
+- reg_write(encoder, REG_AIP_CLKSEL, clksel_aip | clksel_fs);
+-
+- /* Reset CTS generator */
+- reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS);
+- reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_CTS);
+-
+- /* Write the channel status */
+- buf[0] = 0x04;
+- buf[1] = 0x00;
+- buf[2] = 0x00;
+- buf[3] = 0xf1;
+- reg_write_range(encoder, REG_CH_STAT_B(0), buf, 4);
+-
+- tda998x_audio_mute(encoder, true);
+- mdelay(20);
+- tda998x_audio_mute(encoder, false);
+-
+- /* Write the audio information packet */
+- tda998x_write_aif(encoder, p);
+-}
+-
+-#if 0
+-static struct tda998x_encoder_params default_params = {
+-#if 0
+- /* This is with a post mux value of 0x12, which is what the nxp driver uses
+- VIP_MUX_G_B | VIP_MUX_B_R | VIP_MUX_R_G = 0x00 | 0x02 | 0x10
+- LCD out Pins VIP Int VP
+- R:7:0 VPC7:0 23:16 7:0[R]
+- G:15:8 VPB7:0 15:8 23:16[G]
+- B:23:16 VPA7:0 7:0 15:8[B]
+- */
+- .swap_a = 0,
+- .swap_b = 1,
+- .swap_c = 2,
+- .swap_d = 3,
+- .swap_e = 4,
+- .swap_f = 5,
+-#else
+- /* With 0x24, there is no translation between vp_out and int_vp
+- FB LCD out Pins VIP Int Vp
+- R:23:16 R:7:0 VPC7:0 7:0 7:0[R]
+- G:15:8 G:15:8 VPB7:0 23:16 23:16[G]
+- B:7:0 B:23:16 VPA7:0 15:8 15:8[B]
+- */
+- .swap_a = 2,
+- .swap_b = 3,
+- .swap_c = 4,
+- .swap_d = 5,
+- .swap_e = 0,
+- .swap_f = 1,
+-#endif
+- .audio_cfg = BIT(2),
+- .audio_frame[1] = 1,
+- .audio_format = AFMT_SPDIF,
+- .audio_sample_rate = 44100,
+-};
+-#else
+-static struct tda998x_encoder_params default_params = {
+- .swap_a = 2,
+- .mirr_a = 0,
+- .swap_b = 3,
+- .mirr_b = 0,
+- .swap_c = 0,
+- .mirr_c = 0,
+- .swap_d = 1,
+- .mirr_d = 0,
+- .swap_e = 4,
+- .mirr_e = 0,
+- .swap_f = 5,
+- .mirr_f = 0,
+-
+- .audio_cfg = 3, /* 2 channels i2s mode */
+- .audio_frame[1] = 1,
+- .audio_format = AFMT_I2S,
+- .audio_sample_rate = 44100,
+- .i2s_fmt = 0x0a,
+-};
+-#endif
+-
+ /* DRM encoder functions */
+
+ static void
+ tda998x_encoder_set_config(struct drm_encoder *encoder, void *params)
+ {
+- struct tda998x_priv *priv = to_tda998x_priv(encoder);
+- struct tda998x_encoder_params *p = params;
+-
+- dev_info(encoder->dev->dev, "%s\n", __func__);
+-
+- p = &default_params;
+-
+- priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(p->swap_a) |
+- (p->mirr_a ? VIP_CNTRL_0_MIRR_A : 0) |
+- VIP_CNTRL_0_SWAP_B(p->swap_b) |
+- (p->mirr_b ? VIP_CNTRL_0_MIRR_B : 0);
+- priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(p->swap_c) |
+- (p->mirr_c ? VIP_CNTRL_1_MIRR_C : 0) |
+- VIP_CNTRL_1_SWAP_D(p->swap_d) |
+- (p->mirr_d ? VIP_CNTRL_1_MIRR_D : 0);
+- priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(p->swap_e) |
+- (p->mirr_e ? VIP_CNTRL_2_MIRR_E : 0) |
+- VIP_CNTRL_2_SWAP_F(p->swap_f) |
+- (p->mirr_f ? VIP_CNTRL_2_MIRR_F : 0);
+-
+- priv->params = *p;
+-
+- if (p->audio_cfg)
+- tda998x_configure_audio(encoder, p);
+ }
+
+ static void
+@@ -759,22 +492,22 @@ tda998x_encoder_dpms(struct drm_encoder *encoder, int mode)
+
+ switch (mode) {
+ case DRM_MODE_DPMS_ON:
+- /* Write the default value MUX register */
+- reg_write(encoder, REG_MUX_VP_VIP_OUT, 0x24);
+ /* enable audio and video ports */
+-// reg_write(encoder, REG_ENA_AP, priv->ena_ap);
+-// reg_write(encoder, REG_ENA_ACLK, priv->ena_aclk);
++ reg_write(encoder, REG_ENA_AP, 0x03);
+ reg_write(encoder, REG_ENA_VP_0, 0xff);
+ reg_write(encoder, REG_ENA_VP_1, 0xff);
+ reg_write(encoder, REG_ENA_VP_2, 0xff);
+ /* set muxing after enabling ports: */
+- reg_write(encoder, REG_VIP_CNTRL_0, priv->vip_cntrl_0);
+- reg_write(encoder, REG_VIP_CNTRL_1, priv->vip_cntrl_1);
+- reg_write(encoder, REG_VIP_CNTRL_2, priv->vip_cntrl_2);
++ reg_write(encoder, REG_VIP_CNTRL_0,
++ VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3));
++ reg_write(encoder, REG_VIP_CNTRL_1,
++ VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1));
++ reg_write(encoder, REG_VIP_CNTRL_2,
++ VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5));
+ break;
+ case DRM_MODE_DPMS_OFF:
+ /* disable audio and video ports */
+-// reg_write(encoder, REG_ENA_AP, 0x00);
++ reg_write(encoder, REG_ENA_AP, 0x00);
+ reg_write(encoder, REG_ENA_VP_0, 0x00);
+ reg_write(encoder, REG_ENA_VP_1, 0x00);
+ reg_write(encoder, REG_ENA_VP_2, 0x00);
+@@ -799,24 +532,8 @@ tda998x_encoder_restore(struct drm_encoder *encoder)
+ static bool
+ tda998x_encoder_mode_fixup(struct drm_encoder *encoder,
+ const struct drm_display_mode *mode,
+- struct drm_display_mode *adjusted)
++ struct drm_display_mode *adjusted_mode)
+ {
+- DBG("");
+-
+- adjusted->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC |
+- DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC |
+- DRM_MODE_FLAG_PCSYNC | DRM_MODE_FLAG_NCSYNC);
+-
+- /* The TDA19988 always requires negative VSYNC? */
+- adjusted->flags |= DRM_MODE_FLAG_NVSYNC;
+-
+- /* The TDA19988 requires positive HSYNC on 1080p or 720p */
+- if ((adjusted->hdisplay == 1920 && adjusted->vdisplay == 1080) ||
+- (adjusted->hdisplay == 1280 && adjusted->vdisplay == 720))
+- adjusted->flags |= DRM_MODE_FLAG_PHSYNC;
+- else
+- adjusted->flags |= DRM_MODE_FLAG_NHSYNC;
+-
+ return true;
+ }
+
+@@ -824,11 +541,90 @@ static int
+ tda998x_encoder_mode_valid(struct drm_encoder *encoder,
+ struct drm_display_mode *mode)
+ {
+- DBG("");
+-
+ return MODE_OK;
+ }
+
++
++static void
++tda998x_audio_infoframe_enable(struct drm_encoder *encoder)
++{
++ uint8_t buffer[20];
++ struct hdmi_audio_infoframe audio_frame;
++ size_t len;
++
++ hdmi_audio_infoframe_init(&audio_frame);
++
++ /* NXP audio is fixed at these values for the time being */
++ audio_frame.channels = 2;
++ audio_frame.coding_type = HDMI_AUDIO_CODING_TYPE_PCM;
++ audio_frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_24;
++ audio_frame.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_48000;
++
++ len = hdmi_audio_infoframe_pack(&audio_frame, buffer, sizeof(buffer));
++ WARN(len < 0, "hdmi_avi_infoframe_pack failed\n");
++
++ reg_write_range(encoder, REG_AUDIO_IF, buffer, len);
++
++ /* enable Audio Infoframe output in DIP_IF Register */
++ reg_clear(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF4);
++ udelay(5);
++ reg_set(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF4);
++}
++
++static void
++tda998x_avi_infoframe_enable(struct drm_encoder *encoder,
++ struct drm_display_mode *mode)
++{
++ uint8_t buffer[20];
++ struct hdmi_avi_infoframe avi_frame;
++ size_t len;
++
++ hdmi_avi_infoframe_init(&avi_frame);
++ avi_frame.video_code = drm_match_cea_mode(mode);
++ avi_frame.picture_aspect = HDMI_PICTURE_ASPECT_NONE;
++ avi_frame.active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
++ len = hdmi_avi_infoframe_pack(&avi_frame, buffer, sizeof(buffer));
++ WARN(len < 0, "hdmi_avi_infoframe_pack failed\n");
++
++ reg_write_range(encoder, REG_AVI_IF, buffer, len);
++
++ /*
++ * enable AVI Infoframe output in DIP_IF Register, but toggle it
++ * so that the hardware acknowledges that the packet data might have
++ * changed
++ */
++ reg_clear(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF2);
++ udelay(5);
++ reg_set(encoder, REG_DIP_IF_FLAGS, DIP_IF_FLAGS_IF2);
++}
++
++/* lookup table for CEA values to VIDFORMAT values taken from NXP datasheet */
++static char cea_to_nxp_mode[34] = {-1, 0, 1, 1, 2, 3, 4, 4, 5, 5, -1, -1,
++ -1, -1, -1, -1, 6, 7, 7, 8, 9, 10, 10,
++ 11, 11, -1, -1, -1, -1, -1, -1, 12, 13};
++
++static char tda998x_cea_to_vidformat(unsigned char cea_mode)
++{
++ if(cea_mode > (sizeof(cea_to_nxp_mode) -1) ) {
++ return -1;
++ }
++ return cea_to_nxp_mode[cea_mode];
++}
++
++static char tda998x_is_monitor_hdmi(struct drm_encoder *encoder)
++{
++ struct edid *edid = (struct edid *)do_get_edid(encoder);
++ char hdmi = 0;
++ if(edid) {
++ hdmi = drm_detect_hdmi_monitor(edid);
++ kfree(edid);
++ } else {
++ return -1;
++ }
++ return hdmi;
++}
++
++
+ static void
+ tda998x_encoder_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+@@ -875,7 +671,7 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder,
+ /* mute the audio FIFO: */
+ reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO);
+
+- /* set HDMI HDCP mode off: */
++ /* HDMI/HDCP mode off... for now...: */
+ reg_set(encoder, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS);
+ reg_clear(encoder, REG_TX33, TX33_HDMI);
+
+@@ -922,8 +718,8 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder,
+ reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_H_TGL);
+
+ reg_write(encoder, REG_VIDFORMAT, 0x00);
+- reg_write16(encoder, REG_NPIX_MSB, mode->htotal);
+- reg_write16(encoder, REG_NLINE_MSB, mode->vtotal);
++ reg_write16(encoder, REG_NPIX_MSB, mode->hdisplay - 1);
++ reg_write16(encoder, REG_NLINE_MSB, mode->vdisplay - 1);
+ reg_write16(encoder, REG_VS_LINE_STRT_1_MSB, line_start);
+ reg_write16(encoder, REG_VS_LINE_END_1_MSB, line_end);
+ reg_write16(encoder, REG_VS_PIX_STRT_1_MSB, hs_start);
+@@ -943,29 +739,69 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder,
+ reg_write16(encoder, REG_REFPIX_MSB, ref_pix);
+ reg_write16(encoder, REG_REFLINE_MSB, ref_line);
+
+- reg = TBG_CNTRL_1_DWIN_DIS | /* HDCP off */
++ reg = TBG_CNTRL_1_VHX_EXT_DE |
++ TBG_CNTRL_1_VHX_EXT_HS |
++ TBG_CNTRL_1_VHX_EXT_VS |
++ TBG_CNTRL_1_DWIN_DIS | /* HDCP off */
+ TBG_CNTRL_1_VH_TGL_2;
+- /*
+- * It is questionable whether this is correct - the nxp driver
+- * does not set VH_TGL_2 and the below for all display modes.
+- */
+ if (mode->flags & (DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC))
+ reg |= TBG_CNTRL_1_VH_TGL_0;
+ reg_set(encoder, REG_TBG_CNTRL_1, reg);
+
+- /* Only setup the info frames if the sink is HDMI */
+- if (priv->is_hdmi_sink) {
+- /* We need to turn HDMI HDCP stuff on to get audio through */
+- reg_clear(encoder, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS);
+- reg_write(encoder, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(1));
++
++
++
++ if(tda998x_is_monitor_hdmi(encoder) == 1) {
++ char vidformat;
++ vidformat = tda998x_cea_to_vidformat(drm_match_cea_mode(mode));
++ if(vidformat == (char)-1) {
++ dev_err(encoder->dev->dev, "Not sure which CEA mode to set, leaving as DVI");
++ goto out;
++ }
++ dev_info(encoder->dev->dev, "Connected to an HDMI monitor with cea mode %d", vidformat);
++
++ /* this is an HDMI monitor, so set things up a bit differently */
++ reg_write(encoder, REG_TBG_CNTRL_1, 0);
++ reg_write(encoder, REG_VIDFORMAT, vidformat);
++ /* get the infoframes pumping */
++ tda998x_avi_infoframe_enable(encoder, mode);
++ tda998x_audio_infoframe_enable(encoder);
+ reg_set(encoder, REG_TX33, TX33_HDMI);
+
+- tda998x_write_avi(encoder, adjusted_mode);
++ /* set up audio registers */
++ reg_write(encoder, REG_ACR_CTS_0, 0x0);
++ reg_write(encoder, REG_ACR_CTS_1, 0x0);
++ reg_write(encoder, REG_ACR_CTS_2, 0x0);
+
+- if (priv->params.audio_cfg)
+- tda998x_configure_audio(encoder, &priv->params);
+- }
++ reg_write(encoder, REG_ACR_N_0, 0x0);
++ reg_write(encoder, REG_ACR_N_1, 0x18);
++ reg_write(encoder, REG_ACR_N_2, 0x0);
++
++ reg_set(encoder, REG_DIP_FLAGS, DIP_FLAGS_ACR);
++
++ reg_write(encoder, REG_ENC_CNTRL, 0x04);
++ reg_write(encoder, REG_CTS_N, 0x33);
++ /* Set 2 channel I2S mode */
++ reg_write(encoder, REG_ENA_AP, 0x3);
++
++ /* set audio divider in pll settings */
++ reg_write(encoder, REG_AUDIO_DIV, 0x2);
+
++ /* select the audio input port clock */
++ reg_write(encoder, REG_AIP_CLKSEL, SEL_AIP_I2S);
++ reg_write(encoder, REG_MUX_AP, MUX_AP_SELECT_I2S);
++
++ /* select I2S format, and datasize */
++ reg_write(encoder, REG_I2S_FORMAT, 0x0a);
++
++ /* enable the audio FIFO: */
++ reg_clear(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO);
++
++ /* mute and then unmute, to get audio going */
++ reg_write(encoder, REG_GC_AVMUTE, GC_AVMUTE_SETMUTE);
++ reg_write(encoder, REG_GC_AVMUTE, GC_AVMUTE_CLRMUTE);
++ }
++out:
+ /* must be last register set: */
+ reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_ONCE);
+
+@@ -1029,7 +865,6 @@ read_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk)
+ static uint8_t *
+ do_get_edid(struct drm_encoder *encoder)
+ {
+- struct tda998x_priv *priv = to_tda998x_priv(encoder);
+ int j = 0, valid_extensions = 0;
+ uint8_t *block, *new;
+ bool print_bad_edid = drm_debug & DRM_UT_KMS;
+@@ -1037,9 +872,6 @@ do_get_edid(struct drm_encoder *encoder)
+ if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
+ return NULL;
+
+- if (priv->rev == TDA19988)
+- reg_clear(encoder, REG_TX4, TX4_PD_RAM);
+-
+ /* base block fetch */
+ if (read_edid_block(encoder, block, 0))
+ goto fail;
+@@ -1049,7 +881,7 @@ do_get_edid(struct drm_encoder *encoder)
+
+ /* if there's no extensions, we're done */
+ if (block[0x7e] == 0)
+- goto done;
++ return block;
+
+ new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL);
+ if (!new)
+@@ -1076,15 +908,9 @@ do_get_edid(struct drm_encoder *encoder)
+ block = new;
+ }
+
+-done:
+- if (priv->rev == TDA19988)
+- reg_set(encoder, REG_TX4, TX4_PD_RAM);
+-
+ return block;
+
+ fail:
+- if (priv->rev == TDA19988)
+- reg_set(encoder, REG_TX4, TX4_PD_RAM);
+ dev_warn(encoder->dev->dev, "failed to read EDID\n");
+ kfree(block);
+ return NULL;
+@@ -1094,14 +920,12 @@ static int
+ tda998x_encoder_get_modes(struct drm_encoder *encoder,
+ struct drm_connector *connector)
+ {
+- struct tda998x_priv *priv = to_tda998x_priv(encoder);
+ struct edid *edid = (struct edid *)do_get_edid(encoder);
+ int n = 0;
+
+ if (edid) {
+ drm_mode_connector_update_edid_property(connector, edid);
+ n = drm_add_edid_modes(connector, edid);
+- priv->is_hdmi_sink = drm_detect_hdmi_monitor(edid);
+ kfree(edid);
+ }
+
+@@ -1163,59 +987,6 @@ tda998x_remove(struct i2c_client *client)
+ return 0;
+ }
+
+-static ssize_t i2c_read_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
+-{
+- struct drm_encoder *encoder = dev_get_drvdata(dev);
+- unsigned int page, addr;
+- unsigned char val;
+-
+- sscanf(buf, "%x %x", &page, &addr);
+-
+- val = reg_read(encoder, REG(page, addr));
+-
+- printk("i2c read %02x @ page:%02x address:%02x\n", val, page, addr);
+- return size;
+-}
+-
+-static ssize_t i2c_write_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
+-{
+- struct drm_encoder *encoder = dev_get_drvdata(dev);
+- unsigned int page, addr, mask, val;
+- unsigned char rval;
+-
+- sscanf(buf, "%x %x %x %x", &page, &addr, &mask, &val);
+-
+- rval = reg_read(encoder, REG(page, addr));
+- rval &= ~mask;
+- rval |= val & mask;
+- reg_write(encoder, REG(page, addr), rval);
+-
+- printk("i2c write %02x @ page:%02x address:%02x\n", rval, page, addr);
+- return size;
+-}
+-
+-static ssize_t i2c_dump_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
+-{
+- struct drm_encoder *encoder = dev_get_drvdata(dev);
+- unsigned int page;
+- char prefix[16];
+- uint8_t tmp[255];
+-
+- sscanf(buf, "%x", &page);
+-
+- reg_read_range(encoder, REG(page, 0), tmp, 254);
+-
+- snprintf(prefix, sizeof(prefix) - 1, "PG-%02x ", page);
+-
+- print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET, 16, 1, tmp, 254, false);
+-
+- return size;
+-}
+-
+-static DEVICE_ATTR(i2c_read, S_IWUSR, NULL, i2c_read_store);
+-static DEVICE_ATTR(i2c_write, S_IWUSR, NULL, i2c_write_store);
+-static DEVICE_ATTR(i2c_dump, S_IWUSR, NULL, i2c_dump_store);
+-
+ static int
+ tda998x_encoder_init(struct i2c_client *client,
+ struct drm_device *dev,
+@@ -1223,42 +994,11 @@ tda998x_encoder_init(struct i2c_client *client,
+ {
+ struct drm_encoder *encoder = &encoder_slave->base;
+ struct tda998x_priv *priv;
+- struct tda998x_encoder_params *p;
+-
+-/* debug */
+- device_create_file(&client->dev, &dev_attr_i2c_read);
+- device_create_file(&client->dev, &dev_attr_i2c_write);
+- device_create_file(&client->dev, &dev_attr_i2c_dump);
+- dev_set_drvdata(&client->dev, encoder);
+-/* debug end */
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+- p = &priv->params;
+-#if 0
+- priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3);
+- priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1);
+- priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5);
+-#else
+-
+- *p = default_params;
+-
+- priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(p->swap_a) |
+- (p->mirr_a ? VIP_CNTRL_0_MIRR_A : 0) |
+- VIP_CNTRL_0_SWAP_B(p->swap_b) |
+- (p->mirr_b ? VIP_CNTRL_0_MIRR_B : 0);
+- priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(p->swap_c) |
+- (p->mirr_c ? VIP_CNTRL_1_MIRR_C : 0) |
+- VIP_CNTRL_1_SWAP_D(p->swap_d) |
+- (p->mirr_d ? VIP_CNTRL_1_MIRR_D : 0);
+- priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(p->swap_e) |
+- (p->mirr_e ? VIP_CNTRL_2_MIRR_E : 0) |
+- VIP_CNTRL_2_SWAP_F(p->swap_f) |
+- (p->mirr_f ? VIP_CNTRL_2_MIRR_F : 0);
+-#endif
+-
+ priv->current_page = 0;
+ priv->cec = i2c_new_dummy(client->adapter, 0x34);
+ priv->dpms = DRM_MODE_DPMS_OFF;
+@@ -1356,3 +1096,4 @@ MODULE_LICENSE("GPL");
+
+ module_init(tda998x_init);
+ module_exit(tda998x_exit);
++
diff --git a/patches/linux-3.8.13/0594-tilcdc-More-refined-audio-mode-compatibility-check.patch b/patches/linux-3.8.13/0594-tilcdc-More-refined-audio-mode-compatibility-check.patch
new file mode 100644
index 0000000..0987fc7
--- /dev/null
+++ b/patches/linux-3.8.13/0594-tilcdc-More-refined-audio-mode-compatibility-check.patch
@@ -0,0 +1,69 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 6 Jun 2013 22:55:04 +0300
+Subject: [PATCH] tilcdc: More refined audio mode compatibility check.
+
+Allow audio modes more selectively. This should end up in DT instead
+but it will do for release.
+---
+ drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 30 ++++++++++++++++++++++++++----
+ 1 file changed, 26 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+index 023092f..375986e 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+@@ -440,6 +440,25 @@ int tilcdc_crtc_max_width(struct drm_crtc *crtc)
+ return max_width;
+ }
+
++/* this should find it's way to DT */
++static int audio_mode_check(int hdisplay, int vdisplay, int refresh,
++ int cea_mode)
++{
++ /* only cea modes can handle audio */
++ if (cea_mode <= 0)
++ return 0;
++
++ /* hardcoded mode that supports audio (at 24Hz) */
++ if (hdisplay == 1920 && vdisplay == 1080 && refresh == 24)
++ return 1;
++
++ /* from the rest, only those modes that refresh at 50/60 */
++ if (refresh != 50 && refresh != 60)
++ return 0;
++
++ return 1;
++}
++
+ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ int rb_check, int audio, struct edid *edid)
+ {
+@@ -447,6 +466,7 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ unsigned int bandwidth;
+ uint32_t hbp, hfp, hsw, vbp, vfp, vsw;
+ int has_audio, is_cea_mode, can_output_audio, refresh;
++ uint8_t cea_mode;
+
+ int rb;
+
+@@ -469,14 +489,16 @@ int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode,
+ refresh = drm_mode_vrefresh(mode);
+
+ /* set if it's a cea mode */
+- is_cea_mode = drm_match_cea_mode(mode) > 0;
++ cea_mode = drm_match_cea_mode(mode);
++ is_cea_mode = cea_mode > 0;
+
+ /* set if we can output audio */
+- can_output_audio = edid && has_audio && is_cea_mode &&
+- (refresh == 50 || refresh == 60);
++ can_output_audio = edid && has_audio &&
++ audio_mode_check(mode->hdisplay, mode->vdisplay,
++ refresh, cea_mode);
+
+ DBG("mode %dx%d@%d pixel-clock %d audio %s cea %s can_output %s",
+- mode->hdisplay, mode->vdisplay,refresh,
++ mode->hdisplay, mode->vdisplay, refresh,
+ mode->clock,
+ has_audio ? "true" : "false",
+ is_cea_mode ? "true" : "false",
diff --git a/patches/linux-3.8.13/0595-drm-tilcdc-Implement-whitelist-blacklist-mode-suppor.patch b/patches/linux-3.8.13/0595-drm-tilcdc-Implement-whitelist-blacklist-mode-suppor.patch
new file mode 100644
index 0000000..03c60f1
--- /dev/null
+++ b/patches/linux-3.8.13/0595-drm-tilcdc-Implement-whitelist-blacklist-mode-suppor.patch
@@ -0,0 +1,435 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 12 Jun 2013 11:11:12 +0300
+Subject: [PATCH] drm: tilcdc: Implement whitelist & blacklist mode support
+
+Some modes just don't work; so we need a way to control which ones
+we select. Implement a DT based whitelist & blacklist.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/gpu/drm/tilcdc/tilcdc_drv.c | 6 +-
+ drivers/gpu/drm/tilcdc/tilcdc_drv.h | 2 +-
+ drivers/gpu/drm/tilcdc/tilcdc_panel.c | 4 +-
+ drivers/gpu/drm/tilcdc/tilcdc_slave.c | 249 +++++++++++++++++++++++++++++++-
+ drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 4 +-
+ 5 files changed, 250 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+index 31e039e..85f972f 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+@@ -140,15 +140,15 @@ static int tilcdc_unload(struct drm_device *dev)
+ flush_workqueue(priv->wq);
+ destroy_workqueue(priv->wq);
+
+- dev->dev_private = NULL;
+-
+ pm_runtime_disable(dev->dev);
+
+ list_for_each_entry_safe(mod, cur, &module_list, list) {
+ DBG("destroying module: %s", mod->name);
+- mod->funcs->destroy(mod);
++ mod->funcs->destroy(mod, dev);
+ }
+
++ dev->dev_private = NULL;
++
+ kfree(priv);
+
+ return 0;
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.h b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+index 40ff5d4..d869519 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.h
++++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.h
+@@ -97,7 +97,7 @@ struct tilcdc_module;
+ struct tilcdc_module_ops {
+ /* create appropriate encoders/connectors: */
+ int (*modeset_init)(struct tilcdc_module *mod, struct drm_device *dev);
+- void (*destroy)(struct tilcdc_module *mod);
++ void (*destroy)(struct tilcdc_module *mod, struct drm_device *dev);
+ #ifdef CONFIG_DEBUG_FS
+ /* create debugfs nodes (can be NULL): */
+ int (*debugfs_init)(struct tilcdc_module *mod, struct drm_minor *minor);
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+index 2aa4a2e..f690583 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+@@ -285,7 +285,7 @@ static int panel_modeset_init(struct tilcdc_module *mod, struct drm_device *dev)
+ return 0;
+ }
+
+-static void panel_destroy(struct tilcdc_module *mod)
++static void panel_destroy(struct tilcdc_module *mod, struct drm_device *dev)
+ {
+ struct panel_module *panel_mod = to_panel_module(mod);
+
+@@ -482,7 +482,7 @@ static int panel_probe(struct platform_device *pdev)
+ return 0;
+
+ fail:
+- panel_destroy(mod);
++ panel_destroy(mod, NULL);
+ return ret;
+ }
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave.c b/drivers/gpu/drm/tilcdc/tilcdc_slave.c
+index 440de4e..641aeee 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_slave.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_slave.c
+@@ -23,12 +23,25 @@
+
+ #include "tilcdc_drv.h"
+
++/* keep a list of text modestrings */
++struct slave_modelist {
++ struct list_head node;
++ const char *modestr; /* the text mode string i.e. 1280x720@50 */
++ struct drm_cmdline_mode clmode; /* the command line mode */
++ struct drm_display_mode *mode; /* the display mode (as seen by the device) */
++ unsigned int parsed : 1; /* parsed (whether good or bad) */
++ unsigned int good : 1; /* it's ok to use it */
++};
++
+ struct slave_module {
+ struct tilcdc_module base;
+ struct tilcdc_panel_info *info;
+ struct i2c_adapter *i2c;
+ struct pinctrl *pinctrl;
+ char *selected_state_name;
++
++ struct list_head whitelist;
++ struct list_head blacklist;
+ };
+ #define to_slave_module(x) container_of(x, struct slave_module, base)
+
+@@ -152,13 +165,152 @@ static int slave_connector_get_modes(struct drm_connector *connector)
+ return get_slave_funcs(encoder)->get_modes(encoder, connector);
+ }
+
++static int slave_modelist_match(struct drm_connector *connector,
++ struct slave_modelist *sml, struct drm_display_mode *mode)
++{
++ struct drm_cmdline_mode *clmode = &sml->clmode;
++
++ if (sml->mode == NULL || !sml->good)
++ return 0;
++
++ /* xres, yres valid */
++ if (clmode->specified &&
++ (drm_mode_width(mode) != clmode->xres ||
++ drm_mode_height(mode) != clmode->yres))
++ return 0;
++
++ /* refresh mode specified */
++ if (clmode->refresh_specified &&
++ drm_mode_vrefresh(mode) != clmode->refresh)
++ return 0;
++
++ /* interlace */
++ if (clmode->interlace && (mode->flags & DRM_MODE_FLAG_INTERLACE) == 0)
++ return 0;
++
++ /* match */
++ return 1;
++}
++
++/* returns 0 if mode is listed, -ENOENT otherwise */
++static int slave_connector_mode_match(struct drm_connector *connector,
++ struct drm_display_mode *mode,
++ struct list_head *lh)
++{
++ struct drm_device *dev = connector->dev;
++ struct slave_modelist *sml;
++ bool parse;
++
++ /* ok, we have to find a match */
++ list_for_each_entry(sml, lh, node) {
++
++ /* if the mode is not parsed, do it now */
++ if (!sml->parsed) {
++
++ /* whether good or bad, we're trying only once */
++ sml->parsed = 1;
++ sml->good = 0;
++
++ parse = drm_mode_parse_command_line_for_connector(
++ sml->modestr, connector, &sml->clmode);
++
++ /* report in case something's off */
++ if (!parse) {
++ dev_err(dev->dev, "Failed to parse mode %s\n",
++ sml->modestr);
++ continue;
++ }
++
++ /* need to hold the mutex */
++ mutex_lock(&dev->mode_config.mutex);
++ sml->mode = drm_mode_create_from_cmdline_mode(dev,
++ &sml->clmode);
++ mutex_unlock(&dev->mode_config.mutex);
++
++ if (sml->mode == NULL) {
++ dev_err(dev->dev, "Failed to create mode %s\n",
++ sml->modestr);
++ continue;
++ }
++ sml->good = 1;
++ }
++
++ /* bad mode is skipped */
++ if (!sml->good)
++ continue;
++
++ /* we can't use drm_mode_equal, we use own own comparison */
++ if (slave_modelist_match(connector, sml, mode)) {
++ return 1;
++ }
++
++ }
++
++ return 0;
++}
++
++static int slave_connector_mode_whitelisted(struct drm_connector *connector,
++ struct drm_display_mode *mode)
++{
++ struct slave_connector *slave_connector = to_slave_connector(connector);
++ struct slave_module *slave_mod = slave_connector->mod;
++ int ret;
++
++ /* if the list is empty, everything is whitelisted */
++ if (list_empty(&slave_mod->whitelist))
++ return 1;
++
++ ret = slave_connector_mode_match(connector, mode, &slave_mod->whitelist);
++ if (ret != 0)
++ return 1;
++
++ /* not found */
++ return 0;
++}
++
++static int slave_connector_mode_blacklisted(struct drm_connector *connector,
++ struct drm_display_mode *mode)
++{
++ struct slave_connector *slave_connector = to_slave_connector(connector);
++ struct slave_module *slave_mod = slave_connector->mod;
++ int ret;
++
++ /* if the list is empty, nothing is blacklisted */
++ if (list_empty(&slave_mod->blacklist))
++ return 0;
++
++ ret = slave_connector_mode_match(connector, mode, &slave_mod->blacklist);
++ if (ret != 0)
++ return 1;
++
++ /* not found; all is OK */
++ return 0;
++}
++
+ static int slave_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+ {
+ struct drm_encoder *encoder = to_slave_connector(connector)->encoder;
+- struct tilcdc_drm_private *priv = connector->dev->dev_private;
++ struct drm_device *dev = connector->dev;
++ struct tilcdc_drm_private *priv = dev->dev_private;
+ int ret;
+
++ /* if there's a whitelist, we must be in it */
++ if (!slave_connector_mode_whitelisted(connector, mode)) {
++ dev_info(dev->dev, "mode %dx%d@%d is not whitelisted\n",
++ drm_mode_width(mode), drm_mode_height(mode),
++ drm_mode_vrefresh(mode));
++ return MODE_BAD;
++ }
++
++ /* if there's a blacklist, we shouldn't be in it */
++ if (slave_connector_mode_blacklisted(connector, mode)) {
++ dev_info(dev->dev, "mode %dx%d@%d is blacklisted\n",
++ drm_mode_width(mode), drm_mode_height(mode),
++ drm_mode_vrefresh(mode));
++ return MODE_BAD;
++ }
++
+ ret = tilcdc_crtc_mode_valid(priv->crtc, mode,
+ priv->allow_non_rblank ? 0 : 1,
+ priv->allow_non_audio ? 0 : 1,
+@@ -254,6 +406,12 @@ static int slave_modeset_init(struct tilcdc_module *mod, struct drm_device *dev)
+ struct drm_encoder *encoder;
+ struct drm_connector *connector;
+
++ if (priv->num_encoders >= ARRAY_SIZE(priv->encoders))
++ return -ENOENT;
++
++ if (priv->num_connectors >= ARRAY_SIZE(priv->connectors))
++ return -ENOENT;
++
+ encoder = slave_encoder_create(dev, slave_mod);
+ if (!encoder)
+ return -ENOMEM;
+@@ -268,18 +426,33 @@ static int slave_modeset_init(struct tilcdc_module *mod, struct drm_device *dev)
+ return 0;
+ }
+
+-static void slave_destroy(struct tilcdc_module *mod)
++static void slave_destroy(struct tilcdc_module *mod, struct drm_device *dev)
+ {
+ struct slave_module *slave_mod = to_slave_module(mod);
++ struct slave_modelist *sml;
+
+ tilcdc_module_cleanup(mod);
++
++ if (dev != NULL) {
++ /* no need to free sml, it's res tracked */
++ list_for_each_entry(sml, &slave_mod->whitelist, node) {
++ if (sml->mode != NULL)
++ drm_mode_destroy(dev, sml->mode);
++ }
++
++ list_for_each_entry(sml, &slave_mod->whitelist, node) {
++ if (sml->mode != NULL)
++ drm_mode_destroy(dev, sml->mode);
++ }
++ }
++
+ kfree(slave_mod->info);
+ kfree(slave_mod);
+ }
+
+ static const struct tilcdc_module_ops slave_module_ops = {
+- .modeset_init = slave_modeset_init,
+- .destroy = slave_destroy,
++ .modeset_init = slave_modeset_init,
++ .destroy = slave_destroy,
+ };
+
+ /*
+@@ -355,10 +528,54 @@ static const struct attribute_group pinmux_attr_group = {
+ .attrs = pinmux_attributes,
+ };
+
++/* fill in the mode list via the string list property */
++static int slave_mode_of_mode_list(struct platform_device *pdev,
++ const char *propname, struct list_head *lh)
++{
++ struct device *dev = &pdev->dev;
++ struct device_node *node = dev->of_node;
++ struct slave_modelist *sml;
++ int ret, i, count;
++
++ /* count the string list property */
++ count = of_property_count_strings(node, propname);
++
++ /* negative or zero, means no mode list */
++ if (count <= 0)
++ return 0;
++
++ for (i = 0; i < count; i++) {
++
++ sml = devm_kzalloc(dev, sizeof(*sml), GFP_KERNEL);
++ if (sml == NULL) {
++ dev_err(dev, "Failed to allocate mode list for %s\n",
++ propname);
++ return -ENOMEM;
++ }
++
++ ret = of_property_read_string_index(node, propname, i,
++ &sml->modestr);
++ if (ret != 0) {
++ dev_err(dev, "Failed to read string #%d for %s \n",
++ i, propname);
++ return ret;
++ }
++
++ /* add it to the tail */
++ list_add_tail(&sml->node, lh);
++
++ dev_info(dev, "%s #%d -> %s\n",
++ propname, i, sml->modestr);
++
++ }
++
++ return 0;
++}
++
+ static int slave_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+- struct device_node *node = pdev->dev.of_node;
++ struct device_node *node = dev->of_node;
+ struct device_node *i2c_node;
+ struct slave_module *slave_mod;
+ struct tilcdc_module *mod;
+@@ -379,6 +596,9 @@ static int slave_probe(struct platform_device *pdev)
+
+ platform_set_drvdata(pdev, slave_mod);
+
++ INIT_LIST_HEAD(&slave_mod->whitelist);
++ INIT_LIST_HEAD(&slave_mod->blacklist);
++
+ mod = &slave_mod->base;
+
+ tilcdc_module_init(mod, "slave", &slave_module_ops);
+@@ -395,8 +615,9 @@ static int slave_probe(struct platform_device *pdev)
+
+ slave_mod->pinctrl = devm_pinctrl_get(dev);
+ if (IS_ERR(slave_mod->pinctrl)) {
+- dev_err(dev, "Failed to get pinctrl\n");
+ ret = PTR_RET(slave_mod->pinctrl);
++ if (ret != -EPROBE_DEFER)
++ dev_err(dev, "Failed to get pinctrl\n");
+ goto fail;
+ }
+
+@@ -443,12 +664,26 @@ static int slave_probe(struct platform_device *pdev)
+ goto fail;
+ }
+
++ ret = slave_mode_of_mode_list(pdev, "modes-blacklisted",
++ &slave_mod->blacklist);
++ if (ret != 0) {
++ dev_err(&pdev->dev, "Invalid modes-blacklisted property\n");
++ goto fail;
++ }
++
++ ret = slave_mode_of_mode_list(pdev, "modes-whitelisted",
++ &slave_mod->whitelist);
++ if (ret != 0) {
++ dev_err(&pdev->dev, "Invalid modes-whitelisted property\n");
++ goto fail;
++ }
++
+ of_node_put(i2c_node);
+
+ return 0;
+
+ fail:
+- slave_destroy(mod);
++ slave_destroy(mod, NULL);
+ return ret;
+ }
+
+diff --git a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
+index c71f955..86fcd1c 100644
+--- a/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
++++ b/drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
+@@ -305,7 +305,7 @@ static int tfp410_modeset_init(struct tilcdc_module *mod, struct drm_device *dev
+ return 0;
+ }
+
+-static void tfp410_destroy(struct tilcdc_module *mod)
++static void tfp410_destroy(struct tilcdc_module *mod, struct drm_device *dev)
+ {
+ struct tfp410_module *tfp410_mod = to_tfp410_module(mod);
+
+@@ -507,7 +507,7 @@ static int tfp410_probe(struct platform_device *pdev)
+ return 0;
+
+ fail:
+- tfp410_destroy(mod);
++ tfp410_destroy(mod, NULL); /* meh */
+ return ret;
+ }
+
diff --git a/patches/linux-3.8.13/0596-boneblack-Remove-default-pinmuxing-for-MMC1.patch b/patches/linux-3.8.13/0596-boneblack-Remove-default-pinmuxing-for-MMC1.patch
new file mode 100644
index 0000000..d61fdc6
--- /dev/null
+++ b/patches/linux-3.8.13/0596-boneblack-Remove-default-pinmuxing-for-MMC1.patch
@@ -0,0 +1,43 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 18 Apr 2013 12:34:45 +0300
+Subject: [PATCH] boneblack: Remove default pinmuxing for MMC1
+
+The MMC driver already has the right pinmuxing options, remove it
+from here.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ arch/arm/boot/dts/am335x-boneblack.dts | 16 ----------------
+ 1 file changed, 16 deletions(-)
+
+diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts
+index 1abf267..a35a106 100644
+--- a/arch/arm/boot/dts/am335x-boneblack.dts
++++ b/arch/arm/boot/dts/am335x-boneblack.dts
+@@ -11,21 +11,6 @@
+
+ /include/ "am335x-bone-common.dtsi"
+
+-&userled_pins {
+- pinctrl-single,pins = <
+- 0x54 0x7 /* gpmc_a5.gpio1_21, OUTPUT | MODE7 */
+- 0x58 0x17 /* gpmc_a6.gpio1_22, OUTPUT_PULLUP | MODE7 */
+- 0x5c 0x7 /* gpmc_a7.gpio1_23, OUTPUT | MODE7 */
+- 0x60 0x17 /* gpmc_a8.gpio1_24, OUTPUT_PULLUP | MODE7 */
+- 0x00c 0x31 /* P8_6 gpmc_ad3.mmc1_dat1 PIN_INPUT_PULLUP | OMAP_MUX_MODE1 */
+- 0x008 0x31 /* P8_5 gpmc_ad2.mmc1_dat2 PIN_INPUT_PULLUP | OMAP_MUX_MODE1 */
+- 0x004 0x31 /* P8_24 gpmc_ad1.mmc1_dat1 PIN_INPUT_PULLUP | OMAP_MUX_MODE1 */
+- 0x000 0x31 /* P8_25 gpmc_ad0.mmc1_dat0 PIN_INPUT_PULLUP | OMAP_MUX_MODE1 */
+- 0x084 0x32 /* P8_20 gpmc_csn2.mmc1_cmd OMAP_MUX_MODE2 | AM33XX_PIN_INPUT_PULLUP} */
+- 0x080 0x32 /* P8_21 gpmc_csn1.immc1_clk OMAP_MUX_MODE2 | AM33XX_PIN_INPUT_PULLUP} */
+- >;
+-};
+-
+ &ldo3_reg {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+@@ -58,4 +43,3 @@
+ 300000 969000
+ >;
+ };
+-
diff --git a/patches/linux-3.8.13/0597-capemgr-Implement-cape-priorities.patch b/patches/linux-3.8.13/0597-capemgr-Implement-cape-priorities.patch
new file mode 100644
index 0000000..1576a13
--- /dev/null
+++ b/patches/linux-3.8.13/0597-capemgr-Implement-cape-priorities.patch
@@ -0,0 +1,276 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 22 Apr 2013 17:11:17 +0300
+Subject: [PATCH] capemgr: Implement cape priorities
+
+Allow capes to define priorities, this is important when you need
+to load built-in capes last, only after all the add-on capes have
+loaded.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/misc/cape/beaglebone/capemgr.c | 139 +++++++++++++++++++++++++++-----
+ 1 file changed, 119 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/misc/cape/beaglebone/capemgr.c b/drivers/misc/cape/beaglebone/capemgr.c
+index 5d87088..820852d 100644
+--- a/drivers/misc/cape/beaglebone/capemgr.c
++++ b/drivers/misc/cape/beaglebone/capemgr.c
+@@ -43,6 +43,7 @@
+ #include <linux/i2c.h>
+ #include <linux/i2c/eeprom.h>
+ #include <linux/kthread.h>
++#include <linux/wait.h>
+
+ /* extra command line overrides */
+ static char *extra_override = NULL;
+@@ -109,6 +110,9 @@ struct bone_cape_slot {
+
+ /* loader thread */
+ struct task_struct *loader_thread;
++
++ /* load priority */
++ int priority;
+ };
+
+ struct bone_capemap {
+@@ -154,6 +158,9 @@ struct bone_capemgr_info {
+
+ /* baseboard EEPROM data */
+ struct bone_baseboard baseboard;
++
++ /* wait queue for keeping the priorities straight */
++ wait_queue_head_t load_wq;
+ };
+
+ static int bone_slot_fill_override(struct bone_cape_slot *slot,
+@@ -162,6 +169,7 @@ static int bone_slot_fill_override(struct bone_cape_slot *slot,
+ static struct bone_cape_slot *bone_capemgr_add_slot(
+ struct bone_capemgr_info *info, struct device_node *node,
+ const char *part_number, const char *version);
++static int bone_capemgr_remove_slot_no_lock(struct bone_cape_slot *slot);
+ static int bone_capemgr_remove_slot(struct bone_cape_slot *slot);
+ static int bone_capemgr_load(struct bone_cape_slot *slot);
+ static int bone_capemgr_unload(struct bone_cape_slot *slot);
+@@ -1014,7 +1022,7 @@ static ssize_t slots_store(struct device *dev, struct device_attribute *attr,
+ mutex_unlock(&info->slots_list_mutex);
+ return -ENODEV;
+ found:
+- ret = bone_capemgr_remove_slot(slot);
++ ret = bone_capemgr_remove_slot_no_lock(slot);
+ mutex_unlock(&info->slots_list_mutex);
+
+ if (ret == 0)
+@@ -1100,6 +1108,9 @@ found:
+
+ ret = bone_capemgr_load(slot);
+
++ if (ret != 0)
++ bone_capemgr_remove_slot(slot);
++
+ return ret == 0 ? strlen(buf) : ret;
+ err_fail:
+ of_node_put(node);
+@@ -1307,6 +1318,7 @@ err_fail:
+ slot->fw = NULL;
+
+ err_fail_no_fw:
++ slot->loading = 0;
+ return err;
+ }
+
+@@ -1327,7 +1339,7 @@ static int bone_capemgr_unload(struct bone_cape_slot *slot)
+ }
+
+ /* slots_list_mutex must be taken */
+-static int bone_capemgr_remove_slot(struct bone_cape_slot *slot)
++static int bone_capemgr_remove_slot_no_lock(struct bone_cape_slot *slot)
+ {
+ struct bone_capemgr_info *info = slot->info;
+ struct device *dev = &info->pdev->dev;
+@@ -1336,11 +1348,13 @@ static int bone_capemgr_remove_slot(struct bone_cape_slot *slot)
+ if (slot == NULL)
+ return 0;
+
+- /* unload just in case */
+- ret = bone_capemgr_unload(slot);
+- if (ret != 0) {
+- dev_err(dev, "Unable to unload slot #%d\n", slot->slotno);
+- return ret;
++ if (slot->loaded && slot->ovinfo) {
++ /* unload just in case */
++ ret = bone_capemgr_unload(slot);
++ if (ret != 0) {
++ dev_err(dev, "Unable to unload slot #%d\n", slot->slotno);
++ return ret;
++ }
+ }
+
+ /* if probed OK, remove the sysfs nodes */
+@@ -1355,6 +1369,18 @@ static int bone_capemgr_remove_slot(struct bone_cape_slot *slot)
+ return 0;
+ }
+
++static int bone_capemgr_remove_slot(struct bone_cape_slot *slot)
++{
++ struct bone_capemgr_info *info = slot->info;
++ int ret;
++
++ mutex_lock(&info->slots_list_mutex);
++ ret = bone_capemgr_remove_slot_no_lock(slot);
++ mutex_unlock(&info->slots_list_mutex);
++
++ return ret;
++}
++
+ static int bone_slot_fill_override(struct bone_cape_slot *slot,
+ struct device_node *node,
+ const char *part_number, const char *version)
+@@ -1362,6 +1388,7 @@ static int bone_slot_fill_override(struct bone_cape_slot *slot,
+ const struct ee_field *sig_field;
+ struct property *prop;
+ int i, len, has_part_number;
++ u32 val;
+ char *p;
+
+ slot->probe_failed = 0;
+@@ -1413,6 +1440,10 @@ static int bone_slot_fill_override(struct bone_cape_slot *slot,
+ if (i == CAPE_EE_FIELD_PART_NUMBER && len > 0)
+ has_part_number = 1;
+ }
++
++ if (of_property_read_u32(node, "priority", &val) != 0)
++ val = 0;
++ slot->priority = val;
+ }
+
+ /* if a part_number is supplied use it */
+@@ -1579,11 +1610,72 @@ err_no_mem:
+ return ERR_PTR(ret);
+ }
+
++static int lowest_loading_cape(struct bone_cape_slot *slot)
++{
++ struct bone_capemgr_info *info = slot->info;
++ int my_prio = slot->priority;
++ struct device *dev = &info->pdev->dev;
++ int ret;
++
++ dev_info(dev, "loader: check slot-%d %s:%s (prio %d)\n", slot->slotno,
++ slot->part_number, slot->version, slot->priority);
++
++ mutex_lock(&info->slots_list_mutex);
++ ret = 1;
++ list_for_each_entry(slot, &info->slot_list, node) {
++ /* if any slot is loading with lowest priority */
++ if (!slot->loading)
++ continue;
++ if (slot->priority < my_prio) {
++ ret = 0;
++ break;
++ }
++ }
++ mutex_unlock(&info->slots_list_mutex);
++ return ret;
++}
++
+ static int bone_capemgr_loader(void *data)
+ {
+ struct bone_cape_slot *slot = data;
++ struct bone_capemgr_info *info = slot->info;
++ struct device *dev = &info->pdev->dev;
++ int ret;
++
++ dev_info(dev, "loader: before slot-%d %s:%s (prio %d)\n", slot->slotno,
++ slot->part_number, slot->version, slot->priority);
++
++ /*
++ * We have a basic priority based arbitration system
++ * Slots have priorities, so the lower priority ones
++ * should start loading first. So each time we end up
++ * here.
++ */
++ ret = wait_event_interruptible(info->load_wq,
++ lowest_loading_cape(slot));
++ if (ret < 0) {
++ dev_info(dev, "loader, Signal pending\n");
++ return ret;
++ }
++
++ dev_info(dev, "loader: after slot-%d %s:%s (prio %d)\n", slot->slotno,
++ slot->part_number, slot->version, slot->priority);
++
++ ret = bone_capemgr_load(slot);
++
++ slot->loading = 0;
++
++ dev_info(dev, "loader: done slot-%d %s:%s (prio %d)\n", slot->slotno,
++ slot->part_number, slot->version, slot->priority);
++
++ /* we're done, wake up all */
++ wake_up_interruptible_all(&info->load_wq);
+
+- return bone_capemgr_load(slot);
++ /* not loaded? remove */
++ if (ret != 0)
++ bone_capemgr_remove_slot(slot);
++
++ return ret;
+ }
+
+ static int
+@@ -1623,6 +1715,8 @@ bone_capemgr_probe(struct platform_device *pdev)
+ INIT_LIST_HEAD(&info->capemap_list);
+ mutex_init(&info->capemap_mutex);
+
++ init_waitqueue_head(&info->load_wq);
++
+ baseboardmaps_node = NULL;
+ capemaps_node = NULL;
+
+@@ -1803,21 +1897,26 @@ bone_capemgr_probe(struct platform_device *pdev)
+ continue;
+ }
+
+- if (!slot->probe_failed && !slot->loaded) {
++ if (!slot->probe_failed && !slot->loaded)
+ slot->loading = 1;
+- slot->loader_thread = kthread_run(bone_capemgr_loader,
+- slot, "capemgr-loader-%d",
+- slot->slotno);
+- if (IS_ERR(slot->loader_thread)) {
+- dev_warn(&pdev->dev, "slot #%d: Failed to "
+- "start loader\n", slot->slotno);
+- slot->loader_thread = NULL;
+- }
+- }
+ }
+
+- mutex_unlock(&info->slots_list_mutex);
++ /* now start the loader thread(s) (all at once) */
++ list_for_each_entry(slot, &info->slot_list, node) {
++
++ if (!slot->loading)
++ continue;
+
++ slot->loader_thread = kthread_run(bone_capemgr_loader,
++ slot, "capemgr-loader-%d",
++ slot->slotno);
++ if (IS_ERR(slot->loader_thread)) {
++ dev_warn(&pdev->dev, "slot #%d: Failed to "
++ "start loader\n", slot->slotno);
++ slot->loader_thread = NULL;
++ }
++ }
++ mutex_unlock(&info->slots_list_mutex);
+
+ dev_info(&pdev->dev, "initialized OK.\n");
+
+@@ -1840,7 +1939,7 @@ static int bone_capemgr_remove(struct platform_device *pdev)
+
+ mutex_lock(&info->slots_list_mutex);
+ list_for_each_entry_safe(slot, slotn, &info->slot_list, node)
+- bone_capemgr_remove_slot(slot);
++ bone_capemgr_remove_slot_no_lock(slot);
+ mutex_unlock(&info->slots_list_mutex);
+
+ bone_capemgr_info_sysfs_unregister(info);
diff --git a/patches/linux-3.8.13/0598-rstctl-Reset-control-subsystem.patch b/patches/linux-3.8.13/0598-rstctl-Reset-control-subsystem.patch
new file mode 100644
index 0000000..93be6b9
--- /dev/null
+++ b/patches/linux-3.8.13/0598-rstctl-Reset-control-subsystem.patch
@@ -0,0 +1,1049 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 11 Apr 2013 18:14:52 +0300
+Subject: [PATCH] rstctl: Reset control subsystem
+
+A reset control subsystem. Similar to pinctrl but for handling
+reset conditions.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/Kconfig | 2 +
+ drivers/Makefile | 2 +
+ drivers/rstctl/Kconfig | 30 +++
+ drivers/rstctl/Makefile | 8 +
+ drivers/rstctl/core.c | 368 +++++++++++++++++++++++++++++++++
+ drivers/rstctl/rstctl-gpio.c | 259 +++++++++++++++++++++++
+ drivers/rstctl/rstctl-test-consumer.c | 82 ++++++++
+ drivers/rstctl/rstctl-test.c | 138 +++++++++++++
+ include/linux/rstctl.h | 71 +++++++
+ 9 files changed, 960 insertions(+)
+ create mode 100644 drivers/rstctl/Kconfig
+ create mode 100644 drivers/rstctl/Makefile
+ create mode 100644 drivers/rstctl/core.c
+ create mode 100644 drivers/rstctl/rstctl-gpio.c
+ create mode 100644 drivers/rstctl/rstctl-test-consumer.c
+ create mode 100644 drivers/rstctl/rstctl-test.c
+ create mode 100644 include/linux/rstctl.h
+
+diff --git a/drivers/Kconfig b/drivers/Kconfig
+index f5fb072..0e8852a 100644
+--- a/drivers/Kconfig
++++ b/drivers/Kconfig
+@@ -158,4 +158,6 @@ source "drivers/irqchip/Kconfig"
+
+ source "drivers/ipack/Kconfig"
+
++source "drivers/rstctl/Kconfig"
++
+ endmenu
+diff --git a/drivers/Makefile b/drivers/Makefile
+index 7863b9f..8c50114 100644
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -11,6 +11,8 @@ obj-y += bus/
+ # GPIO must come after pinctrl as gpios may need to mux pins etc
+ obj-y += pinctrl/
+ obj-y += gpio/
++# similarly rstctl must come very early
++obj-y += rstctl/
+ obj-y += pwm/
+ obj-$(CONFIG_PCI) += pci/
+ obj-$(CONFIG_PARISC) += parisc/
+diff --git a/drivers/rstctl/Kconfig b/drivers/rstctl/Kconfig
+new file mode 100644
+index 0000000..b943253
+--- /dev/null
++++ b/drivers/rstctl/Kconfig
+@@ -0,0 +1,30 @@
++#
++# RSTCTL infrastructure and drivers
++#
++
++menuconfig RSTCTL
++ bool "Reset control subsystem"
++ help
++ Select this to enable the reset control subsystem
++
++if RSTCTL
++
++config RSTCTL_GPIO
++ tristate "GPIO reset driver"
++ depends on RSTCTL
++ help
++ This selects the GPIO based reset driver
++
++config RSTCTL_TEST
++ tristate "Test reset driver"
++ depends on RSTCTL
++ help
++ This selects the test reset driver
++
++config RSTCTL_TEST_CONSUMER
++ tristate "Test reset consumer driver"
++ depends on RSTCTL
++ help
++ This select the test reset consumer driver
++
++endif
+diff --git a/drivers/rstctl/Makefile b/drivers/rstctl/Makefile
+new file mode 100644
+index 0000000..26dfcf6
+--- /dev/null
++++ b/drivers/rstctl/Makefile
+@@ -0,0 +1,8 @@
++# rstctl support
++
++ccflags-$(CONFIG_DEBUG_RSTCTL) += -DDEBUG
++
++obj-$(CONFIG_RSTCTL) += core.o
++obj-$(CONFIG_RSTCTL_TEST) += rstctl-test.o
++obj-$(CONFIG_RSTCTL_TEST_CONSUMER) += rstctl-test-consumer.o
++obj-$(CONFIG_RSTCTL_GPIO) += rstctl-gpio.o
+diff --git a/drivers/rstctl/core.c b/drivers/rstctl/core.c
+new file mode 100644
+index 0000000..a3f02c2
+--- /dev/null
++++ b/drivers/rstctl/core.c
+@@ -0,0 +1,368 @@
++/*
++ * Core driver for the reset control subsystem
++ *
++ * Copyright (C) 2013 Pantelis Antoniou <panto@antoniou-consulting.com>
++ * Based on bits of rstctl, regulator core, gpio core and clk core
++ *
++ * License terms: GNU General Public License (GPL) version 2
++ */
++#define pr_fmt(fmt) "rstctl core: " fmt
++
++#include <linux/kernel.h>
++#include <linux/export.h>
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/slab.h>
++#include <linux/err.h>
++#include <linux/list.h>
++#include <linux/sysfs.h>
++#include <linux/debugfs.h>
++#include <linux/seq_file.h>
++
++#include <linux/rstctl.h>
++
++static inline int reset_request(struct rstctl_dev *rdev,
++ const struct rstctl_line *line)
++{
++ /* no request op? */
++ if (rdev->rdesc->ops->request == NULL)
++ return 0;
++
++ return rdev->rdesc->ops->request(rdev, line);
++}
++
++static inline int reset_release(struct rstctl_dev *rdev,
++ const struct rstctl_line *line)
++{
++ /* no release op? */
++ if (rdev->rdesc->ops->release == NULL)
++ return 0;
++
++ return rdev->rdesc->ops->release(rdev, line);
++}
++
++static inline int reset_assert(struct rstctl_dev *rdev,
++ const struct rstctl_line *line)
++{
++ return rdev->rdesc->ops->assert(rdev, line);
++}
++
++static inline int reset_deassert(struct rstctl_dev *rdev,
++ const struct rstctl_line *line)
++{
++ return rdev->rdesc->ops->deassert(rdev, line);
++}
++
++static inline int reset_pulse(struct rstctl_dev *rdev,
++ const struct rstctl_line *line,
++ unsigned long hold_ns)
++{
++ return rdev->rdesc->ops->pulse(rdev, line, hold_ns);
++}
++
++int rstctl_assert(struct rstctl *rctrl)
++{
++ if (IS_ERR_OR_NULL(rctrl))
++ return -EINVAL;
++ return reset_assert(rctrl->rdev, rctrl->line);
++}
++EXPORT_SYMBOL(rstctl_assert);
++
++int rstctl_deassert(struct rstctl *rctrl)
++{
++ if (IS_ERR_OR_NULL(rctrl))
++ return -EINVAL;
++ return reset_deassert(rctrl->rdev, rctrl->line);
++}
++EXPORT_SYMBOL(rstctl_deassert);
++
++int rstctl_pulse(struct rstctl *rctrl, unsigned long hold_ns)
++{
++ if (IS_ERR_OR_NULL(rctrl))
++ return -EINVAL;
++ return reset_pulse(rctrl->rdev, rctrl->line, hold_ns);
++}
++EXPORT_SYMBOL(rstctl_pulse);
++
++/* Mutex taken by all entry points */
++static DEFINE_MUTEX(rstctl_lock);
++
++/* Global list of reset control devices (struct rstctl_dev) */
++static LIST_HEAD(rstctl_dev_list);
++
++static struct rstctl *rstctl_request_line(struct rstctl_dev *rdev,
++ struct device *dev, const struct rstctl_line *line)
++{
++ struct rstctl *rctrl;
++ int index, err;
++
++ index = line - rdev->rdesc->lines;
++
++ /* find if it's already requested */
++ list_for_each_entry(rctrl, &rdev->handles, node) {
++ /* retreive index from the point */
++ if (rctrl->line == line) {
++ dev_err(dev, "Reset %s:%d already requested\n",
++ rdev->rdesc->name, index);
++ return ERR_PTR(-EEXIST);
++ }
++ }
++
++ /* request from the driver */
++ err = reset_request(rdev, line);
++ if (err != 0) {
++ dev_err(dev, "reset_request on %s:%d failed\n",
++ rdev->rdesc->name, index);
++ return ERR_PTR(err);
++ }
++
++ /* allocate */
++ rctrl = kzalloc(sizeof(*rctrl), GFP_KERNEL);
++ if (rctrl == NULL) {
++ dev_err(dev, "Out of memory on %s:%d request\n",
++ rdev->rdesc->name, index);
++ reset_release(rdev, line);
++ return ERR_PTR(-ENOMEM);
++ }
++
++ INIT_LIST_HEAD(&rctrl->node);
++ rctrl->rdev = rdev;
++ rctrl->dev = dev;
++ rctrl->line = line;
++
++ /* add it to the handle list */
++ list_add_tail(&rctrl->node, &rdev->handles);
++
++ return rctrl;
++}
++
++#ifdef CONFIG_OF
++
++static struct rstctl_dev *of_node_to_rstctl_dev(struct device_node *np)
++{
++ struct rstctl_dev *rdev;
++
++ list_for_each_entry(rdev, &rstctl_dev_list, node) {
++ if (rdev->dev && rdev->dev->of_node == np)
++ return rdev;
++ }
++
++ return ERR_PTR(-EPROBE_DEFER);
++}
++
++static struct rstctl *of_rstctl_get(struct device *dev, const char *id)
++{
++ struct device_node *np;
++ struct rstctl *rctrl;
++ struct rstctl_dev *rdev;
++ const struct rstctl_line *line;
++ struct of_phandle_args args;
++ int index, lineidx, err;
++
++ /* sanity check */
++ if (dev == NULL || dev->of_node == NULL)
++ return NULL;
++ np = dev->of_node;
++
++ index = 0;
++ if (id != NULL) {
++ err = of_property_match_string(np, "reset-names", id);
++ if (err < 0) {
++ dev_err(dev, "of_property_match of 'reset-names' failed\n");
++ rctrl = ERR_PTR(err);
++ goto out;
++ }
++ index = err;
++ }
++
++ err = of_parse_phandle_with_args(np, "reset", "#reset-cells", index,
++ &args);
++ if (err != 0) {
++ dev_err(dev, "of_parse_phandle_with_args of 'reset' failed\n");
++ rctrl = ERR_PTR(err);
++ goto out;
++ }
++
++ mutex_lock(&rstctl_lock);
++
++ rdev = of_node_to_rstctl_dev(args.np);
++ if (IS_ERR_OR_NULL(rdev)) {
++ dev_err(dev, "rstctl node not found\n");
++ rctrl = rdev == NULL ? ERR_PTR(-EINVAL) : (void *)rdev;
++ goto out_unlock;
++ }
++
++ if (args.args_count != 2) {
++ dev_err(dev, "#reset-cells not %d\n", 2);
++ rctrl = ERR_PTR(-EINVAL);
++ goto out_unlock;
++ }
++
++ lineidx = args.args[0];
++ /* make sure it's one we handle */
++ if (lineidx < 0 || lineidx >= rdev->rdesc->nlines) {
++ dev_err(dev, "Illegal reset #%d\n", lineidx);
++ rctrl = ERR_PTR(-EINVAL);
++ goto out_unlock;
++ }
++ line = &rdev->rdesc->lines[lineidx];
++
++ rctrl = rstctl_request_line(rdev, dev, line);
++ if (IS_ERR(rctrl)) {
++ dev_err(dev, "rstctl_request_line failed\n");
++ goto out_unlock;
++ }
++
++ /* put the label in */
++ err = of_property_read_string_index(np, "reset-names", index,
++ &rctrl->label);
++ if (err != 0)
++ rctrl->label = np->name;
++
++out_unlock:
++ mutex_unlock(&rstctl_lock);
++out:
++ return rctrl;
++}
++#else
++static inline struct rstctl *of_rstctl_get(struct device *dev,
++ const char *id)
++{
++ return NULL;
++}
++#endif
++
++struct rstctl *rstctl_get(struct device *dev, const char *id)
++{
++ struct rstctl_dev *rdev;
++ struct rstctl *rctrl;
++ const struct rstctl_line *line;
++ int i;
++
++ /* DT case goes through here */
++ if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node)
++ return of_rstctl_get(dev, id);
++
++ /* non DT case does not support id == NULL */
++ if (id == NULL) {
++ dev_err(dev, "No reset ID supplied\n");
++ return ERR_PTR(-EINVAL);
++ }
++
++ /*
++ * We search all the rstctl devices for a match
++ * with the given label id
++ */
++ mutex_lock(&rstctl_lock);
++ list_for_each_entry(rdev, &rstctl_dev_list, node) {
++ for (i = 0; i < rdev->rdesc->nlines; i++) {
++ line = &rdev->rdesc->lines[i];
++ if (strcmp(line->name, id) == 0) {
++ rctrl = rstctl_request_line(rdev, dev, line);
++ goto out;
++ }
++ }
++ }
++ rctrl = ERR_PTR(-ENODEV);
++out:
++ mutex_unlock(&rstctl_lock);
++
++ return rctrl;
++}
++EXPORT_SYMBOL(rstctl_get);
++
++void rstctl_put(struct rstctl *rctrl)
++{
++ struct rstctl_dev *rdev;
++ struct rstctl *rctrlt;
++
++ /* safe */
++ if (IS_ERR_OR_NULL(rctrl))
++ return;
++ rdev = rctrl->rdev;
++
++ mutex_lock(&rstctl_lock);
++ list_for_each_entry(rctrlt, &rdev->handles, node) {
++ if (rctrlt == rctrl)
++ goto found;
++ }
++ goto out;
++found:
++ /* release the reset */
++ reset_release(rctrl->rdev, rctrl->line);
++ list_del(&rctrl->node);
++ kfree(rctrl);
++out:
++ mutex_unlock(&rstctl_lock);
++}
++EXPORT_SYMBOL(rstctl_put);
++
++struct rstctl_dev *rstctl_register(struct device *dev,
++ const struct rstctl_desc *rdesc)
++{
++ struct rstctl_dev *rdev;
++
++ /* sanity check */
++ if (dev == NULL || rdesc == NULL || rdesc->ops == NULL)
++ return ERR_PTR(-EINVAL);
++
++ /* those three must be defined */
++ if (rdesc->ops->assert == NULL || rdesc->ops->deassert == NULL
++ || rdesc->ops->pulse == NULL)
++ return ERR_PTR(-EINVAL);
++
++ rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
++ if (rdev == NULL) {
++ dev_err(dev, "failed to alloc struct rstctl_dev\n");
++ return ERR_PTR(-ENOMEM);
++ }
++
++ INIT_LIST_HEAD(&rdev->node);
++ rdev->dev = dev;
++ rdev->rdesc = rdesc;
++ INIT_LIST_HEAD(&rdev->handles);
++
++ mutex_lock(&rstctl_lock);
++ list_add_tail(&rdev->node, &rstctl_dev_list);
++ mutex_unlock(&rstctl_lock);
++
++ return rdev;
++}
++
++int rstctl_unregister(struct rstctl_dev *rdev)
++{
++ int err;
++
++ /* guard */
++ if (IS_ERR_OR_NULL(rdev))
++ return -EINVAL;
++
++ err = 0;
++
++ mutex_lock(&rstctl_lock);
++
++ if (!list_empty(&rdev->handles)) {
++ dev_err(rdev->dev, "%s still busy\n", rdev->rdesc->name);
++ err = -EBUSY;
++ goto out;
++ }
++ list_del(&rdev->node);
++
++ /* free */
++ kfree(rdev);
++
++ mutex_unlock(&rstctl_lock);
++
++out:
++ mutex_unlock(&rstctl_lock);
++ return err;
++}
++
++static int __init rstctl_init(void)
++{
++ pr_info("initialized rstctl subsystem\n");
++ return 0;
++}
++
++/* init early, resetting is needed pretty early */
++core_initcall(rstctl_init);
+diff --git a/drivers/rstctl/rstctl-gpio.c b/drivers/rstctl/rstctl-gpio.c
+new file mode 100644
+index 0000000..4f3b5c1
+--- /dev/null
++++ b/drivers/rstctl/rstctl-gpio.c
+@@ -0,0 +1,259 @@
++/*
++ * Test driver for rstctl
++ *
++ * Author: Pantelis Antoniou <panto@antoniou-consulting.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published by
++ * the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program. If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/rstctl.h>
++#include <linux/of.h>
++#include <linux/of_gpio.h>
++#include <linux/slab.h>
++#include <linux/err.h>
++#include <linux/delay.h>
++#include <linux/pinctrl/consumer.h>
++
++struct gpio_data {
++ int gpio;
++ enum of_gpio_flags flags;
++ int hold_ns;
++};
++
++struct gpio_rctrl_info {
++ struct rstctl_dev *rdev;
++ struct rstctl_desc desc;
++ struct gpio_data *gpio_data;
++};
++
++int gpio_rctrl_request(struct rstctl_dev *rdev,
++ const struct rstctl_line *line)
++{
++ struct device *dev = rdev->dev;
++ const struct gpio_data *gd = line->data;
++ unsigned long flags;
++ int err;
++
++ dev_info(dev, "%s %s\n", __func__, line->name);
++
++ flags = GPIOF_DIR_OUT;
++ if (gd->flags & OF_GPIO_ACTIVE_LOW)
++ flags |= GPIOF_INIT_LOW;
++ else
++ flags |= GPIOF_INIT_HIGH;
++ /* XXX more flags ? */
++
++ err = devm_gpio_request_one(dev, gd->gpio, flags, line->name);
++ if (err != 0) {
++ dev_err(dev, "Failed to gpio_request\n");
++ return err;
++ }
++ return 0;
++}
++
++int gpio_rctrl_release(struct rstctl_dev *rdev,
++ const struct rstctl_line *line)
++{
++ struct device *dev = rdev->dev;
++ const struct gpio_data *gd = line->data;
++
++ dev_info(dev, "%s %s\n", __func__, line->name);
++ devm_gpio_free(dev, gd->gpio);
++ return 0;
++}
++
++int gpio_rctrl_assert(struct rstctl_dev *rdev,
++ const struct rstctl_line *line)
++{
++ struct device *dev = rdev->dev;
++ const struct gpio_data *gd = line->data;
++
++ dev_info(dev, "%s %s\n", __func__, line->name);
++ gpio_set_value(gd->gpio,
++ (gd->flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1);
++ return 0;
++}
++
++int gpio_rctrl_deassert(struct rstctl_dev *rdev,
++ const struct rstctl_line *line)
++{
++ struct device *dev = rdev->dev;
++ const struct gpio_data *gd = line->data;
++
++ dev_info(dev, "%s %s\n", __func__, line->name);
++ gpio_set_value(gd->gpio,
++ (gd->flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0);
++ return 0;
++}
++
++int gpio_rctrl_pulse(struct rstctl_dev *rdev,
++ const struct rstctl_line *line,
++ unsigned long hold_ns)
++{
++ struct device *dev = rdev->dev;
++ const struct gpio_data *gd = line->data;
++
++ dev_info(dev, "%s %s\n", __func__, line->name);
++
++ gpio_set_value(gd->gpio,
++ (gd->flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1);
++
++ if (hold_ns == 0)
++ hold_ns = gd->hold_ns;
++
++ if (hold_ns < 1000000)
++ ndelay(hold_ns);
++ else
++ mdelay(hold_ns / 1000000);
++
++ gpio_set_value(gd->gpio,
++ (gd->flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0);
++ return 0;
++}
++
++static const struct rstctl_ops gpio_rctrl_ops = {
++ .request = gpio_rctrl_request,
++ .release = gpio_rctrl_release,
++ .assert = gpio_rctrl_assert,
++ .deassert = gpio_rctrl_deassert,
++ .pulse = gpio_rctrl_pulse,
++};
++
++static int gpio_rctrl_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct device_node *np = dev->of_node;
++ struct gpio_rctrl_info *info;
++ struct rstctl_line *line, *lines;
++ struct gpio_data *gdata, *gd;
++ struct pinctrl *pinctrl;
++ int count, i, err;
++
++ /* we require OF */
++ if (!IS_ENABLED(CONFIG_OF) || np == NULL) {
++ dev_err(dev, "GPIO rstctl requires DT\n");
++ return -ENODEV;
++ }
++
++ pinctrl = devm_pinctrl_get_select_default(dev);
++ if (IS_ERR(pinctrl))
++ dev_warn(dev, "Unable to select pin group\n");
++
++ count = of_gpio_named_count(np, "gpios");
++ if (count == 0) {
++ dev_err(dev, "GPIO rstctl found no GPIO resources\n");
++ return -ENODEV;
++ }
++
++ if (of_property_count_strings(np, "gpio-names") != count) {
++ dev_err(dev, "GPIO rstctl gpio-names property is invalid\n");
++ return -ENODEV;
++ }
++
++ info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
++ if (!info) {
++ dev_err(dev, "GPIO rstctl kzalloc failed\n");
++ return -ENOMEM;
++ }
++ lines = devm_kzalloc(dev, sizeof(*line) * count, GFP_KERNEL);
++ if (!lines) {
++ dev_err(dev, "GPIO rstctl kzalloc failed\n");
++ return -ENOMEM;
++ }
++ gdata = devm_kzalloc(dev, sizeof(*gdata) * count, GFP_KERNEL);
++ if (!gdata) {
++ dev_err(dev, "GPIO rstctl kzalloc failed\n");
++ return -ENOMEM;
++ }
++
++ info->desc.name = "gpio";
++ info->desc.ops = &gpio_rctrl_ops;
++ info->desc.nlines = count;
++ info->desc.lines = lines;
++ info->gpio_data = gdata;
++
++ for (i = 0; i < count; i++) {
++ line = &lines[i];
++ err = of_property_read_string_index(np, "gpio-names",
++ i, &line->name);
++ if (err != 0) {
++ dev_err(dev, "Failed to get string property\n");
++ return err;
++ }
++
++ gd = &gdata[i];
++ err = of_get_named_gpio_flags(np, "gpios", i, &gd->flags);
++ if (IS_ERR_VALUE(err)) {
++ dev_err(dev, "Failed to get named gpio\n");
++ return err;
++ }
++ gd->gpio = err;
++ gd->hold_ns = 1000; /* 1us reset */
++ line->data = gd;
++ }
++
++ info->rdev = rstctl_register(&pdev->dev, &info->desc);
++ if (IS_ERR(info->rdev)) {
++ dev_err(&pdev->dev, "failed to register\n");
++ return PTR_ERR(info->rdev);
++ }
++ platform_set_drvdata(pdev, info);
++
++ dev_info(&pdev->dev, "loaded OK\n");
++
++ return 0;
++}
++
++static int gpio_rctrl_remove(struct platform_device *pdev)
++{
++ struct gpio_rctrl_info *info = platform_get_drvdata(pdev);
++ int err;
++
++ err = rstctl_unregister(info->rdev);
++ if (err == 0)
++ dev_info(&pdev->dev, "removed OK\n");
++
++ return err;
++}
++
++#ifdef CONFIG_OF
++static struct of_device_id gpio_rctrl_of_match[] = {
++ { .compatible = "gpio-rctrl" },
++ { },
++};
++MODULE_DEVICE_TABLE(of, gpio_rctrl_of_match);
++#endif
++
++static struct platform_driver gpio_rctrl_driver = {
++ .driver = {
++ .name = "gpio-rctrl",
++ .of_match_table = of_match_ptr(gpio_rctrl_of_match),
++ },
++ .probe = gpio_rctrl_probe,
++ .remove = gpio_rctrl_remove,
++};
++
++/*
++ * The reset control driver must be done very early.
++ */
++static int __init gpio_rctrl_drv_reg(void)
++{
++ return platform_driver_register(&gpio_rctrl_driver);
++}
++postcore_initcall(gpio_rctrl_drv_reg);
++
++MODULE_AUTHOR("Pantelis Antoniou <panto@antoniou-consulting.com>");
++MODULE_DESCRIPTION("rstctl GPIO driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/rstctl/rstctl-test-consumer.c b/drivers/rstctl/rstctl-test-consumer.c
+new file mode 100644
+index 0000000..dd26ca1
+--- /dev/null
++++ b/drivers/rstctl/rstctl-test-consumer.c
+@@ -0,0 +1,82 @@
++/*
++ * Test consumer driver for rstctl
++ *
++ * Author: Pantelis Antoniou <panto@antoniou-consulting.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published by
++ * the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program. If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/rstctl.h>
++#include <linux/of.h>
++#include <linux/slab.h>
++#include <linux/err.h>
++
++static int test_consumer_rctrl_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct rstctl *rctrl;
++
++ dev_info(dev, "Trying to get NULL (OF case only)\n");
++ rctrl = rstctl_get(dev, NULL);
++ if (IS_ERR(rctrl)) {
++ dev_info(dev, "Failed to get it\n");
++ return PTR_ERR(rctrl);
++ }
++
++ dev_info(dev, "Got it (%s:#%d name %s) label:%s\n",
++ rctrl->rdev->rdesc->name,
++ rctrl->line - rctrl->rdev->rdesc->lines,
++ rctrl->line->name, rctrl->label);
++
++ /* for now always assert */
++ rstctl_assert(rctrl);
++ platform_set_drvdata(pdev, rctrl);
++
++ dev_info(&pdev->dev, "loaded OK\n");
++ return 0;
++}
++
++static int test_consumer_rctrl_remove(struct platform_device *pdev)
++{
++ struct rstctl *rctrl = platform_get_drvdata(pdev);
++
++ rstctl_deassert(rctrl);
++ rstctl_put(rctrl);
++
++ dev_info(&pdev->dev, "unloaded OK\n");
++ return 0;
++}
++
++#ifdef CONFIG_OF
++static struct of_device_id test_consumer_rctrl_of_match[] = {
++ { .compatible = "test-consumer-rctrl" },
++ { },
++};
++MODULE_DEVICE_TABLE(of, test_consumer_rctrl_of_match);
++#endif
++
++static struct platform_driver test_consumer_rctrl_driver = {
++ .driver = {
++ .name = "test-consumer-rctrl",
++ .of_match_table = of_match_ptr(test_consumer_rctrl_of_match),
++ },
++ .probe = test_consumer_rctrl_probe,
++ .remove = test_consumer_rctrl_remove,
++};
++module_platform_driver(test_consumer_rctrl_driver);
++
++MODULE_AUTHOR("Pantelis Antoniou <panto@antoniou-consulting.com>");
++MODULE_DESCRIPTION("rstctl test consumer driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/rstctl/rstctl-test.c b/drivers/rstctl/rstctl-test.c
+new file mode 100644
+index 0000000..144c048
+--- /dev/null
++++ b/drivers/rstctl/rstctl-test.c
+@@ -0,0 +1,138 @@
++/*
++ * Test driver for rstctl
++ *
++ * Author: Pantelis Antoniou <panto@antoniou-consulting.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published by
++ * the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU General Public License along with
++ * this program. If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/rstctl.h>
++#include <linux/of.h>
++#include <linux/slab.h>
++#include <linux/err.h>
++
++struct test_rctrl_info {
++ struct rstctl_dev *rdev;
++};
++
++int test_rctrl_request(struct rstctl_dev *rdev,
++ const struct rstctl_line *line)
++{
++ dev_info(rdev->dev, "%s %s\n", __func__, line->name);
++ return 0;
++}
++
++int test_rctrl_release(struct rstctl_dev *rdev,
++ const struct rstctl_line *line)
++{
++ dev_info(rdev->dev, "%s %s\n", __func__, line->name);
++ return 0;
++}
++
++int test_rctrl_assert(struct rstctl_dev *rdev,
++ const struct rstctl_line *line)
++{
++ dev_info(rdev->dev, "%s %s\n", __func__, line->name);
++ return 0;
++}
++
++int test_rctrl_deassert(struct rstctl_dev *rdev,
++ const struct rstctl_line *line)
++{
++ dev_info(rdev->dev, "%s %s\n", __func__, line->name);
++ return 0;
++}
++
++int test_rctrl_pulse(struct rstctl_dev *rdev,
++ const struct rstctl_line *line,
++ unsigned long hold_ns)
++{
++ dev_info(rdev->dev, "%s %s\n", __func__, line->name);
++ return 0;
++}
++
++static const struct rstctl_ops test_rctrl_ops = {
++ .request = test_rctrl_request,
++ .release = test_rctrl_release,
++ .assert = test_rctrl_assert,
++ .deassert = test_rctrl_deassert,
++ .pulse = test_rctrl_pulse,
++};
++
++static const struct rstctl_line test_rctrl_lines[] = {
++ { .name = "RESET1", },
++ { .name = "RESET2", },
++};
++
++static const struct rstctl_desc test_rctrl_desc = {
++ .name = "test",
++ .ops = &test_rctrl_ops,
++ .nlines = ARRAY_SIZE(test_rctrl_lines),
++ .lines = test_rctrl_lines,
++};
++
++static int test_rctrl_probe(struct platform_device *pdev)
++{
++ struct test_rctrl_info *info;
++
++ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
++ if (!info)
++ return -ENOMEM;
++
++ info->rdev = rstctl_register(&pdev->dev, &test_rctrl_desc);
++ if (IS_ERR(info->rdev)) {
++ dev_err(&pdev->dev, "failed to register\n");
++ return PTR_ERR(info->rdev);
++ }
++ platform_set_drvdata(pdev, info);
++
++ dev_info(&pdev->dev, "loaded OK\n");
++
++ return 0;
++}
++
++static int test_rctrl_remove(struct platform_device *pdev)
++{
++ struct test_rctrl_info *info = platform_get_drvdata(pdev);
++ int err;
++
++ err = rstctl_unregister(info->rdev);
++ if (err == 0)
++ dev_info(&pdev->dev, "removed OK\n");
++
++ return err;
++}
++
++#ifdef CONFIG_OF
++static struct of_device_id test_rctrl_of_match[] = {
++ { .compatible = "test-rctrl" },
++ { },
++};
++MODULE_DEVICE_TABLE(of, test_rctrl_of_match);
++#endif
++
++static struct platform_driver test_rctrl_driver = {
++ .driver = {
++ .name = "test-rctrl",
++ .of_match_table = of_match_ptr(test_rctrl_of_match),
++ },
++ .probe = test_rctrl_probe,
++ .remove = test_rctrl_remove,
++};
++module_platform_driver(test_rctrl_driver);
++
++MODULE_AUTHOR("Pantelis Antoniou <panto@antoniou-consulting.com>");
++MODULE_DESCRIPTION("rstctl test driver");
++MODULE_LICENSE("GPL");
+diff --git a/include/linux/rstctl.h b/include/linux/rstctl.h
+new file mode 100644
+index 0000000..b2e674a
+--- /dev/null
++++ b/include/linux/rstctl.h
+@@ -0,0 +1,71 @@
++/*
++ * Reset control subsystem
++ *
++ * Copyright (C) 2013 Pantelis Antoniou <panto@antoniou-consulting.com>
++ *
++ * License terms: GNU General Public License (GPL) version 2
++ */
++#ifndef __LINUX_RSTCTL_H
++#define __LINUX_RSTCTL_H
++
++#include <linux/of.h>
++#include <linux/list.h>
++
++struct rstctl_dev;
++
++struct rstctl_line {
++ const char *name;
++ void *data;
++};
++
++struct rstctl_ops {
++ int (*request)(struct rstctl_dev *rdev,
++ const struct rstctl_line *line);
++ int (*release)(struct rstctl_dev *rdev,
++ const struct rstctl_line *line);
++ int (*assert)(struct rstctl_dev *rdev,
++ const struct rstctl_line *line);
++ int (*deassert)(struct rstctl_dev *rdev,
++ const struct rstctl_line *line);
++ int (*pulse)(struct rstctl_dev *rdev,
++ const struct rstctl_line *line,
++ unsigned long hold_ns);
++ struct module *owner;
++};
++
++struct rstctl_desc {
++ const char *name;
++ const struct rstctl_ops *ops;
++ int nlines;
++ const struct rstctl_line *lines;
++};
++
++struct rstctl_dev {
++ struct list_head node;
++ struct device *dev;
++ const struct rstctl_desc *rdesc;
++ struct list_head handles;
++};
++
++struct rstctl {
++ struct list_head node; /* linked all in */
++ struct device *dev; /* the user */
++ struct rstctl_dev *rdev; /* the controler */
++ const struct rstctl_line *line;
++ const char *label;
++};
++
++/* driver API */
++struct rstctl_dev *rstctl_register(struct device *dev,
++ const struct rstctl_desc *rdesc);
++int rstctl_unregister(struct rstctl_dev *rdev);
++
++/* consumer API */
++struct rstctl *rstctl_get(struct device *dev, const char *id);
++void rstctl_put(struct rstctl *rctrl);
++
++int rstctl_assert(struct rstctl *rctrl);
++int rstctl_deassert(struct rstctl *rctrl);
++int rstctl_pulse(struct rstctl *rctrl, unsigned long hold_ns);
++
++#endif
diff --git a/patches/linux-3.8.13/0599-omap_hsmmc-Enable-rstctl-bindings.patch b/patches/linux-3.8.13/0599-omap_hsmmc-Enable-rstctl-bindings.patch
new file mode 100644
index 0000000..8e278f4
--- /dev/null
+++ b/patches/linux-3.8.13/0599-omap_hsmmc-Enable-rstctl-bindings.patch
@@ -0,0 +1,82 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 22 Apr 2013 20:32:40 +0300
+Subject: [PATCH] omap_hsmmc: Enable rstctl bindings.
+
+Use the rstctl resource if that's available. If not, don't
+probe the device.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/mmc/host/omap_hsmmc.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
+index 7a35c8e..f6f5875 100644
+--- a/drivers/mmc/host/omap_hsmmc.c
++++ b/drivers/mmc/host/omap_hsmmc.c
+@@ -44,6 +44,7 @@
+ #include <linux/err.h>
+ #include <mach/hardware.h>
+ #include <plat/cpu.h>
++#include <linux/rstctl.h>
+
+ /* OMAP HSMMC Host Controller Registers */
+ #define OMAP_HSMMC_SYSSTATUS 0x0014
+@@ -187,6 +188,8 @@ struct omap_hsmmc_host {
+ struct omap_hsmmc_next next_data;
+
+ struct omap_mmc_platform_data *pdata;
++
++ struct rstctl *rstctl;
+ };
+
+ static int omap_hsmmc_card_detect(struct device *dev, int slot)
+@@ -1810,6 +1813,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
+ unsigned tx_req, rx_req;
+ struct dmaengine_chan_caps *dma_chan_caps;
+ struct pinctrl *pinctrl;
++ struct rstctl *rctrl;
+
+ match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev);
+ if (match) {
+@@ -1830,6 +1834,24 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
+ return -ENXIO;
+ }
+
++ /* request reset control (bail if deffering) */
++ rctrl = rstctl_get(&pdev->dev, NULL);
++ if (IS_ERR(rctrl)) {
++ if (PTR_ERR(rctrl) == -EPROBE_DEFER) {
++ dev_info(&pdev->dev, "Loading deferred\n");
++ return -EPROBE_DEFER;
++ }
++ dev_info(&pdev->dev, "Failed to get rstctl\n");
++ rctrl = NULL;
++ } else {
++ dev_info(&pdev->dev, "Got rstctl (%s:#%d name %s) label:%s\n",
++ rctrl->rdev->rdesc->name,
++ rctrl->line - rctrl->rdev->rdesc->lines,
++ rctrl->line->name, rctrl->label);
++
++ rstctl_deassert(rctrl);
++ }
++
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl))
+ dev_warn(&pdev->dev, "unable to select pin group\n");
+@@ -1865,6 +1887,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
+ host->base = ioremap(host->mapbase, SZ_4K);
+ host->power_mode = MMC_POWER_OFF;
+ host->next_data.cookie = 1;
++ host->rstctl = rctrl;
+
+ platform_set_drvdata(pdev, host);
+
+@@ -2130,6 +2153,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
+
+ omap_hsmmc_gpio_free(host->pdata);
+ iounmap(host->base);
++ rstctl_put(host->rstctl);
+ mmc_free_host(host->mmc);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/patches/linux-3.8.13/0600-bone-Add-rstctl-DT-binding-for-beaglebone.patch b/patches/linux-3.8.13/0600-bone-Add-rstctl-DT-binding-for-beaglebone.patch
new file mode 100644
index 0000000..ca8f3d8
--- /dev/null
+++ b/patches/linux-3.8.13/0600-bone-Add-rstctl-DT-binding-for-beaglebone.patch
@@ -0,0 +1,77 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 22 Apr 2013 20:36:35 +0300
+Subject: [PATCH] bone: Add rstctl DT binding for beaglebone
+
+Add a reset control resource for the eMMC's reset GPIO.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ arch/arm/boot/dts/am335x-bone-common.dtsi | 6 ++++++
+ arch/arm/boot/dts/am335x-boneblack.dts | 24 ++++++++++++++++++++++++
+ 2 files changed, 30 insertions(+)
+
+diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
+index 89ec6f2..e341a08 100644
+--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
+@@ -50,6 +50,12 @@
+ };
+
+ ocp: ocp {
++
++ /* reset controller comes first (even if disabled) */
++ rstctl: rstctl@0 {
++ status = "disabled";
++ };
++
+ uart1: serial@44e09000 {
+ status = "okay";
+ };
+diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts
+index a35a106..1545cca 100644
+--- a/arch/arm/boot/dts/am335x-boneblack.dts
++++ b/arch/arm/boot/dts/am335x-boneblack.dts
+@@ -11,12 +11,33 @@
+
+ /include/ "am335x-bone-common.dtsi"
+
++&am33xx_pinmux {
++ rstctl_pins: pinmux_rstctl_pins {
++ pinctrl-single,pins = <
++ /* eMMC_RSTn */
++ 0x50 0x17 /* gpmc_a4.gpio1_20, OUTPUT | MODE7 | PULLUP */
++ >;
++ };
++};
++
+ &ldo3_reg {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
++&rstctl {
++ status = "okay";
++ compatible = "gpio-rctrl";
++ pinctrl-names = "default";
++ pinctrl-0 = <&rstctl_pins>;
++
++ #reset-cells = <2>;
++
++ gpios = <&gpio2 20 0x00>;
++ gpio-names = "eMMC_RSTn";
++};
++
+ &mmc1 {
+ vmmc-supply = <&vmmcsd_fixed>;
+ };
+@@ -26,6 +47,9 @@
+ bus-width = <8>;
+ ti,non-removable;
+ status = "okay";
++
++ reset = <&rstctl 0 0>;
++ reset-names = "eMMC_RSTn-CONSUMER";
+ };
+
+
diff --git a/patches/linux-3.8.13/0601-bone-eMMC-Add-rstctl-rstctl-DT-bindings.patch b/patches/linux-3.8.13/0601-bone-eMMC-Add-rstctl-rstctl-DT-bindings.patch
new file mode 100644
index 0000000..5ec01ec
--- /dev/null
+++ b/patches/linux-3.8.13/0601-bone-eMMC-Add-rstctl-rstctl-DT-bindings.patch
@@ -0,0 +1,64 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 22 Apr 2013 20:38:11 +0300
+Subject: [PATCH] bone-eMMC: Add rstctl rstctl DT bindings
+
+Add the references to the reset controller for the eMMC capes.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ firmware/capes/BB-BONE-eMMC1-01-00A0.dts | 7 +++----
+ firmware/capes/cape-bone-2g-emmc1.dts | 7 +++----
+ 2 files changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/firmware/capes/BB-BONE-eMMC1-01-00A0.dts b/firmware/capes/BB-BONE-eMMC1-01-00A0.dts
+index ebac267..0776bee 100644
+--- a/firmware/capes/BB-BONE-eMMC1-01-00A0.dts
++++ b/firmware/capes/BB-BONE-eMMC1-01-00A0.dts
+@@ -30,9 +30,6 @@
+ 0x14 0x31 /* gpmc_ad5.mmc1_dat5, INPUT_PULLUP | MODE1 */
+ 0x18 0x31 /* gpmc_ad6.mmc1_dat6, INPUT_PULLUP | MODE1 */
+ 0x1c 0x31 /* gpmc_ad7.mmc1_dat7, INPUT_PULLUP | MODE1 */
+-
+- /* the reset */
+- 0x50 0x17 /* gpmc_a4.gpio1_20, OUTPUT | MODE7 | PULLUP */
+ >;
+ };
+ };
+@@ -46,8 +43,10 @@
+ bus-width = <8>;
+ ti,non-removable;
+ status = "okay";
+- reset-gpios = <&gpio2 20 1>; /* active low */
+ ti,vcc-aux-disable-is-sleep;
++
++ reset = <&rstctl 0 0>;
++ reset-names = "eMMC_RSTn";
+ };
+ };
+ };
+diff --git a/firmware/capes/cape-bone-2g-emmc1.dts b/firmware/capes/cape-bone-2g-emmc1.dts
+index 69bb684..bf26ae1 100644
+--- a/firmware/capes/cape-bone-2g-emmc1.dts
++++ b/firmware/capes/cape-bone-2g-emmc1.dts
+@@ -31,9 +31,6 @@
+ 0x14 0x31 /* gpmc_ad5.mmc1_dat5, INPUT_PULLUP | MODE1 */
+ 0x18 0x31 /* gpmc_ad6.mmc1_dat6, INPUT_PULLUP | MODE1 */
+ 0x1c 0x31 /* gpmc_ad7.mmc1_dat7, INPUT_PULLUP | MODE1 */
+-
+- /* the reset */
+- 0x50 0x17 /* gpmc_a4.gpio1_20, OUTPUT | MODE7 | PULLUP */
+ >;
+ };
+ };
+@@ -47,8 +44,10 @@
+ bus-width = <8>;
+ ti,non-removable;
+ status = "okay";
+- reset-gpios = <&gpio2 20 1>; /* active low */
+ ti,vcc-aux-disable-is-sleep;
++
++ reset = <&rstctl 0 0>;
++ reset-names = "eMMC_RSTn";
+ };
+ };
+ };
diff --git a/patches/linux-3.8.13/0602-capes-Add-testing-capes-for-rstctl.patch b/patches/linux-3.8.13/0602-capes-Add-testing-capes-for-rstctl.patch
new file mode 100644
index 0000000..72ae35a
--- /dev/null
+++ b/patches/linux-3.8.13/0602-capes-Add-testing-capes-for-rstctl.patch
@@ -0,0 +1,115 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 22 Apr 2013 20:40:07 +0300
+Subject: [PATCH] capes: Add testing capes for rstctl
+
+Add a couple of reset control capes for testing rstctl
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ firmware/capes/BB-BONE-RST-00A0.dts | 62 ++++++++++++++++++++++++++++++++++
+ firmware/capes/BB-BONE-RST2-00A0.dts | 27 +++++++++++++++
+ 2 files changed, 89 insertions(+)
+ create mode 100644 firmware/capes/BB-BONE-RST-00A0.dts
+ create mode 100644 firmware/capes/BB-BONE-RST2-00A0.dts
+
+diff --git a/firmware/capes/BB-BONE-RST-00A0.dts b/firmware/capes/BB-BONE-RST-00A0.dts
+new file mode 100644
+index 0000000..acdcda4
+--- /dev/null
++++ b/firmware/capes/BB-BONE-RST-00A0.dts
+@@ -0,0 +1,62 @@
++/*
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "BB-BONE-RST";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&ocp>;
++ __overlay__ {
++ test_rctrl: test_reset {
++ compatible = "test-rctrl";
++ #reset-cells = <2>;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ test_consumer_rctrl: test_consumer_reset {
++ compatible = "test-consumer-rctrl";
++
++ reset = <&test_rctrl 0 0>;
++ reset-names = "RESET_1";
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&ocp>;
++ __overlay__ {
++ gpio_rctrl: gpio_reset {
++ compatible = "gpio-rctrl";
++ #reset-cells = <2>;
++
++ gpios = <&gpio2 28 0x1>, <&gpio2 29 0x0>;
++ gpio-names = "HDMI-reset", "eMMC-reset";
++ };
++ };
++ };
++
++ fragment@3 {
++ target = <&ocp>;
++ __overlay__ {
++ gpio_consumer_rctrl:gpio_consumer_reset {
++ compatible = "test-consumer-rctrl";
++
++ reset = <&gpio_rctrl 0 0>, <&gpio_rctrl 1 0>;
++ reset-names = "RESET_1", "RESET_2";
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/BB-BONE-RST2-00A0.dts b/firmware/capes/BB-BONE-RST2-00A0.dts
+new file mode 100644
+index 0000000..6904cc5
+--- /dev/null
++++ b/firmware/capes/BB-BONE-RST2-00A0.dts
+@@ -0,0 +1,27 @@
++/*
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "BB-BONE-RST2";
++ version = "00A0";
++
++ fragment@0 {
++ target = <&ocp>;
++ __overlay__ {
++ emmc_reset_consumer_rctrl: emmc_reset_consumer {
++ compatible = "test-consumer-rctrl";
++
++ reset = <&rstctl 0 0>;
++ reset-names = "eMMC_RSTn-CONSUMER";
++ };
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0603-omap_hsmmc-Bail-out-when-rstctl-error-is-unrecoverab.patch b/patches/linux-3.8.13/0603-omap_hsmmc-Bail-out-when-rstctl-error-is-unrecoverab.patch
new file mode 100644
index 0000000..25dffb5
--- /dev/null
+++ b/patches/linux-3.8.13/0603-omap_hsmmc-Bail-out-when-rstctl-error-is-unrecoverab.patch
@@ -0,0 +1,35 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 22 Apr 2013 17:05:53 +0300
+Subject: [PATCH] omap_hsmmc: Bail out when rstctl error is unrecoverable
+
+Make sure that when a rstctl resource is requested, but unavailable
+to fail the device probe.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/mmc/host/omap_hsmmc.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
+index f6f5875..e2b97df 100644
+--- a/drivers/mmc/host/omap_hsmmc.c
++++ b/drivers/mmc/host/omap_hsmmc.c
+@@ -1837,11 +1837,15 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
+ /* request reset control (bail if deffering) */
+ rctrl = rstctl_get(&pdev->dev, NULL);
+ if (IS_ERR(rctrl)) {
+- if (PTR_ERR(rctrl) == -EPROBE_DEFER) {
+- dev_info(&pdev->dev, "Loading deferred\n");
++ ret = PTR_ERR(rctrl);
++ if (ret == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
++
++ if (ret != -ENODEV && ret != -ENOENT) {
++ dev_err(&pdev->dev, "Unrecoverable rstctl error\n");
++ return PTR_ERR(rctrl);
+ }
+- dev_info(&pdev->dev, "Failed to get rstctl\n");
++ dev_warn(&pdev->dev, "Failed to get rstctl; not using any\n");
+ rctrl = NULL;
+ } else {
+ dev_info(&pdev->dev, "Got rstctl (%s:#%d name %s) label:%s\n",
diff --git a/patches/linux-3.8.13/0604-bone-Put-priorities-in-built-in-capes.patch b/patches/linux-3.8.13/0604-bone-Put-priorities-in-built-in-capes.patch
new file mode 100644
index 0000000..c9daa76
--- /dev/null
+++ b/patches/linux-3.8.13/0604-bone-Put-priorities-in-built-in-capes.patch
@@ -0,0 +1,114 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 22 Apr 2013 17:08:09 +0300
+Subject: [PATCH] bone: Put priorities in built-in capes
+
+Place priority entries to built-in cape entries. That way we can
+make sure that the add one capes take precedence
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ arch/arm/boot/dts/am335x-bone-common.dtsi | 44 +++++++++++++++++------------
+ arch/arm/boot/dts/am33xx.dtsi | 5 ++++
+ 2 files changed, 31 insertions(+), 18 deletions(-)
+
+diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
+index e341a08..327e592 100644
+--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
+@@ -25,7 +25,7 @@
+
+ am33xx_pinmux: pinmux@44e10800 {
+ pinctrl-names = "default";
+- pinctrl-0 = <&userleds_pins>;
++ pinctrl-0 = <&userled_pins>;
+
+ userled_pins: pinmux_userled_pins {
+ pinctrl-single,pins = <
+@@ -51,11 +51,6 @@
+
+ ocp: ocp {
+
+- /* reset controller comes first (even if disabled) */
+- rstctl: rstctl@0 {
+- status = "disabled";
+- };
+-
+ uart1: serial@44e09000 {
+ status = "okay";
+ };
+@@ -138,10 +133,10 @@
+ slot@4 {
+ ti,cape-override;
+ compatible = "ti,beaglebone-black";
+- board-name = "Bone-LT-eMMC-2G";
++ board-name = "BB-BONE-RST2";
+ version = "00A0";
+ manufacturer = "Texas Instruments";
+- part-number = "BB-BONE-EMMC-2G";
++ part-number = "BB-BONE-RST2";
+ };
+
+ /* geiger cape version A0 without an EEPROM */
+@@ -154,16 +149,6 @@
+ part-number = "BB-BONE-GEIGER";
+ };
+
+- /* Beaglebone black has it soldered on */
+- slot@6 {
+- ti,cape-override;
+- compatible = "ti,beaglebone-black";
+- board-name = "Bone-Black-HDMI";
+- version = "00A0";
+- manufacturer = "Texas Instruments";
+- part-number = "BB-BONELT-HDMI";
+- };
+-
+ /* Nixie cape version A0 without an EEPROM */
+ slot@7 {
+ ti,cape-override;
+@@ -221,6 +206,29 @@
+ manufacturer = "Adafruit";
+ part-number = "BB-BONE-RS232-01";
+ };
++
++ /* Beaglebone black has it soldered on */
++ slot@100 {
++ ti,cape-override;
++ priority = <1>;
++ compatible = "ti,beaglebone-black";
++ board-name = "Bone-LT-eMMC-2G";
++ version = "00A0";
++ manufacturer = "Texas Instruments";
++ part-number = "BB-BONE-EMMC-2G";
++ };
++
++ /* Beaglebone black has it soldered on */
++ slot@101 {
++ ti,cape-override;
++ priority = <1>;
++ compatible = "ti,beaglebone-black";
++ board-name = "Bone-Black-HDMI";
++ version = "00A0";
++ manufacturer = "Texas Instruments";
++ part-number = "BB-BONELT-HDMI";
++ };
++
+ };
+
+ /* mapping between board names and dtb objects */
+diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
+index 76fa03b..eb0d2d4 100644
+--- a/arch/arm/boot/dts/am33xx.dtsi
++++ b/arch/arm/boot/dts/am33xx.dtsi
+@@ -155,6 +155,11 @@
+ interrupts = <62>;
+ };
+
++ /* reset controller comes first (even if disabled) */
++ rstctl: rstctl@0 {
++ status = "disabled";
++ };
++
+ uart1: serial@44e09000 {
+ compatible = "ti,omap3-uart";
+ ti,hwmods = "uart1";
diff --git a/patches/linux-3.8.13/0605-bone-common-dtsi-remove-reset-cape.patch b/patches/linux-3.8.13/0605-bone-common-dtsi-remove-reset-cape.patch
new file mode 100644
index 0000000..bad7a0d
--- /dev/null
+++ b/patches/linux-3.8.13/0605-bone-common-dtsi-remove-reset-cape.patch
@@ -0,0 +1,30 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Thu, 2 May 2013 14:15:13 +0200
+Subject: [PATCH] bone-common dtsi: remove reset cape
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/boot/dts/am335x-bone-common.dtsi | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
+index 327e592..ae407c3 100644
+--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
+@@ -129,16 +129,6 @@
+ eeprom = <&cape_eeprom3>;
+ };
+
+- /* Beaglebone black has it soldered on */
+- slot@4 {
+- ti,cape-override;
+- compatible = "ti,beaglebone-black";
+- board-name = "BB-BONE-RST2";
+- version = "00A0";
+- manufacturer = "Texas Instruments";
+- part-number = "BB-BONE-RST2";
+- };
+-
+ /* geiger cape version A0 without an EEPROM */
+ slot@5 {
+ ti,cape-override;
diff --git a/patches/linux-3.8.13/0606-mmc-add-missing-select-RSTCTL-in-MMC_OMAP.patch b/patches/linux-3.8.13/0606-mmc-add-missing-select-RSTCTL-in-MMC_OMAP.patch
new file mode 100644
index 0000000..4e1b693
--- /dev/null
+++ b/patches/linux-3.8.13/0606-mmc-add-missing-select-RSTCTL-in-MMC_OMAP.patch
@@ -0,0 +1,24 @@
+From: Matt Ranostay <mranostay@gmail.com>
+Date: Sat, 25 May 2013 20:36:52 +0000
+Subject: [PATCH] mmc: add missing select RSTCTL in MMC_OMAP
+
+CONFIG_MMC_OMAP requires CONFIG_RSTCTL to compile and
+should be selected
+
+Signed-off-by: Matt Ranostay <mranostay@gmail.com>
+---
+ drivers/mmc/host/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
+index 009dabd..86d81ee 100644
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -245,6 +245,7 @@ config MMC_OMAP
+ tristate "TI OMAP Multimedia Card Interface support"
+ depends on ARCH_OMAP
+ select TPS65010 if MACH_OMAP_H2
++ select RSTCTL
+ help
+ This selects the TI OMAP Multimedia card Interface.
+ If you have an OMAP board with a Multimedia Card slot,
diff --git a/patches/linux-3.8.13/0607-soc_camera-QL-mt9l112-camera-driver-for-the-beaglebo.patch b/patches/linux-3.8.13/0607-soc_camera-QL-mt9l112-camera-driver-for-the-beaglebo.patch
new file mode 100644
index 0000000..208feb2
--- /dev/null
+++ b/patches/linux-3.8.13/0607-soc_camera-QL-mt9l112-camera-driver-for-the-beaglebo.patch
@@ -0,0 +1,1606 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 1 May 2013 17:43:32 +0300
+Subject: [PATCH] soc_camera: QL/mt9l112 camera driver for the beaglebone
+
+Driver for the Quicklogic camera cape.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/media/platform/soc_camera/Kconfig | 7 +
+ drivers/media/platform/soc_camera/Makefile | 1 +
+ drivers/media/platform/soc_camera/cssp_camera.c | 1560 +++++++++++++++++++++++
+ 3 files changed, 1568 insertions(+)
+ create mode 100644 drivers/media/platform/soc_camera/cssp_camera.c
+
+diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
+index cb6791e..06baabf 100644
+--- a/drivers/media/platform/soc_camera/Kconfig
++++ b/drivers/media/platform/soc_camera/Kconfig
+@@ -86,3 +86,10 @@ config VIDEO_ATMEL_ISI
+ This module makes the ATMEL Image Sensor Interface available
+ as a v4l2 device.
+
++config VIDEO_QL_CAMIF
++ tristate "QuickLogic Camera Interface support (EXPERIMENTAL)"
++ depends on VIDEO_DEV && SOC_CAMERA && SOC_AM33XX && EXPERIMENTAL
++ select VIDEOBUF2_DMA_CONTIG
++ ---help---
++ This is a v4l2 driver for the QuickLogic CAMIF controller.
++
+diff --git a/drivers/media/platform/soc_camera/Makefile b/drivers/media/platform/soc_camera/Makefile
+index 136b7f8..d7ba0eb 100644
+--- a/drivers/media/platform/soc_camera/Makefile
++++ b/drivers/media/platform/soc_camera/Makefile
+@@ -10,5 +10,6 @@ obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o
+ obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
+ obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
+ obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o
++obj-$(CONFIG_VIDEO_QL_CAMIF) += cssp_camera.o
+
+ ccflags-y += -I$(srctree)/drivers/media/i2c/soc_camera
+diff --git a/drivers/media/platform/soc_camera/cssp_camera.c b/drivers/media/platform/soc_camera/cssp_camera.c
+new file mode 100644
+index 0000000..41de42e
+--- /dev/null
++++ b/drivers/media/platform/soc_camera/cssp_camera.c
+@@ -0,0 +1,1560 @@
++/*
++ * cssp-camera driver
++ *
++ * Based on Vivi driver
++ *
++ * Copyright (C) 2012 QuickLogic Corp.
++ *
++ * Developed for QuickLogic by:
++ * Damian Eppel <damian.eppel@teleca.com>
++ * Przemek Szewczyk <przemek.szewczyk@teleca.com>
++ * Dan Aizenstros <daizenstros@quicklogic.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ */
++
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/gpio.h>
++#include <linux/i2c.h>
++#include <linux/delay.h>
++#include <linux/spinlock.h>
++#include <linux/dma-mapping.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/dmaengine.h>
++#include <linux/dma-mapping.h>
++#include <linux/platform_data/edma.h>
++#include <linux/clk.h>
++// V4L2 Interface *********************
++#include <media/soc_camera.h>
++#include <media/v4l2-mediabus.h>
++#include <media/videobuf2-dma-contig.h>
++#include <media/v4l2-ioctl.h>
++#include <media/v4l2-event.h>
++#include <media/mt9t112.h>
++//*************************************
++#include <linux/of.h>
++#include <linux/of_platform.h>
++#include <linux/of_dma.h>
++#include <linux/of_gpio.h>
++#include <linux/of_i2c.h>
++
++static unsigned video_nr = -1;
++module_param(video_nr, uint, 0644);
++MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
++
++static unsigned int vid_limit = 6;
++module_param(vid_limit, uint, 0644);
++MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
++
++#define VGA_WIDTH 640
++#define VGA_HEIGHT 480
++
++#define MAX_WIDTH 2048
++#define MAX_HEIGHT 1536
++
++#define VGA_RES (VGA_WIDTH * VGA_HEIGHT)
++#define BYTES_PER_PIXEL 2
++
++/* PaRAM.opt: */
++#define TCC(v) (((v) & 0x3f) << 12)
++/* PaRAM.a_b_cnt: */
++#define ACNT(v) ((v) & 0xffff)
++#define BCNT(v) (((v) & 0xffff) << 16)
++/* PaRAM.src_dst_bidx: */
++#define SRCBIDX(v) ((v) & 0xffff)
++#define DSTBIDX(v) (((v) & 0xffff) << 16)
++/* PaRAM.link_bcntrld: */
++#define LINK(v) ((v) & 0xffff)
++#define BCNTRLD(v) (((v) & 0xffff) << 16)
++/* PaRAM.src_dst_cidx: */
++#define SRCCIDX(v) ((v) & 0xffff)
++#define DSTCIDX(v) (((v) & 0xffff) << 16)
++/* PaRAM.ccnt: */
++#define CCNT(v) ((v) & 0xffff)
++
++
++struct cssp_cam_platform_data {
++ struct i2c_board_info *cam_i2c_board_info;
++ const char *cam_clk_name;
++ u32 cam_clk_rate;
++ int dma_ch;
++ int gpio_reset_pin;
++};
++
++struct cssp_cam_platform_data_storage {
++ struct cssp_cam_platform_data pdata;
++ struct i2c_board_info i2c_camera;
++ struct soc_camera_link camera_link;
++ /* only support mt9t112 for now */
++ struct mt9t112_camera_info mt9t111_cam_info;
++};
++
++#define to_cssp_platform_data_storage(_x) container_of(_x, \
++ struct cssp_cam_platform_data_storage, pdata)
++
++
++/* ------------------------------------------------------------------
++ video Basic structures
++ ------------------------------------------------------------------*/
++
++struct cssp_cam_fmt {
++ char *name;
++ u32 fourcc; /* v4l2 format id */
++ int depth;
++ enum v4l2_mbus_pixelcode code;
++};
++
++/* buffer for one video frame */
++struct cssp_cam_buffer {
++ /* common v4l buffer stuff -- must be first */
++ struct vb2_buffer vb;
++ struct list_head list;
++ struct cssp_cam_fmt *fmt;
++};
++
++struct cssp_cam_dmaqueue {
++ struct list_head active;
++};
++
++struct cssp_cam_dev {
++ struct v4l2_device v4l2_dev;
++ struct v4l2_ctrl_handler ctrl_handler;
++ struct v4l2_subdev *subdev;
++
++ spinlock_t slock;
++ struct mutex mutex;
++
++ /* various device info */
++ struct video_device *vdev;
++ struct platform_device *pdev;
++
++ struct cssp_cam_dmaqueue vidq;
++ void *dma_cont_ctx;
++ int streaming_started;
++ struct vb2_buffer *current_vb;
++
++ /* video capture */
++ struct cssp_cam_fmt *fmt;
++ u32 width;
++ u32 height;
++ u32 bytesperline;
++ u32 sizeimage;
++ enum v4l2_colorspace colorspace;
++ struct vb2_queue vb_vidq;
++ enum v4l2_field field;
++
++ /* Camera Sensor */
++ struct i2c_board_info *camera_board_info;
++ struct clk *camera_clk;
++
++ void __iomem *reg_base_virt;
++ unsigned int reg_base_phys;
++ resource_size_t reg_size;
++ u16 mode;
++
++ int dma_ch;
++ struct edmacc_param dma_tr_params;
++
++ u64 dma_mask;
++ int dma_req_len;
++
++ int frame_cnt;
++
++ int reset_pin;
++
++ int rev;
++
++ /* OF build platform data here */
++ struct cssp_cam_platform_data_storage *pstore;
++};
++
++/*
++ * ---------------------------------------------------------------------------
++ * QuickLoigc Camera Interface registers
++ * ---------------------------------------------------------------------------
++ */
++
++#define REG_MODE 0x00000
++#define REG_DATA 0x10000
++
++/* MODE bit shifts */
++#define FMT_2X8_EN BIT(15) /* Enable 2 byte format on CAMIF bus (0 - 10 bit, 1 - 16 bit 2x8) */
++#define PCLK_POL BIT(14) /* PCLK polarity (0 - rising edge, 1 - falling edge */
++#define HS_EN BIT(13) /* High speed bus (0 =< 50 MHz, 1 > 50 MHz) */
++#define ENABLE BIT(12)
++#define LDR_EN BIT(11) /* Large DMA Request Support (0 - 32 bytes, 1 - 128 bytes) */
++#define REV 0xFF /* Chip Revision mask */
++
++
++static struct cssp_cam_fmt formats[] = {
++ {
++ .name = "4:2:2, packed, YUYV",
++ .fourcc = V4L2_PIX_FMT_YUYV,
++ .depth = 16,
++ .code = V4L2_MBUS_FMT_YUYV8_2X8,
++ },
++/*
++ * UYVY doesn't work properly. VYUY and YVYU are not tested.
++ * So disable the UYVY, VYUY and YVYU modes for now
++ */
++#if 0
++ {
++ .name = "4:2:2, packed, UYVY",
++ .fourcc = V4L2_PIX_FMT_UYVY,
++ .depth = 16,
++ .code = V4L2_MBUS_FMT_UYVY8_2X8,
++ },
++ {
++ .name = "4:2:2, packed, VYUY",
++ .fourcc = V4L2_PIX_FMT_VYUY,
++ .depth = 16,
++ .code = V4L2_MBUS_FMT_VYUY8_2X8,
++ },
++ {
++ .name = "4:2:2, packed, YVYU",
++ .fourcc = V4L2_PIX_FMT_YVYU,
++ .depth = 16,
++ .code = V4L2_MBUS_FMT_YVYU8_2X8,
++ },
++#endif
++ {
++ .name = "RGB565 (LE)",
++ .fourcc = V4L2_PIX_FMT_RGB565,
++ .depth = 16,
++ .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
++ },
++ {
++ .name = "RGB555 (LE)",
++ .fourcc = V4L2_PIX_FMT_RGB555,
++ .depth = 16,
++ .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
++ },
++};
++
++
++/***************************************************************************/
++
++
++static int configure_gpio(int nr, int val, const char *name)
++{
++ unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
++ int ret;
++ if (!gpio_is_valid(nr))
++ return 0;
++ ret = gpio_request_one(nr, flags, name);
++ if (!ret)
++ gpio_export(nr, 0);
++ return ret;
++}
++
++static int reset_cssp(struct cssp_cam_dev *cam)
++{
++ struct platform_device *pdev = cam->pdev;
++ struct cssp_cam_platform_data *pdata = pdev->dev.platform_data;
++ int err;
++
++ cam->reset_pin = pdata->gpio_reset_pin;
++ if (!gpio_is_valid(cam->reset_pin))
++ return 0;
++
++ err = configure_gpio(cam->reset_pin, 0, "cssp_reset");
++ if (err) {
++ dev_err(&pdev->dev, "failed to configure cssp reset pin\n");
++ return -1;
++ }
++
++ mdelay(1);
++
++ gpio_direction_output(cam->reset_pin, 1);
++
++ return err;
++}
++
++static int trigger_dma_transfer_to_buf(struct cssp_cam_dev *dev, struct vb2_buffer *vb)
++{
++ dma_addr_t dma_buf = vb2_dma_contig_plane_dma_addr(vb, 0);
++
++ if (!dma_buf) {
++ /* Is this possible? Release the vb2_buffer with an error here, */
++ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
++ dev->current_vb = NULL;
++ return -ENOMEM;
++ }
++
++ dev->dma_tr_params.dst = dma_buf;
++
++ // Enable DMA
++ edma_write_slot(dev->dma_ch, &dev->dma_tr_params);
++
++ dev->current_vb = vb;
++
++ // Enable data capture
++ dev->mode |= ENABLE;
++ writew(dev->mode, dev->reg_base_virt + REG_MODE);
++ readw(dev->reg_base_virt + REG_MODE);
++
++ return 0;
++}
++
++static void dequeue_buffer_for_dma(struct cssp_cam_dev *dev)
++{
++ struct cssp_cam_dmaqueue *dma_q = &dev->vidq;
++ unsigned long flags = 0;
++
++ spin_lock_irqsave(&dev->slock, flags);
++ if (!list_empty(&dma_q->active)) {
++ struct cssp_cam_buffer *buf;
++
++ buf = list_entry(dma_q->active.next, struct cssp_cam_buffer, list);
++ list_del(&buf->list);
++ spin_unlock_irqrestore(&dev->slock, flags);
++
++ buf->fmt = dev->fmt;
++
++ trigger_dma_transfer_to_buf(dev, &buf->vb);
++ } else {
++ spin_unlock_irqrestore(&dev->slock, flags);
++ }
++}
++
++static void dma_callback(unsigned lch, u16 ch_status, void *data)
++{
++ struct cssp_cam_dev *dev = data;
++ struct vb2_buffer *vb;
++ struct edmacc_param dma_tr_params;
++
++ // Disable data capture
++ dev->mode &= ~ENABLE;
++ writew(dev->mode, dev->reg_base_virt + REG_MODE);
++ readw(dev->reg_base_virt + REG_MODE);
++
++ if (ch_status == DMA_COMPLETE) {
++
++ vb = dev->current_vb;
++
++ edma_read_slot(dev->dma_ch, &dma_tr_params);
++ if ((dma_tr_params.opt != 0) ||
++ (dma_tr_params.src != 0) ||
++ (dma_tr_params.a_b_cnt != 0) ||
++ (dma_tr_params.dst != 0) ||
++ (dma_tr_params.src_dst_bidx != 0) ||
++ (dma_tr_params.link_bcntrld != 0xffff) ||
++ (dma_tr_params.src_dst_cidx != 0) ||
++ (dma_tr_params.ccnt != 0)) {
++
++ trigger_dma_transfer_to_buf(dev, dev->current_vb);
++ return;
++ }
++
++ vb->v4l2_buf.field = dev->field;
++ vb->v4l2_buf.sequence = dev->frame_cnt++;
++ do_gettimeofday(&vb->v4l2_buf.timestamp);
++ vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
++ dev->current_vb = NULL;
++
++ /* check if we have new buffer queued */
++ dequeue_buffer_for_dma(dev);
++ } else {
++ /* we got a missed interrupt so just start a new DMA with the existing buffer */
++ if (dev->current_vb != NULL) {
++ if (trigger_dma_transfer_to_buf(dev, dev->current_vb))
++ dev_err(&dev->pdev->dev, "No buffer allocated!\n");
++ }
++ }
++}
++
++static int configure_edma(struct cssp_cam_dev *cam)
++{
++ struct platform_device *pdev = cam->pdev;
++ struct cssp_cam_platform_data *pdata = pdev->dev.platform_data;
++ struct edmacc_param *param;
++ int dma_channel;
++
++ dma_channel = pdata->dma_ch;
++
++ /* wtf? do we need to this here? */
++ pdev->dev.dma_mask = &cam->dma_mask;
++ pdev->dev.coherent_dma_mask = (u32)~0;
++ if (dma_set_mask(&pdev->dev, (u32)~0)) {
++ dev_err(&pdev->dev, "failed setting mask for DMA\n");
++ return -EINVAL;
++ }
++ cam->dma_ch = edma_alloc_channel(dma_channel, dma_callback, cam, EVENTQ_0);
++ if (cam->dma_ch < 0) {
++ dev_err(&pdev->dev, "allocating channel for DMA failed\n");
++ return -EBUSY;
++ }
++
++ cam->dma_req_len = cam->rev > 3 ? 128 : 32;
++
++ param = &cam->dma_tr_params;
++ param->opt = TCINTEN | TCC(cam->dma_ch);
++ param->src = cam->reg_base_phys + REG_DATA;
++ param->a_b_cnt = ACNT(cam->dma_req_len) |
++ BCNT((VGA_WIDTH * BYTES_PER_PIXEL) / cam->dma_req_len);
++ param->src_dst_bidx = SRCBIDX(0) | DSTBIDX(cam->dma_req_len);
++ param->link_bcntrld = BCNTRLD((VGA_WIDTH * BYTES_PER_PIXEL) /
++ cam->dma_req_len) | LINK(0xffff);
++ param->src_dst_cidx = SRCCIDX(0) | DSTCIDX(cam->dma_req_len);
++ param->ccnt = CCNT(VGA_HEIGHT);
++
++ return 0;
++}
++
++static int configure_cssp(struct cssp_cam_dev *cam)
++{
++ struct platform_device *pdev = cam->pdev;
++ int ret = 0;
++ unsigned int val;
++ struct resource *res;
++
++ ret = reset_cssp(cam);
++ if (ret)
++ return ret;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (res == NULL) {
++ dev_err(&pdev->dev, "no mem resource\n");
++ return -ENODEV;
++ }
++
++ /*
++ * Request the region.
++ */
++ if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
++ dev_err(&pdev->dev, "request_mem_region failed\n");
++ return -EBUSY;
++ }
++
++ cam->reg_base_phys = res->start;
++ cam->reg_size = resource_size(res);
++
++ cam->reg_base_virt = ioremap(cam->reg_base_phys, cam->reg_size);
++ if (cam->reg_base_virt == NULL) {
++ dev_err(&pdev->dev, "ioremap of registers region failed\n");
++ release_mem_region(cam->reg_base_phys, cam->reg_size);
++ return -ENOMEM;
++ }
++
++ /* double reads */
++ readw(cam->reg_base_virt + REG_MODE);
++ val = readw(cam->reg_base_virt + REG_MODE);
++ cam->rev = val & REV;
++ dev_info(&pdev->dev, "CSSP Revision %c%d\n",
++ 'A' + ((cam->rev & 0xf0) >> 4), cam->rev & 0x0f);
++
++ cam->dma_req_len = cam->rev > 3 ? 128 : 32;
++
++ return 0;
++}
++
++static int configure_camera_sensor(struct cssp_cam_dev *cam)
++{
++ struct i2c_board_info *info = cam->camera_board_info;
++ struct i2c_client *client;
++ struct i2c_adapter *adapter;
++ struct v4l2_subdev *subdev;
++ struct v4l2_mbus_framefmt f_format = {
++ .width = VGA_WIDTH,
++ .height = VGA_HEIGHT,
++ .code = V4L2_MBUS_FMT_YUYV8_2X8,
++ .colorspace = V4L2_COLORSPACE_JPEG,
++ };
++
++ /* Enable the clock just for the time of loading the camera driver and disable after that */
++ /* It is going to be be re-enabled later, when camera will be in use */
++ clk_enable(cam->camera_clk);
++ udelay(5); // let the clock stabilize
++
++ adapter = i2c_get_adapter(((struct soc_camera_link *)(info->platform_data))->i2c_adapter_id);
++ if (!adapter) {
++ dev_err(&cam->pdev->dev, "failed to get i2c adapter...\n");
++ return -ENODEV;
++ }
++
++ client = i2c_new_device(adapter, info);
++ i2c_put_adapter(adapter);
++
++ if (client == NULL) {
++ return -ENODEV;
++ }
++
++ subdev = (struct v4l2_subdev *)i2c_get_clientdata(client);
++ if (subdev == NULL) {
++ i2c_unregister_device(client);
++ return -ENODEV;
++ }
++
++ cam->subdev = subdev;
++
++ v4l2_subdev_call(subdev, video, s_mbus_fmt, &f_format);
++
++ clk_disable(cam->camera_clk);
++
++ return 0;
++}
++
++static int start_camera_sensor(struct cssp_cam_dev *cam)
++{
++ clk_enable(cam->camera_clk);
++ udelay(5); /* let the clock stabilize */
++
++ v4l2_subdev_call(cam->subdev, video, s_stream, 1);
++
++ return 0;
++}
++
++static void stop_camera_sensor(struct cssp_cam_dev *cam)
++{
++ v4l2_subdev_call(cam->subdev, video, s_stream, 0);
++
++ clk_disable(cam->camera_clk);
++
++ return;
++}
++
++static struct cssp_cam_fmt *get_format(struct v4l2_format *f)
++{
++ struct cssp_cam_fmt *fmt;
++ unsigned int k;
++
++ for (k = 0; k < ARRAY_SIZE(formats); k++) {
++ fmt = &formats[k];
++ if (fmt->fourcc == f->fmt.pix.pixelformat)
++ break;
++ }
++
++ if (k == ARRAY_SIZE(formats))
++ return NULL;
++
++ return &formats[k];
++}
++
++
++/* ------------------------------------------------------------------
++ Videobuf operations
++ ------------------------------------------------------------------*/
++
++static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
++ unsigned int *nbuffers, unsigned int *nplanes,
++ unsigned int sizes[], void *alloc_ctxs[])
++{
++ struct cssp_cam_dev *dev = vb2_get_drv_priv(vq);
++ unsigned long size;
++
++ size = dev->sizeimage;
++
++ if (0 == *nbuffers)
++ *nbuffers = 32;
++
++ while (size * *nbuffers > vid_limit * 1024 * 1024)
++ (*nbuffers)--;
++
++ *nplanes = 1;
++
++ sizes[0] = size;
++
++ alloc_ctxs[0] = dev->dma_cont_ctx;
++
++ dev->frame_cnt = 0;
++
++ dev_dbg(&dev->pdev->dev, "%s, count=%d, size=%ld\n", __func__,
++ *nbuffers, size);
++
++ return 0;
++}
++
++static int buffer_init(struct vb2_buffer *vb)
++{
++ struct cssp_cam_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
++
++ BUG_ON(NULL == dev->fmt);
++
++ /*
++ * This callback is called once per buffer, after its allocation.
++ *
++ * Vivi does not allow changing format during streaming, but it is
++ * possible to do so when streaming is paused (i.e. in streamoff state).
++ * Buffers however are not freed when going into streamoff and so
++ * buffer size verification has to be done in buffer_prepare, on each
++ * qbuf.
++ * It would be best to move verification code here to buf_init and
++ * s_fmt though.
++ */
++
++ return 0;
++}
++
++static int buffer_prepare(struct vb2_buffer *vb)
++{
++ struct cssp_cam_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
++ struct cssp_cam_buffer *buf =
++ container_of(vb, struct cssp_cam_buffer, vb);
++ unsigned long size;
++
++ dev_dbg(&dev->pdev->dev, "%s, field=%d\n", __func__,
++ vb->v4l2_buf.field);
++
++ BUG_ON(NULL == dev->fmt);
++
++ /*
++ * Theses properties only change when queue is idle, see s_fmt.
++ * The below checks should not be performed here, on each
++ * buffer_prepare (i.e. on each qbuf). Most of the code in this function
++ * should thus be moved to buffer_init and s_fmt.
++ */
++ if (dev->width < 48 || dev->width > MAX_WIDTH ||
++ dev->height < 32 || dev->height > MAX_HEIGHT)
++ return -EINVAL;
++
++ size = dev->sizeimage;
++ if (vb2_plane_size(vb, 0) < size) {
++ dev_err(&dev->pdev->dev, "%s data will not fit into "
++ "plane (%lu < %lu)\n",
++ __func__, vb2_plane_size(vb, 0), size);
++ return -EINVAL;
++ }
++
++ vb2_set_plane_payload(&buf->vb, 0, size);
++
++ buf->fmt = dev->fmt;
++
++ return 0;
++}
++
++static int buffer_finish(struct vb2_buffer *vb)
++{
++ struct cssp_cam_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++ return 0;
++}
++
++static void buffer_cleanup(struct vb2_buffer *vb)
++{
++ struct cssp_cam_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++}
++
++static void buffer_queue(struct vb2_buffer *vb)
++{
++ struct cssp_cam_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
++ struct cssp_cam_buffer *buf = container_of(vb, struct cssp_cam_buffer, vb);
++ struct cssp_cam_dmaqueue *vidq = &dev->vidq;
++ unsigned long flags = 0;
++
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
++ if (dev->streaming_started && !dev->current_vb) {
++ trigger_dma_transfer_to_buf(dev, &buf->vb);
++ } else {
++ spin_lock_irqsave(&dev->slock, flags);
++ list_add_tail(&buf->list, &vidq->active);
++ spin_unlock_irqrestore(&dev->slock, flags);
++ }
++}
++
++static int start_streaming(struct vb2_queue *vq, unsigned int count)
++{
++ struct cssp_cam_dev *dev = vb2_get_drv_priv(vq);
++ struct platform_device *pdev = dev->pdev;
++ int ret;
++
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
++ ret = start_camera_sensor(dev);
++ if (ret != 0) {
++ dev_err(&pdev->dev, "start_camera_sensor failed\n");
++ return ret;
++ }
++
++ // Enable DMA
++ ret = edma_start(dev->dma_ch);
++ if (ret != 0) {
++ dev_err(&pdev->dev, "edma_start failed\n");
++ return ret;
++ }
++ dev->streaming_started = 1;
++
++ /* check if we have new buffer queued */
++ dequeue_buffer_for_dma(dev);
++
++ return 0;
++}
++
++/* abort streaming and wait for last buffer */
++static int stop_streaming(struct vb2_queue *vq)
++{
++ struct cssp_cam_dev *dev = vb2_get_drv_priv(vq);
++ struct cssp_cam_dmaqueue *dma_q = &dev->vidq;
++
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
++ // Disable DMA
++ edma_stop(dev->dma_ch);
++
++ // Disable data capture
++ dev->mode &= ~ENABLE;
++ writew(dev->mode, dev->reg_base_virt + REG_MODE);
++
++ stop_camera_sensor(dev);
++
++ dev->streaming_started = 0;
++
++ /* Release all active buffers */
++ while (!list_empty(&dma_q->active)) {
++ struct cssp_cam_buffer *buf;
++
++ buf = list_entry(dma_q->active.next,
++ struct cssp_cam_buffer, list);
++ list_del(&buf->list);
++ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
++
++ dev_dbg(&dev->pdev->dev, "[%p/%d] done\n",
++ buf, buf->vb.v4l2_buf.index);
++ }
++
++ dev->current_vb = NULL;
++
++ return 0;
++}
++
++static void cssp_cam_lock(struct vb2_queue *vq)
++{
++ struct cssp_cam_dev *dev = vb2_get_drv_priv(vq);
++ mutex_lock(&dev->mutex);
++}
++
++static void cssp_cam_unlock(struct vb2_queue *vq)
++{
++ struct cssp_cam_dev *dev = vb2_get_drv_priv(vq);
++ mutex_unlock(&dev->mutex);
++}
++
++static struct vb2_ops cssp_cam_video_qops = {
++ .queue_setup = queue_setup,
++ .buf_init = buffer_init,
++ .buf_prepare = buffer_prepare,
++ .buf_finish = buffer_finish,
++ .buf_cleanup = buffer_cleanup,
++ .buf_queue = buffer_queue,
++ .start_streaming = start_streaming,
++ .stop_streaming = stop_streaming,
++ .wait_prepare = cssp_cam_unlock,
++ .wait_finish = cssp_cam_lock,
++};
++
++/* ------------------------------------------------------------------
++ IOCTL vidioc handling
++ ------------------------------------------------------------------*/
++
++static int vidioc_querycap(struct file *file, void *priv,
++ struct v4l2_capability *cap)
++{
++ struct cssp_cam_dev *dev = video_drvdata(file);
++
++ strcpy(cap->driver, "cssp_camera");
++ strcpy(cap->card, "cssp_camera");
++ strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
++ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
++ V4L2_CAP_READWRITE;
++ return 0;
++}
++
++static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
++ struct v4l2_fmtdesc *f)
++{
++ struct cssp_cam_fmt *fmt;
++
++ if (f->index >= ARRAY_SIZE(formats))
++ return -EINVAL;
++
++ fmt = &formats[f->index];
++
++ strlcpy(f->description, fmt->name, sizeof(f->description));
++ f->pixelformat = fmt->fourcc;
++ return 0;
++}
++
++static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
++ struct v4l2_format *f)
++{
++ struct cssp_cam_dev *dev = video_drvdata(file);
++
++ f->fmt.pix.width = dev->width;
++ f->fmt.pix.height = dev->height;
++ f->fmt.pix.field = dev->field;
++ f->fmt.pix.pixelformat = dev->fmt->fourcc;
++ f->fmt.pix.bytesperline = dev->bytesperline;
++ f->fmt.pix.sizeimage = dev->sizeimage;
++ f->fmt.pix.colorspace = dev->colorspace;
++
++ return 0;
++}
++
++static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
++ struct v4l2_format *f)
++{
++ struct cssp_cam_dev *dev = video_drvdata(file);
++ struct cssp_cam_fmt *fmt;
++ struct v4l2_mbus_framefmt mbus_fmt;
++ struct v4l2_pix_format *pix = &f->fmt.pix;
++
++ fmt = get_format(f);
++ if (!fmt) {
++ dev_err(&dev->pdev->dev, "Fourcc format (0x%08x) invalid.\n",
++ f->fmt.pix.pixelformat);
++ return -EINVAL;
++ }
++
++ v4l2_fill_mbus_format(&mbus_fmt, pix, fmt->code);
++ v4l2_subdev_call(dev->subdev, video, try_mbus_fmt, &mbus_fmt);
++ v4l2_fill_pix_format(pix, &mbus_fmt);
++ pix->bytesperline = (pix->width * fmt->depth) >> 3;
++ pix->sizeimage = pix->height * pix->bytesperline;
++
++ if ((pix->sizeimage % dev->dma_req_len) != 0)
++ return -EINVAL;
++
++ switch (mbus_fmt.field) {
++ case V4L2_FIELD_ANY:
++ pix->field = V4L2_FIELD_NONE;
++ break;
++ case V4L2_FIELD_NONE:
++ break;
++ default:
++ dev_err(&dev->pdev->dev, "Field type %d unsupported.\n", mbus_fmt.field);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
++ struct v4l2_format *f)
++{
++ struct cssp_cam_dev *dev = video_drvdata(file);
++ struct vb2_queue *q = &dev->vb_vidq;
++ struct v4l2_pix_format *pix = &f->fmt.pix;
++ struct v4l2_mbus_framefmt mbus_fmt;
++ int i = 0, rem;
++ u32 bytesperline, height;
++
++ int ret = vidioc_try_fmt_vid_cap(file, priv, f);
++ if (ret < 0)
++ return ret;
++
++ if (vb2_is_streaming(q)) {
++ dev_err(&dev->pdev->dev, "%s device busy\n", __func__);
++ return -EBUSY;
++ }
++
++ dev->fmt = get_format(f);
++ dev->width = f->fmt.pix.width;
++ dev->height = f->fmt.pix.height;
++ dev->field = f->fmt.pix.field;
++ dev->colorspace = f->fmt.pix.colorspace;
++ dev->bytesperline = f->fmt.pix.bytesperline;
++ dev->sizeimage = f->fmt.pix.sizeimage;
++
++ /* Set the sensor into the new format */
++ v4l2_fill_mbus_format(&mbus_fmt, pix, dev->fmt->code);
++ v4l2_subdev_call(dev->subdev, video, s_mbus_fmt, &mbus_fmt);
++
++ /* Calculate DMA transfer parameters based on DMA request length */
++ bytesperline = dev->bytesperline;
++ do {
++ rem = bytesperline % dev->dma_req_len;
++ if (rem != 0) {
++ bytesperline <<= 1;
++ i++;
++ }
++ } while (rem != 0);
++ height = dev->height >> i;
++
++ /* Set the EDMA for the new resolution */
++ dev->dma_tr_params.a_b_cnt = ACNT(dev->dma_req_len) | BCNT(bytesperline / dev->dma_req_len);
++ dev->dma_tr_params.link_bcntrld = BCNTRLD(bytesperline / dev->dma_req_len) | LINK(0xffff);
++ dev->dma_tr_params.ccnt = CCNT(height);
++
++ return 0;
++}
++
++static int vidioc_reqbufs(struct file *file, void *priv,
++ struct v4l2_requestbuffers *p)
++{
++ struct cssp_cam_dev *dev = video_drvdata(file);
++ return vb2_reqbufs(&dev->vb_vidq, p);
++}
++
++static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
++{
++ struct cssp_cam_dev *dev = video_drvdata(file);
++ return vb2_querybuf(&dev->vb_vidq, p);
++}
++
++static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
++{
++ struct cssp_cam_dev *dev = video_drvdata(file);
++ return vb2_qbuf(&dev->vb_vidq, p);
++}
++
++static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
++{
++ struct cssp_cam_dev *dev = video_drvdata(file);
++ return vb2_dqbuf(&dev->vb_vidq, p, file->f_flags & O_NONBLOCK);
++}
++
++static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
++{
++ struct cssp_cam_dev *dev = video_drvdata(file);
++ return vb2_streamon(&dev->vb_vidq, i);
++}
++
++static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
++{
++ struct cssp_cam_dev *dev = video_drvdata(file);
++ return vb2_streamoff(&dev->vb_vidq, i);
++}
++
++static int vidioc_log_status(struct file *file, void *priv)
++{
++ struct cssp_cam_dev *dev = video_drvdata(file);
++
++ v4l2_ctrl_handler_log_status(&dev->ctrl_handler, dev->v4l2_dev.name);
++ return 0;
++}
++
++static int vidioc_enum_input(struct file *file, void *priv,
++ struct v4l2_input *inp)
++{
++ if (inp->index > 0)
++ return -EINVAL;
++
++ inp->type = V4L2_INPUT_TYPE_CAMERA;
++ sprintf(inp->name, "Camera %u", inp->index);
++
++ return 0;
++}
++
++static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
++{
++ *i = 0;
++
++ return 0;
++}
++
++static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
++{
++ if (i > 0)
++ return -EINVAL;
++
++ return 0;
++}
++
++static int vidioc_subscribe_event(struct v4l2_fh *fh,
++ const struct v4l2_event_subscription *sub)
++{
++ switch (sub->type) {
++ case V4L2_EVENT_CTRL:
++ return v4l2_event_subscribe(fh, sub, 0, NULL);
++ default:
++ return -EINVAL;
++ }
++}
++
++static const struct v4l2_ioctl_ops cssp_cam_ioctl_ops = {
++ .vidioc_querycap = vidioc_querycap,
++ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
++ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
++ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
++ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
++ .vidioc_reqbufs = vidioc_reqbufs,
++ .vidioc_querybuf = vidioc_querybuf,
++ .vidioc_qbuf = vidioc_qbuf,
++ .vidioc_dqbuf = vidioc_dqbuf,
++ .vidioc_enum_input = vidioc_enum_input,
++ .vidioc_g_input = vidioc_g_input,
++ .vidioc_s_input = vidioc_s_input,
++ .vidioc_streamon = vidioc_streamon,
++ .vidioc_streamoff = vidioc_streamoff,
++ .vidioc_log_status = vidioc_log_status,
++ .vidioc_subscribe_event = vidioc_subscribe_event,
++ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
++};
++
++
++/* ------------------------------------------------------------------
++ File operations
++ ------------------------------------------------------------------*/
++
++static unsigned int video_poll(struct file *file, struct poll_table_struct *wait)
++{
++ struct cssp_cam_dev *dev = video_drvdata(file);
++ struct v4l2_fh *fh = file->private_data;
++ struct vb2_queue *q = &dev->vb_vidq;
++ unsigned int res;
++
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
++ res = vb2_poll(q, file, wait);
++ if (v4l2_event_pending(fh))
++ res |= POLLPRI;
++ else
++ poll_wait(file, &fh->wait, wait);
++ return res;
++}
++
++static int video_mmap(struct file *file, struct vm_area_struct *vma)
++{
++ struct cssp_cam_dev *dev = video_drvdata(file);
++ int ret;
++
++ dev_dbg(&dev->pdev->dev, "mmap called, vma=0x%08lx\n",
++ (unsigned long)vma);
++
++ ret = vb2_mmap(&dev->vb_vidq, vma);
++ dev_dbg(&dev->pdev->dev, "vma start=0x%08lx, size=%ld, ret=%d\n",
++ (unsigned long)vma->vm_start,
++ (unsigned long)vma->vm_end - (unsigned long)vma->vm_start,
++ ret);
++ return ret;
++}
++
++static ssize_t video_read(struct file *file, char __user *buf,
++ size_t size, loff_t *offset)
++{
++ struct cssp_cam_dev *cam_dev = video_drvdata(file);
++
++ dev_dbg(&cam_dev->pdev->dev, "%s\n", __func__);
++
++ return vb2_read(&cam_dev->vb_vidq, buf, size, offset,
++ file->f_flags & O_NONBLOCK);
++}
++
++static int video_close(struct file *file)
++{
++ struct video_device *vdev = video_devdata(file);
++ struct cssp_cam_dev *cam_dev = video_drvdata(file);
++
++ dev_dbg(&cam_dev->pdev->dev, "close called (dev=%s), file %p\n",
++ video_device_node_name(vdev), file);
++
++ if (v4l2_fh_is_singular_file(file))
++ vb2_queue_release(&cam_dev->vb_vidq);
++ return v4l2_fh_release(file);
++}
++
++static const struct v4l2_file_operations cssp_cam_fops = {
++ .owner = THIS_MODULE,
++ .open = v4l2_fh_open,
++ .release = video_close,
++ .read = video_read,
++ .poll = video_poll,
++ .unlocked_ioctl = video_ioctl2,
++ .mmap = video_mmap,
++};
++
++
++/* ------------------------------------------------------------------
++ Driver initialization
++ ------------------------------------------------------------------*/
++
++static struct video_device cssp_cam_template = {
++ .name = "cssp_camera",
++ .fops = &cssp_cam_fops,
++ .ioctl_ops = &cssp_cam_ioctl_ops,
++ .minor = -1,
++ .release = video_device_release,
++};
++
++static int video_probe(struct cssp_cam_dev *cam_dev)
++{
++ struct video_device *vfd;
++ struct v4l2_ctrl_handler *hdl;
++ struct vb2_queue *q;
++ int ret = 0;
++
++ snprintf(cam_dev->v4l2_dev.name, sizeof(cam_dev->v4l2_dev.name),
++ "%s-%03d", "cssp_camera", 0);
++ ret = v4l2_device_register(NULL, &cam_dev->v4l2_dev);
++ if (ret)
++ goto free_dev;
++
++ cam_dev->fmt = &formats[0];
++ cam_dev->width = VGA_WIDTH;
++ cam_dev->height = VGA_HEIGHT;
++ cam_dev->sizeimage = VGA_WIDTH * VGA_HEIGHT * BYTES_PER_PIXEL;
++ hdl = &cam_dev->ctrl_handler;
++ v4l2_ctrl_handler_init(hdl, 0);
++
++ if (hdl->error) {
++ ret = hdl->error;
++ goto unreg_dev;
++ }
++ cam_dev->v4l2_dev.ctrl_handler = hdl;
++
++ /* initialize locks */
++ spin_lock_init(&cam_dev->slock);
++
++ /* initialize queue */
++ q = &cam_dev->vb_vidq;
++ memset(q, 0, sizeof(cam_dev->vb_vidq));
++ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++ q->io_modes = VB2_MMAP | VB2_READ;
++ q->drv_priv = cam_dev;
++ q->buf_struct_size = sizeof(struct cssp_cam_buffer);
++ q->ops = &cssp_cam_video_qops;
++ q->mem_ops = &vb2_dma_contig_memops;
++
++ ret = vb2_queue_init(q);
++ if (ret != 0) {
++ goto unreg_dev;
++ }
++
++ mutex_init(&cam_dev->mutex);
++
++ /* init video dma queues */
++ INIT_LIST_HEAD(&cam_dev->vidq.active);
++
++ ret = -ENOMEM;
++ vfd = video_device_alloc();
++ if (!vfd)
++ goto unreg_dev;
++
++ *vfd = cssp_cam_template;
++ vfd->v4l2_dev = &cam_dev->v4l2_dev;
++ set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
++
++ /*
++ * Provide a mutex to v4l2 core. It will be used to protect
++ * all fops and v4l2 ioctls.
++ */
++ vfd->lock = &cam_dev->mutex;
++
++ ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
++ if (ret < 0)
++ goto rel_vdev;
++
++ video_set_drvdata(vfd, cam_dev);
++
++ if (video_nr != -1)
++ video_nr++;
++
++ cam_dev->vdev = vfd;
++ v4l2_info(&cam_dev->v4l2_dev, "V4L2 device registered as %s\n",
++ video_device_node_name(vfd));
++
++ return 0;
++
++rel_vdev:
++ video_device_release(vfd);
++unreg_dev:
++ v4l2_ctrl_handler_free(hdl);
++ v4l2_device_unregister(&cam_dev->v4l2_dev);
++free_dev:
++ return ret;
++}
++
++static int video_remove(struct cssp_cam_dev *cam_dev)
++{
++ if (cam_dev->dma_cont_ctx != NULL)
++ vb2_dma_contig_cleanup_ctx(cam_dev->dma_cont_ctx);
++
++ v4l2_info(&cam_dev->v4l2_dev, "unregistering %s\n",
++ video_device_node_name(cam_dev->vdev));
++ video_unregister_device(cam_dev->vdev);
++ v4l2_device_unregister(&cam_dev->v4l2_dev);
++ v4l2_ctrl_handler_free(&cam_dev->ctrl_handler);
++
++ return 0;
++}
++
++#ifdef CONFIG_OF
++
++static const struct of_device_id cssp_camera_of_match[] = {
++ { .compatible = "cssp-camera", },
++ { },
++};
++MODULE_DEVICE_TABLE(of, cssp_camera_of_match);
++
++struct cssp_cam_platform_data *
++of_get_cssp_platform_data(struct platform_device *pdev)
++{
++ struct cssp_cam_platform_data *pdata;
++ struct cssp_cam_platform_data_storage *pstore;
++ struct device *dev = &pdev->dev;
++ struct device_node *np, *nps, *npc, *npa;
++ struct i2c_adapter *adap;
++ struct of_phandle_args args;
++ u32 val, valarr[9];
++ int ret, found, gpio_orientation_pin;
++
++ np = dev->of_node;
++ nps = NULL;
++ npc = NULL;
++ npa = NULL;
++ adap = NULL;
++ memset(&args, 0, sizeof(args));
++ pstore = NULL;
++ gpio_orientation_pin = -1;
++
++ if (np == NULL) {
++ dev_err(dev, "No OF device node\n");
++ goto err_fail;
++ }
++ pstore = devm_kzalloc(dev, sizeof(*pstore), GFP_KERNEL);
++ if (pstore == NULL) {
++ dev_err(dev, "Failed to allocate platform data storage\n");
++ goto err_fail;
++ }
++
++ /* link the structures together */
++ pdata = &pstore->pdata;
++ pdata->cam_i2c_board_info = &pstore->i2c_camera;
++ pstore->i2c_camera.platform_data = &pstore->camera_link;
++ pstore->camera_link.priv = &pstore->mt9t111_cam_info;
++
++ ret = of_property_read_string(np, "cssp,camera-clk-name",
++ &pdata->cam_clk_name);
++ if (ret != 0) {
++ dev_err(dev, "No cssp,camera-clk-name property\n");
++ goto err_fail;
++ }
++
++ ret = of_property_read_u32(np, "cssp,camera-clk-rate",
++ &pdata->cam_clk_rate);
++ if (ret != 0) {
++ dev_err(dev, "no cssp,camera-clk-rate property\n");
++ goto err_fail;
++ }
++
++ /* we don't use the dma accessors, but we use the format */
++ ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", 0, &args);
++ if (ret != 0 || args.args_count < 1) {
++ dev_err(dev, "No valid dmas property\n");
++ goto err_fail;
++ }
++ pdata->dma_ch = args.args[0];
++ /* release ref */
++ of_node_put(args.np);
++ args.np = NULL;
++
++ /* can possibly fail */
++ pdata->gpio_reset_pin = of_get_named_gpio(np,
++ "reset-gpio", 0);
++
++ gpio_orientation_pin = of_get_named_gpio(np,
++ "orientation-gpio", 0);
++
++ /* get sensor node */
++ nps = of_get_child_by_name(np, "cssp,sensor");
++ if (nps == NULL) {
++ dev_err(dev, "Failed to get sensor node\n");
++ goto err_fail;
++ }
++
++ /* find the i2c adapter number */
++ npa = of_parse_phandle(nps, "i2c-adapter", 0);
++ if (np == NULL) {
++ dev_err(dev, "Failed to get i2c-adapter property");
++ goto err_fail;
++ }
++ adap = of_find_i2c_adapter_by_node(npa);
++ if (adap == NULL) {
++ dev_err(dev, "Failed to find i2c-adapter");
++ goto err_fail;
++ }
++ pstore->camera_link.i2c_adapter_id = adap->nr;
++
++ /* release i2c adapter device ref */
++ put_device(&adap->dev);
++ adap = NULL;
++
++ /* release i2c adapter device node */
++ of_node_put(npa);
++ npa = NULL;
++
++ /* now find the sensor node */
++ for_each_available_child_of_node(nps, npc) {
++ /* we only support a single sensor for now */
++ if (of_device_is_compatible(npc, "aptina,mt9t112")) {
++ strncpy(pstore->i2c_camera.type, "mt9t112",
++ sizeof(pstore->i2c_camera.type));
++ found = 1;
++ break;
++ }
++ }
++
++ if (!found) {
++ dev_err(dev, "Failed to find sensor node");
++ goto err_fail;
++ }
++
++ if (of_property_read_u32(npc, "reg", &val) != 0) {
++ dev_err(dev, "Could not get sensor reg property\n");
++ goto err_fail;
++ }
++ pstore->i2c_camera.addr = val;
++
++ if (of_property_read_u32_array(npc, "pll-divider", valarr, ARRAY_SIZE(valarr)) != 0) {
++ dev_err(dev, "Could not get pll-divider property\n");
++ goto err_fail;
++ }
++ pstore->mt9t111_cam_info.divider.m = valarr[0];
++ pstore->mt9t111_cam_info.divider.n = valarr[1];
++ pstore->mt9t111_cam_info.divider.p1 = valarr[2];
++ pstore->mt9t111_cam_info.divider.p2 = valarr[3];
++ pstore->mt9t111_cam_info.divider.p3 = valarr[4];
++ pstore->mt9t111_cam_info.divider.p4 = valarr[5];
++ pstore->mt9t111_cam_info.divider.p5 = valarr[6];
++ pstore->mt9t111_cam_info.divider.p6 = valarr[7];
++ pstore->mt9t111_cam_info.divider.p7 = valarr[8];
++
++ if (of_property_read_u32(npc, "flags", &val) != 0) {
++ dev_err(dev, "Could not get sensor flags property\n");
++ goto err_fail;
++ }
++
++ /* read orientation gpio and set/clr MT9T112_FLAG_VFLIP */
++ if (gpio_is_valid(gpio_orientation_pin)) {
++ ret = gpio_request(gpio_orientation_pin, "camera orientation");
++ if (ret != 0) {
++ dev_err(dev, "Could not gpio_request orientation\n");
++ goto err_fail;
++ }
++ ret = gpio_direction_input(gpio_orientation_pin);
++ if (ret != 0) {
++ dev_err(dev, "Could not set orientation to input\n");
++ gpio_free(gpio_orientation_pin);
++ goto err_fail;
++ }
++ ret = gpio_get_value(gpio_orientation_pin);
++ if (ret < 0) {
++ dev_err(dev, "Could not get orientation value\n");
++ gpio_free(gpio_orientation_pin);
++ goto err_fail;
++ }
++ gpio_free(gpio_orientation_pin);
++
++ /* set orientation flag */
++
++ /*
++ * But the driver in mainline doesn't support flip
++ * Commented out for now...
++ *
++ * if (ret)
++ * val |= MT9T112_FLAG_VFLIP;
++ * else
++ * val &= ~MT9T112_FLAG_VFLIP
++ */
++ }
++ pstore->mt9t111_cam_info.flags = val;
++
++ /* release refs */
++
++ of_node_put(npc);
++ npc = NULL;
++ of_node_put(nps);
++ nps = NULL;
++
++ return pdata;
++
++err_fail:
++ /* NULL is handled as a NOP */
++ of_node_put(nps);
++ of_node_put(npc);
++ of_node_put(npa);
++
++ /* release adapter */
++ if (adap != NULL)
++ put_device(&adap->dev);
++
++ /* free memory (even if it will be automatically freed it's good practice) */
++ if (pstore != NULL)
++ devm_kfree(dev, pstore);
++
++ return NULL;
++}
++
++#else
++struct cssp_cam_platform_data *of_get_cssp_platform_data(struct platform_device *pdev)
++{
++ return NULL;
++}
++#endif
++
++static int cssp_cam_probe(struct platform_device *pdev)
++{
++ struct cssp_cam_dev *cam_dev;
++ struct cssp_cam_platform_data *pdata;
++ struct pinctrl *pinctrl;
++ int ret = 0, use_of_pdata = 0;
++
++ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
++ if (IS_ERR(pinctrl))
++ dev_warn(&pdev->dev,
++ "pins are not configured from the driver\n");
++
++ pdata = pdev->dev.platform_data;
++
++ /* if not found, try DT */
++ if (pdata == NULL) {
++ pdata = of_get_cssp_platform_data(pdev);
++ use_of_pdata = pdata != NULL;
++ }
++
++ if (pdata == NULL) {
++ dev_err(&pdev->dev, "missing platform data\n");
++ return -ENODEV;
++ }
++ pdev->dev.platform_data = pdata;
++
++ if (pdata->cam_i2c_board_info == NULL) {
++ dev_err(&pdev->dev, "missing camera i2c board info\n");
++ return -ENODEV;
++ }
++
++ cam_dev = kzalloc(sizeof(*cam_dev), GFP_KERNEL);
++ if (!cam_dev)
++ return -ENOMEM;
++
++ /* keep the pointer of the of pdata storage */
++ if (use_of_pdata)
++ cam_dev->pstore = to_cssp_platform_data_storage(pdata);
++
++ cam_dev->pdev = pdev;
++ platform_set_drvdata(pdev, cam_dev);
++
++ cam_dev->camera_board_info = pdata->cam_i2c_board_info;
++
++ cam_dev->camera_clk = clk_get(&pdev->dev, pdata->cam_clk_name);
++ if (IS_ERR(cam_dev->camera_clk)) {
++ ret = PTR_ERR(cam_dev->camera_clk);
++ dev_err(&pdev->dev, "cannot clk_get %s\n", pdata->cam_clk_name);
++ goto fail0;
++ }
++
++ /* 32MHz */
++ ret = clk_set_rate(cam_dev->camera_clk, pdata->cam_clk_rate);
++ if (ret != 0) {
++ dev_err(&pdev->dev, "failed to set clk rate\n");
++ goto fail1;
++ }
++
++ if (clk_get_rate(cam_dev->camera_clk) != pdata->cam_clk_rate) {
++ dev_err(&pdev->dev, "No accurate clock found\n");
++ goto fail1;
++ }
++
++ clk_prepare(cam_dev->camera_clk);
++
++ ret = configure_cssp(cam_dev);
++ if (ret) {
++ dev_err(&pdev->dev, "configure_cssp failed\n");
++ goto fail1;
++ }
++
++ ret = configure_edma(cam_dev);
++ if (ret) {
++ dev_err(&pdev->dev, "configure_dma failed\n");
++ goto fail2;
++ }
++
++ cam_dev->mode = FMT_2X8_EN | PCLK_POL | HS_EN; // falling edge
++ if (cam_dev->rev > 3)
++ cam_dev->mode |= LDR_EN;
++
++ ret = configure_camera_sensor(cam_dev);
++ if (ret) {
++ dev_err(&pdev->dev, "camera sensor configuration failed\n");
++ goto fail3;
++ }
++
++ cam_dev->dma_cont_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
++ if (IS_ERR(cam_dev->dma_cont_ctx)) {
++ ret = PTR_ERR(cam_dev->dma_cont_ctx);
++ goto fail3;
++ }
++
++ ret = video_probe(cam_dev);
++ if (ret)
++ goto fail4;
++
++ dev_err(&pdev->dev, "Loaded OK.\n");
++
++ return 0;
++
++fail4:
++ vb2_dma_contig_cleanup_ctx(cam_dev->dma_cont_ctx);
++
++fail3:
++ edma_free_channel(cam_dev->dma_ch);
++fail2:
++ if (gpio_is_valid(cam_dev->reset_pin))
++ gpio_free(cam_dev->reset_pin);
++
++ iounmap(cam_dev->reg_base_virt);
++ release_mem_region(cam_dev->reg_base_phys, cam_dev->reg_size);
++
++fail1:
++ clk_put(cam_dev->camera_clk);
++
++fail0:
++ kfree(cam_dev);
++
++ return ret;
++}
++
++static int cssp_cam_remove(struct platform_device *pdev)
++{
++ struct cssp_cam_dev *cam = platform_get_drvdata(pdev);
++
++ iounmap(cam->reg_base_virt);
++
++ release_mem_region(cam->reg_base_phys, cam->reg_size);
++
++ if (gpio_is_valid(cam->reset_pin))
++ gpio_free(cam->reset_pin);
++
++ if (cam->dma_ch)
++ edma_free_channel(cam->dma_ch);
++
++ video_remove(cam);
++
++ clk_put(cam->camera_clk);
++
++ kfree(cam);
++
++ dev_info(&pdev->dev, "removed\n");
++
++ return 0;
++}
++
++
++static struct platform_driver cssp_cam_driver = {
++ .probe = cssp_cam_probe,
++ .remove = cssp_cam_remove,
++ .driver = {
++ .name = "cssp-camera",
++ .owner = THIS_MODULE,
++ .of_match_table = of_match_ptr(cssp_camera_of_match),
++ },
++};
++
++module_platform_driver(cssp_cam_driver);
++
++
++/*
++ * Macros sets license, author and description
++ */
++MODULE_LICENSE("GPLv2");
++MODULE_AUTHOR("Dan Aizenstros, Damian Eppel, Przemek Szewczyk");
++MODULE_DESCRIPTION("QuickLogic Camera Interface driver");
++
diff --git a/patches/linux-3.8.13/0608-capes-Add-BB-BONE-CAM3-cape.patch b/patches/linux-3.8.13/0608-capes-Add-BB-BONE-CAM3-cape.patch
new file mode 100644
index 0000000..f59fd15
--- /dev/null
+++ b/patches/linux-3.8.13/0608-capes-Add-BB-BONE-CAM3-cape.patch
@@ -0,0 +1,202 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 1 May 2013 16:51:56 +0300
+Subject: [PATCH] capes: Add BB-BONE-CAM3 cape
+
+Add the cape definition for the CAM3 cape
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ firmware/capes/BB-BONE-CAM3-01-00A2.dts | 184 +++++++++++++++++++++++++++++++
+ 1 file changed, 184 insertions(+)
+ create mode 100644 firmware/capes/BB-BONE-CAM3-01-00A2.dts
+
+diff --git a/firmware/capes/BB-BONE-CAM3-01-00A2.dts b/firmware/capes/BB-BONE-CAM3-01-00A2.dts
+new file mode 100644
+index 0000000..97bdcfd
+--- /dev/null
++++ b/firmware/capes/BB-BONE-CAM3-01-00A2.dts
+@@ -0,0 +1,184 @@
++/*
++ * Copyright (C) 2013 Circuit Co.
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone";
++
++ /* identification */
++ part-number = "BB-BONE-CAM3-01";
++ version = "00A2", "A2";
++
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ gpmc_pins: pinmux_gpmc_pins {
++ pinctrl-single,pins = <
++ 0x000 0x30 /* gpmc_ad0.gpmc_ad0 MODE0 | INPUT | PULLUP */
++ 0x004 0x30 /* gpmc_ad1.gpmc_ad1 MODE0 | INPUT | PULLUP */
++ 0x008 0x30 /* gpmc_ad2.gpmc_ad2 MODE0 | INPUT | PULLUP */
++ 0x00C 0x30 /* gpmc_ad3.gpmc_ad3 MODE0 | INPUT | PULLUP */
++ 0x010 0x30 /* gpmc_ad4.gpmc_ad4 MODE0 | INPUT | PULLUP */
++ 0x014 0x30 /* gpmc_ad5.gpmc_ad5 MODE0 | INPUT | PULLUP */
++ 0x018 0x30 /* gpmc_ad6.gpmc_ad6 MODE0 | INPUT | PULLUP */
++ 0x01C 0x30 /* gpmc_ad7.gpmc_ad7 MODE0 | INPUT | PULLUP */
++ 0x020 0x30 /* gpmc_ad8.gpmc_ad8 MODE0 | INPUT | PULLUP */
++ 0x024 0x30 /* gpmc_ad9.gpmc_ad9 MODE0 | INPUT | PULLUP */
++ 0x028 0x30 /* gpmc_ad10.gpmc_ad10 MODE0 | INPUT | PULLUP */
++ 0x02C 0x30 /* gpmc_ad11.gpmc_ad11 MODE0 | INPUT | PULLUP */
++ 0x030 0x30 /* gpmc_ad12.gpmc_ad12 MODE0 | INPUT | PULLUP */
++ 0x034 0x30 /* gpmc_ad13.gpmc_ad13 MODE0 | INPUT | PULLUP */
++ 0x038 0x30 /* gpmc_ad14.gpmc_ad14 MODE0 | INPUT | PULLUP */
++ 0x03C 0x30 /* gpmc_ad15.gpmc_ad15 MODE0 | INPUT | PULLUP */
++ 0x074 0x30 /* gpmc_wpn.gpmc_wpn MODE0 | INPUT | PULLUP */ /* WAS MODE 7 */
++ 0x080 0x08 /* gpmc_wait0.gpmc_cscn1 MODE0 | OUTPUT */
++ 0x08C 0x28 /* gpmc_clk.gpmc_clk MODE0 | INPUT */
++ 0x090 0x08 /* gpmc_advn_ale.gpmc_advn_ale MODE0 | OUTPUT */
++ 0x094 0x08 /* gpmc_oen_ren.gpmc_oen_ren MODE0 | OUTPUT */
++ 0x098 0x08 /* gpmc_wen.gpmc_wen MODE0 | OUTPUT */
++ 0x09C 0x08 /* gpmc_ben0_cle.gpmc_ben0_cle MODE0 | OUTPUT */
++ >;
++ };
++ cssp_camera_pins: pinmux_cssp_camera_pins {
++ pinctrl-single,pins = <
++ /* clkout2 */
++ 0x1B4 0x03 /* xdma_event_intr1.clkout2 MODE3 | OUTPUT clkout2 */
++
++ /* dmar */
++ 0x164 0x2e /* ecap0_in_pwm0_out.xdma_event_intr2 MODE6 | INPUT */
++
++ /* cssp camera */
++ 0x158 0x07 /* spi0_d1.gpio0_4 MODE7 | OUTPUT, QL CSSP and Camera Sensor Reset */
++ 0x15C 0x17 /* spi0_cs0.gpio0_5 MODE7 | OUTPUT | PULLUP, 1V8 and 2V8 Power Enable */
++ 0x070 0x2f /* gpmc_wait0.gpio0_30 MODE0 | INPUT | PULLUPDIS, Sensor orientation detect: low -> frontfacing, high -> backfacing */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&gpmc>;
++ depth = <1>; /* only create devices on depth 1 */
++
++ /* stupid warnings */
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges;
++
++ __overlay__ {
++
++ status = "okay";
++
++ #address-cells = <2>;
++ #size-cells = <1>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&gpmc_pins>;
++
++ /* chip select ranges */
++ ranges = <0 0 0x08000000 0x10000000>, /* bootloader has this enabled */
++ <1 0 0x18000000 0x08000000>,
++ <2 0 0x20000000 0x08000000>,
++ <3 0 0x28000000 0x08000000>,
++ <4 0 0x30000000 0x08000000>,
++ <5 0 0x38000000 0x04000000>,
++ <6 0 0x3c000000 0x04000000>;
++
++ /*
++ * This is complete and utter cr*p
++ * It doesn't belong here, but we don't
++ * have a memory controller abstraction.
++ * So we muddle along...
++ */
++ camera {
++ compatible = "cssp-camera";
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&cssp_camera_pins>;
++
++ reg = <1 0 0x01000000>; /* CS1 */
++
++ bank-width = <2>; /* GPMC_CONFIG1_DEVICESIZE(1) */
++
++ gpmc,burst-read; /* GPMC_CONFIG1_READMULTIPLE_SUPP */
++ gpmc,sync-read; /* GPMC_CONFIG1_READTYPE_SYNC */
++ gpmc,sync-write; /* GPMC_CONFIG1_WRITETYPE_SYNC */
++ gpmc,clk-activation-ns = <20>; /* GPMC_CONFIG1_CLKACTIVATIONTIME(2) */
++ gpmc,burst-length = <16>; /* GPMC_CONFIG1_PAGE_LEN(2) */
++ gpmc,mux-add-data = <2>; /* GPMC_CONFIG1_MUXTYPE(2) */
++
++ gpmc,sync-clk-ps = <20000>; /* CONFIG2 */
++
++ gpmc,cs-on-ns = <1>;
++ gpmc,cs-rd-off-ns = <160>;
++ gpmc,cs-wr-off-ns = <310>;
++
++ gpmc,adv-on-ns = <0>; /* CONFIG3 */
++ gpmc,adv-rd-off-ns = <40>;
++ gpmc,adv-wr-off-ns = <40>;
++
++ gpmc,we-on-ns = <60>; /* CONFIG4 */
++ gpmc,we-off-ns = <310>;
++ gpmc,oe-on-ns = <60>;
++ gpmc,oe-off-ns = <160>;
++
++ gpmc,page-burst-access-ns = <20>; /* CONFIG 5 */
++ gpmc,access-ns = <140>;
++ gpmc,rd-cycle-ns = <160>;
++ gpmc,wr-cycle-ns = <310>;
++
++ gpmc,wr-access-ns = <100>; /* CONFIG 6 */
++ gpmc,wr-data-mux-bus-ns = <60>;
++
++ gpmc,bus-turnaround-ns = <40>; /* CONFIG6:3:0 = 4 */
++ gpmc,cycle2cycle-samecsen; /* CONFIG6:7 = 1 */
++ gpmc,cycle2cycle-delay-ns = <40>; /* CONFIG6:11:8 = 4 */
++
++ /* not using dma engine yet, but we can get the channel number here */
++ dmas = <&edma 20>;
++ dma-names = "cssp";
++
++ /* clocks */
++ cssp,camera-clk-name = "adjustable_clkout2_ck";
++ cssp,camera-clk-rate = <32000000>;
++
++ /* reset */
++ reset-gpio = <&gpio1 4 0>;
++
++ /* orientation; -> MT9T112_FLAG_VFLIP */
++ orientation-gpio = <&gpio1 30 0>;
++
++ /* camera sensor */
++ cssp,sensor {
++ i2c-adapter = <&i2c2>;
++
++ /* need it to stop the whinning */
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* fake i2c device node */
++ m59t112 {
++ compatible = "aptina,mt9t112";
++ reg = <0x3c>;
++
++ /* m, n, p1-7 */
++ flags = <0>;
++ pll-divider = <24 1 0 7 0 10 14 7 0>;
++ };
++ };
++ };
++
++ };
++ };
++
++};
diff --git a/patches/linux-3.8.13/0609-cssp_camera-Correct-license-identifier.patch b/patches/linux-3.8.13/0609-cssp_camera-Correct-license-identifier.patch
new file mode 100644
index 0000000..974b5d7
--- /dev/null
+++ b/patches/linux-3.8.13/0609-cssp_camera-Correct-license-identifier.patch
@@ -0,0 +1,24 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 1 May 2013 20:49:48 +0300
+Subject: [PATCH] cssp_camera: Correct license identifier
+
+GPLv2 != GPL v2 for license reasons
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/media/platform/soc_camera/cssp_camera.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/media/platform/soc_camera/cssp_camera.c b/drivers/media/platform/soc_camera/cssp_camera.c
+index 41de42e..0bc6a28 100644
+--- a/drivers/media/platform/soc_camera/cssp_camera.c
++++ b/drivers/media/platform/soc_camera/cssp_camera.c
+@@ -1554,7 +1554,7 @@ module_platform_driver(cssp_cam_driver);
+ /*
+ * Macros sets license, author and description
+ */
+-MODULE_LICENSE("GPLv2");
++MODULE_LICENSE("GPL v2");
+ MODULE_AUTHOR("Dan Aizenstros, Damian Eppel, Przemek Szewczyk");
+ MODULE_DESCRIPTION("QuickLogic Camera Interface driver");
+
diff --git a/patches/linux-3.8.13/0610-cssp_camera-increase-delays-make-sensor-detection-wo.patch b/patches/linux-3.8.13/0610-cssp_camera-increase-delays-make-sensor-detection-wo.patch
new file mode 100644
index 0000000..45c09f7
--- /dev/null
+++ b/patches/linux-3.8.13/0610-cssp_camera-increase-delays-make-sensor-detection-wo.patch
@@ -0,0 +1,32 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Thu, 2 May 2013 12:06:12 +0200
+Subject: [PATCH] cssp_camera: increase delays make sensor detection work
+ better
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ drivers/media/platform/soc_camera/cssp_camera.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/cssp_camera.c b/drivers/media/platform/soc_camera/cssp_camera.c
+index 0bc6a28..0a0cd8f 100644
+--- a/drivers/media/platform/soc_camera/cssp_camera.c
++++ b/drivers/media/platform/soc_camera/cssp_camera.c
+@@ -471,7 +471,7 @@ static int configure_camera_sensor(struct cssp_cam_dev *cam)
+ /* Enable the clock just for the time of loading the camera driver and disable after that */
+ /* It is going to be be re-enabled later, when camera will be in use */
+ clk_enable(cam->camera_clk);
+- udelay(5); // let the clock stabilize
++ mdelay(50); // let the clock stabilize
+
+ adapter = i2c_get_adapter(((struct soc_camera_link *)(info->platform_data))->i2c_adapter_id);
+ if (!adapter) {
+@@ -504,7 +504,7 @@ static int configure_camera_sensor(struct cssp_cam_dev *cam)
+ static int start_camera_sensor(struct cssp_cam_dev *cam)
+ {
+ clk_enable(cam->camera_clk);
+- udelay(5); /* let the clock stabilize */
++ mdelay(100); /* let the clock stabilize */
+
+ v4l2_subdev_call(cam->subdev, video, s_stream, 1);
+
diff --git a/patches/linux-3.8.13/0611-mt9t112-forward-port-optimizations-from-Angstrom-3.2.patch b/patches/linux-3.8.13/0611-mt9t112-forward-port-optimizations-from-Angstrom-3.2.patch
new file mode 100644
index 0000000..1beec04
--- /dev/null
+++ b/patches/linux-3.8.13/0611-mt9t112-forward-port-optimizations-from-Angstrom-3.2.patch
@@ -0,0 +1,585 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Thu, 2 May 2013 12:06:27 +0200
+Subject: [PATCH] mt9t112: forward port optimizations from Angstrom 3.2 kernel
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ drivers/media/i2c/soc_camera/mt9t112.c | 502 +++++++++++++++++++++++++++++++-
+ include/media/mt9t112.h | 2 +
+ 2 files changed, 502 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c
+index de7cd83..d83d217 100644
+--- a/drivers/media/i2c/soc_camera/mt9t112.c
++++ b/drivers/media/i2c/soc_camera/mt9t112.c
+@@ -33,6 +33,8 @@
+ /* you can check PLL/clock info */
+ /* #define EXT_CLOCK 24000000 */
+
++//#define TEST_PATTERN
++
+ /************************************************************************
+ macro
+ ************************************************************************/
+@@ -67,6 +69,8 @@
+
+ #define mt9t112_reg_read(ret, client, a) \
+ ECHECKER(ret, __mt9t112_reg_read(client, a))
++#define mt9t112_mcu_read(ret, client, a) \
++ ECHECKER(ret, __mt9t112_mcu_read(client, a))
+
+ /*
+ * Logical address
+@@ -85,6 +89,33 @@ struct mt9t112_format {
+ u16 order;
+ };
+
++struct mt9t112_resolution_param {
++ u16 col_strt;
++ u16 row_end;
++ u16 col_end;
++ u16 read_mode;
++ u16 fine_cor;
++ u16 fine_min;
++ u16 fine_max;
++ u16 base_lines;
++ u16 min_lin_len;
++ u16 line_len;
++ u16 con_width;
++ u16 con_height;
++ u16 s_f1_50;
++ u16 s_f2_50;
++ u16 s_f1_60;
++ u16 s_f2_60;
++ u16 per_50;
++ u16 per_50_M;
++ u16 per_60;
++ u16 fd_w_height;
++ u16 tx_water;
++ u16 max_fd_50;
++ u16 max_fd_60;
++ u16 targ_fd;
++};
++
+ struct mt9t112_priv {
+ struct v4l2_subdev subdev;
+ struct mt9t112_camera_info *info;
+@@ -96,6 +127,7 @@ struct mt9t112_priv {
+ /* for flags */
+ #define INIT_DONE (1 << 0)
+ #define PCLK_RISING (1 << 1)
++ struct mt9t112_resolution_param resolution;
+ };
+
+ /************************************************************************
+@@ -412,6 +444,453 @@ static int mt9t112_set_pll_dividers(const struct i2c_client *client,
+ return ret;
+ }
+
++static int mt9t112_set_resolution_params(const struct i2c_client *client)
++{
++ int ret = 1;
++ struct mt9t112_priv *priv = to_mt9t112(client);
++ struct mt9t112_resolution_param *resolution = &priv->resolution;
++
++ if ((priv->frame.width == 1280) && (priv->frame.height == 720)) {
++ resolution->col_strt = 0x0004;
++ resolution->row_end = 0x05AD;
++ resolution->col_end = 0x050B;
++ resolution->read_mode = 0x002C;
++ resolution->fine_cor = 0x008C;
++ resolution->fine_min = 0x01F1;
++ resolution->fine_max = 0x00FF;
++ resolution->base_lines = 0x032D;
++ resolution->min_lin_len = 0x0378;
++ resolution->line_len = 0x091C;
++ resolution->con_width = 0x0508;
++ resolution->con_height = 0x02D8;
++ resolution->s_f1_50 = 0x23;
++ resolution->s_f2_50 = 0x25;
++ resolution->s_f1_60 = 0x2B;
++ resolution->s_f2_60 = 0x2D;
++ resolution->per_50 = 0xDC;
++ resolution->per_50_M = 0x00;
++ resolution->per_60 = 0xB7;
++ resolution->fd_w_height = 0x05;
++ resolution->tx_water = 0x0210;
++ resolution->max_fd_50 = 0x0004;
++ resolution->max_fd_60 = 0x0004;
++ resolution->targ_fd = 0x0004;
++ } else if ((priv->frame.width <= 1024) && (priv->frame.height <= 768) &&
++ (priv->frame.width != priv->frame.height)) {
++ resolution->col_strt = 0x000;
++ resolution->row_end = 0x60D;
++ resolution->col_end = 0x80D;
++ resolution->read_mode = 0x046C;
++ resolution->fine_cor = 0x00CC;
++ resolution->fine_min = 0x0381;
++ resolution->fine_max = 0x024F;
++ resolution->base_lines = 0x0364;
++ resolution->min_lin_len = 0x05D0;
++ resolution->line_len = 0x07AC;
++ resolution->con_width = 0x0408;
++ resolution->con_height = 0x0308;
++ resolution->s_f1_50 = 0x23;
++ resolution->s_f2_50 = 0x25;
++ resolution->s_f1_60 = 0x2A;
++ resolution->s_f2_60 = 0x2C;
++ resolution->per_50 = 0x05;
++ resolution->per_50_M = 0x01;
++ resolution->per_60 = 0xD9;
++ resolution->fd_w_height = 0x06;
++ resolution->max_fd_50 = 0x0003;
++ resolution->max_fd_60 = 0x0004;
++ resolution->targ_fd = 0x0003;
++ if ((priv->frame.width == 1024) && (priv->frame.height == 768)) {
++ resolution->tx_water = 0x0218;
++ } else if ((priv->frame.width == 800) && (priv->frame.height == 480)) {
++ resolution->tx_water = 0x02DA;
++ } else { // 640 x 480 but use it with everything else until we figure out how to calc it
++ resolution->tx_water = 0x0352;
++ }
++ } else {
++ ret = 0;
++ }
++
++ return ret;
++}
++
++static int mt9t112_pll_setup_custom_pll(const struct i2c_client *client)
++{
++/*
++; Bypass PLL: Unchecked
++; Input Frequency: 32.000
++; Target Pads Frequency: 96.000
++; Target I2C Clock Frequency: 100.000
++; Target VCO Frequency: Unspecified
++; For Parallel Output: Checked
++; "M" Value: Unspecified
++; "N" Value: Unspecified
++;
++; Target Pads Clock Frequency: 96 MHz
++; Input Clock Frequency: 32 MHz
++;
++; Actual Pads Clock Frequency: 96 MHz
++; Sensor Core Clock Frequency: 54.857 MHz
++; SOC Clock Frequency: 54.857 MHz
++; MCU Clock Frequency: 96 MHz
++; I2C Master Clock Frequency: 99.740 KHz
++;
++; M = 24
++; N = 1
++; Fpdf = 16 MHz
++; Fvco = 768 MHz
++; P2 = 8
++; P4 = 14
++; P5 = 14
++; P6 = 8
++*/
++ int data, i, ret;
++
++ mt9t112_reg_mask_set(ret, client, 0x14, 1, 1); // Bypass PLL
++ mt9t112_reg_mask_set(ret, client, 0X14, 2, 0); // Power-down PLL
++ mt9t112_reg_write(ret, client, 0x0014, 0x2145); // PLL control: BYPASS PLL = 8517
++ mt9t112_reg_write(ret, client, 0x0010, 0x0118); // PLL Dividers = 280
++ mt9t112_reg_write(ret, client, 0x0012, 0x0070); // PLL P Dividers = 112
++ mt9t112_reg_write(ret, client, 0x002A, 0x77EE); // PLL P Dividers 4-5-6 = 30685
++ mt9t112_reg_write(ret, client, 0x001A, 0x218); // Reset Misc. Control = 536
++ mt9t112_reg_write(ret, client, 0x0014, 0x2545); // PLL control: TEST_BYPASS on = 9541
++ mt9t112_reg_write(ret, client, 0x0014, 0x2547); // PLL control: PLL_ENABLE on = 9543
++ mt9t112_reg_write(ret, client, 0x0014, 0x2447); // PLL control: SEL_LOCK_DET on = 9287
++ mt9t112_reg_write(ret, client, 0x0014, 0x2047); // PLL control: TEST_BYPASS off = 8263
++
++ // Wait for the PLL to lock
++ for (i=0; i<1000; i++) {
++ mt9t112_reg_read(data, client, 0x0014);
++ if (0x8000 & data)
++ break;
++
++ mdelay(10);
++ }
++
++ mt9t112_reg_write(ret, client, 0x0014, 0x2046); // PLL control: PLL_BYPASS off = 8262
++ mt9t112_reg_write(ret, client, 0x0022, 0x0280); // Reference clock count for 20 us = 640
++ mt9t112_reg_write(ret, client, 0x001E, 0x0777); // Pad Slew Rate = 1911
++ mt9t112_reg_write(ret, client, 0x0016, 0x0400); // JPEG Clock = 1024
++
++ return ret;
++}
++
++static int mt9t112_sysctl_startup_K26A_rev_3(const struct i2c_client *client)
++{
++ int ret;
++
++ // reset
++ mt9t112_reset(client);
++
++ // Setup PLL
++ mt9t112_pll_setup_custom_pll(client);
++
++ // crank up the output slew rate (don't forget to enable these bits in TX_SS)
++ mt9t112_reg_write(ret, client, 0x001E, 0x0777);
++
++ return ret;
++}
++
++static int mt9t112_high_speed_overrides(const struct i2c_client *client)
++{
++ int ret;
++
++// Use this section to apply settings that are specific to this revision of SOC
++// or for any other specialized settings
++
++// clear the "Output Buffer Enable Adaptive Clock" bit to enable the SYSCTL
++// slew rate settings, change this in the variables and register
++
++ // PRI_A_CONFIG_JPEG_OB_TX_CONTROL_VAR
++ mt9t112_mcu_write(ret, client, VAR(26, 160), 0x082E);
++ // PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR
++ mt9t112_mcu_write(ret, client, VAR(27, 160), 0x082E);
++ //SEC_A_CONFIG_JPEG_OB_TX_CONTROL_VAR
++ mt9t112_mcu_write(ret, client, VAR(28, 160), 0x082E);
++ //SEC_B_CONFIG_JPEG_OB_TX_CONTROL_VAR
++ mt9t112_mcu_write(ret, client, VAR(29, 160), 0x082E);
++ mt9t112_reg_mask_set(ret, client, 0x3C52, 0x0040, 0); // set this value in HW
++
++ // Set correct values for Context B FIFO control
++ // CAM1_CTX_B_RX_FIFO_TRIGGER_MARK
++ mt9t112_mcu_write(ret, client, VAR(18, 142), 32);
++ // PRI_B_CONFIG_IO_OB_MANUAL_FLAG
++ mt9t112_mcu_write(ret, client, VAR(27, 172), 0);
++
++ return ret;
++}
++
++static int mt9t112_go(const struct i2c_client *client)
++{
++ int data, i, ret;
++
++ // release MCU from standby
++ mt9t112_reg_mask_set(ret, client, 0x0018, 0x0001, 0);
++
++ // wait for K26A to come out of standby
++ for (i=0; i<100; i++) {
++ mt9t112_reg_read(data, client, 0x0018);
++ if (!(0x4000 & data))
++ break;
++
++ mdelay(10);
++ }
++
++ return ret;
++}
++
++static int mt9t112_continue(const struct i2c_client *client)
++{
++ int data, i, ret;
++
++ // clear powerup stop bit
++ mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0);
++
++ // wait for sequencer to enter preview state
++ for (i=0; i<100; i++) {
++ mt9t112_mcu_read(data, client, VAR8(1, 1));
++ if (data == 3)
++ break;
++
++ mdelay(10);
++ }
++
++ return ret;
++}
++
++static int mt9t112_mcu_powerup_stop_enable(const struct i2c_client *client)
++{
++ int ret;
++
++ // set powerup stop bit
++ mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 1);
++
++ return ret;
++}
++
++static int mt9t112_custom_setup(const struct i2c_client *client)
++{
++ struct mt9t112_priv *priv = to_mt9t112(client);
++ struct mt9t112_resolution_param *resolution = &priv->resolution;
++ int ret;
++
++ //I2C Master Clock Divider
++ mt9t112_mcu_write(ret, client, 0x6006, 0x0100); // = 275
++ //Output Width (A)
++ mt9t112_mcu_write(ret, client, 0x6800, priv->frame.width);
++ //Output Height (A)
++ mt9t112_mcu_write(ret, client, 0x6802, priv->frame.height);
++ //JPEG (A)
++ mt9t112_mcu_write(ret, client, 0xE88E, 0x00); // = 0
++ //Adaptive Output Clock (A)
++ mt9t112_mcu_mask_set(ret, client, 0x68A0, 0x0040, 0x0000); // = 0
++ //Row Start (A)
++ mt9t112_mcu_write(ret, client, 0x4802, 0x000); // = 0
++ //Column Start (A)
++ mt9t112_mcu_write(ret, client, 0x4804, resolution->col_strt);
++ //Row End (A)
++ mt9t112_mcu_write(ret, client, 0x4806, resolution->row_end);
++ //Column End (A)
++ mt9t112_mcu_write(ret, client, 0x4808, resolution->col_end);
++ //Row Speed (A)
++ mt9t112_mcu_write(ret, client, 0x480A, 0x0111); // = 273
++ //Read Mode (A)
++ mt9t112_mcu_write(ret, client, 0x480C, resolution->read_mode);
++ //Fine Correction (A)
++ mt9t112_mcu_write(ret, client, 0x480F, resolution->fine_cor);
++ //Fine IT Min (A)
++ mt9t112_mcu_write(ret, client, 0x4811, resolution->fine_min);
++ //Fine IT Max Margin (A)
++ mt9t112_mcu_write(ret, client, 0x4813, resolution->fine_max);
++ //Base Frame Lines (A)
++ mt9t112_mcu_write(ret, client, 0x481D, resolution->base_lines);
++ //Min Line Length (A)
++ mt9t112_mcu_write(ret, client, 0x481F, resolution->min_lin_len);
++ //Line Length (A)
++ mt9t112_mcu_write(ret, client, 0x4825, resolution->line_len);
++ //Contex Width (A)
++ mt9t112_mcu_write(ret, client, 0x482B, resolution->con_width);
++ //Context Height (A)
++ mt9t112_mcu_write(ret, client, 0x482D, resolution->con_height);
++ //Output Width (B)
++ mt9t112_mcu_write(ret, client, 0x6C00, 0x0800); // = 2048
++ //Output Height (B)
++ mt9t112_mcu_write(ret, client, 0x6C02, 0x0600); // = 1536
++ //JPEG (B)
++ mt9t112_mcu_write(ret, client, 0xEC8E, 0x01); // = 1
++ //Adaptive Output Clock (B)
++ mt9t112_mcu_mask_set(ret, client, 0x6CA0, 0x0040, 0x0000); // = 0
++ //Row Start (B)
++ mt9t112_mcu_write(ret, client, 0x484A, 0x004); // = 4
++ //Column Start (B)
++ mt9t112_mcu_write(ret, client, 0x484C, 0x004); // = 4
++ //Row End (B)
++ mt9t112_mcu_write(ret, client, 0x484E, 0x60B); // = 1547
++ //Column End (B)
++ mt9t112_mcu_write(ret, client, 0x4850, 0x80B); // = 2059
++ //Row Speed (B)
++ mt9t112_mcu_write(ret, client, 0x4852, 0x0111); // = 273
++ //Read Mode (B)
++ mt9t112_mcu_write(ret, client, 0x4854, 0x0024); // = 36
++ //Fine Correction (B)
++ mt9t112_mcu_write(ret, client, 0x4857, 0x008C); // = 140
++ //Fine IT Min (B)
++ mt9t112_mcu_write(ret, client, 0x4859, 0x01F1); // = 497
++ //Fine IT Max Margin (B)
++ mt9t112_mcu_write(ret, client, 0x485B, 0x00FF); // = 255
++ //Base Frame Lines (B)
++ mt9t112_mcu_write(ret, client, 0x4865, 0x06AE); // = 1710
++ //Min Line Length (B)
++ mt9t112_mcu_write(ret, client, 0x4867, 0x0378); // = 888
++ //Line Length (B)
++ mt9t112_mcu_write(ret, client, 0x486D, 0x0A3A); // = 2618
++ //Contex Width (B)
++ mt9t112_mcu_write(ret, client, 0x4873, 0x0808); // = 2056
++ //Context Height (B)
++ mt9t112_mcu_write(ret, client, 0x4875, 0x0608); // = 1544
++ //search_f1_50
++ mt9t112_mcu_write(ret, client, 0xC8A5, resolution->s_f1_50);
++ //search_f2_50
++ mt9t112_mcu_write(ret, client, 0xC8A6, resolution->s_f2_50);
++ //search_f1_60
++ mt9t112_mcu_write(ret, client, 0xC8A7, resolution->s_f1_60);
++ //search_f2_60
++ mt9t112_mcu_write(ret, client, 0xC8A8, resolution->s_f2_60);
++ //period_50Hz (A)
++ mt9t112_mcu_write(ret, client, 0xC844, resolution->per_50);
++ //period_50Hz (A MSB)
++ mt9t112_mcu_write(ret, client, 0xC92F, resolution->per_50_M);
++ //period_60Hz (A)
++ mt9t112_mcu_write(ret, client, 0xC845, resolution->per_60);
++ //period_60Hz (A MSB)
++ mt9t112_mcu_write(ret, client, 0xC92D, 0x00); // = 0
++ //period_50Hz (B)
++ mt9t112_mcu_write(ret, client, 0xC88C, 0xD2); // = 210
++ //period_50Hz (B) MSB
++ mt9t112_mcu_write(ret, client, 0xC930, 0x00); // = 0
++ //period_60Hz (B)
++ mt9t112_mcu_write(ret, client, 0xC88D, 0xAF); // = 175
++ //period_60Hz (B) MSB
++ mt9t112_mcu_write(ret, client, 0xC92E, 0x00); // = 0
++ //FD Window Height
++ mt9t112_mcu_write(ret, client, 0xB825, resolution->fd_w_height);
++ //Stat_min
++ mt9t112_mcu_write(ret, client, 0xA009, 0x02); // = 2
++ //Stat_max
++ mt9t112_mcu_write(ret, client, 0xA00A, 0x03); // = 3
++ //Min_amplitude
++ mt9t112_mcu_write(ret, client, 0xA00C, 0x0A); // = 10
++ //RX FIFO Watermark (A)
++ mt9t112_mcu_write(ret, client, 0x4846, 0x0080); // = 128
++ //TX FIFO Watermark (A)
++ mt9t112_mcu_write(ret, client, 0x68AA, resolution->tx_water);
++ //Max FD Zone 50 Hz
++ mt9t112_mcu_write(ret, client, 0x6815, resolution->max_fd_50);
++ //Max FD Zone 60 Hz
++ mt9t112_mcu_write(ret, client, 0x6817, resolution->max_fd_60);
++ //AE Target FD Zone
++ mt9t112_mcu_write(ret, client, 0x682D, resolution->targ_fd);
++ //RX FIFO Watermark (B)
++ mt9t112_mcu_write(ret, client, 0x488E, 0x0080); // = 128
++ //TX FIFO Watermark (B)
++ mt9t112_mcu_write(ret, client, 0x6CAA, 0x01D0); // = 464
++ //Refresh Sequencer Mode
++ mt9t112_mcu_write(ret, client, 0x8400, 0x06); // = 6
++ //Refresh Sequencer
++ mt9t112_mcu_write(ret, client, 0x8400, 0x05); // = 5
++
++#ifdef TEST_PATTERN
++ mt9t112_mcu_write(ret, client, VAR(24, 0x03), 0x100);
++ mt9t112_mcu_write(ret, client, VAR(24, 0x25), 0x0B); // B - Color Bar Test Pattern (supposed to be 6 ?)
++#endif
++
++ return ret;
++}
++
++static int mt9t112_optimal_power_consumption(const struct i2c_client *client)
++{
++ int ret;
++
++ // Analog setting B
++
++ mt9t112_reg_write(ret, client, 0x3084, 0x2409);
++ mt9t112_reg_write(ret, client, 0x3092, 0x0A49);
++ mt9t112_reg_write(ret, client, 0x3094, 0x4949);
++ mt9t112_reg_write(ret, client, 0x3096, 0x4950);
++
++ return ret;
++}
++
++static int mt9t112_blooming_row_pattern(const struct i2c_client *client)
++{
++ int ret;
++
++ // Improve high light image quality
++ // [CAM1_CTX_A_COARSE_ITMIN]
++ mt9t112_mcu_write(ret, client, 0x4815, 0x0004);
++ // [CAM1_CTX_B_COARSE_ITMIN]
++ mt9t112_mcu_write(ret, client, 0x485D, 0x0004);
++
++ return ret;
++}
++
++static int mt9t112_set_orientation(const struct i2c_client *client, int flip)
++{
++ int ret;
++
++ // if flip = 0 set [normal]
++ // if flip = 1 set [horizontal mirror]
++ // if flip = 2 set [vertical flip]
++ // if flip = 3 set [rotate 180]
++ flip &= 0x3;
++
++ // [CAM1_CTX_A_READ_MODE]
++ mt9t112_mcu_mask_set(ret, client, VAR(18, 0x000C), 0x0003, flip);
++ // [CAM1_CTX_A_PIXEL_ORDER]
++ mt9t112_mcu_write(ret, client, VAR8(18, 0x000E), flip);
++
++ // [CAM1_CTX_B_READ_MODE]
++ mt9t112_mcu_mask_set(ret, client, VAR(18, 0x0054), 0x0003, flip);
++ // [CAM1_CTX_B_PIXEL_ORDER]
++ mt9t112_mcu_write(ret, client, VAR8(18, 0x0056), flip);
++
++ // [SEQ_CMD]
++ mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
++
++ return ret;
++}
++
++static int mt9t112_init_camera_optimized(const struct i2c_client *client)
++{
++ int ret;
++
++ // basic startup
++ ECHECKER(ret, mt9t112_sysctl_startup_K26A_rev_3(client));
++
++ // enable powerup stop
++ ECHECKER(ret, mt9t112_mcu_powerup_stop_enable(client));
++
++ // start MCU
++ ECHECKER(ret, mt9t112_go(client));
++
++ // customize the configuration
++ ECHECKER(ret, mt9t112_custom_setup(client));
++
++ // enable operation with fastest clocks
++ ECHECKER(ret, mt9t112_high_speed_overrides(client));
++
++ // Optimal power consumption setting
++ ECHECKER(ret, mt9t112_optimal_power_consumption(client));
++
++ // load anti-blooming settings
++ ECHECKER(ret, mt9t112_blooming_row_pattern(client));
++
++ // continue after powerup stop
++ ECHECKER(ret, mt9t112_continue(client));
++
++ return ret;
++}
++
+ static int mt9t112_init_pll(const struct i2c_client *client)
+ {
+ struct mt9t112_priv *priv = to_mt9t112(client);
+@@ -802,6 +1281,7 @@ static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct mt9t112_priv *priv = to_mt9t112(client);
+ int ret = 0;
++ int optimize = 0;
+
+ if (!enable) {
+ /* FIXME
+@@ -830,15 +1310,33 @@ static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
+ priv->flags |= INIT_DONE;
+ }
+
++ // fill the structure with new resolution parameters
++ optimize = mt9t112_set_resolution_params(client);
++
++ if (optimize)
++ ECHECKER(ret, mt9t112_init_camera_optimized(client));
++ else
++ ECHECKER(ret, mt9t112_init_camera(client));
++
++ /* Invert PCLK (Data sampled on falling edge of pixclk) */
++ mt9t112_reg_write(ret, client, 0x3C20, (PCLK_RISING & priv->flags ? 0x0001 : 0x0000));
++ mdelay(5);
++
+ mt9t112_mcu_write(ret, client, VAR(26, 7), priv->format->fmt);
+ mt9t112_mcu_write(ret, client, VAR(26, 9), priv->format->order);
+ mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06);
+
+- mt9t112_set_a_frame_size(client,
++ if (!optimize) {
++ mt9t112_set_a_frame_size(client,
+ priv->frame.width,
+ priv->frame.height);
+
+- ECHECKER(ret, mt9t112_auto_focus_trigger(client));
++ ECHECKER(ret, mt9t112_auto_focus_trigger(client));
++ }
++
++ if (priv->info->flags & MT9T112_FLAG_VFLIP) {
++ ECHECKER(ret, mt9t112_set_orientation(client, 2));
++ }
+
+ dev_dbg(&client->dev, "format : %d\n", priv->format->code);
+ dev_dbg(&client->dev, "size : %d x %d\n",
+diff --git a/include/media/mt9t112.h b/include/media/mt9t112.h
+index a43c74a..bab2746 100644
+--- a/include/media/mt9t112.h
++++ b/include/media/mt9t112.h
+@@ -13,6 +13,8 @@
+
+ #define MT9T112_FLAG_PCLK_RISING_EDGE (1 << 0)
+ #define MT9T112_FLAG_DATAWIDTH_8 (1 << 1) /* default width is 10 */
++#define MT9T112_FLAG_VFLIP (1 << 2)
++#define MT9T112_FLAG_HFLIP (1 << 3)
+
+ struct mt9t112_pll_divider {
+ u8 m, n;
diff --git a/patches/linux-3.8.13/0612-cssp_camera-Use-flip-if-available.patch b/patches/linux-3.8.13/0612-cssp_camera-Use-flip-if-available.patch
new file mode 100644
index 0000000..8be0a94
--- /dev/null
+++ b/patches/linux-3.8.13/0612-cssp_camera-Use-flip-if-available.patch
@@ -0,0 +1,53 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 2 May 2013 14:16:40 +0300
+Subject: [PATCH] cssp_camera: Use flip if available.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/media/platform/soc_camera/cssp_camera.c | 19 ++++++++-----------
+ 1 file changed, 8 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/cssp_camera.c b/drivers/media/platform/soc_camera/cssp_camera.c
+index 0a0cd8f..788acc4 100644
+--- a/drivers/media/platform/soc_camera/cssp_camera.c
++++ b/drivers/media/platform/soc_camera/cssp_camera.c
+@@ -16,7 +16,7 @@
+ *
+ */
+
+-
++#define DEBUG
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/gpio.h>
+@@ -1345,15 +1345,12 @@ of_get_cssp_platform_data(struct platform_device *pdev)
+
+ /* set orientation flag */
+
+- /*
+- * But the driver in mainline doesn't support flip
+- * Commented out for now...
+- *
+- * if (ret)
+- * val |= MT9T112_FLAG_VFLIP;
+- * else
+- * val &= ~MT9T112_FLAG_VFLIP
+- */
++#ifdef MT9T112_FLAG_VFLIP
++ if (ret)
++ val |= MT9T112_FLAG_VFLIP;
++ else
++ val &= ~MT9T112_FLAG_VFLIP;
++#endif
+ }
+ pstore->mt9t111_cam_info.flags = val;
+
+@@ -1376,7 +1373,7 @@ err_fail:
+ if (adap != NULL)
+ put_device(&adap->dev);
+
+- /* free memory (even if it will be automatically freed it's good practice) */
++ /* free memory (even if automatically freed it's good practice) */
+ if (pstore != NULL)
+ devm_kfree(dev, pstore);
+
diff --git a/patches/linux-3.8.13/0613-cssp_camera-Fix-it-for-small-resolutions.patch b/patches/linux-3.8.13/0613-cssp_camera-Fix-it-for-small-resolutions.patch
new file mode 100644
index 0000000..67eb34c
--- /dev/null
+++ b/patches/linux-3.8.13/0613-cssp_camera-Fix-it-for-small-resolutions.patch
@@ -0,0 +1,932 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 9 May 2013 23:01:53 +0300
+Subject: [PATCH] cssp_camera: Fix it for small resolutions
+
+This should make it work reliably for resolutions up to 1024x768
+
+1280x960 and higher hang, or crash..
+---
+ drivers/media/platform/soc_camera/cssp_camera.c | 567 +++++++++++++++++------
+ 1 file changed, 415 insertions(+), 152 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/cssp_camera.c b/drivers/media/platform/soc_camera/cssp_camera.c
+index 788acc4..62d8702 100644
+--- a/drivers/media/platform/soc_camera/cssp_camera.c
++++ b/drivers/media/platform/soc_camera/cssp_camera.c
+@@ -53,13 +53,12 @@ static unsigned int vid_limit = 6;
+ module_param(vid_limit, uint, 0644);
+ MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
+
+-#define VGA_WIDTH 640
+-#define VGA_HEIGHT 480
++#define INIT_WIDTH 640
++#define INIT_HEIGHT 480
+
+ #define MAX_WIDTH 2048
+ #define MAX_HEIGHT 1536
+
+-#define VGA_RES (VGA_WIDTH * VGA_HEIGHT)
+ #define BYTES_PER_PIXEL 2
+
+ /* PaRAM.opt: */
+@@ -117,10 +116,14 @@ struct cssp_cam_buffer {
+ struct vb2_buffer vb;
+ struct list_head list;
+ struct cssp_cam_fmt *fmt;
++ unsigned long queued_jiffies;
+ };
+
++#define to_cssp_cam_buffer(_x) container_of(_x, struct cssp_cam_buffer, vb)
++
+ struct cssp_cam_dmaqueue {
+ struct list_head active;
++ int count;
+ };
+
+ struct cssp_cam_dev {
+@@ -138,7 +141,9 @@ struct cssp_cam_dev {
+ struct cssp_cam_dmaqueue vidq;
+ void *dma_cont_ctx;
+ int streaming_started;
+- struct vb2_buffer *current_vb;
++ struct vb2_buffer *current_vb[2];
++ void *spillover;
++ dma_addr_t spillover_dma_addr;
+
+ /* video capture */
+ struct cssp_cam_fmt *fmt;
+@@ -160,10 +165,13 @@ struct cssp_cam_dev {
+ u16 mode;
+
+ int dma_ch;
++ int dma_link[2];
+ struct edmacc_param dma_tr_params;
++ struct edmacc_param dma_link_params;
+
+ u64 dma_mask;
+ int dma_req_len;
++ int dma_req_shift;
+
+ int frame_cnt;
+
+@@ -241,6 +249,65 @@ static struct cssp_cam_fmt formats[] = {
+
+ /***************************************************************************/
+
++static inline dma_addr_t vb2_dma_contig_cookie(void *a, void *b)
++{
++ /* Same functionality as the vb2_dma_contig_plane_paddr */
++ dma_addr_t *paddr = vb2_dma_contig_memops.cookie(b);
++
++ return *paddr;
++}
++
++/* MFC definitions */
++
++static void set_capture_enable_no_lock(struct cssp_cam_dev *dev, int enable)
++{
++ u16 val;
++
++ // readw(dev->reg_base_virt + REG_MODE);
++ if (enable) {
++ ioread16(dev->reg_base_virt + REG_MODE);
++ iowrite16(dev->mode & ~ENABLE, dev->reg_base_virt + REG_MODE);
++ ioread16(dev->reg_base_virt + REG_MODE);
++ iowrite16(dev->mode | ENABLE, dev->reg_base_virt + REG_MODE);
++ } else {
++ ioread16(dev->reg_base_virt + REG_MODE);
++ iowrite16(dev->mode | ENABLE, dev->reg_base_virt + REG_MODE);
++ ioread16(dev->reg_base_virt + REG_MODE);
++ iowrite16(dev->mode & ~ENABLE, dev->reg_base_virt + REG_MODE);
++ }
++
++ val = ioread16(dev->reg_base_virt + REG_MODE);
++ dev_dbg(&dev->pdev->dev, "%s enable=%d val=0x%04x\n", __func__,
++ enable, val);
++}
++
++static int set_capture_enable(struct cssp_cam_dev *dev, int enable)
++{
++ unsigned long flags;
++ unsigned long tmo;
++
++ spin_lock_irqsave(&dev->slock, flags);
++ set_capture_enable_no_lock(dev, enable);
++ spin_unlock_irqrestore(&dev->slock, flags);
++
++ /* sigh, check whether the device gets data */
++ if (enable) {
++ tmo = jiffies + msecs_to_jiffies(1000);
++ while ((ioread16(dev->reg_base_virt + REG_MODE) & 0x0100) != 0) {
++ if (time_after(jiffies, tmo))
++ break;
++ cpu_relax();
++ }
++
++ if (time_after(jiffies, tmo)) {
++ spin_lock_irqsave(&dev->slock, flags);
++ set_capture_enable_no_lock(dev, 0);
++ spin_unlock_irqrestore(&dev->slock, flags);
++ return -EAGAIN;
++ }
++ }
++ return 0;
++}
+
+ static int configure_gpio(int nr, int val, const char *name)
+ {
+@@ -277,96 +344,209 @@ static int reset_cssp(struct cssp_cam_dev *cam)
+ return err;
+ }
+
+-static int trigger_dma_transfer_to_buf(struct cssp_cam_dev *dev, struct vb2_buffer *vb)
++#if 0
++static void dump_slot(struct cssp_cam_dev *cam, int slot, char *name)
+ {
+- dma_addr_t dma_buf = vb2_dma_contig_plane_dma_addr(vb, 0);
++ struct device *dev = &cam->pdev->dev;
++ struct edmacc_param p;
+
+- if (!dma_buf) {
+- /* Is this possible? Release the vb2_buffer with an error here, */
+- vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+- dev->current_vb = NULL;
+- return -ENOMEM;
+- }
++ if (slot < 0)
++ return;
++
++ edma_read_slot(slot, &p);
++ dev_dbg(dev, "%s: 0x%x, opt=%x, src=%x, a_b_cnt=%x dst=%x\n",
++ name, slot, p.opt, p.src, p.a_b_cnt, p.dst);
++ dev_dbg(dev, " src_dst_bidx=%x link_bcntrld=%x src_dst_cidx=%x ccnt=%x\n",
++ p.src_dst_bidx, p.link_bcntrld, p.src_dst_cidx, p.ccnt);
++}
++#endif
+
+- dev->dma_tr_params.dst = dma_buf;
++void enqueue_dma(struct cssp_cam_dev *dev, int ch, struct vb2_buffer *vb)
++{
++ dma_addr_t dma_buf;
++ int i, rem;
++ u32 bytesperline, height;
++ u16 acnt, bcnt, ccnt;
++ struct edmacc_param params;
+
+- // Enable DMA
+- edma_write_slot(dev->dma_ch, &dev->dma_tr_params);
++ /* Calculate DMA transfer parameters based on DMA request length */
++ bytesperline = dev->bytesperline;
++ i = 0;
++ do {
++ rem = bytesperline % dev->dma_req_len;
++ if (rem != 0) {
++ bytesperline <<= 1;
++ i++;
++ }
++ } while (rem != 0);
++ height = dev->height >> i;
++ acnt = dev->dma_req_len;
++ bcnt = bytesperline / dev->dma_req_len;
++ ccnt = height;
+
+- dev->current_vb = vb;
++ if (vb != NULL)
++ dma_buf = vb2_dma_contig_plane_dma_addr(vb, 0);
++ else
++ dma_buf = dev->spillover_dma_addr;
++
++ edma_set_src(ch, dev->reg_base_phys + REG_DATA, INCR, W8BIT);
++ edma_set_dest(ch, dma_buf, INCR, W8BIT);
++ edma_set_src_index(ch, 0, 0);
++ edma_set_dest_index(ch,
++ dev->dma_req_len, /* dest bidx */
++ dev->dma_req_len); /* dest cidx */
++ edma_set_transfer_params(ch,
++ dev->dma_req_len, /* acnt */
++ bytesperline / dev->dma_req_len, /* bcnt */
++ height, /* ccnt */
++ bytesperline / dev->dma_req_len, /* bcnt_rld */
++ ASYNC);
+
+- // Enable data capture
+- dev->mode |= ENABLE;
+- writew(dev->mode, dev->reg_base_virt + REG_MODE);
+- readw(dev->reg_base_virt + REG_MODE);
++ /*
++ * Issue transfer completion IRQ when the channel completes
++ * a transfer, and then always reload from the same slot
++ */
++ edma_read_slot(ch, &params);
++ params.opt |= TCINTEN | EDMA_TCC(EDMA_CHAN_SLOT(dev->dma_ch));
++ params.link_bcntrld = (params.link_bcntrld & ~0xffff) |
++ ((EDMA_CHAN_SLOT(dev->dma_link[0]) << 5) & 0xffff);
++ edma_write_slot(ch, &params);
++
++#if 0
++ {
++ struct edmacc_param p;
++
++ edma_read_slot(ch, &p);
++ dev_dbg(&dev->pdev->dev,
++ "1. opt=%08x, src=%08x, a_b_cnt=%08x dst=%08x src_dst_bidx=%08x "
++ "link_bcntrld=%08x src_dst_cidx=%08x ccnt=%08x\n",
++ p.opt, p.src, p.a_b_cnt, p.dst, p.src_dst_bidx,
++ p.link_bcntrld, p.src_dst_cidx, p.ccnt);
++
++ p.opt = TCINTEN | TCC(dev->dma_ch);
++ p.src = dev->reg_base_phys + REG_DATA;
++ p.dst = dma_buf;
++ p.a_b_cnt = ACNT(dev->dma_req_len) | BCNT((INIT_WIDTH * BYTES_PER_PIXEL) / dev->dma_req_len);
++ p.src_dst_bidx = SRCBIDX(0) | DSTBIDX(dev->dma_req_len);
++ p.link_bcntrld = BCNTRLD((INIT_WIDTH * BYTES_PER_PIXEL) / dev->dma_req_len) | LINK(0xffff);
++ p.src_dst_cidx = SRCCIDX(0) | DSTCIDX(dev->dma_req_len);
++ p.ccnt = CCNT(INIT_HEIGHT);
++
++ dev_dbg(&dev->pdev->dev,
++ "2. opt=%08x, src=%08x, a_b_cnt=%08x dst=%08x src_dst_bidx=%08x "
++ "link_bcntrld=%08x src_dst_cidx=%08x ccnt=%08x\n",
++ p.opt, p.src, p.a_b_cnt, p.dst, p.src_dst_bidx,
++ p.link_bcntrld, p.src_dst_cidx, p.ccnt);
++
++ }
++#endif
++
++ // dump_slot(dev, ch, "q");
++
++ /*
++ param->a_b_cnt = ACNT(dev->dma_req_len) | BCNT(bytesperline / dev->dma_req_len);
++ param->src_dst_bidx = SRCBIDX(0) | DSTBIDX(dev->dma_req_len);
++ param->link_bcntrld = BCNTRLD(bytesperline / dev->dma_req_len) | LINK(0xffff);
++ param->src_dst_cidx = SRCCIDX(0) | DSTCIDX(dev->dma_req_len);
++ param->ccnt = CCNT(height);
++ */
+
+- return 0;
+ }
+
+-static void dequeue_buffer_for_dma(struct cssp_cam_dev *dev)
++static int fillup_dma(struct cssp_cam_dev *dev)
+ {
+ struct cssp_cam_dmaqueue *dma_q = &dev->vidq;
+- unsigned long flags = 0;
++ struct cssp_cam_buffer *buf;
++ struct vb2_buffer *vb;
++ int i, ch, cnt;
++ unsigned long flags;
+
+ spin_lock_irqsave(&dev->slock, flags);
+- if (!list_empty(&dma_q->active)) {
+- struct cssp_cam_buffer *buf;
+
+- buf = list_entry(dma_q->active.next, struct cssp_cam_buffer, list);
++ /* while there's a buffer queued, and there's space */
++ cnt = 0;
++ while (!list_empty(&dma_q->active) &&
++ (dev->current_vb[0] == NULL || dev->current_vb[1] == NULL)) {
++
++ if (dev->current_vb[0] == NULL) {
++ i = 0;
++ ch = dev->dma_ch;
++ } else {
++ i = 1;
++ ch = dev->dma_link[0];
++ }
++
++ buf = list_entry(dma_q->active.next,
++ struct cssp_cam_buffer, list);
+ list_del(&buf->list);
+- spin_unlock_irqrestore(&dev->slock, flags);
++ dma_q->count--;
+
+- buf->fmt = dev->fmt;
++ vb = &buf->vb;
++ enqueue_dma(dev, ch, vb);
++ dev->current_vb[i] = vb;
+
+- trigger_dma_transfer_to_buf(dev, &buf->vb);
+- } else {
+- spin_unlock_irqrestore(&dev->slock, flags);
++ cnt++;
++ /* dev_dbg(&pdev->dev, "queued vb %p (#=%d, ch=%d)\n", vb, i, ch); */
+ }
++ spin_unlock_irqrestore(&dev->slock, flags);
++
++ return cnt;
+ }
+
+ static void dma_callback(unsigned lch, u16 ch_status, void *data)
+ {
+ struct cssp_cam_dev *dev = data;
+ struct vb2_buffer *vb;
+- struct edmacc_param dma_tr_params;
++ unsigned long flags;
++ struct cssp_cam_buffer *buf;
++ struct cssp_cam_dmaqueue *dma_q = &dev->vidq;
++ int ch;
+
+- // Disable data capture
+- dev->mode &= ~ENABLE;
+- writew(dev->mode, dev->reg_base_virt + REG_MODE);
+- readw(dev->reg_base_virt + REG_MODE);
+-
+- if (ch_status == DMA_COMPLETE) {
+-
+- vb = dev->current_vb;
+-
+- edma_read_slot(dev->dma_ch, &dma_tr_params);
+- if ((dma_tr_params.opt != 0) ||
+- (dma_tr_params.src != 0) ||
+- (dma_tr_params.a_b_cnt != 0) ||
+- (dma_tr_params.dst != 0) ||
+- (dma_tr_params.src_dst_bidx != 0) ||
+- (dma_tr_params.link_bcntrld != 0xffff) ||
+- (dma_tr_params.src_dst_cidx != 0) ||
+- (dma_tr_params.ccnt != 0)) {
+-
+- trigger_dma_transfer_to_buf(dev, dev->current_vb);
+- return;
+- }
++ if (ch_status != DMA_COMPLETE) {
++ dev_dbg(&dev->pdev->dev, "%s - missed interrupt\n",
++ __func__);
++ return;
++ }
++
++ spin_lock_irqsave(&dev->slock, flags);
++
++ vb = dev->current_vb[0];
++ dev->current_vb[0] = dev->current_vb[1];
++ dev->current_vb[1] = NULL;
++
++ /* if there's a buffer, link to the next */
++ ch = dev->dma_link[0];
++
++ if (!list_empty(&dma_q->active)) {
++
++ buf = list_entry(dma_q->active.next,
++ struct cssp_cam_buffer, list);
++ list_del(&buf->list);
++ dma_q->count--;
++
++ enqueue_dma(dev, ch, &buf->vb);
++ dev->current_vb[1] = &buf->vb;
++ } else {
++ /* no buffer, we need to put the spillover there */
++ enqueue_dma(dev, ch, NULL);
++ }
++
++ spin_unlock_irqrestore(&dev->slock, flags);
++
++ /* fillup_dma(dev); */
++
++ if (vb != NULL) {
++ /* queue the current buffer */
++ buf = to_cssp_cam_buffer(vb);
+
+ vb->v4l2_buf.field = dev->field;
+ vb->v4l2_buf.sequence = dev->frame_cnt++;
+ do_gettimeofday(&vb->v4l2_buf.timestamp);
+ vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+- dev->current_vb = NULL;
+
+- /* check if we have new buffer queued */
+- dequeue_buffer_for_dma(dev);
+- } else {
+- /* we got a missed interrupt so just start a new DMA with the existing buffer */
+- if (dev->current_vb != NULL) {
+- if (trigger_dma_transfer_to_buf(dev, dev->current_vb))
+- dev_err(&dev->pdev->dev, "No buffer allocated!\n");
+- }
++ dev_dbg(&dev->pdev->dev, "[%p/%d] done\n",
++ buf, buf->vb.v4l2_buf.index);
++
+ }
+ }
+
+@@ -374,8 +554,8 @@ static int configure_edma(struct cssp_cam_dev *cam)
+ {
+ struct platform_device *pdev = cam->pdev;
+ struct cssp_cam_platform_data *pdata = pdev->dev.platform_data;
+- struct edmacc_param *param;
+ int dma_channel;
++ int ret;
+
+ dma_channel = pdata->dma_ch;
+
+@@ -386,24 +566,22 @@ static int configure_edma(struct cssp_cam_dev *cam)
+ dev_err(&pdev->dev, "failed setting mask for DMA\n");
+ return -EINVAL;
+ }
+- cam->dma_ch = edma_alloc_channel(dma_channel, dma_callback, cam, EVENTQ_0);
+- if (cam->dma_ch < 0) {
++ ret = edma_alloc_channel(dma_channel, dma_callback, cam, EVENTQ_0);
++ if (ret < 0) {
+ dev_err(&pdev->dev, "allocating channel for DMA failed\n");
+- return -EBUSY;
++ return ret;
+ }
++ cam->dma_ch = ret;
++ dev_info(&pdev->dev, "dma_ch=%d\n", cam->dma_ch);
+
+- cam->dma_req_len = cam->rev > 3 ? 128 : 32;
+-
+- param = &cam->dma_tr_params;
+- param->opt = TCINTEN | TCC(cam->dma_ch);
+- param->src = cam->reg_base_phys + REG_DATA;
+- param->a_b_cnt = ACNT(cam->dma_req_len) |
+- BCNT((VGA_WIDTH * BYTES_PER_PIXEL) / cam->dma_req_len);
+- param->src_dst_bidx = SRCBIDX(0) | DSTBIDX(cam->dma_req_len);
+- param->link_bcntrld = BCNTRLD((VGA_WIDTH * BYTES_PER_PIXEL) /
+- cam->dma_req_len) | LINK(0xffff);
+- param->src_dst_cidx = SRCCIDX(0) | DSTCIDX(cam->dma_req_len);
+- param->ccnt = CCNT(VGA_HEIGHT);
++ /* allocate link channels */
++ ret = edma_alloc_slot(EDMA_CTLR(cam->dma_ch), EDMA_SLOT_ANY);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "allocating slot for DMA failed\n");
++ return ret;
++ }
++ cam->dma_link[0] = ret;
++ dev_info(&pdev->dev, "dma_link[0]=%d\n", cam->dma_link[0]);
+
+ return 0;
+ }
+@@ -450,7 +628,13 @@ static int configure_cssp(struct cssp_cam_dev *cam)
+ dev_info(&pdev->dev, "CSSP Revision %c%d\n",
+ 'A' + ((cam->rev & 0xf0) >> 4), cam->rev & 0x0f);
+
+- cam->dma_req_len = cam->rev > 3 ? 128 : 32;
++ if (cam->rev > 3) {
++ cam->dma_req_len = 128;
++ cam->dma_req_shift = 7;
++ } else {
++ cam->dma_req_len = 32;
++ cam->dma_req_shift = 5;
++ }
+
+ return 0;
+ }
+@@ -461,17 +645,19 @@ static int configure_camera_sensor(struct cssp_cam_dev *cam)
+ struct i2c_client *client;
+ struct i2c_adapter *adapter;
+ struct v4l2_subdev *subdev;
++ int ret;
+ struct v4l2_mbus_framefmt f_format = {
+- .width = VGA_WIDTH,
+- .height = VGA_HEIGHT,
++ .width = INIT_WIDTH,
++ .height = INIT_HEIGHT,
+ .code = V4L2_MBUS_FMT_YUYV8_2X8,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ };
+
+ /* Enable the clock just for the time of loading the camera driver and disable after that */
+ /* It is going to be be re-enabled later, when camera will be in use */
+- clk_enable(cam->camera_clk);
+- mdelay(50); // let the clock stabilize
++ ret = clk_prepare_enable(cam->camera_clk);
++ BUG_ON(ret != 0);
++ mdelay(1); // let the clock stabilize
+
+ adapter = i2c_get_adapter(((struct soc_camera_link *)(info->platform_data))->i2c_adapter_id);
+ if (!adapter) {
+@@ -496,17 +682,21 @@ static int configure_camera_sensor(struct cssp_cam_dev *cam)
+
+ v4l2_subdev_call(subdev, video, s_mbus_fmt, &f_format);
+
+- clk_disable(cam->camera_clk);
++ clk_disable_unprepare(cam->camera_clk);
+
+ return 0;
+ }
+
+ static int start_camera_sensor(struct cssp_cam_dev *cam)
+ {
+- clk_enable(cam->camera_clk);
+- mdelay(100); /* let the clock stabilize */
++ int ret;
+
+- v4l2_subdev_call(cam->subdev, video, s_stream, 1);
++ ret = v4l2_subdev_call(cam->subdev, video, s_stream, 1);
++ if (ret != 0) {
++ dev_err(&cam->pdev->dev, "%s: v4l2_subdev_call failed\n",
++ __func__);
++ return ret;
++ }
+
+ return 0;
+ }
+@@ -514,10 +704,6 @@ static int start_camera_sensor(struct cssp_cam_dev *cam)
+ static void stop_camera_sensor(struct cssp_cam_dev *cam)
+ {
+ v4l2_subdev_call(cam->subdev, video, s_stream, 0);
+-
+- clk_disable(cam->camera_clk);
+-
+- return;
+ }
+
+ static struct cssp_cam_fmt *get_format(struct v4l2_format *f)
+@@ -577,18 +763,6 @@ static int buffer_init(struct vb2_buffer *vb)
+
+ BUG_ON(NULL == dev->fmt);
+
+- /*
+- * This callback is called once per buffer, after its allocation.
+- *
+- * Vivi does not allow changing format during streaming, but it is
+- * possible to do so when streaming is paused (i.e. in streamoff state).
+- * Buffers however are not freed when going into streamoff and so
+- * buffer size verification has to be done in buffer_prepare, on each
+- * qbuf.
+- * It would be best to move verification code here to buf_init and
+- * s_fmt though.
+- */
+-
+ return 0;
+ }
+
+@@ -649,30 +823,34 @@ static void buffer_queue(struct vb2_buffer *vb)
+ struct cssp_cam_dmaqueue *vidq = &dev->vidq;
+ unsigned long flags = 0;
+
+- dev_dbg(&dev->pdev->dev, "%s\n", __func__);
+-
+- if (dev->streaming_started && !dev->current_vb) {
+- trigger_dma_transfer_to_buf(dev, &buf->vb);
+- } else {
+- spin_lock_irqsave(&dev->slock, flags);
+- list_add_tail(&buf->list, &vidq->active);
+- spin_unlock_irqrestore(&dev->slock, flags);
+- }
++ /* just add it to the queue */
++ spin_lock_irqsave(&dev->slock, flags);
++ list_add_tail(&buf->list, &vidq->active);
++ vidq->count++;
++ spin_unlock_irqrestore(&dev->slock, flags);
+ }
+
+ static int start_streaming(struct vb2_queue *vq, unsigned int count)
+ {
+ struct cssp_cam_dev *dev = vb2_get_drv_priv(vq);
+ struct platform_device *pdev = dev->pdev;
+- int ret;
++ int ret, retries;
+
+- dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++ dev_dbg(&dev->pdev->dev, "%s count=%d\n", __func__, count);
+
+- ret = start_camera_sensor(dev);
++ retries = 0;
++
++ set_capture_enable(dev, 0);
++
++ ret = clk_prepare_enable(dev->camera_clk);
+ if (ret != 0) {
+- dev_err(&pdev->dev, "start_camera_sensor failed\n");
++ dev_err(&pdev->dev, "%s: clk_enable failed\n",
++ __func__);
+ return ret;
+ }
++ mdelay(20); /* let the clock stabilize */
++
++ fillup_dma(dev);
+
+ // Enable DMA
+ ret = edma_start(dev->dma_ch);
+@@ -680,10 +858,25 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
+ dev_err(&pdev->dev, "edma_start failed\n");
+ return ret;
+ }
+- dev->streaming_started = 1;
+
+- /* check if we have new buffer queued */
+- dequeue_buffer_for_dma(dev);
++again:
++ ret = start_camera_sensor(dev);
++ if (ret != 0) {
++ dev_err(&pdev->dev, "start_camera_sensor failed\n");
++ return ret;
++ }
++
++ // Enable data capture
++ ret = set_capture_enable(dev, 1);
++ if (ret != 0) {
++ retries++;
++ dev_warn(&pdev->dev, "no stream; retry #%d\n", retries);
++ if (retries < 3)
++ goto again;
++ goto again;
++ }
++
++ dev->streaming_started = 1;
+
+ return 0;
+ }
+@@ -693,6 +886,10 @@ static int stop_streaming(struct vb2_queue *vq)
+ {
+ struct cssp_cam_dev *dev = vb2_get_drv_priv(vq);
+ struct cssp_cam_dmaqueue *dma_q = &dev->vidq;
++ struct cssp_cam_buffer *buf;
++ unsigned long flags;
++ struct vb2_buffer *vb;
++ int i;
+
+ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
+
+@@ -700,27 +897,43 @@ static int stop_streaming(struct vb2_queue *vq)
+ edma_stop(dev->dma_ch);
+
+ // Disable data capture
+- dev->mode &= ~ENABLE;
+- writew(dev->mode, dev->reg_base_virt + REG_MODE);
++ set_capture_enable(dev, 0);
+
+ stop_camera_sensor(dev);
+
++ clk_disable_unprepare(dev->camera_clk);
++
+ dev->streaming_started = 0;
+
+ /* Release all active buffers */
++ spin_lock_irqsave(&dev->slock, flags);
++
++ for (i = 0; i < 2; i++) {
++ vb = dev->current_vb[i];
++ if (vb == NULL)
++ continue;
++ dev->current_vb[i] = NULL;
++
++ buf = to_cssp_cam_buffer(vb);
++
++ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
++
++ dev_dbg(&dev->pdev->dev, "[%p/%d] in flight\n",
++ buf, buf->vb.v4l2_buf.index);
++ }
++
+ while (!list_empty(&dma_q->active)) {
+- struct cssp_cam_buffer *buf;
+
+ buf = list_entry(dma_q->active.next,
+ struct cssp_cam_buffer, list);
+ list_del(&buf->list);
++
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+
+- dev_dbg(&dev->pdev->dev, "[%p/%d] done\n",
++ dev_dbg(&dev->pdev->dev, "[%p/%d] queued\n",
+ buf, buf->vb.v4l2_buf.index);
+ }
+-
+- dev->current_vb = NULL;
++ spin_unlock_irqrestore(&dev->slock, flags);
+
+ return 0;
+ }
+@@ -759,6 +972,8 @@ static int vidioc_querycap(struct file *file, void *priv,
+ {
+ struct cssp_cam_dev *dev = video_drvdata(file);
+
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
+ strcpy(cap->driver, "cssp_camera");
+ strcpy(cap->card, "cssp_camera");
+ strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
+@@ -770,8 +985,11 @@ static int vidioc_querycap(struct file *file, void *priv,
+ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+ {
++ struct cssp_cam_dev *dev = video_drvdata(file);
+ struct cssp_cam_fmt *fmt;
+
++ dev_dbg(&dev->pdev->dev, "%s index=%d\n", __func__, f->index);
++
+ if (f->index >= ARRAY_SIZE(formats))
+ return -EINVAL;
+
+@@ -787,6 +1005,10 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+ {
+ struct cssp_cam_dev *dev = video_drvdata(file);
+
++ dev_dbg(&dev->pdev->dev, "%s: dev->width=%u dev->height=%u "
++ "dev->sizeimage=%u\n", __func__,
++ dev->width, dev->height, dev->sizeimage);
++
+ f->fmt.pix.width = dev->width;
+ f->fmt.pix.height = dev->height;
+ f->fmt.pix.field = dev->field;
+@@ -806,6 +1028,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_mbus_framefmt mbus_fmt;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
+ fmt = get_format(f);
+ if (!fmt) {
+ dev_err(&dev->pdev->dev, "Fourcc format (0x%08x) invalid.\n",
+@@ -843,12 +1067,16 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct vb2_queue *q = &dev->vb_vidq;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ struct v4l2_mbus_framefmt mbus_fmt;
+- int i = 0, rem;
+- u32 bytesperline, height;
++ int ret;
+
+- int ret = vidioc_try_fmt_vid_cap(file, priv, f);
+- if (ret < 0)
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
++ ret = vidioc_try_fmt_vid_cap(file, priv, f);
++ if (ret < 0) {
++ dev_err(&dev->pdev->dev, "%s: vidioc_try_fmt_vid_cap failed\n",
++ __func__);
+ return ret;
++ }
+
+ if (vb2_is_streaming(q)) {
+ dev_err(&dev->pdev->dev, "%s device busy\n", __func__);
+@@ -863,26 +1091,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ dev->bytesperline = f->fmt.pix.bytesperline;
+ dev->sizeimage = f->fmt.pix.sizeimage;
+
++ dev_dbg(&dev->pdev->dev, "width=%u height=%u byteperline=%u\n",
++ dev->width, dev->height, dev->bytesperline);
++
+ /* Set the sensor into the new format */
+ v4l2_fill_mbus_format(&mbus_fmt, pix, dev->fmt->code);
+ v4l2_subdev_call(dev->subdev, video, s_mbus_fmt, &mbus_fmt);
+
+- /* Calculate DMA transfer parameters based on DMA request length */
+- bytesperline = dev->bytesperline;
+- do {
+- rem = bytesperline % dev->dma_req_len;
+- if (rem != 0) {
+- bytesperline <<= 1;
+- i++;
+- }
+- } while (rem != 0);
+- height = dev->height >> i;
+-
+- /* Set the EDMA for the new resolution */
+- dev->dma_tr_params.a_b_cnt = ACNT(dev->dma_req_len) | BCNT(bytesperline / dev->dma_req_len);
+- dev->dma_tr_params.link_bcntrld = BCNTRLD(bytesperline / dev->dma_req_len) | LINK(0xffff);
+- dev->dma_tr_params.ccnt = CCNT(height);
+-
+ return 0;
+ }
+
+@@ -890,36 +1105,57 @@ static int vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *p)
+ {
+ struct cssp_cam_dev *dev = video_drvdata(file);
++
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
+ return vb2_reqbufs(&dev->vb_vidq, p);
+ }
+
+ static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
+ {
+ struct cssp_cam_dev *dev = video_drvdata(file);
++
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
+ return vb2_querybuf(&dev->vb_vidq, p);
+ }
+
+ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+ {
+ struct cssp_cam_dev *dev = video_drvdata(file);
++
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
+ return vb2_qbuf(&dev->vb_vidq, p);
+ }
+
+ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+ {
+ struct cssp_cam_dev *dev = video_drvdata(file);
++ u16 val;
++
++ val = ioread16(dev->reg_base_virt + REG_MODE);
++ dev_dbg(&dev->pdev->dev, "%s MODE=0x%04x\n", __func__,
++ val);
++
+ return vb2_dqbuf(&dev->vb_vidq, p, file->f_flags & O_NONBLOCK);
+ }
+
+ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+ {
+ struct cssp_cam_dev *dev = video_drvdata(file);
++
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
+ return vb2_streamon(&dev->vb_vidq, i);
+ }
+
+ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+ {
+ struct cssp_cam_dev *dev = video_drvdata(file);
++
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
+ return vb2_streamoff(&dev->vb_vidq, i);
+ }
+
+@@ -927,6 +1163,8 @@ static int vidioc_log_status(struct file *file, void *priv)
+ {
+ struct cssp_cam_dev *dev = video_drvdata(file);
+
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
+ v4l2_ctrl_handler_log_status(&dev->ctrl_handler, dev->v4l2_dev.name);
+ return 0;
+ }
+@@ -934,6 +1172,10 @@ static int vidioc_log_status(struct file *file, void *priv)
+ static int vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *inp)
+ {
++ struct cssp_cam_dev *dev = video_drvdata(file);
++
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
+ if (inp->index > 0)
+ return -EINVAL;
+
+@@ -945,6 +1187,10 @@ static int vidioc_enum_input(struct file *file, void *priv,
+
+ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+ {
++ struct cssp_cam_dev *dev = video_drvdata(file);
++
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
+ *i = 0;
+
+ return 0;
+@@ -952,6 +1198,10 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+
+ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+ {
++ struct cssp_cam_dev *dev = video_drvdata(file);
++
++ dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++
+ if (i > 0)
+ return -EINVAL;
+
+@@ -1088,9 +1338,10 @@ static int video_probe(struct cssp_cam_dev *cam_dev)
+ goto free_dev;
+
+ cam_dev->fmt = &formats[0];
+- cam_dev->width = VGA_WIDTH;
+- cam_dev->height = VGA_HEIGHT;
+- cam_dev->sizeimage = VGA_WIDTH * VGA_HEIGHT * BYTES_PER_PIXEL;
++ cam_dev->width = INIT_WIDTH;
++ cam_dev->height = INIT_HEIGHT;
++ cam_dev->bytesperline = INIT_WIDTH * BYTES_PER_PIXEL;
++ cam_dev->sizeimage = cam_dev->bytesperline * INIT_HEIGHT;
+ hdl = &cam_dev->ctrl_handler;
+ v4l2_ctrl_handler_init(hdl, 0);
+
+@@ -1450,8 +1701,6 @@ static int cssp_cam_probe(struct platform_device *pdev)
+ goto fail1;
+ }
+
+- clk_prepare(cam_dev->camera_clk);
+-
+ ret = configure_cssp(cam_dev);
+ if (ret) {
+ dev_err(&pdev->dev, "configure_cssp failed\n");
+@@ -1484,6 +1733,20 @@ static int cssp_cam_probe(struct platform_device *pdev)
+ if (ret)
+ goto fail4;
+
++ cam_dev->spillover = vb2_dma_contig_memops.alloc(cam_dev->dma_cont_ctx,
++ MAX_WIDTH * MAX_HEIGHT * BYTES_PER_PIXEL);
++ if (cam_dev->spillover == NULL) {
++ ret = -ENOMEM;
++ goto fail4;
++ }
++ cam_dev->spillover_dma_addr = vb2_dma_contig_cookie(
++ cam_dev->dma_cont_ctx, cam_dev->spillover);
++
++ dev_info(&pdev->dev, "spillover at %p, size %d, phys 0x%08lx\n",
++ cam_dev->spillover,
++ MAX_WIDTH * MAX_HEIGHT * BYTES_PER_PIXEL,
++ (unsigned long)cam_dev->spillover_dma_addr);
++
+ dev_err(&pdev->dev, "Loaded OK.\n");
+
+ return 0;
+@@ -1551,7 +1814,7 @@ module_platform_driver(cssp_cam_driver);
+ /*
+ * Macros sets license, author and description
+ */
+-MODULE_LICENSE("GPL v2");
++MODULE_LICENSE("GPLv2");
+ MODULE_AUTHOR("Dan Aizenstros, Damian Eppel, Przemek Szewczyk");
+ MODULE_DESCRIPTION("QuickLogic Camera Interface driver");
+
diff --git a/patches/linux-3.8.13/0614-cssp_camera-Increase-delay-after-enabling-clocks-to-.patch b/patches/linux-3.8.13/0614-cssp_camera-Increase-delay-after-enabling-clocks-to-.patch
new file mode 100644
index 0000000..1d777a1
--- /dev/null
+++ b/patches/linux-3.8.13/0614-cssp_camera-Increase-delay-after-enabling-clocks-to-.patch
@@ -0,0 +1,30 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Fri, 10 May 2013 09:27:26 +0300
+Subject: [PATCH] cssp_camera: Increase delay after enabling clocks to 100ms
+
+---
+ drivers/media/platform/soc_camera/cssp_camera.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/cssp_camera.c b/drivers/media/platform/soc_camera/cssp_camera.c
+index 62d8702..2c10f61 100644
+--- a/drivers/media/platform/soc_camera/cssp_camera.c
++++ b/drivers/media/platform/soc_camera/cssp_camera.c
+@@ -657,7 +657,7 @@ static int configure_camera_sensor(struct cssp_cam_dev *cam)
+ /* It is going to be be re-enabled later, when camera will be in use */
+ ret = clk_prepare_enable(cam->camera_clk);
+ BUG_ON(ret != 0);
+- mdelay(1); // let the clock stabilize
++ msleep(100); // let the clock stabilize
+
+ adapter = i2c_get_adapter(((struct soc_camera_link *)(info->platform_data))->i2c_adapter_id);
+ if (!adapter) {
+@@ -848,7 +848,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
+ __func__);
+ return ret;
+ }
+- mdelay(20); /* let the clock stabilize */
++ msleep(100); /* let the clock stabilize */
+
+ fillup_dma(dev);
+
diff --git a/patches/linux-3.8.13/0615-Debugging-camera-stuff.patch b/patches/linux-3.8.13/0615-Debugging-camera-stuff.patch
new file mode 100644
index 0000000..59d05e2
--- /dev/null
+++ b/patches/linux-3.8.13/0615-Debugging-camera-stuff.patch
@@ -0,0 +1,93 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Fri, 10 May 2013 10:41:45 +0300
+Subject: [PATCH] Debugging camera stuff
+
+---
+ drivers/media/i2c/soc_camera/mt9t112.c | 4 ++--
+ drivers/media/platform/soc_camera/cssp_camera.c | 16 +++-------------
+ 2 files changed, 5 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c
+index d83d217..3154c1f 100644
+--- a/drivers/media/i2c/soc_camera/mt9t112.c
++++ b/drivers/media/i2c/soc_camera/mt9t112.c
+@@ -16,7 +16,7 @@
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+-
++#define DEBUG
+ #include <linux/delay.h>
+ #include <linux/i2c.h>
+ #include <linux/init.h>
+@@ -31,7 +31,7 @@
+ #include <media/v4l2-common.h>
+
+ /* you can check PLL/clock info */
+-/* #define EXT_CLOCK 24000000 */
++#define EXT_CLOCK 32000000
+
+ //#define TEST_PATTERN
+
+diff --git a/drivers/media/platform/soc_camera/cssp_camera.c b/drivers/media/platform/soc_camera/cssp_camera.c
+index 2c10f61..7c8d40e 100644
+--- a/drivers/media/platform/soc_camera/cssp_camera.c
++++ b/drivers/media/platform/soc_camera/cssp_camera.c
+@@ -544,8 +544,8 @@ static void dma_callback(unsigned lch, u16 ch_status, void *data)
+ do_gettimeofday(&vb->v4l2_buf.timestamp);
+ vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+
+- dev_dbg(&dev->pdev->dev, "[%p/%d] done\n",
+- buf, buf->vb.v4l2_buf.index);
++ /* dev_dbg(&dev->pdev->dev, "[%p/%d] done\n",
++ buf, buf->vb.v4l2_buf.index); */
+
+ }
+ }
+@@ -773,9 +773,6 @@ static int buffer_prepare(struct vb2_buffer *vb)
+ container_of(vb, struct cssp_cam_buffer, vb);
+ unsigned long size;
+
+- dev_dbg(&dev->pdev->dev, "%s, field=%d\n", __func__,
+- vb->v4l2_buf.field);
+-
+ BUG_ON(NULL == dev->fmt);
+
+ /*
+@@ -806,7 +803,6 @@ static int buffer_prepare(struct vb2_buffer *vb)
+ static int buffer_finish(struct vb2_buffer *vb)
+ {
+ struct cssp_cam_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+- dev_dbg(&dev->pdev->dev, "%s\n", __func__);
+ return 0;
+ }
+
+@@ -1124,8 +1120,6 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+ {
+ struct cssp_cam_dev *dev = video_drvdata(file);
+
+- dev_dbg(&dev->pdev->dev, "%s\n", __func__);
+-
+ return vb2_qbuf(&dev->vb_vidq, p);
+ }
+
+@@ -1134,10 +1128,6 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+ struct cssp_cam_dev *dev = video_drvdata(file);
+ u16 val;
+
+- val = ioread16(dev->reg_base_virt + REG_MODE);
+- dev_dbg(&dev->pdev->dev, "%s MODE=0x%04x\n", __func__,
+- val);
+-
+ return vb2_dqbuf(&dev->vb_vidq, p, file->f_flags & O_NONBLOCK);
+ }
+
+@@ -1251,7 +1241,7 @@ static unsigned int video_poll(struct file *file, struct poll_table_struct *wait
+ struct vb2_queue *q = &dev->vb_vidq;
+ unsigned int res;
+
+- dev_dbg(&dev->pdev->dev, "%s\n", __func__);
++ /* dev_dbg(&dev->pdev->dev, "%s\n", __func__); */
+
+ res = vb2_poll(q, file, wait);
+ if (v4l2_event_pending(fh))
diff --git a/patches/linux-3.8.13/0616-cssp_camera-Make-it-work-with-Beaglebone-black.patch b/patches/linux-3.8.13/0616-cssp_camera-Make-it-work-with-Beaglebone-black.patch
new file mode 100644
index 0000000..0824d6c
--- /dev/null
+++ b/patches/linux-3.8.13/0616-cssp_camera-Make-it-work-with-Beaglebone-black.patch
@@ -0,0 +1,112 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Fri, 10 May 2013 14:07:49 +0300
+Subject: [PATCH] cssp_camera: Make it work with Beaglebone black
+
+Using the reset control framework, the camera works on the black.
+I love it when a plan comes together...
+---
+ drivers/media/platform/soc_camera/cssp_camera.c | 25 +++++++++++++++++++++--
+ firmware/capes/BB-BONE-CAM3-01-00A2.dts | 5 +++++
+ 2 files changed, 28 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/cssp_camera.c b/drivers/media/platform/soc_camera/cssp_camera.c
+index 7c8d40e..119c432 100644
+--- a/drivers/media/platform/soc_camera/cssp_camera.c
++++ b/drivers/media/platform/soc_camera/cssp_camera.c
+@@ -45,6 +45,8 @@
+ #include <linux/of_gpio.h>
+ #include <linux/of_i2c.h>
+
++#include <linux/rstctl.h>
++
+ static unsigned video_nr = -1;
+ module_param(video_nr, uint, 0644);
+ MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
+@@ -181,6 +183,8 @@ struct cssp_cam_dev {
+
+ /* OF build platform data here */
+ struct cssp_cam_platform_data_storage *pstore;
++
++ struct rstctl *rctrl;
+ };
+
+ /*
+@@ -802,7 +806,6 @@ static int buffer_prepare(struct vb2_buffer *vb)
+
+ static int buffer_finish(struct vb2_buffer *vb)
+ {
+- struct cssp_cam_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+ return 0;
+ }
+
+@@ -1126,7 +1129,6 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+ {
+ struct cssp_cam_dev *dev = video_drvdata(file);
+- u16 val;
+
+ return vb2_dqbuf(&dev->vb_vidq, p, file->f_flags & O_NONBLOCK);
+ }
+@@ -1634,6 +1636,21 @@ static int cssp_cam_probe(struct platform_device *pdev)
+ struct cssp_cam_platform_data *pdata;
+ struct pinctrl *pinctrl;
+ int ret = 0, use_of_pdata = 0;
++ struct rstctl *rctrl;
++
++ rctrl = rstctl_get(&pdev->dev, NULL);
++ if (IS_ERR(rctrl)) {
++ dev_info(&pdev->dev, "Failed to get rstctl; nevermind\n");
++ rctrl = NULL;
++ } else {
++ dev_info(&pdev->dev, "Got rstctl (%s:#%d name %s) label:%s\n",
++ rctrl->rdev->rdesc->name,
++ rctrl->line - rctrl->rdev->rdesc->lines,
++ rctrl->line->name, rctrl->label);
++
++ /* always assert to keep the emmc at reset */
++ rstctl_assert(rctrl);
++ }
+
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl))
+@@ -1670,6 +1687,8 @@ static int cssp_cam_probe(struct platform_device *pdev)
+ cam_dev->pdev = pdev;
+ platform_set_drvdata(pdev, cam_dev);
+
++ cam_dev->rctrl = rctrl;
++
+ cam_dev->camera_board_info = pdata->cam_i2c_board_info;
+
+ cam_dev->camera_clk = clk_get(&pdev->dev, pdata->cam_clk_name);
+@@ -1780,6 +1799,8 @@ static int cssp_cam_remove(struct platform_device *pdev)
+
+ clk_put(cam->camera_clk);
+
++ rstctl_put(cam->rctrl);
++
+ kfree(cam);
+
+ dev_info(&pdev->dev, "removed\n");
+diff --git a/firmware/capes/BB-BONE-CAM3-01-00A2.dts b/firmware/capes/BB-BONE-CAM3-01-00A2.dts
+index 97bdcfd..e546f08 100644
+--- a/firmware/capes/BB-BONE-CAM3-01-00A2.dts
++++ b/firmware/capes/BB-BONE-CAM3-01-00A2.dts
+@@ -158,6 +158,10 @@
+ /* orientation; -> MT9T112_FLAG_VFLIP */
+ orientation-gpio = <&gpio1 30 0>;
+
++ /* reset controller (for the black) */
++ reset = <&rstctl 0 0>;
++ reset-names = "eMMC_RSTn-CAM3";
++
+ /* camera sensor */
+ cssp,sensor {
+ i2c-adapter = <&i2c2>;
+@@ -176,6 +180,7 @@
+ pll-divider = <24 1 0 7 0 10 14 7 0>;
+ };
+ };
++
+ };
+
+ };
diff --git a/patches/linux-3.8.13/0617-bone-capemgr-Introduce-simple-resource-tracking.patch b/patches/linux-3.8.13/0617-bone-capemgr-Introduce-simple-resource-tracking.patch
new file mode 100644
index 0000000..fa139fb
--- /dev/null
+++ b/patches/linux-3.8.13/0617-bone-capemgr-Introduce-simple-resource-tracking.patch
@@ -0,0 +1,163 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 16 May 2013 18:11:19 +0300
+Subject: [PATCH] bone: capemgr: Introduce simple resource tracking
+
+Now each cape can declare an exclusive-use property which is
+a string list of every resource it requires.
+Attempting to load a cape that uses the same resource will fail.
+---
+ drivers/misc/cape/beaglebone/capemgr.c | 127 +++++++++++++++++++++++++++++++-
+ 1 file changed, 125 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/misc/cape/beaglebone/capemgr.c b/drivers/misc/cape/beaglebone/capemgr.c
+index 820852d..2820e39 100644
+--- a/drivers/misc/cape/beaglebone/capemgr.c
++++ b/drivers/misc/cape/beaglebone/capemgr.c
+@@ -1149,6 +1149,116 @@ static void bone_capemgr_info_sysfs_unregister(struct bone_capemgr_info *info)
+ device_remove_file(dev, &dev_attr_slots);
+ }
+
++/* verify the overlay */
++static int bone_capemgr_verify_overlay(struct bone_cape_slot *slot)
++{
++ struct bone_capemgr_info *info = slot->info;
++ struct device *dev = &info->pdev->dev;
++ struct bone_baseboard *bbrd = &info->baseboard;
++ struct device_node *node = slot->overlay;
++ struct property *prop;
++ struct bone_cape_slot *slotn;
++ int err, counta, countb, i, j;
++ const char *ra, *rb;
++
++ /* validate */
++ if (node == NULL) {
++ dev_err(dev, "slot #%d: No overlay "
++ "for '%s'\n",
++ slot->slotno, slot->part_number);
++ return -EINVAL;
++ }
++
++ /* check if the slot is compatible with the board */
++ prop = of_find_property(node, "compatible", NULL);
++
++ /* no compatible property? */
++ if (prop == NULL) {
++ dev_err(dev, "slot #%d: No compatible property "
++ "for '%s'\n",
++ slot->slotno, slot->part_number);
++ return -EINVAL;
++ }
++
++ /* verify that the cape is baseboard compatible */
++ if (of_multi_prop_cmp(prop, bbrd->compatible_name) != 0) {
++ dev_err(dev, "slot #%d: Incompatible with baseboard "
++ "for '%s'\n",
++ slot->slotno, slot->part_number);
++ return -EINVAL;
++ }
++
++ /* count the strings */
++ counta = of_property_count_strings(node, "exclusive-use");
++ /* no valid property, or no resources; no matter, it's OK */
++ if (counta <= 0)
++ return 0;
++
++ /* and now check if there's a resource conflict */
++ err = 0;
++ mutex_lock(&info->slots_list_mutex);
++ for (i = 0; i < counta; i++) {
++
++ ra = NULL;
++ err = of_property_read_string_index(node, "exclusive-use",
++ i, &ra);
++ if (err != 0) {
++ dev_err(dev, "slot #%d: Could not read string #%d\n",
++ slot->slotno, i);
++ break;
++ }
++
++ list_for_each_entry(slotn, &info->slot_list, node) {
++
++ /* don't check against self */
++ if (slot == slotn)
++ continue;
++
++ /* only check against loaded or loading slots */
++ if (!slotn->loaded && !slotn->loading)
++ continue;
++
++ countb = of_property_count_strings(slotn->overlay,
++ "exclusive-use");
++ /* no valid property, or resources; it's OK */
++ if (countb <= 0)
++ continue;
++
++
++ for (j = 0; j < countb; j++) {
++
++ /* count the resources */
++ rb = NULL;
++ err = of_property_read_string_index(
++ slotn->overlay, "exclusive-use",
++ j, &rb);
++ if (err != 0) {
++ /* error, but we don't care */
++ err = 0;
++ break;
++ }
++
++ /* ignore case; just in case ;) */
++ if (strcasecmp(ra, rb) == 0) {
++
++ /* resource conflict */
++ err = -EEXIST;
++ dev_err(dev, "slot #%d: %s conflict "
++ "%s (#%d:%s)\n", slot->slotno,
++ slot->part_number, ra,
++ slotn->slotno,
++ slotn->part_number);
++ goto out;
++ }
++ }
++ }
++ }
++out:
++ mutex_unlock(&info->slots_list_mutex);
++
++ return err;
++}
++
+ static int bone_capemgr_load(struct bone_cape_slot *slot)
+ {
+ struct bone_capemgr_info *info = slot->info;
+@@ -1273,6 +1383,13 @@ static int bone_capemgr_load(struct bone_cape_slot *slot)
+ goto err_fail;
+ }
+
++ err = bone_capemgr_verify_overlay(slot);
++ if (err != 0) {
++ dev_err(dev, "slot #%d: Failed verification\n",
++ slot->slotno);
++ goto err_fail;
++ }
++
+ /* now build an overlay info array */
+ err = of_build_overlay_info(slot->overlay,
+ &slot->ovinfo_cnt, &slot->ovinfo);
+@@ -1665,8 +1782,14 @@ static int bone_capemgr_loader(void *data)
+
+ slot->loading = 0;
+
+- dev_info(dev, "loader: done slot-%d %s:%s (prio %d)\n", slot->slotno,
+- slot->part_number, slot->version, slot->priority);
++ if (ret == 0)
++ dev_info(dev, "loader: done slot-%d %s:%s (prio %d)\n",
++ slot->slotno, slot->part_number, slot->version,
++ slot->priority);
++ else
++ dev_err(dev, "loader: failed to load slot-%d %s:%s (prio %d)\n",
++ slot->slotno, slot->part_number, slot->version,
++ slot->priority);
+
+ /* we're done, wake up all */
+ wake_up_interruptible_all(&info->load_wq);
diff --git a/patches/linux-3.8.13/0618-capes-Add-resources-to-capes.patch b/patches/linux-3.8.13/0618-capes-Add-resources-to-capes.patch
new file mode 100644
index 0000000..38c4c9c
--- /dev/null
+++ b/patches/linux-3.8.13/0618-capes-Add-resources-to-capes.patch
@@ -0,0 +1,705 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 16 May 2013 18:13:19 +0300
+Subject: [PATCH] capes: Add resources to capes.
+
+Start adding the resource list of each cape.
+---
+ firmware/capes/BB-BONE-AUDI-01-00A0.dts | 15 ++++++++-
+ firmware/capes/BB-BONE-CAM3-01-00A2.dts | 45 +++++++++++++++++++++++++--
+ firmware/capes/BB-BONE-GPEVT-00A0.dts | 2 +-
+ firmware/capes/BB-BONE-PRU-01-00A0.dts | 7 +++++
+ firmware/capes/BB-BONE-PRU-02-00A0.dts | 7 +++++
+ firmware/capes/BB-BONE-PWMT-00A0.dts | 2 +-
+ firmware/capes/BB-BONE-RST-00A0.dts | 2 +-
+ firmware/capes/BB-BONE-RST2-00A0.dts | 2 +-
+ firmware/capes/BB-BONE-eMMC1-01-00A0.dts | 2 +-
+ firmware/capes/am33xx_pwm-00A0.dts | 2 +-
+ firmware/capes/bone_pwm_P8_13-00A0.dts | 2 +-
+ firmware/capes/bone_pwm_P8_19-00A0.dts | 2 +-
+ firmware/capes/bone_pwm_P8_34-00A0.dts | 2 +-
+ firmware/capes/bone_pwm_P8_36-00A0.dts | 2 +-
+ firmware/capes/bone_pwm_P8_45-00A0.dts | 2 +-
+ firmware/capes/bone_pwm_P8_46-00A0.dts | 2 +-
+ firmware/capes/bone_pwm_P9_14-00A0.dts | 2 +-
+ firmware/capes/bone_pwm_P9_16-00A0.dts | 2 +-
+ firmware/capes/bone_pwm_P9_21-00A0.dts | 2 +-
+ firmware/capes/bone_pwm_P9_22-00A0.dts | 2 +-
+ firmware/capes/bone_pwm_P9_28-00A0.dts | 2 +-
+ firmware/capes/bone_pwm_P9_29-00A0.dts | 2 +-
+ firmware/capes/bone_pwm_P9_31-00A0.dts | 2 +-
+ firmware/capes/bone_pwm_P9_42-00A0.dts | 2 +-
+ firmware/capes/cape-bone-2g-emmc1.dts | 18 +++++++++++
+ firmware/capes/cape-bone-dvi-00A1.dts | 2 +-
+ firmware/capes/cape-bone-dvi-00A2.dts | 2 +-
+ firmware/capes/cape-bone-lcd3-00A0.dts | 41 ++++++++++++++++++++++++
+ firmware/capes/cape-bone-lcd3-00A2.dts | 39 +++++++++++++++++++++++
+ firmware/capes/cape-bone-tester-00A0.dts | 2 +-
+ firmware/capes/cape-bone-weather-00A0.dts | 19 +++++------
+ firmware/capes/cape-boneblack-hdmi-00A0.dts | 34 +++++++++++++++++++-
+ 32 files changed, 235 insertions(+), 36 deletions(-)
+
+diff --git a/firmware/capes/BB-BONE-AUDI-01-00A0.dts b/firmware/capes/BB-BONE-AUDI-01-00A0.dts
+index 8e1256e..5e145b9 100644
+--- a/firmware/capes/BB-BONE-AUDI-01-00A0.dts
++++ b/firmware/capes/BB-BONE-AUDI-01-00A0.dts
+@@ -9,12 +9,25 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "BB-BONE-AUDI-01";
+ version = "00A0", "A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.14", /* leds: gpio1_18 */
++ "P9.16", /* leds: gpio1_19 */
++ "P9.31", /* mcasp0: mcasp0_aclkx */
++ "P9.29", /* mcasp0: mcasp0_fsx */
++ "P9.28", /* mcasp0: mcasp0_axr2 */
++ "P9.25", /* mcasp0: mcasp0_ahclkx */
++ /* the hardware ip uses */
++ "gpio1_18", "gpio1_19",
++ "mcasp0";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/BB-BONE-CAM3-01-00A2.dts b/firmware/capes/BB-BONE-CAM3-01-00A2.dts
+index e546f08..2470a76 100644
+--- a/firmware/capes/BB-BONE-CAM3-01-00A2.dts
++++ b/firmware/capes/BB-BONE-CAM3-01-00A2.dts
+@@ -9,12 +9,53 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "BB-BONE-CAM3-01";
+ version = "00A2", "A2";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.25", /* gpmc: gpmc_ad0 */
++ "P8.24", /* gpmc: gpmc_ad1 */
++ "P8.5", /* gpmc: gpmc_ad2 */
++ "P8.6", /* gpmc: gpmc_ad3 */
++ "P8.23", /* gpmc: gpmc_ad4 */
++ "P8.22", /* gpmc: gpmc_ad5 */
++ "P8.3", /* gpmc: gpmc_ad6 */
++ "P8.4", /* gpmc: gpmc_ad7 */
++ "P8.19", /* gpmc: gpmc_ad8 */
++ "P8.13", /* gpmc: gpmc_ad9 */
++ "P8.14", /* gpmc: gpmc_ad10 */
++ "P8.17", /* gpmc: gpmc_ad11 */
++ "P8.12", /* gpmc: gpmc_ad12 */
++ "P8.11", /* gpmc: gpmc_ad13 */
++ "P8.16", /* gpmc: gpmc_ad14 */
++ "P8.15", /* gpmc: gpmc_ad15 */
++ "P9.13", /* gpmc: gpmc_wpn */
++ "P8.21", /* gpmc: gpmc_csn1 */
++ "P8.18", /* gpmc: gpmc_clk */
++ "P8.7", /* gpmc: gpmc_advn_ale */
++ "P8.8", /* gpmc: gpmc_oen_ren */
++ "P8.10", /* gpmc: gpmc_wen */
++ "P8.9", /* gpmc: gpmc_ben0_cle */
++ "P9.41", /* cssp: clkout2 */
++ "P9.42", /* cssp: xdma_event_intr2 */
++ "P9.18", /* cssp: gpio0_4 */
++ "P9.17", /* cssp: gpio0_5 */
++ "P9.11", /* cssp: gpio0_30 */
++
++ /* the hardware IP uses */
++ "gpio0_4",
++ "gpio0_5",
++ "gpio0_30",
++ "gpmc",
++ "clkout2",
++ /* the reset pin */
++ "eMMC_RSTn";
++
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+@@ -41,7 +82,7 @@
+ 0x038 0x30 /* gpmc_ad14.gpmc_ad14 MODE0 | INPUT | PULLUP */
+ 0x03C 0x30 /* gpmc_ad15.gpmc_ad15 MODE0 | INPUT | PULLUP */
+ 0x074 0x30 /* gpmc_wpn.gpmc_wpn MODE0 | INPUT | PULLUP */ /* WAS MODE 7 */
+- 0x080 0x08 /* gpmc_wait0.gpmc_cscn1 MODE0 | OUTPUT */
++ 0x080 0x08 /* gpmc_cscn1.gpmc_cscn1 MODE0 | OUTPUT */
+ 0x08C 0x28 /* gpmc_clk.gpmc_clk MODE0 | INPUT */
+ 0x090 0x08 /* gpmc_advn_ale.gpmc_advn_ale MODE0 | OUTPUT */
+ 0x094 0x08 /* gpmc_oen_ren.gpmc_oen_ren MODE0 | OUTPUT */
+diff --git a/firmware/capes/BB-BONE-GPEVT-00A0.dts b/firmware/capes/BB-BONE-GPEVT-00A0.dts
+index 80f9016..112a6d1 100644
+--- a/firmware/capes/BB-BONE-GPEVT-00A0.dts
++++ b/firmware/capes/BB-BONE-GPEVT-00A0.dts
+@@ -7,7 +7,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "BB-BONE-GPEVT";
+diff --git a/firmware/capes/BB-BONE-PRU-01-00A0.dts b/firmware/capes/BB-BONE-PRU-01-00A0.dts
+index 29ab671..9bf2c7a 100644
+--- a/firmware/capes/BB-BONE-PRU-01-00A0.dts
++++ b/firmware/capes/BB-BONE-PRU-01-00A0.dts
+@@ -15,6 +15,13 @@
+ part-number = "BB-BONE-PRU-01";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.27", /* pru0: pr1_pru0_pru_r30_5 */
++ /* the hardware IP uses */
++ "pru0";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/BB-BONE-PRU-02-00A0.dts b/firmware/capes/BB-BONE-PRU-02-00A0.dts
+index ddb63f7..13389c7 100644
+--- a/firmware/capes/BB-BONE-PRU-02-00A0.dts
++++ b/firmware/capes/BB-BONE-PRU-02-00A0.dts
+@@ -15,6 +15,13 @@
+ part-number = "BB-BONE-PRU-01";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.27", /* pru0: pr1_pru0_pru_r30_5 */
++ /* the hardware IP uses */
++ "pru0";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/BB-BONE-PWMT-00A0.dts b/firmware/capes/BB-BONE-PWMT-00A0.dts
+index fb2b8b1..02c2c0e 100644
+--- a/firmware/capes/BB-BONE-PWMT-00A0.dts
++++ b/firmware/capes/BB-BONE-PWMT-00A0.dts
+@@ -9,7 +9,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "BB-BONE-PWMT";
+diff --git a/firmware/capes/BB-BONE-RST-00A0.dts b/firmware/capes/BB-BONE-RST-00A0.dts
+index acdcda4..12c696f 100644
+--- a/firmware/capes/BB-BONE-RST-00A0.dts
++++ b/firmware/capes/BB-BONE-RST-00A0.dts
+@@ -7,7 +7,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "BB-BONE-RST";
+diff --git a/firmware/capes/BB-BONE-RST2-00A0.dts b/firmware/capes/BB-BONE-RST2-00A0.dts
+index 6904cc5..50b3a60 100644
+--- a/firmware/capes/BB-BONE-RST2-00A0.dts
++++ b/firmware/capes/BB-BONE-RST2-00A0.dts
+@@ -7,7 +7,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "BB-BONE-RST2";
+diff --git a/firmware/capes/BB-BONE-eMMC1-01-00A0.dts b/firmware/capes/BB-BONE-eMMC1-01-00A0.dts
+index 0776bee..ac3c0c3 100644
+--- a/firmware/capes/BB-BONE-eMMC1-01-00A0.dts
++++ b/firmware/capes/BB-BONE-eMMC1-01-00A0.dts
+@@ -9,7 +9,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "BB-BONE-eMMC1-01";
+diff --git a/firmware/capes/am33xx_pwm-00A0.dts b/firmware/capes/am33xx_pwm-00A0.dts
+index 609c1db..fa8d770 100644
+--- a/firmware/capes/am33xx_pwm-00A0.dts
++++ b/firmware/capes/am33xx_pwm-00A0.dts
+@@ -10,7 +10,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "test1";
+diff --git a/firmware/capes/bone_pwm_P8_13-00A0.dts b/firmware/capes/bone_pwm_P8_13-00A0.dts
+index 6c2168a..d7a22f8 100644
+--- a/firmware/capes/bone_pwm_P8_13-00A0.dts
++++ b/firmware/capes/bone_pwm_P8_13-00A0.dts
+@@ -10,7 +10,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "bone_pwm_P8_13";
+diff --git a/firmware/capes/bone_pwm_P8_19-00A0.dts b/firmware/capes/bone_pwm_P8_19-00A0.dts
+index f5f7454..c8071766 100644
+--- a/firmware/capes/bone_pwm_P8_19-00A0.dts
++++ b/firmware/capes/bone_pwm_P8_19-00A0.dts
+@@ -10,7 +10,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "bone_pwm_P8_19";
+diff --git a/firmware/capes/bone_pwm_P8_34-00A0.dts b/firmware/capes/bone_pwm_P8_34-00A0.dts
+index be227bf..44e4ff7 100644
+--- a/firmware/capes/bone_pwm_P8_34-00A0.dts
++++ b/firmware/capes/bone_pwm_P8_34-00A0.dts
+@@ -10,7 +10,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "bone_pwm_P8_34";
+diff --git a/firmware/capes/bone_pwm_P8_36-00A0.dts b/firmware/capes/bone_pwm_P8_36-00A0.dts
+index 7ca8694c..12fe6ef 100644
+--- a/firmware/capes/bone_pwm_P8_36-00A0.dts
++++ b/firmware/capes/bone_pwm_P8_36-00A0.dts
+@@ -10,7 +10,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "bone_pwm_P8_36";
+diff --git a/firmware/capes/bone_pwm_P8_45-00A0.dts b/firmware/capes/bone_pwm_P8_45-00A0.dts
+index 3bc8103..07c8457 100644
+--- a/firmware/capes/bone_pwm_P8_45-00A0.dts
++++ b/firmware/capes/bone_pwm_P8_45-00A0.dts
+@@ -10,7 +10,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "bone_pwm_P8_45";
+diff --git a/firmware/capes/bone_pwm_P8_46-00A0.dts b/firmware/capes/bone_pwm_P8_46-00A0.dts
+index 4cc6170..147a3c6 100644
+--- a/firmware/capes/bone_pwm_P8_46-00A0.dts
++++ b/firmware/capes/bone_pwm_P8_46-00A0.dts
+@@ -10,7 +10,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "bone_pwm_P8_46";
+diff --git a/firmware/capes/bone_pwm_P9_14-00A0.dts b/firmware/capes/bone_pwm_P9_14-00A0.dts
+index 6a6c01a..0c6c784 100644
+--- a/firmware/capes/bone_pwm_P9_14-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_14-00A0.dts
+@@ -10,7 +10,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "bone_pwm_P9_14";
+diff --git a/firmware/capes/bone_pwm_P9_16-00A0.dts b/firmware/capes/bone_pwm_P9_16-00A0.dts
+index a1ee9d8..252ee8c 100644
+--- a/firmware/capes/bone_pwm_P9_16-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_16-00A0.dts
+@@ -10,7 +10,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "bone_pwm_P9_16";
+diff --git a/firmware/capes/bone_pwm_P9_21-00A0.dts b/firmware/capes/bone_pwm_P9_21-00A0.dts
+index e667f81..f2d540a 100644
+--- a/firmware/capes/bone_pwm_P9_21-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_21-00A0.dts
+@@ -10,7 +10,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "bone_pwm_P9_21";
+diff --git a/firmware/capes/bone_pwm_P9_22-00A0.dts b/firmware/capes/bone_pwm_P9_22-00A0.dts
+index f7c5ed2..df338f7 100644
+--- a/firmware/capes/bone_pwm_P9_22-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_22-00A0.dts
+@@ -10,7 +10,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "bone_pwm_P9_22";
+diff --git a/firmware/capes/bone_pwm_P9_28-00A0.dts b/firmware/capes/bone_pwm_P9_28-00A0.dts
+index 96df33d..ace91df 100644
+--- a/firmware/capes/bone_pwm_P9_28-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_28-00A0.dts
+@@ -10,7 +10,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "bone_pwm_P9_28";
+diff --git a/firmware/capes/bone_pwm_P9_29-00A0.dts b/firmware/capes/bone_pwm_P9_29-00A0.dts
+index 5cff5a8..33ae722 100644
+--- a/firmware/capes/bone_pwm_P9_29-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_29-00A0.dts
+@@ -10,7 +10,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "bone_pwm_P9_29";
+diff --git a/firmware/capes/bone_pwm_P9_31-00A0.dts b/firmware/capes/bone_pwm_P9_31-00A0.dts
+index 8126597..8096f62 100644
+--- a/firmware/capes/bone_pwm_P9_31-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_31-00A0.dts
+@@ -10,7 +10,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "bone_pwm_P9_31";
+diff --git a/firmware/capes/bone_pwm_P9_42-00A0.dts b/firmware/capes/bone_pwm_P9_42-00A0.dts
+index 7ffcb9b..5ba487f 100644
+--- a/firmware/capes/bone_pwm_P9_42-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_42-00A0.dts
+@@ -10,7 +10,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "bone_pwm_P9_42";
+diff --git a/firmware/capes/cape-bone-2g-emmc1.dts b/firmware/capes/cape-bone-2g-emmc1.dts
+index bf26ae1..90067d5 100644
+--- a/firmware/capes/cape-bone-2g-emmc1.dts
++++ b/firmware/capes/cape-bone-2g-emmc1.dts
+@@ -16,6 +16,24 @@
+ part-number = "*"; /* any part number */
+ version = "*"; /* any version */
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.21", /* mmc1: mmc1_clk */
++ "P8.20", /* mmc1: mmc1_cmd */
++ "P8.25", /* mmc1: mmc1_dat0 */
++ "P8.24", /* mmc1: mmc1_dat1 */
++ "P8.5", /* mmc1: mmc1_dat2 */
++ "P8.6", /* mmc1: mmc1_dat3 */
++ "P8.23", /* mmc1: mmc1_dat4 */
++ "P8.22", /* mmc1: mmc1_dat5 */
++ "P8.3", /* mmc1: mmc1_dat6 */
++ "P8.4", /* mmc1: mmc1_dat7 */
++ /* the hardware IP uses */
++ "mmc1",
++ /* the reset pin */
++ "eMMC_RSTn";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/cape-bone-dvi-00A1.dts b/firmware/capes/cape-bone-dvi-00A1.dts
+index ed9099c..b320d4f 100644
+--- a/firmware/capes/cape-bone-dvi-00A1.dts
++++ b/firmware/capes/cape-bone-dvi-00A1.dts
+@@ -9,7 +9,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "BB-BONE-DVID-01";
+diff --git a/firmware/capes/cape-bone-dvi-00A2.dts b/firmware/capes/cape-bone-dvi-00A2.dts
+index a3cd39d..d5c49bb 100644
+--- a/firmware/capes/cape-bone-dvi-00A2.dts
++++ b/firmware/capes/cape-bone-dvi-00A2.dts
+@@ -9,7 +9,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+ part-number = "BB-BONE-DVID-01";
+diff --git a/firmware/capes/cape-bone-lcd3-00A0.dts b/firmware/capes/cape-bone-lcd3-00A0.dts
+index 1ac8462..a2f8b35 100644
+--- a/firmware/capes/cape-bone-lcd3-00A0.dts
++++ b/firmware/capes/cape-bone-lcd3-00A0.dts
+@@ -15,6 +15,47 @@
+ part-number = "BB-BONE-LCD3-01";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.45", /* lcd: lcd_data0 */
++ "P8.46", /* lcd: lcd_data1 */
++ "P8.43", /* lcd: lcd_data2 */
++ "P8.44", /* lcd: lcd_data3 */
++ "P8.41", /* lcd: lcd_data4 */
++ "P8.42", /* lcd: lcd_data5 */
++ "P8.39", /* lcd: lcd_data6 */
++ "P8.40", /* lcd: lcd_data7 */
++ "P8.37", /* lcd: lcd_data8 */
++ "P8.38", /* lcd: lcd_data9 */
++ "P8.36", /* lcd: lcd_data10 */
++ "P8.34", /* lcd: lcd_data11 */
++ "P8.35", /* lcd: lcd_data12 */
++ "P8.33", /* lcd: lcd_data13 */
++ "P8.31", /* lcd: lcd_data14 */
++ "P8.32", /* lcd: lcd_data15 */
++ "P8.27", /* lcd: lcd_vsync */
++ "P8.29", /* lcd: lcd_hsync */
++ "P8.28", /* lcd: lcd_pclk */
++ "P8.30", /* lcd: lcd_ac_bias_en */
++ "P9.14", /* led: gpio1_18 */
++ "P9.16", /* led: gpio1_19 */
++ "P9.15", /* keys: gpio1_16 */
++ "P9.23", /* keys: gpio1_17 */
++ "P9.27", /* keys: gpio3_19 */
++ "P9.12", /* keys: gpio1_28 */
++ "P9.42", /* keys: gpio0_7 */
++ /* the hardware IP uses */
++ "gpio1_18",
++ "gpio1_19",
++ "gpio1_16",
++ "gpio1_17",
++ "gpio3_19",
++ "gpio0_7",
++ "lcd",
++ "tps-bl",
++ "tscadc";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/cape-bone-lcd3-00A2.dts b/firmware/capes/cape-bone-lcd3-00A2.dts
+index 9c7bb17..c2cdedc 100644
+--- a/firmware/capes/cape-bone-lcd3-00A2.dts
++++ b/firmware/capes/cape-bone-lcd3-00A2.dts
+@@ -15,6 +15,45 @@
+ part-number = "BB-BONE-LCD3-01";
+ version = "00A2";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.45", /* lcd: lcd_data0 */
++ "P8.46", /* lcd: lcd_data1 */
++ "P8.43", /* lcd: lcd_data2 */
++ "P8.44", /* lcd: lcd_data3 */
++ "P8.41", /* lcd: lcd_data4 */
++ "P8.42", /* lcd: lcd_data5 */
++ "P8.39", /* lcd: lcd_data6 */
++ "P8.40", /* lcd: lcd_data7 */
++ "P8.37", /* lcd: lcd_data8 */
++ "P8.38", /* lcd: lcd_data9 */
++ "P8.36", /* lcd: lcd_data10 */
++ "P8.34", /* lcd: lcd_data11 */
++ "P8.35", /* lcd: lcd_data12 */
++ "P8.33", /* lcd: lcd_data13 */
++ "P8.31", /* lcd: lcd_data14 */
++ "P8.32", /* lcd: lcd_data15 */
++ "P8.27", /* lcd: lcd_vsync */
++ "P8.29", /* lcd: lcd_hsync */
++ "P8.28", /* lcd: lcd_pclk */
++ "P8.30", /* lcd: lcd_ac_bias_en */
++ "P9.27", /* led: gpio3_19 */
++ "P9.14", /* bl: ehrpwm1a*/
++ "P9.15", /* keys: gpio1_16*/
++ "P9.23", /* keys: gpio1_17*/
++ "P9.16", /* keys: gpio1_19*/
++ "P9.21", /* keys: gpio0_3*/
++ /* the hardware IP uses */
++ "gpio3_19",
++ "gpio1_16",
++ "gpio1_17",
++ "gpio1_19",
++ "gpio0_3",
++ "lcd",
++ "ehrpwm1a",
++ "tscadc";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/cape-bone-tester-00A0.dts b/firmware/capes/cape-bone-tester-00A0.dts
+index 4d7dc68..b5b1be8 100644
+--- a/firmware/capes/cape-bone-tester-00A0.dts
++++ b/firmware/capes/cape-bone-tester-00A0.dts
+@@ -9,7 +9,7 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone", "ti,beaglebone-black";
++ compatible = "ti,beaglebone";
+
+ /* identification */
+ part-number = "BB-BONE-TESTER";
+diff --git a/firmware/capes/cape-bone-weather-00A0.dts b/firmware/capes/cape-bone-weather-00A0.dts
+index 76284d6..7cb479a 100644
+--- a/firmware/capes/cape-bone-weather-00A0.dts
++++ b/firmware/capes/cape-bone-weather-00A0.dts
+@@ -9,11 +9,12 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
+- part-number = "BB-BONE-WTHR-01";
+- version = "00A0";
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+- fragment@0 {
++ part-number = "BB-BONE-WTHR-01";
++ version = "00A0";
++
++ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+ weather_cape_w1_pins: pinmux_weather_cape_w1_pins {
+@@ -22,9 +23,9 @@
+ >;
+ };
+ };
+- };
++ };
+
+- fragment@1 {
++ fragment@1 {
+ target = <&i2c2>;
+
+ __overlay__ {
+@@ -50,9 +51,9 @@
+ reg = <0x77>;
+ };
+ };
+- };
++ };
+
+- fragment@2 {
++ fragment@2 {
+ target = <&ocp>;
+ __overlay__ {
+ onewire@0 {
+@@ -64,5 +65,5 @@
+ gpios = <&gpio2 3 0>;
+ };
+ };
+- };
++ };
+ };
+diff --git a/firmware/capes/cape-boneblack-hdmi-00A0.dts b/firmware/capes/cape-boneblack-hdmi-00A0.dts
+index e5f714a..5fdbd9e 100644
+--- a/firmware/capes/cape-boneblack-hdmi-00A0.dts
++++ b/firmware/capes/cape-boneblack-hdmi-00A0.dts
+@@ -9,10 +9,42 @@
+ /plugin/;
+
+ / {
+- compatible = "ti,beaglebone";
++ compatible = "ti,beaglebone-black";
+ part-number = "BB-BONELT-HDMI";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.25", /* mcasp0: mcasp0_ahclkx */
++ "P9.28", /* mcasp0: mcasp0_axr2 */
++ "P9.29", /* mcasp0: mcasp0_fsx */
++ "P9.31", /* mcasp0: mcasp0_aclkx */
++ "P8.45", /* lcd: lcd_data0 */
++ "P8.46", /* lcd: lcd_data1 */
++ "P8.43", /* lcd: lcd_data2 */
++ "P8.44", /* lcd: lcd_data3 */
++ "P8.41", /* lcd: lcd_data4 */
++ "P8.42", /* lcd: lcd_data5 */
++ "P8.39", /* lcd: lcd_data6 */
++ "P8.40", /* lcd: lcd_data7 */
++ "P8.37", /* lcd: lcd_data8 */
++ "P8.38", /* lcd: lcd_data9 */
++ "P8.36", /* lcd: lcd_data10 */
++ "P8.34", /* lcd: lcd_data11 */
++ "P8.35", /* lcd: lcd_data12 */
++ "P8.33", /* lcd: lcd_data13 */
++ "P8.31", /* lcd: lcd_data14 */
++ "P8.32", /* lcd: lcd_data15 */
++ "P8.27", /* lcd: lcd_vsync */
++ "P8.29", /* lcd: lcd_hsync */
++ "P8.28", /* lcd: lcd_pclk */
++ "P8.30", /* lcd: lcd_ac_bias_en */
++ /* the hardware IP uses */
++ "gpio1_27",
++ "mcasp0",
++ "lcd";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
diff --git a/patches/linux-3.8.13/0619-capes-Update-most-of-the-capes-with-resource-definit.patch b/patches/linux-3.8.13/0619-capes-Update-most-of-the-capes-with-resource-definit.patch
new file mode 100644
index 0000000..70046c8
--- /dev/null
+++ b/patches/linux-3.8.13/0619-capes-Update-most-of-the-capes-with-resource-definit.patch
@@ -0,0 +1,1100 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Fri, 17 May 2013 18:38:30 +0300
+Subject: [PATCH] capes: Update most of the capes with resource definitions
+
+Updated all the standard capes with their resource definitions.
+---
+ firmware/capes/BB-BONE-GPEVT-00A0.dts | 7 ++++
+ firmware/capes/BB-BONE-LCD4-01-00A0.dts | 31 +++++++++++++++
+ firmware/capes/BB-BONE-LCD4-01-00A1.dts | 46 +++++++++++++++++++++--
+ firmware/capes/BB-BONE-LCD7-01-00A2.dts | 46 +++++++++++++++++++++--
+ firmware/capes/BB-BONE-LCD7-01-00A3.dts | 48 ++++++++++++++++++++++--
+ firmware/capes/BB-BONE-LCD7-01-00A4.dts | 47 ++++++++++++++++++++++-
+ firmware/capes/BB-BONE-PWMT-00A0.dts | 9 ++++-
+ firmware/capes/BB-BONE-eMMC1-01-00A0.dts | 16 ++++++++
+ firmware/capes/BB-BONELT-BT-00A0.dts | 7 ++++
+ firmware/capes/bone_pwm_P8_13-00A0.dts | 13 ++++++-
+ firmware/capes/bone_pwm_P8_19-00A0.dts | 13 ++++++-
+ firmware/capes/bone_pwm_P8_34-00A0.dts | 7 ++++
+ firmware/capes/bone_pwm_P8_36-00A0.dts | 7 ++++
+ firmware/capes/bone_pwm_P8_45-00A0.dts | 7 ++++
+ firmware/capes/bone_pwm_P8_46-00A0.dts | 7 ++++
+ firmware/capes/bone_pwm_P9_14-00A0.dts | 7 ++++
+ firmware/capes/bone_pwm_P9_16-00A0.dts | 7 ++++
+ firmware/capes/bone_pwm_P9_21-00A0.dts | 7 ++++
+ firmware/capes/bone_pwm_P9_22-00A0.dts | 7 ++++
+ firmware/capes/bone_pwm_P9_28-00A0.dts | 7 ++++
+ firmware/capes/bone_pwm_P9_29-00A0.dts | 7 ++++
+ firmware/capes/bone_pwm_P9_31-00A0.dts | 7 ++++
+ firmware/capes/bone_pwm_P9_42-00A0.dts | 7 ++++
+ firmware/capes/cape-bone-adafruit-lcd-00A0.dts | 31 +++++++++++----
+ firmware/capes/cape-bone-adafruit-rtc-00A0.dts | 15 ++++++++
+ firmware/capes/cape-bone-dvi-00A0.dts | 32 ++++++++++++++++
+ firmware/capes/cape-bone-dvi-00A1.dts | 37 ++++++++++++++++++
+ firmware/capes/cape-bone-dvi-00A2.dts | 32 ++++++++++++++++
+ firmware/capes/cape-bone-geiger-00A0.dts | 15 ++++++++
+ firmware/capes/cape-bone-iio-00A0.dts | 13 +++++++
+ firmware/capes/cape-bone-mrf24j40-00A0.dts | 16 ++++++++
+ firmware/capes/cape-bone-nixie-00A0.dts | 18 ++++++++-
+ firmware/capes/cape-bone-tester-00A0.dts | 2 +
+ firmware/capes/cape-bone-weather-00A0.dts | 7 ++++
+ 34 files changed, 559 insertions(+), 26 deletions(-)
+
+diff --git a/firmware/capes/BB-BONE-GPEVT-00A0.dts b/firmware/capes/BB-BONE-GPEVT-00A0.dts
+index 112a6d1..e773dee 100644
+--- a/firmware/capes/BB-BONE-GPEVT-00A0.dts
++++ b/firmware/capes/BB-BONE-GPEVT-00A0.dts
+@@ -13,6 +13,13 @@
+ part-number = "BB-BONE-GPEVT";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.7",
++ /* the hardware IP uses */
++ "gpio2_2";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/BB-BONE-LCD4-01-00A0.dts b/firmware/capes/BB-BONE-LCD4-01-00A0.dts
+index b1c7e00..4b6f3cc 100644
+--- a/firmware/capes/BB-BONE-LCD4-01-00A0.dts
++++ b/firmware/capes/BB-BONE-LCD4-01-00A0.dts
+@@ -15,6 +15,37 @@
+ part-number = "BB-BONE-LCD4-01";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.45", /* lcd: lcd_data0 */
++ "P8.46", /* lcd: lcd_data1 */
++ "P8.43", /* lcd: lcd_data2 */
++ "P8.44", /* lcd: lcd_data3 */
++ "P8.41", /* lcd: lcd_data4 */
++ "P8.42", /* lcd: lcd_data5 */
++ "P8.39", /* lcd: lcd_data6 */
++ "P8.40", /* lcd: lcd_data7 */
++ "P8.37", /* lcd: lcd_data8 */
++ "P8.38", /* lcd: lcd_data9 */
++ "P8.36", /* lcd: lcd_data10 */
++ "P8.34", /* lcd: lcd_data11 */
++ "P8.35", /* lcd: lcd_data12 */
++ "P8.33", /* lcd: lcd_data13 */
++ "P8.31", /* lcd: lcd_data14 */
++ "P8.32", /* lcd: lcd_data15 */
++ "P8.27", /* lcd: lcd_vsync */
++ "P8.29", /* lcd: lcd_hsync */
++ "P8.28", /* lcd: lcd_pclk */
++ "P8.30", /* lcd: lcd_ac_bias_en */
++ "P9.16", /* tsc: gpio1_19 */
++ "P9.14", /* led: gpio1_18 */
++ /* the hardware IP uses */
++ "gpio1_19",
++ "gpio1_18",
++ "lcd",
++ "tps-bl";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/BB-BONE-LCD4-01-00A1.dts b/firmware/capes/BB-BONE-LCD4-01-00A1.dts
+index bd3c2a8..b424c09 100644
+--- a/firmware/capes/BB-BONE-LCD4-01-00A1.dts
++++ b/firmware/capes/BB-BONE-LCD4-01-00A1.dts
+@@ -15,13 +15,53 @@
+ part-number = "BB-BONE-LCD4-01";
+ version = "00A1";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.45", /* lcd: lcd_data0 */
++ "P8.46", /* lcd: lcd_data1 */
++ "P8.43", /* lcd: lcd_data2 */
++ "P8.44", /* lcd: lcd_data3 */
++ "P8.41", /* lcd: lcd_data4 */
++ "P8.42", /* lcd: lcd_data5 */
++ "P8.39", /* lcd: lcd_data6 */
++ "P8.40", /* lcd: lcd_data7 */
++ "P8.37", /* lcd: lcd_data8 */
++ "P8.38", /* lcd: lcd_data9 */
++ "P8.36", /* lcd: lcd_data10 */
++ "P8.34", /* lcd: lcd_data11 */
++ "P8.35", /* lcd: lcd_data12 */
++ "P8.33", /* lcd: lcd_data13 */
++ "P8.31", /* lcd: lcd_data14 */
++ "P8.32", /* lcd: lcd_data15 */
++ "P8.27", /* lcd: lcd_vsync */
++ "P8.29", /* lcd: lcd_hsync */
++ "P8.28", /* lcd: lcd_pclk */
++ "P8.30", /* lcd: lcd_ac_bias_en */
++ "P9.27", /* lcd: gpio3_19 */
++ "P9.12", /* led: gpio1_28 */
++ "P9.14", /* pwm: ehrpwm1a */
++ "P9.15", /* keys: gpio1_16 */
++ "P9.23", /* keys: gpio1_17 */
++ "P9.16", /* keys: gpio1_19 */
++ "P9.21", /* keys: gpio0_3 */
++ /* the hardware IP uses */
++ "gpio3_19",
++ "gpio1_28",
++ "gpio1_16",
++ "gpio1_17",
++ "gpio1_19",
++ "gpio0_3",
++ "lcd",
++ "ehrpwm1a";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+
+- bone_lcd4_cape_led_00A2_pins: pinmux_bone_lcd4_cape_led_00A2_pins {
++ bone_lcd4_cape_led_00A1_pins: pinmux_bone_lcd4_cape_led_00A1_pins {
+ pinctrl-single,pins = <
+- 0x078 0x2f /* gpmc_ben1.gpio1_28, INPUT | PULLDIS | MODE7 */
++ 0x078 0x2f /* gpmc_be1n.gpio1_28, INPUT | PULLDIS | MODE7 */
+ >;
+ };
+
+@@ -129,7 +169,7 @@
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+
+- pinctrl-0 = <&bone_lcd4_cape_led_00A2_pins>;
++ pinctrl-0 = <&bone_lcd4_cape_led_00A1_pins>;
+
+ lcd4-led0 {
+ label = "lcd4:green:usr0";
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A2.dts b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
+index d1eac3b..77ef5ec 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A2.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
+@@ -15,13 +15,53 @@
+ part-number = "BB-BONE-LCD7-01";
+ version = "00A2";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.45", /* lcd: lcd_data0 */
++ "P8.46", /* lcd: lcd_data1 */
++ "P8.43", /* lcd: lcd_data2 */
++ "P8.44", /* lcd: lcd_data3 */
++ "P8.41", /* lcd: lcd_data4 */
++ "P8.42", /* lcd: lcd_data5 */
++ "P8.39", /* lcd: lcd_data6 */
++ "P8.40", /* lcd: lcd_data7 */
++ "P8.37", /* lcd: lcd_data8 */
++ "P8.38", /* lcd: lcd_data9 */
++ "P8.36", /* lcd: lcd_data10 */
++ "P8.34", /* lcd: lcd_data11 */
++ "P8.35", /* lcd: lcd_data12 */
++ "P8.33", /* lcd: lcd_data13 */
++ "P8.31", /* lcd: lcd_data14 */
++ "P8.32", /* lcd: lcd_data15 */
++ "P8.27", /* lcd: lcd_vsync */
++ "P8.29", /* lcd: lcd_hsync */
++ "P8.28", /* lcd: lcd_pclk */
++ "P8.30", /* lcd: lcd_ac_bias_en */
++ "P8.20", /* lcd: gpio1_31 */
++ "P9.12", /* led: gpio1_28 */
++ "P9.14", /* pwm: ehrpwm1a */
++ "P9.15", /* keys: gpio1_16 */
++ "P9.23", /* keys: gpio1_17 */
++ "P9.16", /* keys: gpio1_19 */
++ "P9.27", /* keys: gpio3_19 */
++ /* the hardware IP uses */
++ "gpio1_31",
++ "gpio1_28",
++ "gpio1_16",
++ "gpio1_17",
++ "gpio1_19",
++ "gpio3_19",
++ "lcd",
++ "ehrpwm1a";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+
+ bone_lcd7_cape_led_00A2_pins: pinmux_bone_lcd7_cape_led_00A2_pins {
+ pinctrl-single,pins = <
+- 0x078 0x2f /* gpmc_ben1.gpio1_28, INPUT | PULLDIS | MODE7 */
++ 0x078 0x2f /* gpmc_be1n.gpio1_28, INPUT | PULLDIS | MODE7 */
+ >;
+ };
+
+@@ -33,7 +73,7 @@
+
+ bone_lcd7_cape_lcd_pins: pinmux_bone_lcd7_cape_lcd_pins {
+ pinctrl-single,pins = <
+- //0x84 0x07 /* gpmc_csn2.gpio1_31, OUTPUT | MODE7 - AVDD_EN */
++ 0x84 0x07 /* gpmc_csn2.gpio1_31, OUTPUT | MODE7 - AVDD_EN */
+ 0xa0 0x08 /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xa4 0x08 /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xa8 0x08 /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+@@ -62,8 +102,8 @@
+ 0x040 0x2f /* KEY_LEFT gpmc_a0.gpio1_16, INPUT | PULLDIS | MODE7 */
+ 0x044 0x2f /* KEY_RIGHT gpmc_a1.gpio1_17, INPUT | PULLDIS | MODE7 */
+ 0x04c 0x2f /* KEY_UP gpmc_a3.gpio1_19, INPUT | PULLDIS | MODE7 */
++ 0x198 0x2f /* KEY_DOWN mcasp0_axr0.gpio3_16, INPUT | PULLDIS | MODE7 */
+ 0x1a4 0x2f /* KEY_ENTER mcasp0_fsr.gpio3_19, INPUT | PULLDIS | MODE7 */
+- // gpio3_16 KEY_DOWN
+ >;
+ };
+
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A3.dts b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+index 979fd73..f5fab09 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A3.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+@@ -15,6 +15,48 @@
+ part-number = "BB-BONE-LCD7-01";
+ version = "00A3";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.45", /* lcd: lcd_data0 */
++ "P8.46", /* lcd: lcd_data1 */
++ "P8.43", /* lcd: lcd_data2 */
++ "P8.44", /* lcd: lcd_data3 */
++ "P8.41", /* lcd: lcd_data4 */
++ "P8.42", /* lcd: lcd_data5 */
++ "P8.39", /* lcd: lcd_data6 */
++ "P8.40", /* lcd: lcd_data7 */
++ "P8.37", /* lcd: lcd_data8 */
++ "P8.38", /* lcd: lcd_data9 */
++ "P8.36", /* lcd: lcd_data10 */
++ "P8.34", /* lcd: lcd_data11 */
++ "P8.35", /* lcd: lcd_data12 */
++ "P8.33", /* lcd: lcd_data13 */
++ "P8.31", /* lcd: lcd_data14 */
++ "P8.32", /* lcd: lcd_data15 */
++ "P8.27", /* lcd: lcd_vsync */
++ "P8.29", /* lcd: lcd_hsync */
++ "P8.28", /* lcd: lcd_pclk */
++ "P8.30", /* lcd: lcd_ac_bias_en */
++ "P8.20", /* lcd: gpio1_31 */
++ "P9.12", /* led: gpio1_28 */
++ "P9.14", /* pwm: ehrpwm1a */
++ "P9.15", /* keys: gpio1_16 */
++ "P9.23", /* keys: gpio1_17 */
++ "P9.16", /* keys: gpio1_19 */
++ "P9.30", /* keys: gpio3_16 */
++ "P9.21", /* keys: gpio0_3 */
++ /* the hardware IP uses */
++ "gpio1_31",
++ "gpio1_28",
++ "gpio1_16",
++ "gpio1_17",
++ "gpio1_19",
++ "gpio3_16",
++ "gpio0_3",
++ "lcd",
++ "ehrpwm1a";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+@@ -33,7 +75,7 @@
+
+ bone_lcd7_cape_lcd_pins: pinmux_bone_lcd7_cape_lcd_pins {
+ pinctrl-single,pins = <
+- //0x84 0x07 /* gpmc_csn2.gpio1_31, OUTPUT | MODE7 - AVDD_EN */
++ 0x84 0x07 /* gpmc_csn2.gpio1_31, OUTPUT | MODE7 - AVDD_EN */
+ 0xa0 0x08 /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xa3 0x08 /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xa8 0x08 /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+@@ -62,8 +104,8 @@
+ 0x040 0x2f /* KEY_LEFT gpmc_a0.gpio1_16, INPUT | PULLDIS | MODE7 */
+ 0x044 0x2f /* KEY_RIGHT gpmc_a1.gpio1_17, INPUT | PULLDIS | MODE7 */
+ 0x04c 0x2f /* KEY_UP gpmc_a3.gpio1_19, INPUT | PULLDIS | MODE7 */
+- 0x1a3 0x2f /* TSC_INTn mcasp0_fsr.gpio3_19, INPUT | PULLDIS | MODE7 */
+- // gpio3_16 KEY_DOWN
++ 0x198 0x2f /* KEY_DOWN mcasp0_axr0.gpio3_16, INPUT | PULLDIS | MODE7 */
++ 0x070 0x2f /* KEY_ENTER gpmc_wait0.gpio0_3, INPUT | PULLDIS | MODE7 */
+ >;
+ };
+
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A4.dts b/firmware/capes/BB-BONE-LCD7-01-00A4.dts
+index 6f34b79..81553e6 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A4.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A4.dts
+@@ -15,6 +15,48 @@
+ part-number = "BB-BONE-LCD7-01";
+ version = "00A4";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.45", /* lcd: lcd_data0 */
++ "P8.46", /* lcd: lcd_data1 */
++ "P8.43", /* lcd: lcd_data2 */
++ "P8.44", /* lcd: lcd_data3 */
++ "P8.41", /* lcd: lcd_data4 */
++ "P8.42", /* lcd: lcd_data5 */
++ "P8.39", /* lcd: lcd_data6 */
++ "P8.40", /* lcd: lcd_data7 */
++ "P8.37", /* lcd: lcd_data8 */
++ "P8.38", /* lcd: lcd_data9 */
++ "P8.36", /* lcd: lcd_data10 */
++ "P8.34", /* lcd: lcd_data11 */
++ "P8.35", /* lcd: lcd_data12 */
++ "P8.33", /* lcd: lcd_data13 */
++ "P8.31", /* lcd: lcd_data14 */
++ "P8.32", /* lcd: lcd_data15 */
++ "P8.27", /* lcd: lcd_vsync */
++ "P8.29", /* lcd: lcd_hsync */
++ "P8.28", /* lcd: lcd_pclk */
++ "P8.30", /* lcd: lcd_ac_bias_en */
++ "P8.20", /* lcd: gpio1_31 */
++ "P9.12", /* led: gpio1_28 */
++ "P9.14", /* pwm: ehrpwm1a */
++ "P9.15", /* keys: gpio1_16 */
++ "P9.23", /* keys: gpio1_17 */
++ "P9.16", /* keys: gpio1_19 */
++ "P9.30", /* keys: gpio3_16 */
++ "P9.21", /* keys: gpio0_3 */
++ /* the hardware IP uses */
++ "gpio1_31",
++ "gpio1_28",
++ "gpio1_16",
++ "gpio1_17",
++ "gpio1_19",
++ "gpio3_16",
++ "gpio0_3",
++ "lcd",
++ "ehrpwm1a";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+@@ -33,7 +75,7 @@
+
+ bone_lcd7_cape_lcd_pins: pinmux_bone_lcd7_cape_lcd_pins {
+ pinctrl-single,pins = <
+- //0x84 0x07 /* gpmc_csn2.gpio1_31, OUTPUT | MODE7 - AVDD_EN */
++ 0x84 0x07 /* gpmc_csn2.gpio1_31, OUTPUT | MODE7 - AVDD_EN */
+ 0xa0 0x08 /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xa4 0x08 /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xa8 0x08 /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+@@ -62,8 +104,9 @@
+ 0x040 0x2f /* KEY_LEFT gpmc_a0.gpio1_16, INPUT | PULLDIS | MODE7 */
+ 0x044 0x2f /* KEY_RIGHT gpmc_a1.gpio1_17, INPUT | PULLDIS | MODE7 */
+ 0x04c 0x2f /* KEY_UP gpmc_a3.gpio1_19, INPUT | PULLDIS | MODE7 */
++ 0x198 0x2f /* KEY_DOWN mcasp0_axr0.gpio3_16, INPUT | PULLDIS | MODE7 */
++ 0x070 0x2f /* KEY_ENTER gpmc_wait0.gpio0_3, INPUT | PULLDIS | MODE7 */
+ 0x1a4 0x2f /* TSC_INTn mcasp0_fsr.gpio3_19, INPUT | PULLDIS | MODE7 */
+- // gpio3_16 KEY_DOWN
+ >;
+ };
+
+diff --git a/firmware/capes/BB-BONE-PWMT-00A0.dts b/firmware/capes/BB-BONE-PWMT-00A0.dts
+index 02c2c0e..49747c9 100644
+--- a/firmware/capes/BB-BONE-PWMT-00A0.dts
++++ b/firmware/capes/BB-BONE-PWMT-00A0.dts
+@@ -15,11 +15,18 @@
+ part-number = "BB-BONE-PWMT";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.22", /* pwm: ehrpwm0a */
++ /* the hardware ip uses */
++ "ehrpwm0a";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+ pwm_test_pins: pinmux_pwm_test_pins {
+- pinctrl-single,pins = <0x150 0x3>; /* spi0_sclk = ehrpwm0A = P9_14 = Heater_HBP | MODE 3 */
++ pinctrl-single,pins = <0x150 0x3>; /* spi0_sclk = ehrpwm0A = P9_14 | MODE 3 */
+ };
+ };
+ };
+diff --git a/firmware/capes/BB-BONE-eMMC1-01-00A0.dts b/firmware/capes/BB-BONE-eMMC1-01-00A0.dts
+index ac3c0c3..44c01fe 100644
+--- a/firmware/capes/BB-BONE-eMMC1-01-00A0.dts
++++ b/firmware/capes/BB-BONE-eMMC1-01-00A0.dts
+@@ -15,6 +15,22 @@
+ part-number = "BB-BONE-eMMC1-01";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.21", /* mmc1: mmc1_clk */
++ "P8.20", /* mmc1: mmc1_cmd */
++ "P8.25", /* mmc1: mmc1_dat0 */
++ "P8.24", /* mmc1: mmc1_dat1 */
++ "P8.5", /* mmc1: mmc1_dat2 */
++ "P8.6", /* mmc1: mmc1_dat3 */
++ "P8.23", /* mmc1: mmc1_dat4 */
++ "P8.22", /* mmc1: mmc1_dat5 */
++ "P8.3", /* mmc1: mmc1_dat6 */
++ "P8.4", /* mmc1: mmc1_dat7 */
++ /* the hardware IP uses */
++ "mmc1";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/BB-BONELT-BT-00A0.dts b/firmware/capes/BB-BONELT-BT-00A0.dts
+index 94b9a12..dc3b386 100644
+--- a/firmware/capes/BB-BONELT-BT-00A0.dts
++++ b/firmware/capes/BB-BONELT-BT-00A0.dts
+@@ -15,6 +15,13 @@
+ part-number = "BB-BONELT-BT";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.43", /* bt: gpio2_8 */
++ /* the hardware IP uses */
++ "gpio2_8";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/bone_pwm_P8_13-00A0.dts b/firmware/capes/bone_pwm_P8_13-00A0.dts
+index d7a22f8..dde034e 100644
+--- a/firmware/capes/bone_pwm_P8_13-00A0.dts
++++ b/firmware/capes/bone_pwm_P8_13-00A0.dts
+@@ -16,6 +16,13 @@
+ part-number = "bone_pwm_P8_13";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.13", /* pwm: ehrpwm2B */
++ /* the hardware IP uses */
++ "ehrpwm2B";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+@@ -32,8 +39,10 @@
+ compatible = "pwm_test";
+ pwms = <&ehrpwm2 1 500000 1>;
+ pwm-names = "PWM_P8_13";
+- pinctrl-names = "default";
+- pinctrl-0 = <&pwm_P8_13>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P8_13>;
++
+ enabled = <1>;
+ duty = <0>;
+ status = "okay";
+diff --git a/firmware/capes/bone_pwm_P8_19-00A0.dts b/firmware/capes/bone_pwm_P8_19-00A0.dts
+index c8071766..ea52f65 100644
+--- a/firmware/capes/bone_pwm_P8_19-00A0.dts
++++ b/firmware/capes/bone_pwm_P8_19-00A0.dts
+@@ -16,6 +16,13 @@
+ part-number = "bone_pwm_P8_19";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.19", /* pwm: ehrpwm2A */
++ /* the hardware IP uses */
++ "ehrpwm2A";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+@@ -32,8 +39,10 @@
+ compatible = "pwm_test";
+ pwms = <&ehrpwm2 0 500000 1>;
+ pwm-names = "PWM_P8_19";
+- pinctrl-names = "default";
+- pinctrl-0 = <&pwm_P8_19>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_P8_19>;
++
+ enabled = <1>;
+ duty = <0>;
+ status = "okay";
+diff --git a/firmware/capes/bone_pwm_P8_34-00A0.dts b/firmware/capes/bone_pwm_P8_34-00A0.dts
+index 44e4ff7..d7b22bd 100644
+--- a/firmware/capes/bone_pwm_P8_34-00A0.dts
++++ b/firmware/capes/bone_pwm_P8_34-00A0.dts
+@@ -16,6 +16,13 @@
+ part-number = "bone_pwm_P8_34";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.34", /* pwm: ehrpwm1B */
++ /* the hardware IP uses */
++ "ehrpwm1B";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/bone_pwm_P8_36-00A0.dts b/firmware/capes/bone_pwm_P8_36-00A0.dts
+index 12fe6ef..ab1f436 100644
+--- a/firmware/capes/bone_pwm_P8_36-00A0.dts
++++ b/firmware/capes/bone_pwm_P8_36-00A0.dts
+@@ -16,6 +16,13 @@
+ part-number = "bone_pwm_P8_36";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.36", /* pwm: ehrpwm1A */
++ /* the hardware IP uses */
++ "ehrpwm1A";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/bone_pwm_P8_45-00A0.dts b/firmware/capes/bone_pwm_P8_45-00A0.dts
+index 07c8457..a612209 100644
+--- a/firmware/capes/bone_pwm_P8_45-00A0.dts
++++ b/firmware/capes/bone_pwm_P8_45-00A0.dts
+@@ -16,6 +16,13 @@
+ part-number = "bone_pwm_P8_45";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.45", /* pwm: ehrpwm2A */
++ /* the hardware IP uses */
++ "ehrpwm2A";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/bone_pwm_P8_46-00A0.dts b/firmware/capes/bone_pwm_P8_46-00A0.dts
+index 147a3c6..45e4432 100644
+--- a/firmware/capes/bone_pwm_P8_46-00A0.dts
++++ b/firmware/capes/bone_pwm_P8_46-00A0.dts
+@@ -16,6 +16,13 @@
+ part-number = "bone_pwm_P8_46";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.46", /* pwm: ehrpwm2B */
++ /* the hardware IP uses */
++ "ehrpwm2B";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/bone_pwm_P9_14-00A0.dts b/firmware/capes/bone_pwm_P9_14-00A0.dts
+index 0c6c784..23c3c89 100644
+--- a/firmware/capes/bone_pwm_P9_14-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_14-00A0.dts
+@@ -16,6 +16,13 @@
+ part-number = "bone_pwm_P9_14";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.14", /* pwm: ehrpwm1A */
++ /* the hardware IP uses */
++ "ehrpwm1A";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/bone_pwm_P9_16-00A0.dts b/firmware/capes/bone_pwm_P9_16-00A0.dts
+index 252ee8c..fdb7258 100644
+--- a/firmware/capes/bone_pwm_P9_16-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_16-00A0.dts
+@@ -16,6 +16,13 @@
+ part-number = "bone_pwm_P9_16";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.16", /* pwm: ehrpwm1B */
++ /* the hardware IP uses */
++ "ehrpwm1B";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/bone_pwm_P9_21-00A0.dts b/firmware/capes/bone_pwm_P9_21-00A0.dts
+index f2d540a..485ffd7 100644
+--- a/firmware/capes/bone_pwm_P9_21-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_21-00A0.dts
+@@ -16,6 +16,13 @@
+ part-number = "bone_pwm_P9_21";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.21", /* pwm: ehrpwm0B */
++ /* the hardware IP uses */
++ "ehrpwm0B";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/bone_pwm_P9_22-00A0.dts b/firmware/capes/bone_pwm_P9_22-00A0.dts
+index df338f7..111e6e4 100644
+--- a/firmware/capes/bone_pwm_P9_22-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_22-00A0.dts
+@@ -16,6 +16,13 @@
+ part-number = "bone_pwm_P9_22";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.22", /* pwm: ehrpwm0A */
++ /* the hardware IP uses */
++ "ehrpwm0A";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/bone_pwm_P9_28-00A0.dts b/firmware/capes/bone_pwm_P9_28-00A0.dts
+index ace91df..73c59c9 100644
+--- a/firmware/capes/bone_pwm_P9_28-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_28-00A0.dts
+@@ -16,6 +16,13 @@
+ part-number = "bone_pwm_P9_28";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.28", /* pwm: eCAP2_in_PWM2_out */
++ /* the hardware IP uses */
++ "eCAP2_in_PWM2_out";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/bone_pwm_P9_29-00A0.dts b/firmware/capes/bone_pwm_P9_29-00A0.dts
+index 33ae722..16a3533 100644
+--- a/firmware/capes/bone_pwm_P9_29-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_29-00A0.dts
+@@ -16,6 +16,13 @@
+ part-number = "bone_pwm_P9_29";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.29", /* pwm: ehrpwm0B */
++ /* the hardware IP uses */
++ "ehrpwm0B";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/bone_pwm_P9_31-00A0.dts b/firmware/capes/bone_pwm_P9_31-00A0.dts
+index 8096f62..467c993 100644
+--- a/firmware/capes/bone_pwm_P9_31-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_31-00A0.dts
+@@ -16,6 +16,13 @@
+ part-number = "bone_pwm_P9_31";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.31", /* pwm: ehrpwm0A */
++ /* the hardware IP uses */
++ "ehrpwm0A";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/bone_pwm_P9_42-00A0.dts b/firmware/capes/bone_pwm_P9_42-00A0.dts
+index 5ba487f..90e1df8 100644
+--- a/firmware/capes/bone_pwm_P9_42-00A0.dts
++++ b/firmware/capes/bone_pwm_P9_42-00A0.dts
+@@ -16,6 +16,13 @@
+ part-number = "bone_pwm_P9_42";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.42", /* pwm: eCAP0_in_PWM0_out */
++ /* the hardware IP uses */
++ "eCAP0_in_PWM0_out";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/cape-bone-adafruit-lcd-00A0.dts b/firmware/capes/cape-bone-adafruit-lcd-00A0.dts
+index 6fe5dcf..8c0343b 100644
+--- a/firmware/capes/cape-bone-adafruit-lcd-00A0.dts
++++ b/firmware/capes/cape-bone-adafruit-lcd-00A0.dts
+@@ -24,13 +24,29 @@
+ */
+
+ / {
+- compatible = "ti,beaglebone", "ti,beaglebone-black";
+- part-number = "BB-BONE-TFT-01";
+- version = "00A0";
+-
+- fragment@0 {
+- target = <&am33xx_pinmux>;
+- __overlay__ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++ part-number = "BB-BONE-TFT-01";
++ version = "00A0";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.19", /* bl: ehrpwm2A */
++ "P9.27", /* lcd: gpio3_19 */
++ "P9.25", /* lcd: gpio3_21 */
++ "P9.31", /* spi: spi1_sclk */
++ "P9.29", /* spi: spi1_d0 */
++ "P9.30", /* spi: spi1_d1 */
++ "P9.28", /* spi: spi1_cs0 */
++ /* the hardware IP uses */
++ "gpio3_19",
++ "gpio3_21",
++ "ehrpwm2A",
++ "spi1";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
+ pwm_backlight_pins: pinmux_pwm_backlight_pins {
+ pinctrl-single,pins = <
+ 0x020 0x4 /* gpmc_ad8.gpio0_22 | MODE4 */
+@@ -122,5 +138,4 @@
+ };
+ };
+ };
+-
+ };
+diff --git a/firmware/capes/cape-bone-adafruit-rtc-00A0.dts b/firmware/capes/cape-bone-adafruit-rtc-00A0.dts
+index 9436fd4..35344fd 100644
+--- a/firmware/capes/cape-bone-adafruit-rtc-00A0.dts
++++ b/firmware/capes/cape-bone-adafruit-rtc-00A0.dts
+@@ -23,6 +23,21 @@
+ part-number = "BB-BONE-RTC-01";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.19", /* bl: ehrpwm2A */
++ "P9.27", /* lcd: gpio3_19 */
++ "P9.25", /* lcd: gpio3_21 */
++ "P9.31", /* spi: spi1_sclk */
++ "P9.29", /* spi: spi1_d0 */
++ "P9.30", /* spi: spi1_d1 */
++ "P9.28", /* spi: spi1_cs0 */
++ /* the hardware IP uses */
++ "gpio3_19",
++ "gpio3_21",
++ "ehrpwm2A",
++ "spi1";
+
+ fragment@0 {
+ target = <&i2c2>;
+diff --git a/firmware/capes/cape-bone-dvi-00A0.dts b/firmware/capes/cape-bone-dvi-00A0.dts
+index 92fc6be..577a474 100644
+--- a/firmware/capes/cape-bone-dvi-00A0.dts
++++ b/firmware/capes/cape-bone-dvi-00A0.dts
+@@ -15,6 +15,38 @@
+ part-number = "BB-BONE-DVID-01";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.14", /* led: gpio1_18 */
++ "P9.16", /* led: gpio1_19 */
++ "P8.4", /* lcd: gpio1_7 */
++ "P8.45", /* lcd: lcd_data0 */
++ "P8.46", /* lcd: lcd_data1 */
++ "P8.43", /* lcd: lcd_data2 */
++ "P8.44", /* lcd: lcd_data3 */
++ "P8.41", /* lcd: lcd_data4 */
++ "P8.42", /* lcd: lcd_data5 */
++ "P8.39", /* lcd: lcd_data6 */
++ "P8.40", /* lcd: lcd_data7 */
++ "P8.37", /* lcd: lcd_data8 */
++ "P8.38", /* lcd: lcd_data9 */
++ "P8.36", /* lcd: lcd_data10 */
++ "P8.34", /* lcd: lcd_data11 */
++ "P8.35", /* lcd: lcd_data12 */
++ "P8.33", /* lcd: lcd_data13 */
++ "P8.31", /* lcd: lcd_data14 */
++ "P8.32", /* lcd: lcd_data15 */
++ "P8.27", /* lcd: lcd_vsync */
++ "P8.29", /* lcd: lcd_hsync */
++ "P8.28", /* lcd: lcd_pclk */
++ "P8.30", /* lcd: lcd_ac_bias_en */
++ /* the hardware IP uses */
++ "gpio1_18",
++ "gpio1_19",
++ "gpio1_7",
++ "lcd";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/cape-bone-dvi-00A1.dts b/firmware/capes/cape-bone-dvi-00A1.dts
+index b320d4f..ac8b4c5 100644
+--- a/firmware/capes/cape-bone-dvi-00A1.dts
++++ b/firmware/capes/cape-bone-dvi-00A1.dts
+@@ -15,6 +15,43 @@
+ part-number = "BB-BONE-DVID-01";
+ version = "00A1", "A1";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.14", /* led: gpio1_18 */
++ "P9.16", /* led: gpio1_19 */
++ "P9.25", /* mcasp0: mcasp0_ahclkx */
++ "P9.28", /* mcasp0: mcasp0_axr2 */
++ "P9.29", /* mcasp0: mcasp0_fsx */
++ "P9.31", /* mcasp0: mcasp0_aclkx */
++ "P8.4", /* lcd: gpio1_7 */
++ "P8.45", /* lcd: lcd_data0 */
++ "P8.46", /* lcd: lcd_data1 */
++ "P8.43", /* lcd: lcd_data2 */
++ "P8.44", /* lcd: lcd_data3 */
++ "P8.41", /* lcd: lcd_data4 */
++ "P8.42", /* lcd: lcd_data5 */
++ "P8.39", /* lcd: lcd_data6 */
++ "P8.40", /* lcd: lcd_data7 */
++ "P8.37", /* lcd: lcd_data8 */
++ "P8.38", /* lcd: lcd_data9 */
++ "P8.36", /* lcd: lcd_data10 */
++ "P8.34", /* lcd: lcd_data11 */
++ "P8.35", /* lcd: lcd_data12 */
++ "P8.33", /* lcd: lcd_data13 */
++ "P8.31", /* lcd: lcd_data14 */
++ "P8.32", /* lcd: lcd_data15 */
++ "P8.27", /* lcd: lcd_vsync */
++ "P8.29", /* lcd: lcd_hsync */
++ "P8.28", /* lcd: lcd_pclk */
++ "P8.30", /* lcd: lcd_ac_bias_en */
++ /* the hardware IP uses */
++ "gpio1_18",
++ "gpio1_19",
++ "gpio1_7",
++ "mcasp0",
++ "lcd";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/cape-bone-dvi-00A2.dts b/firmware/capes/cape-bone-dvi-00A2.dts
+index d5c49bb..4c54804 100644
+--- a/firmware/capes/cape-bone-dvi-00A2.dts
++++ b/firmware/capes/cape-bone-dvi-00A2.dts
+@@ -15,6 +15,38 @@
+ part-number = "BB-BONE-DVID-01";
+ version = "00A3", "00A2", "A2";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.14", /* led: gpio1_18 */
++ "P9.16", /* led: gpio1_19 */
++ "P8.4", /* lcd: gpio1_7 */
++ "P8.45", /* lcd: lcd_data0 */
++ "P8.46", /* lcd: lcd_data1 */
++ "P8.43", /* lcd: lcd_data2 */
++ "P8.44", /* lcd: lcd_data3 */
++ "P8.41", /* lcd: lcd_data4 */
++ "P8.42", /* lcd: lcd_data5 */
++ "P8.39", /* lcd: lcd_data6 */
++ "P8.40", /* lcd: lcd_data7 */
++ "P8.37", /* lcd: lcd_data8 */
++ "P8.38", /* lcd: lcd_data9 */
++ "P8.36", /* lcd: lcd_data10 */
++ "P8.34", /* lcd: lcd_data11 */
++ "P8.35", /* lcd: lcd_data12 */
++ "P8.33", /* lcd: lcd_data13 */
++ "P8.31", /* lcd: lcd_data14 */
++ "P8.32", /* lcd: lcd_data15 */
++ "P8.27", /* lcd: lcd_vsync */
++ "P8.29", /* lcd: lcd_hsync */
++ "P8.28", /* lcd: lcd_pclk */
++ "P8.30", /* lcd: lcd_ac_bias_en */
++ /* the hardware IP uses */
++ "gpio1_18",
++ "gpio1_19",
++ "gpio1_7",
++ "lcd";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/cape-bone-geiger-00A0.dts b/firmware/capes/cape-bone-geiger-00A0.dts
+index 967e03b..fed2a63 100644
+--- a/firmware/capes/cape-bone-geiger-00A0.dts
++++ b/firmware/capes/cape-bone-geiger-00A0.dts
+@@ -15,6 +15,21 @@
+ part-number = "BB-BONE-GEIGER";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.29", /* led: gpio2_23 */
++ "P8.30", /* led: gpio2_25 */
++ "P9.14", /* geiger: ehrpwm1A */
++ "P9.28", /* geiger: gpio3_17 */
++ "P9.36", /* geiger: AIN5 */
++ /* the hardware IP uses */
++ "gpio2_23",
++ "gpio2_25",
++ "gpio3_17",
++ "ehrpwm1A",
++ "tscadc";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/cape-bone-iio-00A0.dts b/firmware/capes/cape-bone-iio-00A0.dts
+index f1cf814..416712b 100644
+--- a/firmware/capes/cape-bone-iio-00A0.dts
++++ b/firmware/capes/cape-bone-iio-00A0.dts
+@@ -14,6 +14,19 @@
+ /* identification */
+ part-number = "iio-test";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.39", /* AIN0 */
++ "P9.40", /* AIN1 */
++ "P9.37", /* AIN2 */
++ "P9.38", /* AIN3 */
++ "P9.33", /* AIN4 */
++ "P9.36", /* AIN5 */
++ "P9.35", /* AIN6 */
++ /* the hardware IP uses */
++ "tscadc";
++
+ fragment@0 {
+ target = <&ocp>;
+ __overlay__ {
+diff --git a/firmware/capes/cape-bone-mrf24j40-00A0.dts b/firmware/capes/cape-bone-mrf24j40-00A0.dts
+index 0fc2aea..7e7b6b8 100644
+--- a/firmware/capes/cape-bone-mrf24j40-00A0.dts
++++ b/firmware/capes/cape-bone-mrf24j40-00A0.dts
+@@ -16,6 +16,22 @@
+ part-number = "BB-BONE-MRF24J40";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.11", /* gpio1_13 */
++ "P8.16", /* gpio1_14 */
++ "P8.26", /* gpio1_29 */
++ "P9.31", /* spi1_sclk */
++ "P9.29", /* spi1_d0 */
++ "P9.30", /* spi1_d1 */
++ "P9.28", /* spi1_cs0 */
++ /* the hardware IP uses */
++ "gpio1_13",
++ "gpio1_14",
++ "gpio1_29",
++ "spi1";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/cape-bone-nixie-00A0.dts b/firmware/capes/cape-bone-nixie-00A0.dts
+index 7ec2c46..e4ff3ab 100644
+--- a/firmware/capes/cape-bone-nixie-00A0.dts
++++ b/firmware/capes/cape-bone-nixie-00A0.dts
+@@ -15,6 +15,20 @@
+ part-number = "BB-BONE-NIXIE";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.25", /* gpio3_21 */
++ "P8.45", /* ehrpwm2A */
++ "P8.46", /* ehrpwm2B */
++ "P9.31", /* pr1_pru0_pru_r30_0 */
++ "P9.29", /* pr1_pru0_pru_r30_1 */
++ "P9.27", /* pr1_pru0_pru_r30_5 */
++ /* the hardware IP uses */
++ "gpio3_21",
++ "ehrpwm2A", "ehrpwm2B",
++ "pru";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+@@ -28,7 +42,7 @@
+ bone_nixie_cape_pins: pinmux_bone_nixie_cape_pins {
+ pinctrl-single,pins = <
+ 0x0a0 0x03 /* lcd_data0.gpio2_6 | MODE3 */
+- 0x0a4 0x03 /* lcd_data1.gpio2_7 | MODE3 */
++ 0x0a4 0x03 /* lcd_data1.gpio2_7 | MODE3 */
+ >;
+ };
+
+@@ -39,7 +53,7 @@
+ 0x1a4 0x05 /* mcasp0_fsr.pr1_pru1_pru_r30_5, MODE5 | CLK */
+ >;
+ };
+- };
++ };
+ };
+
+ fragment@2 {
+diff --git a/firmware/capes/cape-bone-tester-00A0.dts b/firmware/capes/cape-bone-tester-00A0.dts
+index b5b1be8..df04f6d 100644
+--- a/firmware/capes/cape-bone-tester-00A0.dts
++++ b/firmware/capes/cape-bone-tester-00A0.dts
+@@ -15,6 +15,8 @@
+ part-number = "BB-BONE-TESTER";
+ version = "00A0";
+
++ /* NOTE: we don't use resources for the tester - it's not a normal cape */
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/cape-bone-weather-00A0.dts b/firmware/capes/cape-bone-weather-00A0.dts
+index 7cb479a..c017cdb 100644
+--- a/firmware/capes/cape-bone-weather-00A0.dts
++++ b/firmware/capes/cape-bone-weather-00A0.dts
+@@ -14,6 +14,13 @@
+ part-number = "BB-BONE-WTHR-01";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.6", /* gpio1_3 */
++ /* the hardware IP uses */
++ "gpio1_3";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
diff --git a/patches/linux-3.8.13/0620-capes-Update-RS232-CAN-capes-with-resources.patch b/patches/linux-3.8.13/0620-capes-Update-RS232-CAN-capes-with-resources.patch
new file mode 100644
index 0000000..d04a4aa
--- /dev/null
+++ b/patches/linux-3.8.13/0620-capes-Update-RS232-CAN-capes-with-resources.patch
@@ -0,0 +1,47 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 20 May 2013 16:11:38 +0300
+Subject: [PATCH] capes: Update RS232 + CAN capes with resources
+
+---
+ firmware/capes/BB-BONE-RS232-00A0.dts | 8 ++++++++
+ firmware/capes/BB-BONE-SERL-01-00A1.dts | 8 ++++++++
+ 2 files changed, 16 insertions(+)
+
+diff --git a/firmware/capes/BB-BONE-RS232-00A0.dts b/firmware/capes/BB-BONE-RS232-00A0.dts
+index 220c85d..ad627c5 100644
+--- a/firmware/capes/BB-BONE-RS232-00A0.dts
++++ b/firmware/capes/BB-BONE-RS232-00A0.dts
+@@ -15,6 +15,14 @@
+ part-number = "BB-BONE-RS232";
+ version = "00A0";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.22", /* rs232: uart2_rxd */
++ "P9.21", /* rs232: uart2_txd */
++ /* the hardware IP uses */
++ "uart2";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
+diff --git a/firmware/capes/BB-BONE-SERL-01-00A1.dts b/firmware/capes/BB-BONE-SERL-01-00A1.dts
+index b0459c8..93b1bfc 100644
+--- a/firmware/capes/BB-BONE-SERL-01-00A1.dts
++++ b/firmware/capes/BB-BONE-SERL-01-00A1.dts
+@@ -14,6 +14,14 @@
+ part-number = "BB-BONE-SERL-01";
+ version = "00A1";
+
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.26", /* dcan1: dcan1_tx */
++ "P9.24", /* dcan1: dcan1_rx */
++ /* the hardware IP uses */
++ "dcan1";
++
+ fragment@0 {
+ target = <&am33xx_pinmux>;
+ __overlay__ {
diff --git a/patches/linux-3.8.13/0621-capemgr-Add-enable_partno-parameter.patch b/patches/linux-3.8.13/0621-capemgr-Add-enable_partno-parameter.patch
new file mode 100644
index 0000000..6415566
--- /dev/null
+++ b/patches/linux-3.8.13/0621-capemgr-Add-enable_partno-parameter.patch
@@ -0,0 +1,114 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Tue, 4 Jun 2013 19:42:45 +0300
+Subject: [PATCH] capemgr: Add enable_partno parameter
+
+Add analogous option to disable_partno; this one doesn't require the presence of
+a base dts override.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/misc/cape/beaglebone/capemgr.c | 66 ++++++++++++++++++++++++++++++++
+ 1 file changed, 66 insertions(+)
+
+diff --git a/drivers/misc/cape/beaglebone/capemgr.c b/drivers/misc/cape/beaglebone/capemgr.c
+index 2820e39..b1a8b65c 100644
+--- a/drivers/misc/cape/beaglebone/capemgr.c
++++ b/drivers/misc/cape/beaglebone/capemgr.c
+@@ -57,6 +57,13 @@ module_param(disable_partno, charp, 0444);
+ MODULE_PARM_DESC(disable_partno,
+ "Comma delimited list of PART-NUMBER[:REV] of disabled capes");
+
++/* enable capes */
++static char *enable_partno = NULL;
++module_param(enable_partno, charp, 0444);
++MODULE_PARM_DESC(enable_partno,
++ "Comma delimited list of PART-NUMBER[:REV] of enabled capes");
++
++
+ struct bone_capemgr_info;
+
+ struct slot_ee_attribute {
+@@ -1812,10 +1819,12 @@ bone_capemgr_probe(struct platform_device *pdev)
+ struct device_node *slots_node, *capemaps_node, *node;
+ struct device_node *eeprom_node;
+ const char *part_number;
++ const char *version;
+ const char *board_name;
+ const char *compatible_name;
+ struct bone_capemap *capemap;
+ int ret, len;
++ char *wbuf, *s, *p, *e;
+
+ /* we don't use platform_data at all; we require OF */
+ if (pnode == NULL)
+@@ -1996,6 +2005,62 @@ bone_capemgr_probe(struct platform_device *pdev)
+ }
+ slots_node = NULL;
+
++ /* iterate over enable_partno (if there) */
++ if (enable_partno && strlen(enable_partno) > 0) {
++
++ /* allocate a temporary buffer */
++ wbuf = devm_kzalloc(&pdev->dev, PAGE_SIZE, GFP_KERNEL);
++ if (wbuf == NULL) {
++ dev_err(&pdev->dev, "Failed to allocate temporary buffer\n");
++ ret = -ENOMEM;
++ goto err_exit;
++ }
++
++ /* add any enable_partno capes */
++ s = enable_partno;
++ while (*s) {
++ /* form is PART[:REV],PART.. */
++ p = strchr(s, ',');
++ if (p == NULL)
++ e = s + strlen(s);
++ else
++ e = p;
++
++ /* copy to temp buffer */
++ len = e - s;
++ if (len >= PAGE_SIZE - 1)
++ len = PAGE_SIZE - 1;
++ memcpy(wbuf, s, len);
++ wbuf[len] = '\0';
++
++ /* move to the next */
++ s = *e ? e + 1 : e;
++
++ /* now split the rev part */
++ p = strchr(wbuf, ':');
++ if (p != NULL)
++ *p++ = '\0';
++
++ part_number = wbuf;
++ version = p;
++
++ dev_info(&pdev->dev, "enabled_partno part_number '%s', version '%s'\n",
++ part_number, version ? version : "N/A");
++
++ /* only immediate slots are allowed here */
++ slot = bone_capemgr_add_slot(info, NULL,
++ part_number, version);
++
++ /* we continue even in case of an error */
++ if (IS_ERR_OR_NULL(slot)) {
++ dev_warn(&pdev->dev, "Failed to add slot #%d\n",
++ atomic_read(&info->next_slot_nr) - 1);
++ }
++ }
++
++ devm_kfree(&pdev->dev, wbuf);
++ }
++
+ pm_runtime_enable(&pdev->dev);
+ ret = pm_runtime_get_sync(&pdev->dev);
+ if (IS_ERR_VALUE(ret)) {
+@@ -2009,6 +2074,7 @@ bone_capemgr_probe(struct platform_device *pdev)
+
+ /* now load each (take lock to be sure */
+ mutex_lock(&info->slots_list_mutex);
++
+ list_for_each_entry(slot, &info->slot_list, node) {
+
+ /* if matches the disabled ones skip */
diff --git a/patches/linux-3.8.13/0622-cape-GPIOHELP-use-correct-part-number.patch b/patches/linux-3.8.13/0622-cape-GPIOHELP-use-correct-part-number.patch
new file mode 100644
index 0000000..123e82e
--- /dev/null
+++ b/patches/linux-3.8.13/0622-cape-GPIOHELP-use-correct-part-number.patch
@@ -0,0 +1,21 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 5 Jun 2013 10:34:32 +0300
+Subject: [PATCH] cape: GPIOHELP use correct part number
+
+---
+ firmware/capes/BB-GPIOHELP-00A0.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/firmware/capes/BB-GPIOHELP-00A0.dts b/firmware/capes/BB-GPIOHELP-00A0.dts
+index d7e0b4b..ba2a74b 100644
+--- a/firmware/capes/BB-GPIOHELP-00A0.dts
++++ b/firmware/capes/BB-GPIOHELP-00A0.dts
+@@ -12,7 +12,7 @@
+ compatible = "ti,beaglebone", "ti,beaglebone-black";
+
+ /* identification */
+- part-number = "BB-BONE-PRU-01";
++ part-number = "BB-GPIOHELP";
+ version = "00A0";
+
+ /* state the resources this cape uses */
diff --git a/patches/linux-3.8.13/0623-bbb-Add-a-fall-back-non-audio-HDMI-cape.patch b/patches/linux-3.8.13/0623-bbb-Add-a-fall-back-non-audio-HDMI-cape.patch
new file mode 100644
index 0000000..4e3e870
--- /dev/null
+++ b/patches/linux-3.8.13/0623-bbb-Add-a-fall-back-non-audio-HDMI-cape.patch
@@ -0,0 +1,186 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Tue, 4 Jun 2013 17:54:45 +0300
+Subject: [PATCH] bbb: Add a fall-back non-audio HDMI cape
+
+When a user cape hogs the audio, allow booting with a HDMI cape which
+only supports video.
+---
+ arch/arm/boot/dts/am335x-bone-common.dtsi | 21 +++++
+ firmware/Makefile | 5 +-
+ firmware/capes/cape-boneblack-hdmin-00A0.dts | 112 ++++++++++++++++++++++++++
+ 3 files changed, 136 insertions(+), 2 deletions(-)
+ create mode 100644 firmware/capes/cape-boneblack-hdmin-00A0.dts
+
+diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
+index ae407c3..aa95810 100644
+--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
+@@ -219,6 +219,17 @@
+ part-number = "BB-BONELT-HDMI";
+ };
+
++ /* Beaglebone black has it soldered on (but no audio) */
++ slot@102 {
++ ti,cape-override;
++ priority = <2>;
++ compatible = "ti,beaglebone-black";
++ board-name = "Bone-Black-HDMIN";
++ version = "00A0";
++ manufacturer = "Texas Instruments";
++ part-number = "BB-BONELT-HDMIN";
++ };
++
+ };
+
+ /* mapping between board names and dtb objects */
+@@ -349,6 +360,16 @@
+ dtbo = "BB-BONE-RS232-00A0.dtbo";
+ };
+ };
++
++ /* beaglebone black hdmi on board (No audio) */
++ cape@13 {
++ part-number = "BB-BONELT-HDMIN";
++ version@00A0 {
++ version = "00A0";
++ dtbo = "cape-boneblack-hdmin-00A0.dtbo";
++ };
++ };
++
+ };
+ };
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index 646eea5..182de29 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -200,8 +200,9 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE_NIXIE) += \
+ # the weather cape
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += cape-bone-weather-00A0.dtbo
+
+-# the HDMI virtual cape on the beaglebone-black
+-fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += cape-boneblack-hdmi-00A0.dtbo
++# the HDMI virtual capes on the beaglebone-black
++fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
++ cape-boneblack-hdmi-00A0.dtbo cape-boneblack-hdmin-00A0.dtbo
+
+ # the Tester cape (tester-side)
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += cape-bone-tester-00A0.dtbo
+diff --git a/firmware/capes/cape-boneblack-hdmin-00A0.dts b/firmware/capes/cape-boneblack-hdmin-00A0.dts
+new file mode 100644
+index 0000000..44ae0ea
+--- /dev/null
++++ b/firmware/capes/cape-boneblack-hdmin-00A0.dts
+@@ -0,0 +1,112 @@
++/*
++* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
++*
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License version 2 as
++* published by the Free Software Foundation.
++*/
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone-black";
++ part-number = "BB-BONELT-HDMIN"; /* No audio */
++ version = "00A0";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.45", /* lcd: lcd_data0 */
++ "P8.46", /* lcd: lcd_data1 */
++ "P8.43", /* lcd: lcd_data2 */
++ "P8.44", /* lcd: lcd_data3 */
++ "P8.41", /* lcd: lcd_data4 */
++ "P8.42", /* lcd: lcd_data5 */
++ "P8.39", /* lcd: lcd_data6 */
++ "P8.40", /* lcd: lcd_data7 */
++ "P8.37", /* lcd: lcd_data8 */
++ "P8.38", /* lcd: lcd_data9 */
++ "P8.36", /* lcd: lcd_data10 */
++ "P8.34", /* lcd: lcd_data11 */
++ "P8.35", /* lcd: lcd_data12 */
++ "P8.33", /* lcd: lcd_data13 */
++ "P8.31", /* lcd: lcd_data14 */
++ "P8.32", /* lcd: lcd_data15 */
++ "P8.27", /* lcd: lcd_vsync */
++ "P8.29", /* lcd: lcd_hsync */
++ "P8.28", /* lcd: lcd_pclk */
++ "P8.30", /* lcd: lcd_ac_bias_en */
++ /* the hardware IP uses */
++ "gpio1_27",
++ "lcd";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins {
++ pinctrl-single,pins = <
++ 0x1b0 0x03 /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */
++ 0xa0 0x08 /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xa4 0x08 /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xa8 0x08 /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xac 0x08 /* lcd_data3.lcd_data3, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xb0 0x08 /* lcd_data4.lcd_data4, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xb4 0x08 /* lcd_data5.lcd_data5, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xb8 0x08 /* lcd_data6.lcd_data6, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xbc 0x08 /* lcd_data7.lcd_data7, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xc0 0x08 /* lcd_data8.lcd_data8, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xc4 0x08 /* lcd_data9.lcd_data9, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xc8 0x08 /* lcd_data10.lcd_data10, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xcc 0x08 /* lcd_data11.lcd_data11, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xd0 0x08 /* lcd_data12.lcd_data12, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xd4 0x08 /* lcd_data13.lcd_data13, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xd8 0x08 /* lcd_data14.lcd_data14, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xdc 0x08 /* lcd_data15.lcd_data15, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
++ 0xe0 0x00 /* lcd_vsync.lcd_vsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0xe4 0x00 /* lcd_hsync.lcd_hsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0xe8 0x00 /* lcd_pclk.lcd_pclk, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ >;
++ };
++ nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins {
++ pinctrl-single,pins = <
++ 0x1b0 0x03 /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */
++ >;
++ };
++ };
++ };
++
++ fragment@2 {
++ target = <&ocp>;
++ __overlay__ {
++
++ /* avoid stupid warning */
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ nxptda: nxptda@0 {
++ compatible = "nxp,nxptda";
++ status = "okay";
++ };
++
++ hdmi {
++ compatible = "tilcdc,slave";
++ i2c = <&i2c0>;
++ pinctrl-names = "default", "off";
++ pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
++ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
++ };
++
++ fb {
++ compatible = "ti,am33xx-tilcdc";
++ reg = <0x4830e000 0x1000>;
++ interrupt-parent = <&intc>;
++ interrupts = <36>;
++ ti,hwmods = "lcdc";
++ ti,allow-non-reduced-blanking-modes;
++ ti,allow-non-audio-modes;
++ };
++
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0624-capes-HDMI-slaves-need-panel-settings.patch b/patches/linux-3.8.13/0624-capes-HDMI-slaves-need-panel-settings.patch
new file mode 100644
index 0000000..8d763f1
--- /dev/null
+++ b/patches/linux-3.8.13/0624-capes-HDMI-slaves-need-panel-settings.patch
@@ -0,0 +1,57 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 6 Jun 2013 11:47:15 +0300
+Subject: [PATCH] capes: HDMI slaves need panel settings
+
+---
+ firmware/capes/cape-boneblack-hdmi-00A0.dts | 13 +++++++++++++
+ firmware/capes/cape-boneblack-hdmin-00A0.dts | 13 +++++++++++++
+ 2 files changed, 26 insertions(+)
+
+diff --git a/firmware/capes/cape-boneblack-hdmi-00A0.dts b/firmware/capes/cape-boneblack-hdmi-00A0.dts
+index 5fdbd9e..a312bc1 100644
+--- a/firmware/capes/cape-boneblack-hdmi-00A0.dts
++++ b/firmware/capes/cape-boneblack-hdmi-00A0.dts
+@@ -110,6 +110,19 @@
+ pinctrl-names = "default", "off";
+ pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
+ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
++
++ panel-info {
++ bpp = <16>;
++ ac-bias = <255>;
++ ac-bias-intrpt = <0>;
++ dma-burst-sz = <16>;
++ fdd = <16>;
++ sync-edge = <1>;
++ sync-ctrl = <1>;
++ raster-order = <0>;
++ fifo-th = <0>;
++ invert-pxl-clk;
++ };
+ };
+
+ fb {
+diff --git a/firmware/capes/cape-boneblack-hdmin-00A0.dts b/firmware/capes/cape-boneblack-hdmin-00A0.dts
+index 44ae0ea..e193426 100644
+--- a/firmware/capes/cape-boneblack-hdmin-00A0.dts
++++ b/firmware/capes/cape-boneblack-hdmin-00A0.dts
+@@ -95,6 +95,19 @@
+ pinctrl-names = "default", "off";
+ pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
+ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
++
++ panel-info {
++ bpp = <16>;
++ ac-bias = <255>;
++ ac-bias-intrpt = <0>;
++ dma-burst-sz = <16>;
++ fdd = <16>;
++ sync-edge = <1>;
++ sync-ctrl = <1>;
++ raster-order = <0>;
++ fifo-th = <0>;
++ invert-pxl-clk;
++ };
+ };
+
+ fb {
diff --git a/patches/linux-3.8.13/0625-capes-boneblack-HDMI-capes-have-blacklisted-modes.patch b/patches/linux-3.8.13/0625-capes-boneblack-HDMI-capes-have-blacklisted-modes.patch
new file mode 100644
index 0000000..3ef3b6f
--- /dev/null
+++ b/patches/linux-3.8.13/0625-capes-boneblack-HDMI-capes-have-blacklisted-modes.patch
@@ -0,0 +1,65 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 12 Jun 2013 11:12:26 +0300
+Subject: [PATCH] capes: boneblack HDMI capes have blacklisted modes.
+
+Added a few modes that are known not to work on my end.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ firmware/capes/cape-boneblack-hdmi-00A0.dts | 13 ++++++++++++-
+ firmware/capes/cape-boneblack-hdmin-00A0.dts | 11 +++++++++++
+ 2 files changed, 23 insertions(+), 1 deletion(-)
+
+diff --git a/firmware/capes/cape-boneblack-hdmi-00A0.dts b/firmware/capes/cape-boneblack-hdmi-00A0.dts
+index a312bc1..04b7b54 100644
+--- a/firmware/capes/cape-boneblack-hdmi-00A0.dts
++++ b/firmware/capes/cape-boneblack-hdmi-00A0.dts
+@@ -83,7 +83,7 @@
+ pinctrl-single,pins = <
+ 0x1ac 0x30 /* mcasp0_ahclkx, MODE0 | INPUT */
+ 0x19c 0x02 /* mcasp0_ahclkr, */
+- 0x194 0x10 /* mcasp0_fsx, MODE0 | OUTPUT */
++ 0x194 0x10 /* mcasp0_fsx, MODE0 | OUTPUT */
+ 0x190 0x00 /* mcasp0_aclkr.mcasp0_aclkx, MODE0 | OUTPUT_PULLDOWN */
+ 0x1a8 0x1f /* mcasp0_axr1 GPIO1_27 | OUTPUT | PULLUP */
+ >;
+@@ -111,6 +111,17 @@
+ pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
+ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
+
++ modes-blacklisted =
++ "1920x1080@25",
++ "832x624@75";
++
++ // Enable this when we figure out the modes
++ //
++ // modes-whitelisted =
++ // "1920x1080@24",
++ // "1280x720@50", "1280x720@60",
++ // "720x576@50","720x480@60";
++
+ panel-info {
+ bpp = <16>;
+ ac-bias = <255>;
+diff --git a/firmware/capes/cape-boneblack-hdmin-00A0.dts b/firmware/capes/cape-boneblack-hdmin-00A0.dts
+index e193426..ad55c4d 100644
+--- a/firmware/capes/cape-boneblack-hdmin-00A0.dts
++++ b/firmware/capes/cape-boneblack-hdmin-00A0.dts
+@@ -96,6 +96,17 @@
+ pinctrl-0 = <&nxp_hdmi_bonelt_pins>;
+ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>;
+
++ modes-blacklisted =
++ "1920x1080@25",
++ "832x624@75";
++
++ // Enable this when we figure out the modes
++ //
++ // modes-whitelisted =
++ // "1920x1080@24",
++ // "1280x720@50", "1280x720@60",
++ // "720x576@50","720x480@60";
++
+ panel-info {
+ bpp = <16>;
+ ac-bias = <255>;
diff --git a/patches/linux-3.8.13/0626-capes-LCD7-Fix-definitions.patch b/patches/linux-3.8.13/0626-capes-LCD7-Fix-definitions.patch
new file mode 100644
index 0000000..68e0063
--- /dev/null
+++ b/patches/linux-3.8.13/0626-capes-LCD7-Fix-definitions.patch
@@ -0,0 +1,106 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 12 Jun 2013 21:02:20 +0300
+Subject: [PATCH] capes: LCD7: Fix definitions
+
+LCD7 rev A3/A4 had some pins wrong
+---
+ firmware/capes/BB-BONE-LCD7-01-00A3.dts | 8 ++++----
+ firmware/capes/BB-BONE-LCD7-01-00A4.dts | 11 ++++++-----
+ 2 files changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A3.dts b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+index f5fab09..76a187d 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A3.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+@@ -38,7 +38,7 @@
+ "P8.29", /* lcd: lcd_hsync */
+ "P8.28", /* lcd: lcd_pclk */
+ "P8.30", /* lcd: lcd_ac_bias_en */
+- "P8.20", /* lcd: gpio1_31 */
++ "P9.22", /* lcd: gpio0_2 */
+ "P9.12", /* led: gpio1_28 */
+ "P9.14", /* pwm: ehrpwm1a */
+ "P9.15", /* keys: gpio1_16 */
+@@ -47,7 +47,7 @@
+ "P9.30", /* keys: gpio3_16 */
+ "P9.21", /* keys: gpio0_3 */
+ /* the hardware IP uses */
+- "gpio1_31",
++ "gpio0_2",
+ "gpio1_28",
+ "gpio1_16",
+ "gpio1_17",
+@@ -75,7 +75,7 @@
+
+ bone_lcd7_cape_lcd_pins: pinmux_bone_lcd7_cape_lcd_pins {
+ pinctrl-single,pins = <
+- 0x84 0x07 /* gpmc_csn2.gpio1_31, OUTPUT | MODE7 - AVDD_EN */
++ 0x150 0x07 /* spi0_sclk.gpio0_2, OUTPUT | MODE7 - AVDD_EN */
+ 0xa0 0x08 /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xa3 0x08 /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xa8 0x08 /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+@@ -275,7 +275,7 @@
+ interrupt-parent = <&intc>;
+ interrupts = <36>;
+ ti,hwmods = "lcdc";
+- ti,power-gpio = <&gpio2 31 0x0>;
++ ti,power-gpio = <&gpio1 2 0x0>;
+ ti,allow-non-reduced-blanking-modes;
+ };
+
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A4.dts b/firmware/capes/BB-BONE-LCD7-01-00A4.dts
+index 81553e6..0c3abff 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A4.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A4.dts
+@@ -38,7 +38,7 @@
+ "P8.29", /* lcd: lcd_hsync */
+ "P8.28", /* lcd: lcd_pclk */
+ "P8.30", /* lcd: lcd_ac_bias_en */
+- "P8.20", /* lcd: gpio1_31 */
++ "P9.22", /* lcd: gpio0_2 */
+ "P9.12", /* led: gpio1_28 */
+ "P9.14", /* pwm: ehrpwm1a */
+ "P9.15", /* keys: gpio1_16 */
+@@ -46,13 +46,15 @@
+ "P9.16", /* keys: gpio1_19 */
+ "P9.30", /* keys: gpio3_16 */
+ "P9.21", /* keys: gpio0_3 */
++ "P9.27", /* captouch: gpio3_19 */
+ /* the hardware IP uses */
+- "gpio1_31",
++ "gpio0_2",
+ "gpio1_28",
+ "gpio1_16",
+ "gpio1_17",
+ "gpio1_19",
+ "gpio3_16",
++ "gpio3_19",
+ "gpio0_3",
+ "lcd",
+ "ehrpwm1a";
+@@ -75,7 +77,7 @@
+
+ bone_lcd7_cape_lcd_pins: pinmux_bone_lcd7_cape_lcd_pins {
+ pinctrl-single,pins = <
+- 0x84 0x07 /* gpmc_csn2.gpio1_31, OUTPUT | MODE7 - AVDD_EN */
++ 0x150 0x07 /* spi0_sclk.gpio0_2, OUTPUT | MODE7 - AVDD_EN */
+ 0xa0 0x08 /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xa4 0x08 /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+ 0xa8 0x08 /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */
+@@ -255,7 +257,7 @@
+ interrupt-parent = <&intc>;
+ interrupts = <36>;
+ ti,hwmods = "lcdc";
+- ti,power-gpio = <&gpio2 31 0x0>;
++ ti,power-gpio = <&gpio1 2 0x0>;
+ ti,allow-non-reduced-blanking-modes;
+ };
+
+@@ -277,7 +279,6 @@
+ interrupts = <19 0x0>;
+ atmel,irq-gpio = <&gpio4 19 0>;
+ };
+-
+ };
+ };
+ };
diff --git a/patches/linux-3.8.13/0627-capes-LCD7-Fix-enter-key-pinmux.patch b/patches/linux-3.8.13/0627-capes-LCD7-Fix-enter-key-pinmux.patch
new file mode 100644
index 0000000..018df89
--- /dev/null
+++ b/patches/linux-3.8.13/0627-capes-LCD7-Fix-enter-key-pinmux.patch
@@ -0,0 +1,37 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 12 Jun 2013 22:49:19 +0300
+Subject: [PATCH] capes: LCD7: Fix enter key pinmux
+
+---
+ firmware/capes/BB-BONE-LCD7-01-00A3.dts | 2 +-
+ firmware/capes/BB-BONE-LCD7-01-00A4.dts | 4 +++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A3.dts b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+index 76a187d..8b9cf14 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A3.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+@@ -105,7 +105,7 @@
+ 0x044 0x2f /* KEY_RIGHT gpmc_a1.gpio1_17, INPUT | PULLDIS | MODE7 */
+ 0x04c 0x2f /* KEY_UP gpmc_a3.gpio1_19, INPUT | PULLDIS | MODE7 */
+ 0x198 0x2f /* KEY_DOWN mcasp0_axr0.gpio3_16, INPUT | PULLDIS | MODE7 */
+- 0x070 0x2f /* KEY_ENTER gpmc_wait0.gpio0_3, INPUT | PULLDIS | MODE7 */
++ 0x154 0x2f /* KEY_ENTER spi0_d0.gpio0_3, INPUT | PULLDIS | MODE7 */
+ >;
+ };
+
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A4.dts b/firmware/capes/BB-BONE-LCD7-01-00A4.dts
+index 0c3abff..a23a809 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A4.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A4.dts
+@@ -107,7 +107,9 @@
+ 0x044 0x2f /* KEY_RIGHT gpmc_a1.gpio1_17, INPUT | PULLDIS | MODE7 */
+ 0x04c 0x2f /* KEY_UP gpmc_a3.gpio1_19, INPUT | PULLDIS | MODE7 */
+ 0x198 0x2f /* KEY_DOWN mcasp0_axr0.gpio3_16, INPUT | PULLDIS | MODE7 */
+- 0x070 0x2f /* KEY_ENTER gpmc_wait0.gpio0_3, INPUT | PULLDIS | MODE7 */
++ 0x154 0x2f /* KEY_ENTER spi0_d0.gpio0_3, INPUT | PULLDIS | MODE7 */
++
++ /* the next one should be in the tsc driver */
+ 0x1a4 0x2f /* TSC_INTn mcasp0_fsr.gpio3_19, INPUT | PULLDIS | MODE7 */
+ >;
+ };
diff --git a/patches/linux-3.8.13/0628-Fix-timings-for-LCD3-cape.patch b/patches/linux-3.8.13/0628-Fix-timings-for-LCD3-cape.patch
new file mode 100644
index 0000000..d79b898
--- /dev/null
+++ b/patches/linux-3.8.13/0628-Fix-timings-for-LCD3-cape.patch
@@ -0,0 +1,41 @@
+From: David Anders <danders@circuitco.com>
+Date: Thu, 13 Jun 2013 08:37:19 +0200
+Subject: [PATCH] Fix timings for LCD3 cape
+
+In the 3.2 kernel using the da8xx lcdc fb, the HSW, HFP, and HBP are written to the lcdc registers directly as entered. i.e. if HSW=47 , then 47 is written to the register and the value that is generated is the register value plus one (total of 48 clocks).
+
+with the 3.8 kernel using the DRM driver, the code subtracts one from the set value before writing it to the register, i.e. if HSW=47, then 46 is written to the register and the value that is generated is the register value plus one (total of 47 clocks).
+
+specifically with the LCD3 board, the lcd panel does not use data enable as a timing signal. it specifically counts the number of vertical clocks and horizontal clocks to determine data start points. the lcd panel expects for the sum of the HSW and HBP to be 70 pixel clocks. currently it is 68. this is the root cause of the color shift and poor image quality....
+
+the HSW, HFP, and HBP for all three lcd panels needs to be incremented by one.
+---
+ firmware/capes/cape-bone-lcd3-00A2.dts | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/firmware/capes/cape-bone-lcd3-00A2.dts b/firmware/capes/cape-bone-lcd3-00A2.dts
+index c2cdedc..85085b9 100644
+--- a/firmware/capes/cape-bone-lcd3-00A2.dts
++++ b/firmware/capes/cape-bone-lcd3-00A2.dts
+@@ -245,16 +245,17 @@
+ sync-ctrl = <1>;
+ raster-order = <0>;
+ fifo-th = <0>;
++ invert-pxl-clk;
+ };
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: 320x240 {
+ hactive = <320>;
+ vactive = <240>;
+- hback-porch = <21>;
+- hfront-porch = <58>;
+- hsync-len = <47>;
+- vback-porch = <11>;
++ hback-porch = <22>;
++ hfront-porch = <59>;
++ hsync-len = <48>;
++ vback-porch = <12>;
+ vfront-porch = <23>;
+ vsync-len = <2>;
+ clock-frequency = <8000000>;
diff --git a/patches/linux-3.8.13/0629-capes-LCD-capes-updated-with-timing-fixes.patch b/patches/linux-3.8.13/0629-capes-LCD-capes-updated-with-timing-fixes.patch
new file mode 100644
index 0000000..d3dd022
--- /dev/null
+++ b/patches/linux-3.8.13/0629-capes-LCD-capes-updated-with-timing-fixes.patch
@@ -0,0 +1,183 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 13 Jun 2013 12:24:42 +0300
+Subject: [PATCH] capes: LCD capes updated with timing fixes
+
+---
+ firmware/capes/BB-BONE-LCD4-01-00A0.dts | 8 ++++----
+ firmware/capes/BB-BONE-LCD4-01-00A1.dts | 8 ++++----
+ firmware/capes/BB-BONE-LCD7-01-00A2.dts | 8 ++++----
+ firmware/capes/BB-BONE-LCD7-01-00A3.dts | 8 ++++----
+ firmware/capes/BB-BONE-LCD7-01-00A4.dts | 9 +++++----
+ firmware/capes/cape-bone-lcd3-00A0.dts | 13 ++++++++-----
+ firmware/capes/cape-bone-lcd3-00A2.dts | 5 ++++-
+ 7 files changed, 33 insertions(+), 26 deletions(-)
+
+diff --git a/firmware/capes/BB-BONE-LCD4-01-00A0.dts b/firmware/capes/BB-BONE-LCD4-01-00A0.dts
+index 4b6f3cc..3bef8b6 100644
+--- a/firmware/capes/BB-BONE-LCD4-01-00A0.dts
++++ b/firmware/capes/BB-BONE-LCD4-01-00A0.dts
+@@ -166,10 +166,10 @@
+ timing0: 480x272 {
+ hactive = <480>;
+ vactive = <272>;
+- hback-porch = <43>;
+- hfront-porch = <8>;
+- hsync-len = <4>;
+- vback-porch = <12>;
++ hback-porch = <44>;
++ hfront-porch = <9>;
++ hsync-len = <5>;
++ vback-porch = <13>;
+ vfront-porch = <4>;
+ vsync-len = <10>;
+ clock-frequency = <9000000>;
+diff --git a/firmware/capes/BB-BONE-LCD4-01-00A1.dts b/firmware/capes/BB-BONE-LCD4-01-00A1.dts
+index b424c09..4d9fceb 100644
+--- a/firmware/capes/BB-BONE-LCD4-01-00A1.dts
++++ b/firmware/capes/BB-BONE-LCD4-01-00A1.dts
+@@ -253,10 +253,10 @@
+ timing0: 480x272 {
+ hactive = <480>;
+ vactive = <272>;
+- hback-porch = <43>;
+- hfront-porch = <8>;
+- hsync-len = <4>;
+- vback-porch = <12>;
++ hback-porch = <44>;
++ hfront-porch = <9>;
++ hsync-len = <5>;
++ vback-porch = <13>;
+ vfront-porch = <4>;
+ vsync-len = <10>;
+ clock-frequency = <9000000>;
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A2.dts b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
+index 77ef5ec..3b834ab 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A2.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
+@@ -254,10 +254,10 @@
+ timing0: 800x480 {
+ hactive = <800>;
+ vactive = <480>;
+- hback-porch = <39>;
+- hfront-porch = <39>;
+- hsync-len = <47>;
+- vback-porch = <29>;
++ hback-porch = <40>;
++ hfront-porch = <40>;
++ hsync-len = <48>;
++ vback-porch = <30>;
+ vfront-porch = <13>;
+ vsync-len = <2>;
+ clock-frequency = <30000000>;
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A3.dts b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+index 8b9cf14..043ed2b 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A3.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+@@ -256,10 +256,10 @@
+ timing0: 800x480 {
+ hactive = <800>;
+ vactive = <480>;
+- hback-porch = <39>;
+- hfront-porch = <39>;
+- hsync-len = <47>;
+- vback-porch = <29>;
++ hback-porch = <40>;
++ hfront-porch = <40>;
++ hsync-len = <48>;
++ vback-porch = <30>;
+ vfront-porch = <13>;
+ vsync-len = <2>;
+ clock-frequency = <30000000>;
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A4.dts b/firmware/capes/BB-BONE-LCD7-01-00A4.dts
+index a23a809..ae4941e 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A4.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A4.dts
+@@ -234,16 +234,17 @@
+ sync-ctrl = <1>;
+ raster-order = <0>;
+ fifo-th = <0>;
++ invert-pxl-clk;
+ };
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: 800x480 {
+ hactive = <800>;
+ vactive = <480>;
+- hback-porch = <39>;
+- hfront-porch = <39>;
+- hsync-len = <47>;
+- vback-porch = <29>;
++ hback-porch = <40>;
++ hfront-porch = <40>;
++ hsync-len = <48>;
++ vback-porch = <30>;
+ vfront-porch = <13>;
+ vsync-len = <2>;
+ clock-frequency = <30000000>;
+diff --git a/firmware/capes/cape-bone-lcd3-00A0.dts b/firmware/capes/cape-bone-lcd3-00A0.dts
+index a2f8b35..8628219 100644
+--- a/firmware/capes/cape-bone-lcd3-00A0.dts
++++ b/firmware/capes/cape-bone-lcd3-00A0.dts
+@@ -88,7 +88,8 @@
+ 0xe0 0x00 /* lcd_vsync.lcd_vsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+ 0xe4 0x00 /* lcd_hsync.lcd_hsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+ 0xe8 0x00 /* lcd_pclk.lcd_pclk, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+- 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ // 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0xec 0x07 /* lcd_ac_bias_en.gpio2_25 OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT */
+ >;
+ };
+
+@@ -236,16 +237,17 @@
+ sync-ctrl = <1>;
+ raster-order = <0>;
+ fifo-th = <0>;
++ invert-pxl-clk;
+ };
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: 320x240 {
+ hactive = <320>;
+ vactive = <240>;
+- hback-porch = <21>;
+- hfront-porch = <58>;
+- hsync-len = <47>;
+- vback-porch = <11>;
++ hback-porch = <22>;
++ hfront-porch = <59>;
++ hsync-len = <48>;
++ vback-porch = <12>;
+ vfront-porch = <23>;
+ vsync-len = <2>;
+ clock-frequency = <8000000>;
+@@ -261,6 +263,7 @@
+ interrupt-parent = <&intc>;
+ interrupts = <36>;
+ ti,hwmods = "lcdc";
++ ti,power-gpio = <&gpio3 25 0>;
+ };
+
+ };
+diff --git a/firmware/capes/cape-bone-lcd3-00A2.dts b/firmware/capes/cape-bone-lcd3-00A2.dts
+index 85085b9..ceee1f5 100644
+--- a/firmware/capes/cape-bone-lcd3-00A2.dts
++++ b/firmware/capes/cape-bone-lcd3-00A2.dts
+@@ -91,7 +91,9 @@
+ 0xe0 0x00 /* lcd_vsync.lcd_vsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+ 0xe4 0x00 /* lcd_hsync.lcd_hsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+ 0xe8 0x00 /* lcd_pclk.lcd_pclk, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
+- 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ // 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */
++ 0xec 0x07 /* lcd_ac_bias_en.gpio2_25 OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT */
++
+ >;
+ };
+
+@@ -271,6 +273,7 @@
+ interrupt-parent = <&intc>;
+ interrupts = <36>;
+ ti,hwmods = "lcdc";
++ ti,power-gpio = <&gpio3 25 0>;
+ };
+
+ };
diff --git a/patches/linux-3.8.13/0630-Fix-mmc2-being-enabled-when-eMMC-is-disabled.patch b/patches/linux-3.8.13/0630-Fix-mmc2-being-enabled-when-eMMC-is-disabled.patch
new file mode 100644
index 0000000..2ac70ce
--- /dev/null
+++ b/patches/linux-3.8.13/0630-Fix-mmc2-being-enabled-when-eMMC-is-disabled.patch
@@ -0,0 +1,22 @@
+From: Bas Laarhoven <sjml@xs4all.nl>
+Date: Mon, 10 Jun 2013 13:53:35 +0200
+Subject: [PATCH] Fix mmc2 being enabled when eMMC is disabled.
+
+Signed-off-by: Bas Laarhoven <sjml@xs4all.nl>
+---
+ arch/arm/boot/dts/am335x-boneblack.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts
+index 1545cca..a7eb55b 100644
+--- a/arch/arm/boot/dts/am335x-boneblack.dts
++++ b/arch/arm/boot/dts/am335x-boneblack.dts
+@@ -46,7 +46,7 @@
+ vmmc-supply = <&vmmcsd_fixed>;
+ bus-width = <8>;
+ ti,non-removable;
+- status = "okay";
++ status = "disabled";
+
+ reset = <&rstctl 0 0>;
+ reset-names = "eMMC_RSTn-CONSUMER";
diff --git a/patches/linux-3.8.13/0631-capes-LCD7-fix-vsync-len-off-by-one.patch b/patches/linux-3.8.13/0631-capes-LCD7-fix-vsync-len-off-by-one.patch
new file mode 100644
index 0000000..6ddab82
--- /dev/null
+++ b/patches/linux-3.8.13/0631-capes-LCD7-fix-vsync-len-off-by-one.patch
@@ -0,0 +1,49 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 13 Jun 2013 18:43:27 +0300
+Subject: [PATCH] capes: LCD7: fix vsync-len off by one
+
+---
+ firmware/capes/BB-BONE-LCD7-01-00A2.dts | 2 +-
+ firmware/capes/BB-BONE-LCD7-01-00A3.dts | 2 +-
+ firmware/capes/BB-BONE-LCD7-01-00A4.dts | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A2.dts b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
+index 3b834ab..688e7a1 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A2.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
+@@ -259,7 +259,7 @@
+ hsync-len = <48>;
+ vback-porch = <30>;
+ vfront-porch = <13>;
+- vsync-len = <2>;
++ vsync-len = <3>;
+ clock-frequency = <30000000>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A3.dts b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+index 043ed2b..43a4a22 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A3.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+@@ -261,7 +261,7 @@
+ hsync-len = <48>;
+ vback-porch = <30>;
+ vfront-porch = <13>;
+- vsync-len = <2>;
++ vsync-len = <3>;
+ clock-frequency = <30000000>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A4.dts b/firmware/capes/BB-BONE-LCD7-01-00A4.dts
+index ae4941e..2d0ed3f 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A4.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A4.dts
+@@ -246,7 +246,7 @@
+ hsync-len = <48>;
+ vback-porch = <30>;
+ vfront-porch = <13>;
+- vsync-len = <2>;
++ vsync-len = <3>;
+ clock-frequency = <30000000>;
+ hsync-active = <0>;
+ vsync-active = <0>;
diff --git a/patches/linux-3.8.13/0632-LCD-capes-set-default-brightness-to-100.patch b/patches/linux-3.8.13/0632-LCD-capes-set-default-brightness-to-100.patch
new file mode 100644
index 0000000..98875b7
--- /dev/null
+++ b/patches/linux-3.8.13/0632-LCD-capes-set-default-brightness-to-100.patch
@@ -0,0 +1,106 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Thu, 20 Jun 2013 10:54:55 -0400
+Subject: [PATCH] LCD capes: set default brightness to 100%
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ firmware/capes/BB-BONE-LCD4-01-00A1.dts | 2 +-
+ firmware/capes/BB-BONE-LCD7-01-00A2.dts | 2 +-
+ firmware/capes/BB-BONE-LCD7-01-00A3.dts | 2 +-
+ firmware/capes/BB-BONE-LCD7-01-00A4.dts | 2 +-
+ firmware/capes/cape-bone-adafruit-lcd-00A0.dts | 2 +-
+ firmware/capes/cape-bone-hexy-00A0.dts | 2 +-
+ firmware/capes/cape-bone-lcd3-00A2.dts | 2 +-
+ 7 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/firmware/capes/BB-BONE-LCD4-01-00A1.dts b/firmware/capes/BB-BONE-LCD4-01-00A1.dts
+index 4d9fceb..633a509 100644
+--- a/firmware/capes/BB-BONE-LCD4-01-00A1.dts
++++ b/firmware/capes/BB-BONE-LCD4-01-00A1.dts
+@@ -140,7 +140,7 @@
+ pwms = <&ehrpwm1 0 500000 0>;
+ pwm-names = "LCD4";
+ brightness-levels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100>;
+- default-brightness-level = <50>; /* index to the array above */
++ default-brightness-level = <101>; /* index to the array above */
+ status = "okay";
+ };
+
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A2.dts b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
+index 688e7a1..03645ad 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A2.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A2.dts
+@@ -142,7 +142,7 @@
+ pwms = <&ehrpwm1 0 500000 0>;
+ pwm-names = "LCD7";
+ brightness-levels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100>;
+- default-brightness-level = <50>; /* index to the array above */
++ default-brightness-level = <101>; /* index to the array above */
+ };
+
+ tscadc {
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A3.dts b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+index 43a4a22..b90e7c2 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A3.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+@@ -144,7 +144,7 @@
+ pwms = <&ehrpwm1 0 500000 0>;
+ pwm-names = "LCD7";
+ brightness-levels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100>;
+- default-brightness-level = <50>; /* index to the array above */
++ default-brightness-level = <101>; /* index to the array above */
+ };
+
+ tscadc {
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A4.dts b/firmware/capes/BB-BONE-LCD7-01-00A4.dts
+index 2d0ed3f..3455596 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A4.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A4.dts
+@@ -149,7 +149,7 @@
+ pwms = <&ehrpwm1 0 500000 0>;
+ pwm-names = "LCD7";
+ brightness-levels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100>;
+- default-brightness-level = <50>; /* index to the array above */
++ default-brightness-level = <101>; /* index to the array above */
+ };
+
+ gpio-leds-cape-lcd7 {
+diff --git a/firmware/capes/cape-bone-adafruit-lcd-00A0.dts b/firmware/capes/cape-bone-adafruit-lcd-00A0.dts
+index 8c0343b..8422bb5 100644
+--- a/firmware/capes/cape-bone-adafruit-lcd-00A0.dts
++++ b/firmware/capes/cape-bone-adafruit-lcd-00A0.dts
+@@ -134,7 +134,7 @@
+
+ pwm-names = "st7735fb";
+ brightness-levels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100>;
+- default-brightness-level = <50>; /* index to the array above */
++ default-brightness-level = <101>; /* index to the array above */
+ };
+ };
+ };
+diff --git a/firmware/capes/cape-bone-hexy-00A0.dts b/firmware/capes/cape-bone-hexy-00A0.dts
+index f02abd7..358f5e1 100644
+--- a/firmware/capes/cape-bone-hexy-00A0.dts
++++ b/firmware/capes/cape-bone-hexy-00A0.dts
+@@ -119,7 +119,7 @@
+
+ pwm-names = "st7735fb";
+ brightness-levels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100>;
+- default-brightness-level = <50>; /* index to the array above */
++ default-brightness-level = <101>; /* index to the array above */
+ };
+ };
+ };
+diff --git a/firmware/capes/cape-bone-lcd3-00A2.dts b/firmware/capes/cape-bone-lcd3-00A2.dts
+index ceee1f5..f285196 100644
+--- a/firmware/capes/cape-bone-lcd3-00A2.dts
++++ b/firmware/capes/cape-bone-lcd3-00A2.dts
+@@ -140,7 +140,7 @@
+ pwms = <&ehrpwm1 0 500000 0>;
+ pwm-names = "LCD3";
+ brightness-levels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100>;
+- default-brightness-level = <50>; /* index to the array above */
++ default-brightness-level = <101>; /* index to the array above */
+ status = "okay";
+ };
+
diff --git a/patches/linux-3.8.13/0633-lcd-capes-update-adc-channels.patch b/patches/linux-3.8.13/0633-lcd-capes-update-adc-channels.patch
new file mode 100644
index 0000000..9e09798
--- /dev/null
+++ b/patches/linux-3.8.13/0633-lcd-capes-update-adc-channels.patch
@@ -0,0 +1,50 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Mon, 8 Jul 2013 12:56:56 +0200
+Subject: [PATCH] lcd capes: update adc channels
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ firmware/capes/BB-BONE-LCD4-01-00A0.dts | 2 +-
+ firmware/capes/BB-BONE-LCD4-01-00A1.dts | 2 +-
+ firmware/capes/BB-BONE-LCD7-01-00A3.dts | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/firmware/capes/BB-BONE-LCD4-01-00A0.dts b/firmware/capes/BB-BONE-LCD4-01-00A0.dts
+index 3bef8b6..f355b06 100644
+--- a/firmware/capes/BB-BONE-LCD4-01-00A0.dts
++++ b/firmware/capes/BB-BONE-LCD4-01-00A0.dts
+@@ -124,7 +124,7 @@
+ };
+
+ adc {
+- ti,adc-channels = <4>;
++ ti,adc-channels = <4 5 6 7>;
+ };
+ };
+
+diff --git a/firmware/capes/BB-BONE-LCD4-01-00A1.dts b/firmware/capes/BB-BONE-LCD4-01-00A1.dts
+index 633a509..19f52fc 100644
+--- a/firmware/capes/BB-BONE-LCD4-01-00A1.dts
++++ b/firmware/capes/BB-BONE-LCD4-01-00A1.dts
+@@ -161,7 +161,7 @@
+ };
+
+ adc {
+- ti,adc-channels = <4>;
++ ti,adc-channels = <4 5 6 7>;
+ };
+ };
+
+diff --git a/firmware/capes/BB-BONE-LCD7-01-00A3.dts b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+index b90e7c2..744fc79 100644
+--- a/firmware/capes/BB-BONE-LCD7-01-00A3.dts
++++ b/firmware/capes/BB-BONE-LCD7-01-00A3.dts
+@@ -164,7 +164,7 @@
+ };
+
+ adc {
+- ti,adc-channels = <4>;
++ ti,adc-channels = <4 5 6 7>;
+ };
+ };
+
diff --git a/patches/linux-3.8.13/0634-bone-renamed-adafruit-RTC-cape.patch b/patches/linux-3.8.13/0634-bone-renamed-adafruit-RTC-cape.patch
new file mode 100644
index 0000000..a27494e
--- /dev/null
+++ b/patches/linux-3.8.13/0634-bone-renamed-adafruit-RTC-cape.patch
@@ -0,0 +1,177 @@
+From: Matt Ranostay <mranostay@gmail.com>
+Date: Sat, 29 Jun 2013 23:51:36 +0000
+Subject: [PATCH] bone: renamed adafruit RTC cape
+
+rename RTC protocape to a more consistent naming
+
+Signed-off-by: Matt Ranostay <mranostay@gmail.com>
+---
+ arch/arm/boot/dts/am335x-bone-common.dtsi | 2 +-
+ firmware/Makefile | 4 +-
+ firmware/capes/BB-BONE-RTC-00A0.dts | 57 ++++++++++++++++++++++++
+ firmware/capes/cape-bone-adafruit-rtc-00A0.dts | 57 ------------------------
+ 4 files changed, 60 insertions(+), 60 deletions(-)
+ create mode 100644 firmware/capes/BB-BONE-RTC-00A0.dts
+ delete mode 100644 firmware/capes/cape-bone-adafruit-rtc-00A0.dts
+
+diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
+index aa95810..ff4b5d2 100644
+--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
+@@ -326,7 +326,7 @@
+ part-number = "BB-BONE-RTC-01";
+ version@00A0 {
+ version = "00A0";
+- dtbo = "cape-bone-adafruit-rtc-00A0.dtbo";
++ dtbo = "BB-BONE-RTC-00A0.dtbo";
+ };
+ };
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index 182de29..e6d178e 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -155,6 +155,7 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ BB-BONE-LCD7-01-00A4.dtbo \
+ BB-BONE-eMMC1-01-00A0.dtbo \
+ BB-BONE-GPEVT-00A0.dtbo \
++ BB-BONE-RTC-00A0.dtbo \
+ BB-BONE-RS232-00A0.dtbo \
+ BB-BONE-SERL-01-00A1.dtbo \
+ cape-bone-iio-00A0.dtbo \
+@@ -186,8 +187,7 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ BB-BONE-RST2-00A0.dtbo \
+ BB-BONE-CAM3-01-00A2.dtbo \
+ TT3201-001-01.dtbo \
+- BB-BONE-SERL-03-00A1.dtbo \
+- BB-BONE-PRU-01-00A0.dtbo
++ BB-BONE-SERL-03-00A1.dtbo
+
+ # the geiger cape
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE_GEIGER) += \
+diff --git a/firmware/capes/BB-BONE-RTC-00A0.dts b/firmware/capes/BB-BONE-RTC-00A0.dts
+new file mode 100644
+index 0000000..35344fd
+--- /dev/null
++++ b/firmware/capes/BB-BONE-RTC-00A0.dts
+@@ -0,0 +1,57 @@
++/*
++* Copyright (C) 2013 Matt Ranostay <mranostay@gmail.com>
++*
++* This program is free software; you can redistribute it and/or modify
++* it under the terms of the GNU General Public License version 2 as
++* published by the Free Software Foundation.
++*/
++/dts-v1/;
++/plugin/;
++
++/*
++ * Pin assignments
++ *
++ * Module Connector
++ * SCL -> P9.19
++ * SDA <- P9.20
++ * SQW <- NC
++ *
++ */
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++ part-number = "BB-BONE-RTC-01";
++ version = "00A0";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P8.19", /* bl: ehrpwm2A */
++ "P9.27", /* lcd: gpio3_19 */
++ "P9.25", /* lcd: gpio3_21 */
++ "P9.31", /* spi: spi1_sclk */
++ "P9.29", /* spi: spi1_d0 */
++ "P9.30", /* spi: spi1_d1 */
++ "P9.28", /* spi: spi1_cs0 */
++ /* the hardware IP uses */
++ "gpio3_19",
++ "gpio3_21",
++ "ehrpwm2A",
++ "spi1";
++
++ fragment@0 {
++ target = <&i2c2>;
++
++ __overlay__ {
++ /* shut up DTC warnings */
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* DS1307 RTC module */
++ rtc@68 {
++ compatible = "dallas,ds1307";
++ reg = <0x68>;
++ };
++ };
++ };
++};
+diff --git a/firmware/capes/cape-bone-adafruit-rtc-00A0.dts b/firmware/capes/cape-bone-adafruit-rtc-00A0.dts
+deleted file mode 100644
+index 35344fd..0000000
+--- a/firmware/capes/cape-bone-adafruit-rtc-00A0.dts
++++ /dev/null
+@@ -1,57 +0,0 @@
+-/*
+-* Copyright (C) 2013 Matt Ranostay <mranostay@gmail.com>
+-*
+-* This program is free software; you can redistribute it and/or modify
+-* it under the terms of the GNU General Public License version 2 as
+-* published by the Free Software Foundation.
+-*/
+-/dts-v1/;
+-/plugin/;
+-
+-/*
+- * Pin assignments
+- *
+- * Module Connector
+- * SCL -> P9.19
+- * SDA <- P9.20
+- * SQW <- NC
+- *
+- */
+-
+-/ {
+- compatible = "ti,beaglebone", "ti,beaglebone-black";
+- part-number = "BB-BONE-RTC-01";
+- version = "00A0";
+-
+- /* state the resources this cape uses */
+- exclusive-use =
+- /* the pin header uses */
+- "P8.19", /* bl: ehrpwm2A */
+- "P9.27", /* lcd: gpio3_19 */
+- "P9.25", /* lcd: gpio3_21 */
+- "P9.31", /* spi: spi1_sclk */
+- "P9.29", /* spi: spi1_d0 */
+- "P9.30", /* spi: spi1_d1 */
+- "P9.28", /* spi: spi1_cs0 */
+- /* the hardware IP uses */
+- "gpio3_19",
+- "gpio3_21",
+- "ehrpwm2A",
+- "spi1";
+-
+- fragment@0 {
+- target = <&i2c2>;
+-
+- __overlay__ {
+- /* shut up DTC warnings */
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- /* DS1307 RTC module */
+- rtc@68 {
+- compatible = "dallas,ds1307";
+- reg = <0x68>;
+- };
+- };
+- };
+-};
diff --git a/patches/linux-3.8.13/0635-bone-add-PPS-to-BB-BONE-RTC-cape.patch b/patches/linux-3.8.13/0635-bone-add-PPS-to-BB-BONE-RTC-cape.patch
new file mode 100644
index 0000000..9e4c577
--- /dev/null
+++ b/patches/linux-3.8.13/0635-bone-add-PPS-to-BB-BONE-RTC-cape.patch
@@ -0,0 +1,79 @@
+From: Matt Ranostay <mranostay@gmail.com>
+Date: Sat, 29 Jun 2013 23:51:37 +0000
+Subject: [PATCH] bone: add PPS to BB-BONE-RTC cape
+
+Added PPS input from SQW pin on the DS1307
+
+Signed-off-by: Matt Ranostay <mranostay@gmail.com>
+---
+ firmware/capes/BB-BONE-RTC-00A0.dts | 43 ++++++++++++++++++++++++-----------
+ 1 file changed, 30 insertions(+), 13 deletions(-)
+
+diff --git a/firmware/capes/BB-BONE-RTC-00A0.dts b/firmware/capes/BB-BONE-RTC-00A0.dts
+index 35344fd..e90c12b 100644
+--- a/firmware/capes/BB-BONE-RTC-00A0.dts
++++ b/firmware/capes/BB-BONE-RTC-00A0.dts
+@@ -14,7 +14,7 @@
+ * Module Connector
+ * SCL -> P9.19
+ * SDA <- P9.20
+- * SQW <- NC
++ * SQW/PPS <- P9.15
+ *
+ */
+
+@@ -26,20 +26,22 @@
+ /* state the resources this cape uses */
+ exclusive-use =
+ /* the pin header uses */
+- "P8.19", /* bl: ehrpwm2A */
+- "P9.27", /* lcd: gpio3_19 */
+- "P9.25", /* lcd: gpio3_21 */
+- "P9.31", /* spi: spi1_sclk */
+- "P9.29", /* spi: spi1_d0 */
+- "P9.30", /* spi: spi1_d1 */
+- "P9.28", /* spi: spi1_cs0 */
+- /* the hardware IP uses */
+- "gpio3_19",
+- "gpio3_21",
+- "ehrpwm2A",
+- "spi1";
++ "P9.15"; /*gpio1_16 */
++
+
+ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++ pps_pins: pinmux_pps_pins {
++ pinctrl-single,pins = <
++ 0x040 0x27 /* gpmc_a0.gpio1_16, INPUT | PULLDIS | MODE7 */
++ >;
++ };
++ };
++ };
++
++
++ fragment@1 {
+ target = <&i2c2>;
+
+ __overlay__ {
+@@ -54,4 +56,19 @@
+ };
+ };
+ };
++
++ fragment@2 {
++ target = <&ocp>;
++ __overlay__ {
++ pps {
++ compatible = "pps-gpio";
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pps_pins>;
++
++ gpios = <&gpio2 16 0>;
++ assert-falling-edge;
++ };
++ };
++ };
+ };
diff --git a/patches/linux-3.8.13/0636-firmware-remove-rule-for-cape-bone-adafruit-lcd-00A0.patch b/patches/linux-3.8.13/0636-firmware-remove-rule-for-cape-bone-adafruit-lcd-00A0.patch
new file mode 100644
index 0000000..4f3982e
--- /dev/null
+++ b/patches/linux-3.8.13/0636-firmware-remove-rule-for-cape-bone-adafruit-lcd-00A0.patch
@@ -0,0 +1,21 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Wed, 10 Jul 2013 14:32:25 +0200
+Subject: [PATCH] firmware: remove rule for cape-bone-adafruit-lcd-00A0
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ firmware/Makefile | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index e6d178e..cdfc800 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -140,7 +140,6 @@ fw-shipped-$(CONFIG_YAM) += yam/1200.bin yam/9600.bin
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ cape-bone-2g-emmc1.dtbo \
+ cape-bone-adafruit-lcd-00A0.dtbo \
+- cape-bone-adafruit-rtc-00A0.dtbo \
+ cape-bone-dvi-00A0.dtbo \
+ cape-bone-dvi-00A1.dtbo \
+ cape-bone-dvi-00A2.dtbo \
diff --git a/patches/linux-3.8.13/0637-tps65217-Enable-KEY_POWER-press-on-AC-loss-PWR_BUT.patch b/patches/linux-3.8.13/0637-tps65217-Enable-KEY_POWER-press-on-AC-loss-PWR_BUT.patch
new file mode 100644
index 0000000..fb322ba
--- /dev/null
+++ b/patches/linux-3.8.13/0637-tps65217-Enable-KEY_POWER-press-on-AC-loss-PWR_BUT.patch
@@ -0,0 +1,201 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 27 May 2013 17:14:23 +0300
+Subject: [PATCH] tps65217: Enable KEY_POWER press on AC loss / PWR_BUT
+
+Adaption of the original patch by Andrew Bradford <andrew.bradford@omni-id.com>
+Some minor devm_* changes and DT support.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ drivers/mfd/tps65217.c | 121 +++++++++++++++++++++++++++++++++++++++++-
+ include/linux/mfd/tps65217.h | 6 +++
+ 2 files changed, 125 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c
+index b8f4864..818f2cd 100644
+--- a/drivers/mfd/tps65217.c
++++ b/drivers/mfd/tps65217.c
+@@ -26,6 +26,9 @@
+ #include <linux/err.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
++#include <linux/of_irq.h>
++#include <linux/of_gpio.h>
++#include <linux/interrupt.h>
+
+ #include <linux/mfd/core.h>
+ #include <linux/mfd/tps65217.h>
+@@ -153,6 +156,82 @@ static const struct of_device_id tps65217_of_match[] = {
+ { /* sentinel */ },
+ };
+
++static irqreturn_t tps65217_irq(int irq, void *irq_data)
++{
++ struct tps65217 *tps = irq_data;
++ unsigned int int_reg = 0, status_reg = 0;
++
++ tps65217_reg_read(tps, TPS65217_REG_INT, &int_reg);
++ tps65217_reg_read(tps, TPS65217_REG_STATUS, &status_reg);
++ if (status_reg)
++ dev_dbg(tps->dev, "status now: 0x%X\n", status_reg);
++
++ if (!int_reg)
++ return IRQ_NONE;
++
++ if (int_reg & TPS65217_INT_PBI) {
++ /* Handle push button */
++ dev_dbg(tps->dev, "power button status change\n");
++ input_report_key(tps->pwr_but, KEY_POWER,
++ status_reg & TPS65217_STATUS_PB);
++ input_sync(tps->pwr_but);
++ }
++ if (int_reg & TPS65217_INT_ACI) {
++ /* Handle AC power status change */
++ dev_dbg(tps->dev, "AC power status change\n");
++ /* Press KEY_POWER when AC not present */
++ input_report_key(tps->pwr_but, KEY_POWER,
++ ~status_reg & TPS65217_STATUS_ACPWR);
++ input_sync(tps->pwr_but);
++ }
++ if (int_reg & TPS65217_INT_USBI) {
++ /* Handle USB power status change */
++ dev_dbg(tps->dev, "USB power status change\n");
++ }
++
++ return IRQ_HANDLED;
++}
++
++static int tps65217_probe_pwr_but(struct tps65217 *tps)
++{
++ int ret;
++ unsigned int int_reg;
++
++ tps->pwr_but = devm_input_allocate_device(tps->dev);
++ if (!tps->pwr_but) {
++ dev_err(tps->dev,
++ "Failed to allocated pwr_but input device\n");
++ return -ENOMEM;
++ }
++
++ tps->pwr_but->evbit[0] = BIT_MASK(EV_KEY);
++ tps->pwr_but->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
++ tps->pwr_but->name = "tps65217_pwr_but";
++ ret = input_register_device(tps->pwr_but);
++ if (ret) {
++ /* NOTE: devm managed device */
++ dev_err(tps->dev, "Failed to register button device\n");
++ return ret;
++ }
++ ret = devm_request_threaded_irq(tps->dev,
++ tps->irq, NULL, tps65217_irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
++ "tps65217", tps);
++ if (ret != 0) {
++ dev_err(tps->dev, "Failed to request IRQ %d\n", tps->irq);
++ return ret;
++ }
++
++ /* enable the power button interrupt */
++ ret = tps65217_reg_read(tps, TPS65217_REG_INT, &int_reg);
++ if (ret < 0) {
++ dev_err(tps->dev, "Failed to read INT reg\n");
++ return ret;
++ }
++ int_reg &= ~TPS65217_INT_PBM;
++ tps65217_reg_write(tps, TPS65217_REG_INT, int_reg, TPS65217_PROTECT_NONE);
++ return 0;
++}
++
+ static int tps65217_probe(struct i2c_client *client,
+ const struct i2c_device_id *ids)
+ {
+@@ -160,10 +239,13 @@ static int tps65217_probe(struct i2c_client *client,
+ unsigned int version;
+ unsigned int chip_id = ids->driver_data;
+ const struct of_device_id *match;
++ struct device_node *node;
+ bool status_off = false;
++ int irq = -1, irq_gpio = -1;
+ int ret;
+
+- if (client->dev.of_node) {
++ node = client->dev.of_node;
++ if (node) {
+ match = of_match_device(tps65217_of_match, &client->dev);
+ if (!match) {
+ dev_err(&client->dev,
+@@ -171,8 +253,31 @@ static int tps65217_probe(struct i2c_client *client,
+ return -EINVAL;
+ }
+ chip_id = (unsigned int)match->data;
+- status_off = of_property_read_bool(client->dev.of_node,
++ status_off = of_property_read_bool(node,
+ "ti,pmic-shutdown-controller");
++
++ /* at first try to get irq via OF method */
++ irq = irq_of_parse_and_map(node, 0);
++ if (irq <= 0) {
++ irq = -1;
++ irq_gpio = of_get_named_gpio(node, "irq-gpio", 0);
++ if (irq_gpio >= 0) {
++ /* valid gpio; convert to irq */
++ ret = devm_gpio_request_one(&client->dev,
++ irq_gpio, GPIOF_DIR_IN,
++ "tps65217-gpio-irq");
++ if (ret != 0)
++ dev_warn(&client->dev, "Failed to "
++ "request gpio #%d\n", irq_gpio);
++ irq = gpio_to_irq(irq_gpio);
++ if (irq <= 0) {
++ dev_warn(&client->dev, "Failed to "
++ "convert gpio #%d to irq\n",
++ irq_gpio);
++ irq = -1;
++ }
++ }
++ }
+ }
+
+ if (!chip_id) {
+@@ -196,6 +301,18 @@ static int tps65217_probe(struct i2c_client *client,
+ return ret;
+ }
+
++ tps->irq = irq;
++ tps->irq_gpio = irq_gpio;
++
++ /* we got an irq, request it */
++ if (tps->irq >= 0) {
++ ret = tps65217_probe_pwr_but(tps);
++ if (ret < 0) {
++ dev_err(tps->dev, "Failed to probe pwr_but\n");
++ return ret;
++ }
++ }
++
+ ret = mfd_add_devices(tps->dev, -1, tps65217s,
+ ARRAY_SIZE(tps65217s), NULL, 0, NULL);
+ if (ret < 0) {
+diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h
+index 290762f..b138fa3 100644
+--- a/include/linux/mfd/tps65217.h
++++ b/include/linux/mfd/tps65217.h
+@@ -21,6 +21,7 @@
+ #include <linux/i2c.h>
+ #include <linux/regulator/driver.h>
+ #include <linux/regulator/machine.h>
++#include <linux/input.h>
+
+ /* TPS chip id list */
+ #define TPS65217 0xF0
+@@ -274,6 +275,11 @@ struct tps65217 {
+ struct regulator_dev *rdev[TPS65217_NUM_REGULATOR];
+ struct tps_info *info[TPS65217_NUM_REGULATOR];
+ struct regmap *regmap;
++
++ /* Power button and IRQ handling */
++ int irq_gpio; /* might not be set */
++ int irq;
++ struct input_dev *pwr_but;
+ };
+
+ static inline struct tps65217 *dev_to_tps65217(struct device *dev)
diff --git a/patches/linux-3.8.13/0638-dt-bone-common-Add-interrupt-for-PMIC.patch b/patches/linux-3.8.13/0638-dt-bone-common-Add-interrupt-for-PMIC.patch
new file mode 100644
index 0000000..5060d56
--- /dev/null
+++ b/patches/linux-3.8.13/0638-dt-bone-common-Add-interrupt-for-PMIC.patch
@@ -0,0 +1,33 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 27 May 2013 17:16:35 +0300
+Subject: [PATCH] dt: bone-common: Add interrupt for PMIC
+
+Add support for the PMIC interrupt, supports power-button presses.
+
+Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
+---
+ arch/arm/boot/dts/am335x-bone-common.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
+index ff4b5d2..cd009ea 100644
+--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
+@@ -431,6 +431,9 @@
+ &tps {
+ ti,pmic-shutdown-controller;
+
++ interrupt-parent = <&intc>;
++ interrupts = <7>; /* NNMI */
++
+ regulators {
+ dcdc1_reg: regulator@0 {
+ regulator-always-on;
+@@ -472,6 +475,7 @@
+ regulator-always-on;
+ };
+ };
++
+ };
+
+ &cpsw_emac0 {
diff --git a/patches/linux-3.8.13/0639-drivers-pps-clients-pps-gpio.c-convert-to-module_pla.patch b/patches/linux-3.8.13/0639-drivers-pps-clients-pps-gpio.c-convert-to-module_pla.patch
new file mode 100644
index 0000000..4be4a8c
--- /dev/null
+++ b/patches/linux-3.8.13/0639-drivers-pps-clients-pps-gpio.c-convert-to-module_pla.patch
@@ -0,0 +1,44 @@
+From: Jan Luebbe <jlu@pengutronix.de>
+Date: Mon, 17 Jun 2013 20:30:28 +0000
+Subject: [PATCH] drivers/pps/clients/pps-gpio.c: convert to
+ module_platform_driver
+
+This removes some boilerplate code (no functional changes).
+
+Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
+Acked-by: Rodolfo Giometti <giometti@enneenne.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Matt Ranostay <mranostay@gmail.com>
+---
+ drivers/pps/clients/pps-gpio.c | 18 +-----------------
+ 1 file changed, 1 insertion(+), 17 deletions(-)
+
+diff --git a/drivers/pps/clients/pps-gpio.c b/drivers/pps/clients/pps-gpio.c
+index 2bf0c1b..4c53c6d 100644
+--- a/drivers/pps/clients/pps-gpio.c
++++ b/drivers/pps/clients/pps-gpio.c
+@@ -203,23 +203,7 @@ static struct platform_driver pps_gpio_driver = {
+ },
+ };
+
+-static int __init pps_gpio_init(void)
+-{
+- int ret = platform_driver_register(&pps_gpio_driver);
+- if (ret < 0)
+- pr_err("failed to register platform driver\n");
+- return ret;
+-}
+-
+-static void __exit pps_gpio_exit(void)
+-{
+- platform_driver_unregister(&pps_gpio_driver);
+- pr_debug("unregistered platform driver\n");
+-}
+-
+-module_init(pps_gpio_init);
+-module_exit(pps_gpio_exit);
+-
++module_platform_driver(pps_gpio_driver);
+ MODULE_AUTHOR("Ricardo Martins <rasm@fe.up.pt>");
+ MODULE_AUTHOR("James Nuss <jamesnuss@nanometrics.ca>");
+ MODULE_DESCRIPTION("Use GPIO pin as PPS source");
diff --git a/patches/linux-3.8.13/0640-drivers-pps-clients-pps-gpio.c-convert-to-devm_-help.patch b/patches/linux-3.8.13/0640-drivers-pps-clients-pps-gpio.c-convert-to-devm_-help.patch
new file mode 100644
index 0000000..1065e28
--- /dev/null
+++ b/patches/linux-3.8.13/0640-drivers-pps-clients-pps-gpio.c-convert-to-devm_-help.patch
@@ -0,0 +1,88 @@
+From: Matt Ranostay <mranostay@gmail.com>
+Date: Mon, 17 Jun 2013 20:30:29 +0000
+Subject: [PATCH] drivers/pps/clients/pps-gpio.c: convert to devm_* helpers
+
+Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
+Acked-by: Rodolfo Giometti <giometti@enneenne.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Matt Ranostay <mranostay@gmail.com>
+---
+ drivers/pps/clients/pps-gpio.c | 22 +++++-----------------
+ 1 file changed, 5 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/pps/clients/pps-gpio.c b/drivers/pps/clients/pps-gpio.c
+index 4c53c6d..7e0e93b 100644
+--- a/drivers/pps/clients/pps-gpio.c
++++ b/drivers/pps/clients/pps-gpio.c
+@@ -109,7 +109,6 @@ static int pps_gpio_probe(struct platform_device *pdev)
+ struct pps_gpio_device_data *data;
+ int irq;
+ int ret;
+- int err;
+ int pps_default_params;
+ const struct pps_gpio_platform_data *pdata = pdev->dev.platform_data;
+
+@@ -123,15 +122,13 @@ static int pps_gpio_probe(struct platform_device *pdev)
+ irq = gpio_to_irq(pdata->gpio_pin);
+ if (irq < 0) {
+ pr_err("failed to map GPIO to IRQ: %d\n", irq);
+- err = -EINVAL;
+- goto return_error;
++ return -EINVAL;
+ }
+
+ /* allocate space for device info */
+ data = kzalloc(sizeof(struct pps_gpio_device_data), GFP_KERNEL);
+ if (data == NULL) {
+- err = -ENOMEM;
+- goto return_error;
++ return -ENOMEM;
+ }
+
+ /* initialize PPS specific parts of the bookkeeping data structure. */
+@@ -152,42 +149,33 @@ static int pps_gpio_probe(struct platform_device *pdev)
+ if (data->pps == NULL) {
+ kfree(data);
+ pr_err("failed to register IRQ %d as PPS source\n", irq);
+- err = -EINVAL;
+- goto return_error;
++ return -EINVAL;
+ }
+
+ data->irq = irq;
+ data->pdata = pdata;
+
+ /* register IRQ interrupt handler */
+- ret = request_irq(irq, pps_gpio_irq_handler,
++ ret = devm_request_irq(&pdev->dev, irq, pps_gpio_irq_handler,
+ get_irqf_trigger_flags(pdata), data->info.name, data);
+ if (ret) {
+ pps_unregister_source(data->pps);
+ kfree(data);
+ pr_err("failed to acquire IRQ %d\n", irq);
+- err = -EINVAL;
+- goto return_error;
++ return -EINVAL;
+ }
+
+ platform_set_drvdata(pdev, data);
+ dev_info(data->pps->dev, "Registered IRQ %d as PPS source\n", irq);
+
+ return 0;
+-
+-return_error:
+- gpio_free(pdata->gpio_pin);
+- return err;
+ }
+
+ static int pps_gpio_remove(struct platform_device *pdev)
+ {
+ struct pps_gpio_device_data *data = platform_get_drvdata(pdev);
+- const struct pps_gpio_platform_data *pdata = data->pdata;
+
+ platform_set_drvdata(pdev, NULL);
+- free_irq(data->irq, data);
+- gpio_free(pdata->gpio_pin);
+ pps_unregister_source(data->pps);
+ pr_info("removed IRQ %d as PPS source\n", data->irq);
+ kfree(data);
diff --git a/patches/linux-3.8.13/0641-pps-gpio-add-device-tree-binding-and-support.patch b/patches/linux-3.8.13/0641-pps-gpio-add-device-tree-binding-and-support.patch
new file mode 100644
index 0000000..13c7b46
--- /dev/null
+++ b/patches/linux-3.8.13/0641-pps-gpio-add-device-tree-binding-and-support.patch
@@ -0,0 +1,126 @@
+From: =?UTF-8?q?Jan=20L=C3=BCbbe?= <jlu@pengutronix.de>
+Date: Mon, 17 Jun 2013 20:30:30 +0000
+Subject: [PATCH] pps-gpio: add device-tree binding and support
+
+Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
+Acked-by: Rodolfo Giometti <giometti@enneenne.com>
+Signed-off-by: Matt Ranostay <mranostay@gmail.com>
+---
+ Documentation/devicetree/bindings/pps/pps-gpio.txt | 20 +++++++
+ drivers/pps/clients/pps-gpio.c | 55 +++++++++++++++++++-
+ 2 files changed, 73 insertions(+), 2 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/pps/pps-gpio.txt
+
+diff --git a/Documentation/devicetree/bindings/pps/pps-gpio.txt b/Documentation/devicetree/bindings/pps/pps-gpio.txt
+new file mode 100644
+index 0000000..40bf9c3
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pps/pps-gpio.txt
+@@ -0,0 +1,20 @@
++Device-Tree Bindings for a PPS Signal on GPIO
++
++These properties describe a PPS (pulse-per-second) signal connected to
++a GPIO pin.
++
++Required properties:
++- compatible: should be "pps-gpio"
++- gpios: one PPS GPIO in the format described by ../gpio/gpio.txt
++
++Optional properties:
++- assert-falling-edge: when present, assert is indicated by a falling edge
++ (instead of by a rising edge)
++
++Example:
++ pps {
++ compatible = "pps-gpio";
++ gpios = <&gpio2 6 0>;
++
++ assert-falling-edge;
++ };
+diff --git a/drivers/pps/clients/pps-gpio.c b/drivers/pps/clients/pps-gpio.c
+index 7e0e93b..9b405b3 100644
+--- a/drivers/pps/clients/pps-gpio.c
++++ b/drivers/pps/clients/pps-gpio.c
+@@ -33,6 +33,8 @@
+ #include <linux/pps-gpio.h>
+ #include <linux/gpio.h>
+ #include <linux/list.h>
++#include <linux/of_device.h>
++#include <linux/of_gpio.h>
+
+ /* Info for each registered platform device */
+ struct pps_gpio_device_data {
+@@ -104,14 +106,62 @@ get_irqf_trigger_flags(const struct pps_gpio_platform_data *pdata)
+ return flags;
+ }
+
++#ifdef CONFIG_OF
++static const struct of_device_id pps_gpio_dt_ids[] = {
++ { .compatible = "pps-gpio", },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, pps_gpio_dt_ids);
++
++static struct pps_gpio_platform_data *
++of_get_pps_gpio_pdata(struct platform_device *pdev)
++{
++ struct device_node *np = pdev->dev.of_node;
++ struct pps_gpio_platform_data *pdata;
++ int ret;
++
++ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
++ if (!pdata)
++ return NULL;
++
++ ret = of_get_gpio(np, 0);
++ if (ret < 0) {
++ pr_err("failed to get GPIO from device tree\n");
++ return NULL;
++ }
++
++ pdata->gpio_pin = ret;
++ pdata->gpio_label = PPS_GPIO_NAME;
++
++ if (of_get_property(np, "assert-falling-edge", NULL))
++ pdata->assert_falling_edge = true;
++
++ return pdata;
++}
++#else
++static struct pps_gpio_platform_data *
++of_get_pps_gpio_pdata(struct platform_device *pdev)
++{
++ return NULL;
++}
++#endif
++
+ static int pps_gpio_probe(struct platform_device *pdev)
+ {
+ struct pps_gpio_device_data *data;
+ int irq;
+ int ret;
+ int pps_default_params;
+- const struct pps_gpio_platform_data *pdata = pdev->dev.platform_data;
++ struct pps_gpio_platform_data *pdata;
++ const struct of_device_id *match;
++
++ match = of_match_device(pps_gpio_dt_ids, &pdev->dev);
++ if (match)
++ pdev->dev.platform_data = of_get_pps_gpio_pdata(pdev);
++ pdata = pdev->dev.platform_data;
+
++ if (!pdata)
++ return -ENODEV;
+
+ /* GPIO setup */
+ ret = pps_gpio_setup(pdev);
+@@ -187,7 +237,8 @@ static struct platform_driver pps_gpio_driver = {
+ .remove = pps_gpio_remove,
+ .driver = {
+ .name = PPS_GPIO_NAME,
+- .owner = THIS_MODULE
++ .owner = THIS_MODULE,
++ .of_match_table = of_match_ptr(pps_gpio_dt_ids),
+ },
+ };
+
diff --git a/patches/linux-3.8.13/0642-leds-leds-pwm-Convert-to-use-devm_get_pwm.patch b/patches/linux-3.8.13/0642-leds-leds-pwm-Convert-to-use-devm_get_pwm.patch
new file mode 100644
index 0000000..b215fc5
--- /dev/null
+++ b/patches/linux-3.8.13/0642-leds-leds-pwm-Convert-to-use-devm_get_pwm.patch
@@ -0,0 +1,84 @@
+From: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Date: Fri, 21 Dec 2012 01:43:55 -0800
+Subject: [PATCH] leds: leds-pwm: Convert to use devm_get_pwm
+
+Update the driver to use the new API for requesting pwm so we can take
+advantage of the pwm_lookup table to find the correct pwm to be used for the
+LED functionality.
+
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Signed-off-by: Bryan Wu <cooloney@gmail.com>
+---
+ drivers/leds/leds-pwm.c | 19 ++++++-------------
+ include/linux/leds_pwm.h | 2 +-
+ 2 files changed, 7 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
+index 2157524..351257c 100644
+--- a/drivers/leds/leds-pwm.c
++++ b/drivers/leds/leds-pwm.c
+@@ -67,12 +67,11 @@ static int led_pwm_probe(struct platform_device *pdev)
+ cur_led = &pdata->leds[i];
+ led_dat = &leds_data[i];
+
+- led_dat->pwm = pwm_request(cur_led->pwm_id,
+- cur_led->name);
++ led_dat->pwm = devm_pwm_get(&pdev->dev, cur_led->name);
+ if (IS_ERR(led_dat->pwm)) {
+ ret = PTR_ERR(led_dat->pwm);
+- dev_err(&pdev->dev, "unable to request PWM %d\n",
+- cur_led->pwm_id);
++ dev_err(&pdev->dev, "unable to request PWM for %s\n",
++ cur_led->name);
+ goto err;
+ }
+
+@@ -86,10 +85,8 @@ static int led_pwm_probe(struct platform_device *pdev)
+ led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
+- if (ret < 0) {
+- pwm_free(led_dat->pwm);
++ if (ret < 0)
+ goto err;
+- }
+ }
+
+ platform_set_drvdata(pdev, leds_data);
+@@ -98,10 +95,8 @@ static int led_pwm_probe(struct platform_device *pdev)
+
+ err:
+ if (i > 0) {
+- for (i = i - 1; i >= 0; i--) {
++ for (i = i - 1; i >= 0; i--)
+ led_classdev_unregister(&leds_data[i].cdev);
+- pwm_free(leds_data[i].pwm);
+- }
+ }
+
+ return ret;
+@@ -115,10 +110,8 @@ static int led_pwm_remove(struct platform_device *pdev)
+
+ leds_data = platform_get_drvdata(pdev);
+
+- for (i = 0; i < pdata->num_leds; i++) {
++ for (i = 0; i < pdata->num_leds; i++)
+ led_classdev_unregister(&leds_data[i].cdev);
+- pwm_free(leds_data[i].pwm);
+- }
+
+ return 0;
+ }
+diff --git a/include/linux/leds_pwm.h b/include/linux/leds_pwm.h
+index 33a0711..a65e964 100644
+--- a/include/linux/leds_pwm.h
++++ b/include/linux/leds_pwm.h
+@@ -7,7 +7,7 @@
+ struct led_pwm {
+ const char *name;
+ const char *default_trigger;
+- unsigned pwm_id;
++ unsigned pwm_id __deprecated;
+ u8 active_low;
+ unsigned max_brightness;
+ unsigned pwm_period_ns;
diff --git a/patches/linux-3.8.13/0643-leds-leds-pwm-Preparing-the-driver-for-device-tree-s.patch b/patches/linux-3.8.13/0643-leds-leds-pwm-Preparing-the-driver-for-device-tree-s.patch
new file mode 100644
index 0000000..d95b7ee
--- /dev/null
+++ b/patches/linux-3.8.13/0643-leds-leds-pwm-Preparing-the-driver-for-device-tree-s.patch
@@ -0,0 +1,104 @@
+From: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Date: Fri, 21 Dec 2012 01:43:56 -0800
+Subject: [PATCH] leds: leds-pwm: Preparing the driver for device tree support
+
+In order to be able to add device tree support for leds-pwm driver we need
+to rearrange the data structures used by the drivers.
+
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Signed-off-by: Bryan Wu <cooloney@gmail.com>
+---
+ drivers/leds/leds-pwm.c | 39 +++++++++++++++++++++++----------------
+ 1 file changed, 23 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
+index 351257c..c767837 100644
+--- a/drivers/leds/leds-pwm.c
++++ b/drivers/leds/leds-pwm.c
+@@ -30,6 +30,11 @@ struct led_pwm_data {
+ unsigned int period;
+ };
+
++struct led_pwm_priv {
++ int num_leds;
++ struct led_pwm_data leds[0];
++};
++
+ static void led_pwm_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+ {
+@@ -47,25 +52,29 @@ static void led_pwm_set(struct led_classdev *led_cdev,
+ }
+ }
+
++static inline size_t sizeof_pwm_leds_priv(int num_leds)
++{
++ return sizeof(struct led_pwm_priv) +
++ (sizeof(struct led_pwm_data) * num_leds);
++}
++
+ static int led_pwm_probe(struct platform_device *pdev)
+ {
+ struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
+- struct led_pwm *cur_led;
+- struct led_pwm_data *leds_data, *led_dat;
++ struct led_pwm_priv *priv;
+ int i, ret = 0;
+
+ if (!pdata)
+ return -EBUSY;
+
+- leds_data = devm_kzalloc(&pdev->dev,
+- sizeof(struct led_pwm_data) * pdata->num_leds,
+- GFP_KERNEL);
+- if (!leds_data)
++ priv = devm_kzalloc(&pdev->dev, sizeof_pwm_leds_priv(pdata->num_leds),
++ GFP_KERNEL);
++ if (!priv)
+ return -ENOMEM;
+
+ for (i = 0; i < pdata->num_leds; i++) {
+- cur_led = &pdata->leds[i];
+- led_dat = &leds_data[i];
++ struct led_pwm *cur_led = &pdata->leds[i];
++ struct led_pwm_data *led_dat = &priv->leds[i];
+
+ led_dat->pwm = devm_pwm_get(&pdev->dev, cur_led->name);
+ if (IS_ERR(led_dat->pwm)) {
+@@ -88,15 +97,16 @@ static int led_pwm_probe(struct platform_device *pdev)
+ if (ret < 0)
+ goto err;
+ }
++ priv->num_leds = pdata->num_leds;
+
+- platform_set_drvdata(pdev, leds_data);
++ platform_set_drvdata(pdev, priv);
+
+ return 0;
+
+ err:
+ if (i > 0) {
+ for (i = i - 1; i >= 0; i--)
+- led_classdev_unregister(&leds_data[i].cdev);
++ led_classdev_unregister(&priv->leds[i].cdev);
+ }
+
+ return ret;
+@@ -104,14 +114,11 @@ err:
+
+ static int led_pwm_remove(struct platform_device *pdev)
+ {
++ struct led_pwm_priv *priv = platform_get_drvdata(pdev);
+ int i;
+- struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
+- struct led_pwm_data *leds_data;
+-
+- leds_data = platform_get_drvdata(pdev);
+
+- for (i = 0; i < pdata->num_leds; i++)
+- led_classdev_unregister(&leds_data[i].cdev);
++ for (i = 0; i < priv->num_leds; i++)
++ led_classdev_unregister(&priv->leds[i].cdev);
+
+ return 0;
+ }
diff --git a/patches/linux-3.8.13/0644-leds-leds-pwm-Simplify-cleanup-code.patch b/patches/linux-3.8.13/0644-leds-leds-pwm-Simplify-cleanup-code.patch
new file mode 100644
index 0000000..6338c47
--- /dev/null
+++ b/patches/linux-3.8.13/0644-leds-leds-pwm-Simplify-cleanup-code.patch
@@ -0,0 +1,35 @@
+From: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Date: Fri, 21 Dec 2012 01:44:00 -0800
+Subject: [PATCH] leds: leds-pwm: Simplify cleanup code
+
+The code looks more nicer if we use:
+
+while (i--)
+
+instead:
+if (i > 0)
+ for (i = i - 1; i >= 0; i--)
+
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Signed-off-by: Bryan Wu <cooloney@gmail.com>
+---
+ drivers/leds/leds-pwm.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
+index c767837..46f4e44 100644
+--- a/drivers/leds/leds-pwm.c
++++ b/drivers/leds/leds-pwm.c
+@@ -104,10 +104,8 @@ static int led_pwm_probe(struct platform_device *pdev)
+ return 0;
+
+ err:
+- if (i > 0) {
+- for (i = i - 1; i >= 0; i--)
+- led_classdev_unregister(&priv->leds[i].cdev);
+- }
++ while (i--)
++ led_classdev_unregister(&priv->leds[i].cdev);
+
+ return ret;
+ }
diff --git a/patches/linux-3.8.13/0645-leds-leds-pwm-Add-device-tree-bindings.patch b/patches/linux-3.8.13/0645-leds-leds-pwm-Add-device-tree-bindings.patch
new file mode 100644
index 0000000..a4dd235
--- /dev/null
+++ b/patches/linux-3.8.13/0645-leds-leds-pwm-Add-device-tree-bindings.patch
@@ -0,0 +1,240 @@
+From: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Date: Fri, 21 Dec 2012 01:44:01 -0800
+Subject: [PATCH] leds: leds-pwm: Add device tree bindings
+
+The DT binding for the pwm-leds devices are similar to the gpio-leds type.
+LEDs are represented as sub-nodes of the pwm-leds device.
+The code for handling the DT boot is based on the code found in the
+leds-gpio driver and adapted to use PWMs instead of GPIOs.
+To avoid having custom cleanup code in case of DT boot the newly created
+devm_of_pwm_get() API is used to get the correct PWM instance.
+
+For usage see:
+Documentation/devicetree/bindings/leds/leds-pwm.txt
+
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Acked-by: Grant Likely <grant.likely@secretlab.ca>
+Signed-off-by: Bryan Wu <cooloney@gmail.com>
+---
+ .../devicetree/bindings/leds/leds-pwm.txt | 48 +++++++++
+ drivers/leds/leds-pwm.c | 112 ++++++++++++++++----
+ 2 files changed, 140 insertions(+), 20 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/leds/leds-pwm.txt
+
+diff --git a/Documentation/devicetree/bindings/leds/leds-pwm.txt b/Documentation/devicetree/bindings/leds/leds-pwm.txt
+new file mode 100644
+index 0000000..7297107
+--- /dev/null
++++ b/Documentation/devicetree/bindings/leds/leds-pwm.txt
+@@ -0,0 +1,48 @@
++LED connected to PWM
++
++Required properties:
++- compatible : should be "pwm-leds".
++
++Each LED is represented as a sub-node of the pwm-leds device. Each
++node's name represents the name of the corresponding LED.
++
++LED sub-node properties:
++- pwms : PWM property to point to the PWM device (phandle)/port (id) and to
++ specify the period time to be used: <&phandle id period_ns>;
++- pwm-names : (optional) Name to be used by the PWM subsystem for the PWM device
++ For the pwms and pwm-names property please refer to:
++ Documentation/devicetree/bindings/pwm/pwm.txt
++- max-brightness : Maximum brightness possible for the LED
++- label : (optional)
++ see Documentation/devicetree/bindings/leds/common.txt
++- linux,default-trigger : (optional)
++ see Documentation/devicetree/bindings/leds/common.txt
++
++Example:
++
++twl_pwm: pwm {
++ /* provides two PWMs (id 0, 1 for PWM1 and PWM2) */
++ compatible = "ti,twl6030-pwm";
++ #pwm-cells = <2>;
++};
++
++twl_pwmled: pwmled {
++ /* provides one PWM (id 0 for Charing indicator LED) */
++ compatible = "ti,twl6030-pwmled";
++ #pwm-cells = <2>;
++};
++
++pwmleds {
++ compatible = "pwm-leds";
++ kpad {
++ label = "omap4::keypad";
++ pwms = <&twl_pwm 0 7812500>;
++ max-brightness = <127>;
++ };
++
++ charging {
++ label = "omap4:green:chrg";
++ pwms = <&twl_pwmled 0 7812500>;
++ max-brightness = <255>;
++ };
++};
+diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
+index 46f4e44..a1ea5f6 100644
+--- a/drivers/leds/leds-pwm.c
++++ b/drivers/leds/leds-pwm.c
+@@ -16,6 +16,7 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/platform_device.h>
++#include <linux/of_platform.h>
+ #include <linux/fb.h>
+ #include <linux/leds.h>
+ #include <linux/err.h>
+@@ -58,46 +59,110 @@ static inline size_t sizeof_pwm_leds_priv(int num_leds)
+ (sizeof(struct led_pwm_data) * num_leds);
+ }
+
+-static int led_pwm_probe(struct platform_device *pdev)
++static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev)
+ {
+- struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
++ struct device_node *node = pdev->dev.of_node;
++ struct device_node *child;
+ struct led_pwm_priv *priv;
+- int i, ret = 0;
++ int count, ret;
+
+- if (!pdata)
+- return -EBUSY;
++ /* count LEDs in this device, so we know how much to allocate */
++ count = of_get_child_count(node);
++ if (!count)
++ return NULL;
+
+- priv = devm_kzalloc(&pdev->dev, sizeof_pwm_leds_priv(pdata->num_leds),
++ priv = devm_kzalloc(&pdev->dev, sizeof_pwm_leds_priv(count),
+ GFP_KERNEL);
+ if (!priv)
+- return -ENOMEM;
++ return NULL;
+
+- for (i = 0; i < pdata->num_leds; i++) {
+- struct led_pwm *cur_led = &pdata->leds[i];
+- struct led_pwm_data *led_dat = &priv->leds[i];
++ for_each_child_of_node(node, child) {
++ struct led_pwm_data *led_dat = &priv->leds[priv->num_leds];
+
+- led_dat->pwm = devm_pwm_get(&pdev->dev, cur_led->name);
++ led_dat->cdev.name = of_get_property(child, "label",
++ NULL) ? : child->name;
++
++ led_dat->pwm = devm_of_pwm_get(&pdev->dev, child, NULL);
+ if (IS_ERR(led_dat->pwm)) {
+- ret = PTR_ERR(led_dat->pwm);
+ dev_err(&pdev->dev, "unable to request PWM for %s\n",
+- cur_led->name);
++ led_dat->cdev.name);
+ goto err;
+ }
++ /* Get the period from PWM core when n*/
++ led_dat->period = pwm_get_period(led_dat->pwm);
++
++ led_dat->cdev.default_trigger = of_get_property(child,
++ "linux,default-trigger", NULL);
++ of_property_read_u32(child, "max-brightness",
++ &led_dat->cdev.max_brightness);
+
+- led_dat->cdev.name = cur_led->name;
+- led_dat->cdev.default_trigger = cur_led->default_trigger;
+- led_dat->active_low = cur_led->active_low;
+- led_dat->period = cur_led->pwm_period_ns;
+ led_dat->cdev.brightness_set = led_pwm_set;
+ led_dat->cdev.brightness = LED_OFF;
+- led_dat->cdev.max_brightness = cur_led->max_brightness;
+ led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
+- if (ret < 0)
++ if (ret < 0) {
++ dev_err(&pdev->dev, "failed to register for %s\n",
++ led_dat->cdev.name);
++ of_node_put(child);
+ goto err;
++ }
++ priv->num_leds++;
++ }
++
++ return priv;
++err:
++ while (priv->num_leds--)
++ led_classdev_unregister(&priv->leds[priv->num_leds].cdev);
++
++ return NULL;
++}
++
++static int led_pwm_probe(struct platform_device *pdev)
++{
++ struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
++ struct led_pwm_priv *priv;
++ int i, ret = 0;
++
++ if (pdata && pdata->num_leds) {
++ priv = devm_kzalloc(&pdev->dev,
++ sizeof_pwm_leds_priv(pdata->num_leds),
++ GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ for (i = 0; i < pdata->num_leds; i++) {
++ struct led_pwm *cur_led = &pdata->leds[i];
++ struct led_pwm_data *led_dat = &priv->leds[i];
++
++ led_dat->pwm = devm_pwm_get(&pdev->dev, cur_led->name);
++ if (IS_ERR(led_dat->pwm)) {
++ ret = PTR_ERR(led_dat->pwm);
++ dev_err(&pdev->dev,
++ "unable to request PWM for %s\n",
++ cur_led->name);
++ goto err;
++ }
++
++ led_dat->cdev.name = cur_led->name;
++ led_dat->cdev.default_trigger = cur_led->default_trigger;
++ led_dat->active_low = cur_led->active_low;
++ led_dat->period = cur_led->pwm_period_ns;
++ led_dat->cdev.brightness_set = led_pwm_set;
++ led_dat->cdev.brightness = LED_OFF;
++ led_dat->cdev.max_brightness = cur_led->max_brightness;
++ led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
++
++ ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
++ if (ret < 0)
++ goto err;
++ }
++ priv->num_leds = pdata->num_leds;
++ } else {
++ priv = led_pwm_create_of(pdev);
++ if (!priv)
++ return -ENODEV;
+ }
+- priv->num_leds = pdata->num_leds;
+
+ platform_set_drvdata(pdev, priv);
+
+@@ -121,12 +186,19 @@ static int led_pwm_remove(struct platform_device *pdev)
+ return 0;
+ }
+
++static const struct of_device_id of_pwm_leds_match[] = {
++ { .compatible = "pwm-leds", },
++ {},
++};
++MODULE_DEVICE_TABLE(of, of_pwm_leds_match);
++
+ static struct platform_driver led_pwm_driver = {
+ .probe = led_pwm_probe,
+ .remove = led_pwm_remove,
+ .driver = {
+ .name = "leds_pwm",
+ .owner = THIS_MODULE,
++ .of_match_table = of_match_ptr(of_pwm_leds_match),
+ },
+ };
+
diff --git a/patches/linux-3.8.13/0646-leds-leds-pwm-Defer-led_pwm_set-if-PWM-can-sleep.patch b/patches/linux-3.8.13/0646-leds-leds-pwm-Defer-led_pwm_set-if-PWM-can-sleep.patch
new file mode 100644
index 0000000..48ad4e3
--- /dev/null
+++ b/patches/linux-3.8.13/0646-leds-leds-pwm-Defer-led_pwm_set-if-PWM-can-sleep.patch
@@ -0,0 +1,118 @@
+From: Florian Vaussard <florian.vaussard@epfl.ch>
+Date: Mon, 28 Jan 2013 06:00:59 -0800
+Subject: [PATCH] leds: leds-pwm: Defer led_pwm_set() if PWM can sleep
+
+Call to led_pwm_set() can happen inside atomic context, like triggers.
+If the PWM call can sleep, defer using a worker.
+
+Signed-off-by: Florian Vaussard <florian.vaussard@epfl.ch>
+Reviewed-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Acked-by: Thierry Reding <thierry.reding@avionic-design.de>
+Signed-off-by: Bryan Wu <cooloney@gmail.com>
+---
+ drivers/leds/leds-pwm.c | 50 +++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 42 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
+index a1ea5f6..faf52c0 100644
+--- a/drivers/leds/leds-pwm.c
++++ b/drivers/leds/leds-pwm.c
+@@ -23,12 +23,16 @@
+ #include <linux/pwm.h>
+ #include <linux/leds_pwm.h>
+ #include <linux/slab.h>
++#include <linux/workqueue.h>
+
+ struct led_pwm_data {
+ struct led_classdev cdev;
+ struct pwm_device *pwm;
++ struct work_struct work;
+ unsigned int active_low;
+ unsigned int period;
++ int duty;
++ bool can_sleep;
+ };
+
+ struct led_pwm_priv {
+@@ -36,6 +40,26 @@ struct led_pwm_priv {
+ struct led_pwm_data leds[0];
+ };
+
++static void __led_pwm_set(struct led_pwm_data *led_dat)
++{
++ int new_duty = led_dat->duty;
++
++ pwm_config(led_dat->pwm, new_duty, led_dat->period);
++
++ if (new_duty == 0)
++ pwm_disable(led_dat->pwm);
++ else
++ pwm_enable(led_dat->pwm);
++}
++
++static void led_pwm_work(struct work_struct *work)
++{
++ struct led_pwm_data *led_dat =
++ container_of(work, struct led_pwm_data, work);
++
++ __led_pwm_set(led_dat);
++}
++
+ static void led_pwm_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+ {
+@@ -44,13 +68,12 @@ static void led_pwm_set(struct led_classdev *led_cdev,
+ unsigned int max = led_dat->cdev.max_brightness;
+ unsigned int period = led_dat->period;
+
+- if (brightness == 0) {
+- pwm_config(led_dat->pwm, 0, period);
+- pwm_disable(led_dat->pwm);
+- } else {
+- pwm_config(led_dat->pwm, brightness * period / max, period);
+- pwm_enable(led_dat->pwm);
+- }
++ led_dat->duty = brightness * period / max;
++
++ if (led_dat->can_sleep)
++ schedule_work(&led_dat->work);
++ else
++ __led_pwm_set(led_dat);
+ }
+
+ static inline size_t sizeof_pwm_leds_priv(int num_leds)
+@@ -100,6 +123,10 @@ static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev)
+ led_dat->cdev.brightness = LED_OFF;
+ led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
++ led_dat->can_sleep = pwm_can_sleep(led_dat->pwm);
++ if (led_dat->can_sleep)
++ INIT_WORK(&led_dat->work, led_pwm_work);
++
+ ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to register for %s\n",
+@@ -153,6 +180,10 @@ static int led_pwm_probe(struct platform_device *pdev)
+ led_dat->cdev.max_brightness = cur_led->max_brightness;
+ led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
++ led_dat->can_sleep = pwm_can_sleep(led_dat->pwm);
++ if (led_dat->can_sleep)
++ INIT_WORK(&led_dat->work, led_pwm_work);
++
+ ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
+ if (ret < 0)
+ goto err;
+@@ -180,8 +211,11 @@ static int led_pwm_remove(struct platform_device *pdev)
+ struct led_pwm_priv *priv = platform_get_drvdata(pdev);
+ int i;
+
+- for (i = 0; i < priv->num_leds; i++)
++ for (i = 0; i < priv->num_leds; i++) {
+ led_classdev_unregister(&priv->leds[i].cdev);
++ if (priv->leds[i].can_sleep)
++ cancel_work_sync(&priv->leds[i].work);
++ }
+
+ return 0;
+ }
diff --git a/patches/linux-3.8.13/0647-leds-pwm-Enable-compilation-on-this-version-of-the-k.patch b/patches/linux-3.8.13/0647-leds-pwm-Enable-compilation-on-this-version-of-the-k.patch
new file mode 100644
index 0000000..88a46ea
--- /dev/null
+++ b/patches/linux-3.8.13/0647-leds-pwm-Enable-compilation-on-this-version-of-the-k.patch
@@ -0,0 +1,54 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 10 Jul 2013 23:50:05 +0300
+Subject: [PATCH] leds: pwm: Enable compilation on this version of the kernel
+
+---
+ drivers/leds/Kconfig | 2 +-
+ drivers/leds/leds-pwm.c | 7 ++++---
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
+index b58bc8a..de3fc297c 100644
+--- a/drivers/leds/Kconfig
++++ b/drivers/leds/Kconfig
+@@ -310,7 +310,7 @@ config LEDS_DAC124S085
+ config LEDS_PWM
+ tristate "PWM driven LED Support"
+ depends on LEDS_CLASS
+- depends on HAVE_PWM
++ depends on PWM
+ help
+ This option enables support for pwm driven LEDs
+
+diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
+index faf52c0..730c7c6 100644
+--- a/drivers/leds/leds-pwm.c
++++ b/drivers/leds/leds-pwm.c
+@@ -105,7 +105,8 @@ static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev)
+ led_dat->cdev.name = of_get_property(child, "label",
+ NULL) ? : child->name;
+
+- led_dat->pwm = devm_of_pwm_get(&pdev->dev, child, NULL);
++ /* caution: this is not release automatically */
++ led_dat->pwm = of_pwm_request(child, NULL);
+ if (IS_ERR(led_dat->pwm)) {
+ dev_err(&pdev->dev, "unable to request PWM for %s\n",
+ led_dat->cdev.name);
+@@ -123,7 +124,7 @@ static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev)
+ led_dat->cdev.brightness = LED_OFF;
+ led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
+- led_dat->can_sleep = pwm_can_sleep(led_dat->pwm);
++ led_dat->can_sleep = 0; /* pwm_can_sleep(led_dat->pwm); */
+ if (led_dat->can_sleep)
+ INIT_WORK(&led_dat->work, led_pwm_work);
+
+@@ -180,7 +181,7 @@ static int led_pwm_probe(struct platform_device *pdev)
+ led_dat->cdev.max_brightness = cur_led->max_brightness;
+ led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
+- led_dat->can_sleep = pwm_can_sleep(led_dat->pwm);
++ led_dat->can_sleep = 0; /* pwm_can_sleep(led_dat->pwm); */
+ if (led_dat->can_sleep)
+ INIT_WORK(&led_dat->work, led_pwm_work);
+
diff --git a/patches/linux-3.8.13/0648-capes-Add-bacon-cape.patch b/patches/linux-3.8.13/0648-capes-Add-bacon-cape.patch
new file mode 100644
index 0000000..74f7860
--- /dev/null
+++ b/patches/linux-3.8.13/0648-capes-Add-bacon-cape.patch
@@ -0,0 +1,247 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Wed, 10 Jul 2013 23:51:05 +0300
+Subject: [PATCH] capes: Add bacon cape
+
+This is the full Linux driver enable bacon cape definition.
+---
+ firmware/Makefile | 3 +-
+ firmware/capes/BB-BONE-BACON-00A0.dts | 216 +++++++++++++++++++++++++++++++++
+ 2 files changed, 218 insertions(+), 1 deletion(-)
+ create mode 100644 firmware/capes/BB-BONE-BACON-00A0.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index cdfc800..e0e7522 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -186,7 +186,8 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ BB-BONE-RST2-00A0.dtbo \
+ BB-BONE-CAM3-01-00A2.dtbo \
+ TT3201-001-01.dtbo \
+- BB-BONE-SERL-03-00A1.dtbo
++ BB-BONE-SERL-03-00A1.dtbo \
++ BB-BONE-BACON-00A0.dtbo
+
+ # the geiger cape
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE_GEIGER) += \
+diff --git a/firmware/capes/BB-BONE-BACON-00A0.dts b/firmware/capes/BB-BONE-BACON-00A0.dts
+new file mode 100644
+index 0000000..87f5f01
+--- /dev/null
++++ b/firmware/capes/BB-BONE-BACON-00A0.dts
+@@ -0,0 +1,216 @@
++/*
++ * Copyright (C) 2013 Circuit Co.
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-BONE-BACON";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.36", /* AIN5 */
++ "P8.19", /* gpio-keys: gpio0_23 */
++ "P9.14", /* pwm: ehrpwm1A */
++ "P9.16", /* pwm: ehrpwm1B */
++ "P9.42", /* pwm: eCAP0_in_PWM0_out */
++ "P9.17", /* shift: gpio0_5 LATCH */
++ "P9.18", /* shift: gpio0_4 SERIAL */
++ "P9.22", /* shift: gpio0_2 CLOCK */
++ /* the hardware IP uses */
++ "tscadc",
++ "gpio0_23",
++ "ehrpwm1A",
++ "ehrpwm1B",
++ "eCAP0_in_PWM0_out",
++ "gpio0_5",
++ "gpio0_4",
++ "gpio0_2";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ bacon_key_pins: pinmux_bacon_key_pins {
++ pinctrl-single,pins = <
++ 0x020 0x2f /* gpmc_ad8.gpio0_22, INPUT | PULLDIS | MODE7 */
++ >;
++ };
++
++ bacon_ehrpwm1_pins: pinmux_bacon_ehrpwm1_pins {
++ pinctrl-single,pins = <
++ 0x048 0x6 /* P9_14 (ZCZ ball U14) | MODE 6 */
++ 0x04c 0x6 /* P9_16 (ZCZ ball T14) | MODE 6 */
++ >;
++ };
++
++ bacon_ecap0_pins: pinmux_bacon_ecap0_pins {
++ pinctrl-single,pins = <
++ 0x164 0x0 /* P9_42 (ZCZ ball C18) | MODE 0 */
++ >;
++ };
++
++ bacon_gpiohelp_pins: pinmux_bacon_gpio_helper_pins {
++ pinctrl-single,pins = <
++ 0x15c 0x0f /* P9 17 spi0_cs0.gpio0_5 | MODE7 | OUTPUT */
++ 0x158 0x0f /* P9 18 spi0_d1.gpio0_4 | MODE7 | OUTPUT */
++ 0x150 0x0f /* P9 22 spi0_sclk.gpio0_2 | MODE7 | OUTPUT */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ /* avoid stupid warning */
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ tscadc {
++ compatible = "ti,ti-tscadc";
++ reg = <0x44e0d000 0x1000>;
++
++ interrupt-parent = <&intc>;
++ interrupts = <16>;
++ ti,hwmods = "adc_tsc";
++ status = "okay";
++
++ adc {
++ ti,adc-channels = <8>; /* 8 channels (but only 5 is used) */
++ };
++ };
++
++ bacon_helper {
++ compatible = "bone-iio-helper";
++ vsense-name = "AIN0", "AIN1", "AIN2", "AIN3", "AIN4", "AIN5", "AIN6", "AIN7";
++ /* report micro-volts */
++ vsense-scale = <100000 100000 100000 100000 100000 100000 100000 100000>;
++ status = "okay";
++ };
++
++ /* the single button */
++ bacon_gpio_keys {
++ compatible = "gpio-keys";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bacon_key_pins>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ button@0 {
++ debounce_interval = <50>;
++ linux,code = <28>;
++ label = "enter";
++ gpios = <&gpio1 22 0x1>; /* really gpio0_23 */
++ gpio-key,wakeup;
++ };
++ };
++ };
++ };
++
++ fragment@3 {
++ target = <&epwmss0>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@4 {
++ target = <&ecap0>;
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&bacon_ecap0_pins>;
++ status = "okay";
++ };
++ };
++
++ fragment@5 {
++ target = <&epwmss1>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@6 {
++ target = <&ehrpwm1>;
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&bacon_ehrpwm1_pins>;
++ status = "okay";
++ };
++ };
++
++ fragment@7 {
++ target = <&ocp>;
++ __overlay__ {
++ bacon_pwm_leds {
++ compatible = "pwm-leds";
++
++ bacon_pwm_green {
++ label = "bacon::green";
++ pwms = <&ehrpwm1 0 500000 0>;
++ max-brightness = <255>;
++ };
++
++ bacon_pwm_blue {
++ label = "bacon::blue";
++ pwms = <&ehrpwm1 1 500000 0>;
++ max-brightness = <255>;
++ };
++
++ bacon_pwm_red {
++ label = "bacon::red";
++ pwms = <&ecap0 0 500000 0>;
++ max-brightness = <255>;
++ };
++ };
++ };
++ };
++
++ fragment@8 {
++ target = <&ocp>;
++ __overlay__ {
++
++ bacon_gpiohelp {
++ compatible = "gpio-of-helper";
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bacon_gpiohelp_pins>;
++
++ /* declare your gpios */
++ LATCH {
++ gpio-name = "LATCH";
++ gpio = <&gpio1 5 0x00>; /* gpio1 is gpio0 */
++ output;
++ init-high;
++ };
++
++ SERIAL {
++ gpio-name = "SERIAL";
++ gpio = <&gpio1 4 0x00>; /* gpio1 is gpio0 */
++ output;
++ init-low;
++ };
++
++ CLOCK {
++ gpio-name = "CLOCK";
++ gpio = <&gpio1 2 0x00>; /* gpio1 is gpio0 */
++ output;
++ init-low;
++ };
++ };
++ };
++ };
++
++
++
++};
diff --git a/patches/linux-3.8.13/0649-cape-bacon-Cosmetic-change-of-the-adc-helper-name.patch b/patches/linux-3.8.13/0649-cape-bacon-Cosmetic-change-of-the-adc-helper-name.patch
new file mode 100644
index 0000000..0d608a5
--- /dev/null
+++ b/patches/linux-3.8.13/0649-cape-bacon-Cosmetic-change-of-the-adc-helper-name.patch
@@ -0,0 +1,21 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 11 Jul 2013 10:01:50 +0300
+Subject: [PATCH] cape: bacon: Cosmetic change of the adc helper name
+
+---
+ firmware/capes/BB-BONE-BACON-00A0.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/firmware/capes/BB-BONE-BACON-00A0.dts b/firmware/capes/BB-BONE-BACON-00A0.dts
+index 87f5f01..d25c1baa 100644
+--- a/firmware/capes/BB-BONE-BACON-00A0.dts
++++ b/firmware/capes/BB-BONE-BACON-00A0.dts
+@@ -89,7 +89,7 @@
+ };
+ };
+
+- bacon_helper {
++ bacon_adc_helper {
+ compatible = "bone-iio-helper";
+ vsense-name = "AIN0", "AIN1", "AIN2", "AIN3", "AIN4", "AIN5", "AIN6", "AIN7";
+ /* report micro-volts */
diff --git a/patches/linux-3.8.13/0650-cape-bacon-educational-edition.patch b/patches/linux-3.8.13/0650-cape-bacon-educational-edition.patch
new file mode 100644
index 0000000..8e7e7d5
--- /dev/null
+++ b/patches/linux-3.8.13/0650-cape-bacon-educational-edition.patch
@@ -0,0 +1,199 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 11 Jul 2013 10:04:22 +0300
+Subject: [PATCH] cape: bacon: educational edition
+
+---
+ firmware/Makefile | 3 +-
+ firmware/capes/BB-BONE-BACONE-00A0.dts | 169 ++++++++++++++++++++++++++++++++
+ 2 files changed, 171 insertions(+), 1 deletion(-)
+ create mode 100644 firmware/capes/BB-BONE-BACONE-00A0.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index e0e7522..d2c6161 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -187,7 +187,8 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ BB-BONE-CAM3-01-00A2.dtbo \
+ TT3201-001-01.dtbo \
+ BB-BONE-SERL-03-00A1.dtbo \
+- BB-BONE-BACON-00A0.dtbo
++ BB-BONE-BACON-00A0.dtbo \
++ BB-BONE-BACONE-00A0.dtbo
+
+ # the geiger cape
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE_GEIGER) += \
+diff --git a/firmware/capes/BB-BONE-BACONE-00A0.dts b/firmware/capes/BB-BONE-BACONE-00A0.dts
+new file mode 100644
+index 0000000..a02173d
+--- /dev/null
++++ b/firmware/capes/BB-BONE-BACONE-00A0.dts
+@@ -0,0 +1,169 @@
++/*
++ * Copyright (C) 2013 Circuit Co.
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-BONE-BACONE";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.36", /* AIN5 */
++ "P8.19", /* gpio-keys: gpio0_23 */
++ "P9.14", /* pwm: ehrpwm1A */
++ "P9.16", /* pwm: ehrpwm1B */
++ "P9.42", /* pwm: eCAP0_in_PWM0_out */
++ "P9.17", /* shift: gpio0_5 LATCH */
++ "P9.18", /* shift: gpio0_4 SERIAL */
++ "P9.22", /* shift: gpio0_2 CLOCK */
++ /* the hardware IP uses */
++ "tscadc",
++ "gpio0_23",
++ "ehrpwm1A",
++ "ehrpwm1B",
++ "eCAP0_in_PWM0_out",
++ "gpio0_5",
++ "gpio0_4",
++ "gpio0_2";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ bacon_ehrpwm1_pins: pinmux_bacon_ehrpwm1_pins {
++ pinctrl-single,pins = <
++ 0x048 0x6 /* P9_14 (ZCZ ball U14) | MODE 6 */
++ 0x04c 0x6 /* P9_16 (ZCZ ball T14) | MODE 6 */
++ >;
++ };
++
++ bacon_ecap0_pins: pinmux_bacon_ecap0_pins {
++ pinctrl-single,pins = <
++ 0x164 0x0 /* P9_42 (ZCZ ball C18) | MODE 0 */
++ >;
++ };
++
++ bacon_gpiohelp_pins: pinmux_bacon_gpio_helper_pins {
++ pinctrl-single,pins = <
++ 0x020 0x2f /* gpmc_ad8.gpio0_22, INPUT | PULLDIS | MODE7 */
++ 0x15c 0x0f /* P9 17 spi0_cs0.gpio0_5 | MODE7 | OUTPUT */
++ 0x158 0x0f /* P9 18 spi0_d1.gpio0_4 | MODE7 | OUTPUT */
++ 0x150 0x0f /* P9 22 spi0_sclk.gpio0_2 | MODE7 | OUTPUT */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ /* avoid stupid warning */
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ tscadc {
++ compatible = "ti,ti-tscadc";
++ reg = <0x44e0d000 0x1000>;
++
++ interrupt-parent = <&intc>;
++ interrupts = <16>;
++ ti,hwmods = "adc_tsc";
++ status = "okay";
++
++ adc {
++ ti,adc-channels = <8>; /* 8 channels (but only 5 is used) */
++ };
++ };
++
++ bacon_adc_helper {
++ compatible = "bone-iio-helper";
++ vsense-name = "AIN0", "AIN1", "AIN2", "AIN3", "AIN4", "AIN5", "AIN6", "AIN7";
++ /* report micro-volts */
++ vsense-scale = <100000 100000 100000 100000 100000 100000 100000 100000>;
++ status = "okay";
++ };
++ };
++ };
++
++ fragment@3 {
++ target = <&epwmss0>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@4 {
++ target = <&ecap0>;
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&bacon_ecap0_pins>;
++ status = "okay";
++ };
++ };
++
++ fragment@5 {
++ target = <&epwmss1>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@6 {
++ target = <&ehrpwm1>;
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&bacon_ehrpwm1_pins>;
++ status = "okay";
++ };
++ };
++
++ fragment@8 {
++ target = <&ocp>;
++ __overlay__ {
++
++ bacon_gpiohelp {
++ compatible = "gpio-of-helper";
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bacon_gpiohelp_pins>;
++
++ /* declare your gpios */
++ LATCH {
++ gpio-name = "LATCH";
++ gpio = <&gpio1 5 0x00>; /* gpio1 is gpio0 */
++ output;
++ init-high;
++ };
++
++ SERIAL {
++ gpio-name = "SERIAL";
++ gpio = <&gpio1 4 0x00>; /* gpio1 is gpio0 */
++ output;
++ init-low;
++ };
++
++ CLOCK {
++ gpio-name = "CLOCK";
++ gpio = <&gpio1 2 0x00>; /* gpio1 is gpio0 */
++ output;
++ init-low;
++ };
++
++ BUTTON {
++ gpio-name = "BUTTON";
++ gpio = <&gpio1 22 0x01>; /* gpio1 is gpio0 */
++ input;
++ };
++ };
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0651-capes-bacon-Update-with-new-ADC-driver-method.patch b/patches/linux-3.8.13/0651-capes-bacon-Update-with-new-ADC-driver-method.patch
new file mode 100644
index 0000000..2630d28
--- /dev/null
+++ b/patches/linux-3.8.13/0651-capes-bacon-Update-with-new-ADC-driver-method.patch
@@ -0,0 +1,35 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Thu, 11 Jul 2013 20:03:56 +0300
+Subject: [PATCH] capes: bacon: Update with new ADC driver method
+
+---
+ firmware/capes/BB-BONE-BACON-00A0.dts | 2 +-
+ firmware/capes/BB-BONE-BACONE-00A0.dts | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/firmware/capes/BB-BONE-BACON-00A0.dts b/firmware/capes/BB-BONE-BACON-00A0.dts
+index d25c1baa..96a1a36 100644
+--- a/firmware/capes/BB-BONE-BACON-00A0.dts
++++ b/firmware/capes/BB-BONE-BACON-00A0.dts
+@@ -85,7 +85,7 @@
+ status = "okay";
+
+ adc {
+- ti,adc-channels = <8>; /* 8 channels (but only 5 is used) */
++ ti,adc-channels = <0 1 2 3 4 5 6 7>; /* 8 channels (but only #5 is used) */
+ };
+ };
+
+diff --git a/firmware/capes/BB-BONE-BACONE-00A0.dts b/firmware/capes/BB-BONE-BACONE-00A0.dts
+index a02173d..07fa753 100644
+--- a/firmware/capes/BB-BONE-BACONE-00A0.dts
++++ b/firmware/capes/BB-BONE-BACONE-00A0.dts
+@@ -80,7 +80,7 @@
+ status = "okay";
+
+ adc {
+- ti,adc-channels = <8>; /* 8 channels (but only 5 is used) */
++ ti,adc-channels = <0 1 2 3 4 5 6 7>; /* 8 channels (but only #5 is used) */
+ };
+ };
+
diff --git a/patches/linux-3.8.13/0652-capes-BACON-Educational-cape-with-free-form-muxing.patch b/patches/linux-3.8.13/0652-capes-BACON-Educational-cape-with-free-form-muxing.patch
new file mode 100644
index 0000000..189117b
--- /dev/null
+++ b/patches/linux-3.8.13/0652-capes-BACON-Educational-cape-with-free-form-muxing.patch
@@ -0,0 +1,234 @@
+From: Pantelis Antoniou <panto@antoniou-consulting.com>
+Date: Mon, 15 Jul 2013 23:00:35 +0300
+Subject: [PATCH] capes: BACON Educational cape with free form muxing
+
+---
+ firmware/Makefile | 3 +-
+ firmware/capes/BB-BONE-BACONE2-00A0.dts | 204 +++++++++++++++++++++++++++++++
+ 2 files changed, 206 insertions(+), 1 deletion(-)
+ create mode 100644 firmware/capes/BB-BONE-BACONE2-00A0.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index d2c6161..cea34e6 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -188,7 +188,8 @@ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
+ TT3201-001-01.dtbo \
+ BB-BONE-SERL-03-00A1.dtbo \
+ BB-BONE-BACON-00A0.dtbo \
+- BB-BONE-BACONE-00A0.dtbo
++ BB-BONE-BACONE-00A0.dtbo \
++ BB-BONE-BACONE2-00A0.dtbo
+
+ # the geiger cape
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE_GEIGER) += \
+diff --git a/firmware/capes/BB-BONE-BACONE2-00A0.dts b/firmware/capes/BB-BONE-BACONE2-00A0.dts
+new file mode 100644
+index 0000000..5118f71
+--- /dev/null
++++ b/firmware/capes/BB-BONE-BACONE2-00A0.dts
+@@ -0,0 +1,204 @@
++/*
++ * Copyright (C) 2013 Circuit Co.
++ *
++ * 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.
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "BB-BONE-BACONE2";
++
++ /* state the resources this cape uses */
++ exclusive-use =
++ /* the pin header uses */
++ "P9.36", /* AIN5 */
++ "P8.19", /* gpio-keys: gpio0_23 */
++ "P9.14", /* pwm: ehrpwm1A */
++ "P9.16", /* pwm: ehrpwm1B */
++ "P9.42", /* pwm: eCAP0_in_PWM0_out */
++ "P9.17", /* shift: gpio0_5 LATCH */
++ "P9.18", /* shift: gpio0_4 SERIAL */
++ "P9.22", /* shift: gpio0_2 CLOCK */
++ /* the hardware IP uses */
++ "tscadc",
++ "gpio0_23",
++ "ehrpwm1A",
++ "ehrpwm1B",
++ "eCAP0_in_PWM0_out",
++ "gpio0_5",
++ "gpio0_4",
++ "gpio0_2";
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ bacon_ehrpwm1_pins: pinmux_bacon_ehrpwm1_pins {
++ pinctrl-single,pins = <
++ 0x048 0x6 /* P9_14 (ZCZ ball U14) | MODE 6 */
++ 0x04c 0x6 /* P9_16 (ZCZ ball T14) | MODE 6 */
++ >;
++ };
++
++ bacon_ecap0_pins: pinmux_bacon_ecap0_pins {
++ pinctrl-single,pins = <
++ 0x164 0x0 /* P9_42 (ZCZ ball C18) | MODE 0 */
++ >;
++ };
++
++ bacon_gpiohelp_pins: pinmux_bacon_gpio_helper_pins {
++ pinctrl-single,pins = <
++ 0x020 0x2f /* gpmc_ad8.gpio0_22, INPUT | PULLDIS | MODE7 */
++ >;
++ };
++
++ bacon_LATCH_in_pins: pinmux_bacon_LATCH_in_pins {
++ pinctrl-single,pins = <
++ 0x15c 0x0f /* P9 17 spi0_cs0.gpio0_5 | MODE7 | OUTPUT */
++ >;
++ };
++
++ bacon_LATCH_out_pins: pinmux_bacon_LATCH_out_pins {
++ pinctrl-single,pins = <
++ 0x15c 0x2f /* P9 17 spi0_cs0.gpio0_5 | MODE7 | PULLDIS | INPUT */
++ >;
++ };
++
++ bacon_SERIAL_in_pins: pinmux_bacon_SERIAL_in_pins {
++ pinctrl-single,pins = <
++ 0x158 0x2f /* P9 18 spi0_d1.gpio0_4 | MODE7 | PULLDIS | INPUT */
++ >;
++ };
++
++ bacon_SERIAL_out_pins: pinmux_bacon_SERIAL_out_pins {
++ pinctrl-single,pins = <
++ 0x158 0x0f /* P9 18 spi0_d1.gpio0_4 | MODE7 | OUTPUT */
++ >;
++ };
++
++ bacon_CLOCK_in_pins: pinmux_bacon_CLOCK_in_pins {
++ pinctrl-single,pins = <
++ 0x150 0x2f /* P9 22 spi0_sclk.gpio0_2 | MODE7 | PULLDIS | INPUT */
++ >;
++ };
++
++ bacon_CLOCK_out_pins: pinmux_bacon_CLOCK_out_pins {
++ pinctrl-single,pins = <
++ 0x150 0x0f /* P9 22 spi0_sclk.gpio0_2 | MODE7 | OUTPUT */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++ /* avoid stupid warning */
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ tscadc {
++ compatible = "ti,ti-tscadc";
++ reg = <0x44e0d000 0x1000>;
++
++ interrupt-parent = <&intc>;
++ interrupts = <16>;
++ ti,hwmods = "adc_tsc";
++ status = "okay";
++
++ adc {
++ ti,adc-channels = <0 1 2 3 4 5 6 7>; /* 8 channels (but only #5 is used) */
++ };
++ };
++
++ bacon_adc_helper {
++ compatible = "bone-iio-helper";
++ vsense-name = "AIN0", "AIN1", "AIN2", "AIN3", "AIN4", "AIN5", "AIN6", "AIN7";
++ /* report micro-volts */
++ vsense-scale = <100000 100000 100000 100000 100000 100000 100000 100000>;
++ status = "okay";
++ };
++ };
++ };
++
++ fragment@3 {
++ target = <&epwmss0>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@4 {
++ target = <&ecap0>;
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&bacon_ecap0_pins>;
++ status = "okay";
++ };
++ };
++
++ fragment@5 {
++ target = <&epwmss1>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@6 {
++ target = <&ehrpwm1>;
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&bacon_ehrpwm1_pins>;
++ status = "okay";
++ };
++ };
++
++ fragment@8 {
++ target = <&ocp>;
++ __overlay__ {
++
++ LATCH_helper {
++ compatible = "bone-pinmux-helper";
++ status = "okay";
++ pinctrl-names = "in", "out";
++ pinctrl-0 = <&bacon_LATCH_in_pins>;
++ pinctrl-1 = <&bacon_LATCH_out_pins>;
++ };
++
++ SERIAL_helper {
++ compatible = "bone-pinmux-helper";
++ status = "okay";
++ pinctrl-names = "in", "out";
++ pinctrl-0 = <&bacon_SERIAL_in_pins>;
++ pinctrl-1 = <&bacon_SERIAL_out_pins>;
++ };
++
++ CLOCK_helper {
++ compatible = "bone-pinmux-helper";
++ status = "okay";
++ pinctrl-names = "in", "out";
++ pinctrl-0 = <&bacon_CLOCK_in_pins>;
++ pinctrl-1 = <&bacon_CLOCK_out_pins>;
++ };
++
++ bacon_gpiohelp {
++ compatible = "gpio-of-helper";
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bacon_gpiohelp_pins>;
++
++ BUTTON {
++ gpio-name = "BUTTON";
++ gpio = <&gpio1 22 0x01>; /* gpio1 is gpio0 */
++ input;
++ };
++ };
++ };
++ };
++};
diff --git a/patches/linux-3.8.13/0653-firmware-add-BeBoPr-cape.patch b/patches/linux-3.8.13/0653-firmware-add-BeBoPr-cape.patch
new file mode 100644
index 0000000..a6b6e2d
--- /dev/null
+++ b/patches/linux-3.8.13/0653-firmware-add-BeBoPr-cape.patch
@@ -0,0 +1,446 @@
+From: Koen Kooi <koen@dominion.thruhere.net>
+Date: Wed, 17 Jul 2013 09:05:27 +0200
+Subject: [PATCH] firmware: add BeBoPr cape
+
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ firmware/Makefile | 1 +
+ firmware/capes/2191-R2.dts | 417 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 418 insertions(+)
+ create mode 100644 firmware/capes/2191-R2.dts
+
+diff --git a/firmware/Makefile b/firmware/Makefile
+index cea34e6..677d634 100644
+--- a/firmware/Makefile
++++ b/firmware/Makefile
+@@ -138,6 +138,7 @@ fw-shipped-$(CONFIG_YAM) += yam/1200.bin yam/9600.bin
+
+ # all the generic capes
+ fw-shipped-$(CONFIG_CAPE_BEAGLEBONE) += \
++ 2191-R2.dtbo \
+ cape-bone-2g-emmc1.dtbo \
+ cape-bone-adafruit-lcd-00A0.dtbo \
+ cape-bone-dvi-00A0.dtbo \
+diff --git a/firmware/capes/2191-R2.dts b/firmware/capes/2191-R2.dts
+new file mode 100644
+index 0000000..d179b05
+--- /dev/null
++++ b/firmware/capes/2191-R2.dts
+@@ -0,0 +1,417 @@
++/*
++ * Copyright (C) 2013 Bas Laarhoven
++ *
++ * 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.
++ *
++ * version 1.1 - 2013-06-17 cleanup for release
++ */
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "aes,bebopr", "ti,beaglebone", "ti,beaglebone-black";
++
++ /* identification */
++ part-number = "2191";
++ version = "R2";
++
++ exclusive-use =
++ /* state the resources this cape uses */
++
++ /* ------ IO POWER ------ */
++
++ "P8.3", /* gpio1.6 gpio38 old Enable */
++ "P8.5", /* gpio1.2 gpio34 old Enablen */
++ "P8.7", /* timer4 gpio66 new Enablen */
++
++ /* ------ PWM ------ */
++
++ "P8.36", /* gpio2.16 J4_PWM */
++ "P8.45", /* pru1.r30.0 J3_PWM */
++ "P8.46", /* pru1.r30.1 J2_PWM */
++ "ehrpwm1A",
++ "ehrpwm2A",
++ "ehrpwm2B",
++
++ /* ------ STEPPERS ------ */
++
++ "P8.41", /* gpio2.10 #X_ENA */
++ "P8.44", /* gpio2.9 #X_DIR */
++ "P8.43", /* gpio2.8 #X_STP */
++ "P8.40", /* gpio2.13 #Y_ENA */
++ "P8.39", /* gpio2.12 #Y_DIR */
++ "P8.42", /* gpio2.11 #Y_STP */
++ "P8.28", /* gpio2.24 #Z_ENA */
++ "P8.29", /* gpio2.23 #Z_DIR */
++ "P8.27", /* gpio2.22 #Z_STP */
++ "P8.20", /* gpio1.31 #E_ENA */
++ "P8.21", /* gpio1.30 #E_DIR */
++ "P8.30", /* gpio2.25 #E_STP */
++ "pru1",
++ "pruss",
++
++ /* ------ SENSORS ------ */
++
++ "P8.31", /* gpio0.10 #X_MIN */
++ "P8.32", /* gpio0.11 #X_MAX */
++ "P8.35", /* gpio0.8 #Y_MIN */
++ "P8.33", /* gpio0.9 #Y_MAX */
++ "P8.38", /* gpio2.15 #Z_MIN */
++ "P8.37", /* gpio2.14 #Z_MAX */
++
++ /* ------ ADC ------ */
++
++ "P9.40", /* AIN1 */
++ "P9.38", /* AIN3 */
++ "P9.36", /* AIN5 */
++ "tscadc",
++
++ /* ------ LED ------ */
++
++ "P8.25"; /* gpio1.0 LED */
++
++
++
++ /* ----------- IO POWER ------------ */
++
++ fragment@0 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ bebopr_io_ena_pins: pinmux_bebopr_io_ena_pins {
++ pinctrl-single,pins = <
++ 0x018 0x07 /* P8-3 GPIO1_6 gpmc_ad6.gpio1[6] */
++ 0x008 0x07 /* P8-5 GPIO1_2 gpmc_ad2.gpio1[2] */
++ 0x090 0x07 /* P8-7 TIMER4 gpmc_advn_ale.gpio2[2] */
++ >;
++ };
++ };
++ };
++
++ fragment@1 {
++ target = <&ocp>;
++ __overlay__ {
++
++ bebopr_io_ena {
++ compatible = "aes,bebopr";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bebopr_io_ena_pins>;
++
++ bebopr-io-enable {
++ label = "bebopr:io_enables";
++ gpios = <&gpio2 2 1>, <&gpio2 6 0>, <&gpio3 2 1>;
++ default-state = "off";
++ };
++ };
++ };
++ };
++
++ /* ----------- PWM ------------ */
++
++ fragment@15 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ P8_46_ehrpwm_pin: pinmux_P8_46_ehrpwm_pin {
++ pinctrl-single,pins = <0x0a4 0x3>; /* P8_46 (ZCZ ball R2) | MODE 3 */
++ };
++
++ P8_46_gpio_pin: pinmux_P8_46_gpio_pin {
++ pinctrl-single,pins = <0x0a4 0x7>; /* P8_46 (ZCZ ball R2) | MODE 7 */
++ };
++
++ P8_46_pruss_pin: pinmux_P8_46_pruss_pin {
++ pinctrl-single,pins = <0x0a4 0x5>; /* P8_46 (ZCZ ball R2) | MODE 5 */
++ };
++
++ P8_45_ehrpwm_pin: pinmux_P8_45_ehrpwm_pin {
++ pinctrl-single,pins = <0x0a0 0x3>; /* P8_45 (ZCZ ball R1) | MODE 3 */
++ };
++
++ P8_45_gpio_pin: pinmux_P8_45_gpio_pin {
++ pinctrl-single,pins = <0x0a0 0x7>; /* P8_45 (ZCZ ball R1) | MODE 7 */
++ };
++
++ P8_45_pruss_pin: pinmux_P8_45_pruss_pin {
++ pinctrl-single,pins = <0x0a0 0x5>; /* P8_45 (ZCZ ball R1) | MODE 5 */
++ };
++
++ P8_36_ehrpwm_pin: pinmux_P8_36_ehrpwm_pin {
++ pinctrl-single,pins = <0x0c8 0x2>; /* P8_36 (ZCZ ball U3) | MODE 2 */
++ };
++
++ P8_36_gpio_pin: pinmux_P8_36_gpio_pin {
++ pinctrl-single,pins = <0x0c8 0x7>; /* P8_36 (ZCZ ball U3) | MODE 7 */
++ };
++ };
++ };
++
++ fragment@16 {
++ target = <&ocp>;
++ __overlay__ {
++
++ bebopr_pwm_J2_pinmux {
++ compatible = "bone-pinmux-helper";
++ status = "okay";
++
++ pinctrl-names = "default", "gpio", "pruss";
++ pinctrl-0 = <&P8_46_ehrpwm_pin>;
++ pinctrl-1 = <&P8_46_gpio_pin>;
++ pinctrl-2 = <&P8_46_pruss_pin>;
++ };
++
++ bebopr_pwm_J3_pinmux {
++ compatible = "bone-pinmux-helper";
++ status = "okay";
++
++ pinctrl-names = "default", "gpio", "pruss";
++ pinctrl-0 = <&P8_45_ehrpwm_pin>;
++ pinctrl-1 = <&P8_45_gpio_pin>;
++ pinctrl-2 = <&P8_45_pruss_pin>;
++ };
++
++ bebopr_pwm_J4_pinmux {
++ compatible = "bone-pinmux-helper";
++ status = "okay";
++
++ pinctrl-names = "default", "gpio";
++ pinctrl-0 = <&P8_36_ehrpwm_pin>;
++ pinctrl-1 = <&P8_36_gpio_pin>;
++ };
++
++ bebopr_pwm_J2 {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm2 1 10000000 0>;
++ pwm-names = "PWM_J2_FAN";
++ enabled = <0>;
++ duty = <0>;
++ status = "okay";
++ };
++
++ bebopr_pwm_J3 {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm2 0 10000000 0>;
++ pwm-names = "PWM_J3_EXTR";
++ enabled = <0>;
++ duty = <0>;
++ status = "okay";
++ };
++
++ bebopr_pwm_J4 {
++ compatible = "pwm_test";
++ pwms = <&ehrpwm1 0 100000000 0>;
++ pwm-names = "PWM_J4_BED";
++ enabled = <0>;
++ duty = <0>;
++ status = "okay";
++ };
++ };
++ };
++
++ fragment@11 {
++ target = <&epwmss1>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@12 {
++ target = <&ehrpwm1>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@13 {
++ target = <&epwmss2>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ fragment@14 {
++ target = <&ehrpwm2>;
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ /* ----------- STEPPERS ------------ */
++
++ fragment@21 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ bebopr_pruss_pins: pinmux_bebopr_pruss_pins {
++ status = "okay";
++ pinctrl-single,pins = <
++ 0xb0 5 /* #X_ENA, pr1_pru1_pru_r30_4, P8_41, gpio2.10, mode5 out */
++ 0xac 5 /* #X_DIR, pr1_pru1_pru_r30_3, P8_44, gpio2.9, mode5 out */
++ 0xa8 5 /* #X_STP, pr1_pru1_pru_r30_2, P8_43, gpio2.8, mode5 out */
++ 0xbc 5 /* #Y_ENA, pr1_pru1_pru_r30_7, P8_40, gpio2.13, mode5 out */
++ 0xb8 5 /* #Y_DIR, pr1_pru1_pru_r30_6, P8_39, gpio2.12, mode5 out */
++ 0xb4 5 /* #Y_STP, pr1_pru1_pru_r30_5, P8_42, gpio2.11, mode5 out */
++ 0xe8 5 /* #Z_ENA, pr1_pru1_pru_r30_10, P8_28, gpio2.24, mode5 out */
++ 0xe4 5 /* #Z_DIR, pr1_pru1_pru_r30_9, P8_29, gpio2.23, mode5 out */
++ 0xe0 5 /* #Z_STP, pr1_pru1_pru_r30_8, P8_27, gpio2.22, mode5 out */
++ 0x84 5 /* #E_ENA, pr1_pru1_pru_r30_13, P8_20, gpio1.31, mode5 out */
++ 0x80 5 /* #E_DIR, pr1_pru1_pru_r30_12, P8_21, gpio1.30, mode5 out */
++ 0xec 5 /* #E_STP, pr1_pru1_pru_r30_11, P8_30, gpio2.25, mode5 out */
++ >;
++ };
++ };
++ };
++
++
++ fragment@22 {
++ target = <&pruss>;
++ __overlay__ {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bebopr_pruss_pins>;
++ };
++ };
++
++ fragment@23 {
++ target = <&ocp>;
++ __overlay__ {
++
++ bebopr_pruss {
++ compatible = "pruss_uio";
++ status = "okay";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&bebopr_pruss_pins>;
++
++ stepper_x {
++ pin-names = "bebopr:x_ena", "bebopr:x_dir", "bebpor:x_stp";
++ gpios = <&gpio3 10 0>, <&gpio3 9 0>, <&gpio3 8 0>;
++ };
++ stepper_y {
++ pin-names = "bebopr:y_ena", "bebopr:y_dir", "bebpor:y_stp";
++ gpios = <&gpio3 13 0>, <&gpio3 12 0>, <&gpio3 11 0>;
++ };
++ stepper_z {
++ pin-names = "bebopr:z_ena", "bebopr:z_dir", "bebpor:z_stp";
++ gpios = <&gpio3 24 0>, <&gpio3 23 0>, <&gpio3 22 0>;
++ };
++ stepper_e {
++ pin-names = "bebopr:e_ena", "bebopr:e_dir", "bebpor:e_stp";
++ gpios = <&gpio2 31 0>, <&gpio2 30 0>, <&gpio3 25 0>;
++ };
++ };
++ };
++ };
++
++ /* ----------- SENSORS ------------ */
++
++ fragment@31 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ bebopr_sensor_pins: pinmux_bebopr_sensor_pins {
++ pinctrl-single,pins = <
++ /* all inputs with pull-downs */
++ 0xd8 0x2f /* #X_MIN, P8_31, gpio0.10, mode7 in */
++ 0xdc 0x2f /* #X_MAX, P8_32, gpio0.11, mode7 in */
++ 0xd0 0x2f /* #Y_MIN, P8_35, gpio0.8, mode7 in */
++ 0xd4 0x2f /* #Y_MAX, P8_33, gpio0.9 , mode7 in */
++ 0xc4 0x2f /* #Z_MIN, P8_38, gpio2.15, mode7 in */
++ 0xc0 0x2f /* #Z_MAX, P8_37, gpio2.14, mode7 in */
++ >;
++ };
++ };
++ };
++
++ fragment@33 {
++ target = <&ocp>;
++ __overlay__ {
++
++ compatible = "bone-pinmux-helper";
++
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bebopr_sensor_pins>;
++
++ sensors_x {
++ pin-names = "bebopr:x_min", "bebopr:x_max";
++ gpios = <&gpio1 10 0>, <&gpio1 11 0>;
++ };
++ sensors_y {
++ pin-names = "bebopr:y_min", "bebopr:y_max";
++ gpios = <&gpio1 8 0>, <&gpio1 9 0>;
++ };
++ sensors_z {
++ pin-names = "bebopr:z_min", "bebopr:z_max";
++ gpios = <&gpio3 15 0>, <&gpio3 14 0>;
++ };
++ };
++ };
++
++ /* ----------- ADC ------------ */
++
++ fragment@41 {
++ target = <&ocp>;
++ __overlay__ {
++
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ tscadc {
++ compatible = "ti,ti-tscadc";
++ reg = <0x44e0d000 0x1000>;
++ interrupt-parent = <&intc>;
++ interrupts = <16>;
++ ti,hwmods = "adc_tsc";
++ status = "okay";
++ adc {
++ ti,adc-channels = <8>;
++ };
++ };
++
++ bebopr_adc {
++ compatible = "bone-iio-helper";
++ vsense-name = "AIN0", "AIN1", "AIN2", "AIN3", "AIN4", "AIN5", "AIN6", "AIN7";
++ vsense-scale = < 228 228 228 228 228 228 228 228>;
++ status = "okay";
++ };
++ };
++ };
++
++ /* ----------- LED ------------ */
++
++ fragment@51 {
++ target = <&am33xx_pinmux>;
++ __overlay__ {
++
++ bebopr_led_pins: pinmux_bebopr_led_pins {
++ pinctrl-single,pins = <
++ 0x000 0x07 /* P8-25 GPIO1_0 gpmc_ad0 .gpio1[0] */
++ >;
++ };
++ };
++ };
++
++
++ fragment@52 {
++ target = <&ocp>;
++ __overlay__ {
++
++ bebopr_leds {
++ compatible = "gpio-leds";
++ pinctrl-names = "default";
++ pinctrl-0 = <&bebopr_led_pins>;
++
++ status_led {
++ label = "bebopr:status_led";
++ gpios = <&gpio2 0 0>;
++ linux,default-trigger = "heartbeat";
++ default-state = "off";
++ };
++ };
++ };
++ };
++
++};
diff --git a/patches/linux-3.8.13/0701-Release-distrokit-beaglebone-20130720.patch b/patches/linux-3.8.13/0701-Release-distrokit-beaglebone-20130720.patch
new file mode 100644
index 0000000..cf75680
--- /dev/null
+++ b/patches/linux-3.8.13/0701-Release-distrokit-beaglebone-20130720.patch
@@ -0,0 +1,22 @@
+From: Jan Luebbe <jlu@pengutronix.de>
+Date: Sat, 20 Jul 2013 14:27:34 +0200
+Subject: [PATCH] Release distrokit/beaglebone/20130720
+
+Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
+---
+ Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index 183eff3..0bef6ba 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ VERSION = 3
+ PATCHLEVEL = 8
+ SUBLEVEL = 13
+-EXTRAVERSION =
++EXTRAVERSION =-20130720
+ NAME = Displaced Humerus Anterior
+
+ # *DOCUMENTATION*
diff --git a/patches/linux-3.8.13/series b/patches/linux-3.8.13/series
new file mode 100644
index 0000000..ae0b3f4
--- /dev/null
+++ b/patches/linux-3.8.13/series
@@ -0,0 +1,663 @@
+# umpf-base: v3.8.13
+# umpf-name: distrokit/beaglebone
+# umpf-version: distrokit/beaglebone/20130720
+# umpf-topic: topic/distrokit/beaglebone/board
+# umpf-hashinfo: 6fbec96b98a35ba475bb821a60c903566f35a575
+# umpf-topic-range: dbf932a9b316d5b29b3e220e5a30e7a165ad2992..6fbec96b98a35ba475bb821a60c903566f35a575
+0001-Without-MACH_-option-Early-printk-DEBUG_LL.patch
+0002-ARM-OMAP-Hack-AM33xx-clock-data-to-allow-JTAG-use.patch
+0003-video-st7735fb-add-st7735-framebuffer-driver.patch
+0004-dmaengine-add-helper-function-to-request-a-slave-DMA.patch
+0005-of-Add-generic-device-tree-DMA-helpers.patch
+0006-of-dma-fix-build-break-for-CONFIG_OF.patch
+0007-of-dma-fix-typos-in-generic-dma-binding-definition.patch
+0008-dmaengine-fix-build-failure-due-to-missing-semi-colo.patch
+0009-dmaengine-edma-fix-slave-config-dependency-on-direct.patch
+0010-dmaengine-add-dma_get_channel_caps.patch
+0011-dma-edma-add-device_channel_caps-support.patch
+0012-mmc-davinci-get-SG-segment-limits-with-dma_get_chann.patch
+0013-ARM-davinci-move-private-EDMA-API-to-arm-common.patch
+0014-ARM-edma-remove-unused-transfer-controller-handlers.patch
+0015-ARM-edma-add-AM33XX-support-to-the-private-EDMA-API.patch
+0016-dmaengine-edma-enable-build-for-AM33XX.patch
+0017-dmaengine-edma-Add-TI-EDMA-device-tree-binding.patch
+0018-ARM-dts-add-AM33XX-EDMA-support.patch
+0019-dmaengine-add-dma_request_slave_channel_compat.patch
+0020-mmc-omap_hsmmc-convert-to-dma_request_slave_channel_.patch
+0021-mmc-omap_hsmmc-set-max_segs-based-on-dma-engine-limi.patch
+0022-mmc-omap_hsmmc-add-generic-DMA-request-support-to-th.patch
+0023-ARM-dts-add-AM33XX-MMC-support.patch
+0024-spi-omap2-mcspi-convert-to-dma_request_slave_channel.patch
+0025-spi-omap2-mcspi-add-generic-DMA-request-support-to-t.patch
+0026-ARM-dts-add-AM33XX-SPI-DMA-support.patch
+0027-ARM-dts-Add-SPI-Flash-support-to-am335x-evm.patch
+0028-Documentation-bindings-add-spansion.patch
+0029-ARM-dts-enable-spi1-node-and-pinmux-on-BeagleBone.patch
+0030-ARM-dts-add-BeagleBone-Adafruit-1.8-LCD-support.patch
+0031-misc-add-gpevt-driver.patch
+0032-ARM-dts-add-BeagleBone-gpevt-support.patch
+0033-ARM-configs-working-dmaengine-configs-for-da8xx-and-.patch
+0034-ARM-dts-Add-UART4-support-to-BeagleBone.patch
+0035-gpevnt-Remove-__devinit.patch
+0036-ARM-OMAP2-am33xx-hwmod-Fix-register-offset-NULL-chec.patch
+0037-rtc-OMAP-Add-system-pm_power_off-to-rtc-driver.patch
+0038-ARM-dts-AM33XX-Set-pmic-shutdown-controller-for-Beag.patch
+0039-ARM-dts-AM33XX-Enable-system-power-off-control-in-am.patch
+0040-i2c-pinctrl-ify-i2c-omap.c.patch
+0041-arm-dts-AM33XX-Configure-pinmuxs-for-user-leds-contr.patch
+0042-beaglebone-DT-set-default-triggers-for-LEDS.patch
+0043-beaglebone-add-a-cpu-led-trigger.patch
+0044-am33xx-DT-add-commented-out-OPP-values-for-ES2.0.patch
+0045-mfd-input-iio-ti_am335x_adc-use-one-structure-for-ti.patch
+0046-input-ti_am33x_tsc-Step-enable-bits-made-configurabl.patch
+0047-input-ti_am33x_tsc-Order-of-TSC-wires-made-configura.patch
+0048-input-ti_am33x_tsc-remove-unwanted-fifo-flush.patch
+0049-input-ti_am33x_tsc-Add-DT-support.patch
+0050-iio-ti_am335x_adc-Add-DT-support.patch
+0051-arm-dts-AM335x-evm-Add-TSC-ADC-MFD-device-support.patch
+0052-mfd-ti_am335x_tscadc-Add-DT-support.patch
+0053-iio-ti_tscadc-provide-datasheet_name-and-scan_type.patch
+0054-mfd-ti_tscadc-deal-with-partial-activation.patch
+0055-input-ti_am335x_adc-use-only-FIFO0-and-clean-up-a-li.patch
+0056-input-ti_am335x_tsc-ACK-the-HW_PEN-irq-in-ISR.patch
+0057-input-ti_am335x_tsc-return-IRQ_NONE-if-there-was-no-.patch
+0058-iio-ti_am335x_adc-Allow-to-specify-input-line.patch
+0059-iio-ti_am335x_adc-check-if-we-found-the-value.patch
+0060-MFD-ti_tscadc-disable-TSC-control.patch
+0061-IIO-ADC-ti_adc-Fix-1st-sample-read.patch
+0062-input-ti_tsc-Enable-shared-IRQ-TSC.patch
+0063-Revert.-Backport-IIO.patch
+0064-iio-ti_am335x_adc-Added-iio_voltageX_scale.patch
+0065-iio-ti_am335x_adc-Add-the-in-kernel-IIO-map-interfac.patch
+0066-pinctrl-pinctrl-single-must-be-initialized-early.patch
+0067-Bone-DTS-working-i2c2-i2c3-in-the-tree.patch
+0068-am33xx-Convert-I2C-from-omap-to-am33xx-names.patch
+0069-am335x-evm-hack-around-i2c-node-names.patch
+0070-tsl2550-fix-lux1_input-error-in-low-light.patch
+0071-viafb-rename-display_timing-to-via_display_timing.patch
+0072-video-add-display_timing-and-videomode.patch
+0073-video-add-of-helper-for-display-timings-videomode.patch
+0074-fbmon-add-videomode-helpers.patch
+0075-fbmon-add-of_videomode-helpers.patch
+0076-drm_modes-add-videomode-helpers.patch
+0077-drm_modes-add-of_videomode-helpers.patch
+0078-fbmon-fix-build-error.patch
+0079-of-display-timings-use-of_get_child_by_name.patch
+0080-da8xx-Allow-use-by-am33xx-based-devices.patch
+0081-video-da8xx-fb-fb_check_var-enhancement.patch
+0082-video-da8xx-fb-simplify-lcd_reset.patch
+0083-video-da8xx-fb-use-modedb-helper-to-update-var.patch
+0084-video-da8xx-fb-remove-unneeded-var-initialization.patch
+0085-video-da8xx-fb-store-current-display-information.patch
+0086-video-da8xx-fb-store-clk-rate-even-if-CPUFREQ.patch
+0087-video-da8xx-fb-pix-clk-and-clk-div-handling-cleanup.patch
+0088-video-da8xx-fb-store-struct-device.patch
+0089-video-da8xx-fb-report-correct-pixclock.patch
+0090-video-da8xx-fb-fb_set_par-support.patch
+0091-ARM-dts-AM33XX-Add-lcdc-node.patch
+0092-ARM-dts-AM33XX-Add-am335x-evm-lcdc-panel-timings.patch
+0093-ARM-dts-AM33XX-Add-am335x-evm-lcdc-pincontrol-info.patch
+0094-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-panel-timings.patch
+0095-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-pincontrol-info.patch
+0096-ARM-OMAP-AM33xx-hwmod-Corrects-PWM-subsystem-HWMOD-e.patch
+0097-ARM-OMAP-AM33xx-hwmod-Add-parent-child-relationship-.patch
+0098-ARM-dts-AM33XX-Add-PWMSS-device-tree-nodes.patch
+0099-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch
+0100-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch
+0101-clk-divider-prepare-for-minimum-divider.patch
+0102-clk-divider-handle-minimum-divider.patch
+0103-ARM-OMAP2-dpll-round-rate-to-closest-value.patch
+0104-ARM-OMAP2-dpll-am335x-avoid-freqsel.patch
+0105-ARM-OMAP2-clock-DEFINE_STRUCT_CLK_FLAGS-helper.patch
+0106-ARM-AM33XX-clock-SET_RATE_PARENT-in-lcd-path.patch
+0107-video-da8xx-fb-make-io-operations-safe.patch
+0108-video-da8xx-fb-fix-24bpp-raster-configuration.patch
+0109-video-da8xx-fb-enable-sync-lost-intr-for-v2-ip.patch
+0110-video-da8xx-fb-use-devres.patch
+0111-video-da8xx-fb-ensure-non-null-cfg-in-pdata.patch
+0112-video-da8xx-fb-reorganize-panel-detection.patch
+0113-video-da8xx-fb-minimal-dt-support.patch
+0114-video-da8xx-fb-invoke-platform-callback-safely.patch
+0115-video-da8xx-fb-obtain-fb_videomode-info-from-dt.patch
+0116-video-da8xx-fb-ensure-pdata-only-for-non-dt.patch
+0117-video-da8xx-fb-setup-struct-lcd_ctrl_config-for-dt.patch
+0118-video-da8xx-fb-CCF-clock-divider-handling.patch
+0119-pwm_backlight-Add-device-tree-support-for-Low-Thresh.patch
+0120-Control-module-EHRPWM-clk-enabling.patch
+0121-pwm-pwm_test-Driver-support-for-PWM-module-testing.patch
+0122-ARM-OMAP2-PWM-limit-am33xx_register_ehrpwm-to-soc_is.patch
+0123-pwm-export-of_pwm_request.patch
+0124-pwm-pwm-tiehrpwm-Update-the-clock-handling-of-pwm-ti.patch
+0125-ARM-AM33XX-clk-Add-clock-node-for-EHRPWM-TBCLK.patch
+0126-HACK-am33xx.dtsi-turn-on-all-PWMs.patch
+0127-pwm-add-sysfs-interface.patch
+0128-am33xx.dtsi-enable-MMC-HSPE-bit-for-all-3-controller.patch
+0129-omap-hsmmc-Correct-usage-of-of_find_node_by_name.patch
+0130-ARM-OMAP2xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch
+0131-ARM-OMAP2xxx-hwmod-Add-DMA-support-for-SHAM-module.patch
+0132-ARM-OMAP3xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch
+0133-ARM-OMAP2-Remove-unnecessary-message-when-no-SHA-IP-.patch
+0134-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch
+0135-ARM-AM33XX-Add-sha0-crypto-clock-data.patch
+0136-ARM-AM33XX-hwmod-Update-and-uncomment-SHA0-module-da.patch
+0137-ARM-dts-Add-SHAM-data-and-documentation-for-AM33XX.patch
+0138-ARM-OMAP2xxx-hwmod-Convert-AES-crypto-devcie-data-to.patch
+0139-ARM-OMAP3xxx-hwmod-Convert-AES-crypto-device-data-to.patch
+0140-ARM-OMAP2-Remove-unnecessary-message-when-no-AES-IP-.patch
+0141-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch
+0142-ARM-AM33XX-Add-aes0-crypto-clock-data.patch
+0143-ARM-AM33XX-hwmod-Update-and-uncomment-AES0-module-da.patch
+0144-ARM-dts-Add-AES-data-and-documentation-for-AM33XX.patch
+0145-crypto-omap-sham-Remove-unnecessary-pr_info-noise.patch
+0146-crypto-omap-sham-Convert-to-use-pm_runtime-API.patch
+0147-crypto-omap-sham-Add-suspend-resume-support.patch
+0148-crypto-omap-sham-Add-code-to-use-dmaengine-API.patch
+0149-crypto-omap-sham-Remove-usage-of-private-DMA-API.patch
+0150-crypto-omap-sham-Add-Device-Tree-Support.patch
+0151-crypto-omap-sham-Convert-to-dma_request_slave_channe.patch
+0152-crypto-omap-sham-Add-OMAP4-AM33XX-SHAM-Support.patch
+0153-crypto-omap-sham-Add-SHA224-and-SHA256-Support.patch
+0154-crypto-omap-aes-Remmove-unnecessary-pr_info-noise.patch
+0155-crypto-omap-aes-Don-t-reset-controller-for-every-ope.patch
+0156-crypto-omap-aes-Convert-to-use-pm_runtime-API.patch
+0157-crypto-omap-aes-Add-suspend-resume-support.patch
+0158-crypto-omap-aes-Add-code-to-use-dmaengine-API.patch
+0159-crypto-omap-aes-Remove-usage-of-private-DMA-API.patch
+0160-crypto-omap-aes-Add-Device-Tree-Support.patch
+0161-crypto-omap-aes-Convert-to-dma_request_slave_channel.patch
+0162-crypto-omap-aes-Add-OMAP4-AM33XX-AES-Support.patch
+0163-crypto-omap-aes-Add-CTR-algorithm-Support.patch
+0164-6lowpan-Refactor-packet-delivery-into-a-function.patch
+0165-6lowpan-Handle-uncompressed-IPv6-packets-over-6LoWPA.patch
+0166-wpan-whitespace-fix.patch
+0167-6lowpan-use-stack-buffer-instead-of-heap.patch
+0168-wpan-use-stack-buffer-instead-of-heap.patch
+0169-mrf24j40-pinctrl-support.patch
+0170-mrf24j40-Warn-if-transmit-interrupts-timeout.patch
+0171-mrf24j40-Increase-max-SPI-speed-to-10MHz.patch
+0172-mrf24j40-Fix-byte-order-of-IEEE-address.patch
+0173-6lowpan-lowpan_is_iid_16_bit_compressable-does-not-d.patch
+0174-6lowpan-next-header-is-not-properly-set-upon-decompr.patch
+0175-6lowpan-always-enable-link-layer-acknowledgments.patch
+0176-mac802154-turn-on-ACK-when-enabled-by-the-upper-laye.patch
+0177-6lowpan-use-short-IEEE-802.15.4-addresses-for-broadc.patch
+0178-6lowpan-fix-first-fragment-FRAG1-handling.patch
+0179-6lowpan-add-debug-messages-for-6LoWPAN-fragmentation.patch
+0180-6lowpan-store-fragment-tag-values-per-device-instead.patch
+0181-mac802154-add-mac802154_dev_get_dsn.patch
+0182-6lowpan-obtain-IEEE802.15.4-sequence-number-from-the.patch
+0183-6lowpan-use-the-PANID-provided-by-the-device-instead.patch
+0184-6lowpan-modify-udp-compression-uncompression-to-matc.patch
+0185-6lowpan-fix-a-small-formatting-issue.patch
+0186-6lowpan-use-IEEE802154_ADDR_LEN-instead-of-a-magic-n.patch
+0187-gpio-keys-Pinctrl-fy.patch
+0188-tps65217-Allow-placement-elsewhere-than-parent-mfd-d.patch
+0189-pwm-backlight-Pinctrl-fy.patch
+0190-ARM-CUSTOM-Build-a-uImage-with-dtb-already-appended.patch
+0191-beaglebone-create-a-shared-dtsi-for-beaglebone-based.patch
+0192-beaglebone-enable-emmc-for-bonelt.patch
+0193-Fix-appended-dtb-rule.patch
+0194-deb-pkg-Simplify-architecture-matching-for-cross-bui.patch
+0195-Without-MACH_-option-Early-printk-DEBUG_LL.patch
+0196-ARM-7668-1-fix-memset-related-crashes-caused-by-rece.patch
+0197-ARM-7670-1-fix-the-memset-fix.patch
+0198-regulator-core-if-voltage-scaling-fails-restore-orig.patch
+0199-omap2-twl-common-Add-default-power-configuration.patch
+0200-omap2-irq-fix-interrupt-latency.patch
+0201-OMAP-DSS2-add-bootarg-for-selecting-svideo.patch
+0202-video-add-timings-for-hd720.patch
+0203-Beagle-expansion-add-buddy-param-for-expansionboard-.patch
+0204-Beagle-expansion-add-zippy.patch
+0205-Beagle-expansion-add-zippy2.patch
+0206-Beagle-expansion-add-trainer.patch
+0207-Beagle-expansion-add-CircuitCo-ulcd-Support.patch
+0208-Beagle-expansion-add-wifi.patch
+0209-Beagle-expansion-add-beaglefpga.patch
+0210-Beagle-expansion-add-spidev.patch
+0211-Beagle-expansion-add-Aptina-li5m03-camera.patch
+0212-Beagle-expansion-add-LSR-COM6L-Adapter-Board.patch
+0213-meego-modedb-add-Toshiba-LTA070B220F-800x480-support.patch
+0214-backlight-Add-TLC59108-backlight-control-driver.patch
+0215-tlc59108-adjust-for-beagleboard-uLCD7.patch
+0216-zeroMAP-Open-your-eyes.patch
+0217-ARM-OMAP-Beagle-use-TWL4030-generic-reset-script.patch
+0218-panda-fix-wl12xx-regulator.patch
+0219-ti-st-st-kim-fixing-firmware-path.patch
+0220-am33xx-cpsw-default-to-ethernet-hwaddr-from-efuse-if.patch
+0221-Attempted-SMC911x-BQL-patch.patch
+0222-cpsw-Fix-interrupt-storm-among-other-things.patch
+0223-beaglebone-TT3201-MCP2515-fixes.patch
+0224-add-proper-db.txt-for-CRDA.patch
+0225-mcp251x-add-device-tree-support.patch
+0226-am33xx-Add-clock-for-the-lcdc-DRM-driver.patch
+0227-drm-small-fix-in-drm_send_vblank_event.patch
+0228-drm-cma-add-debugfs-helpers.patch
+0229-drm-i2c-encoder-helper-wrappers.patch
+0230-drm-nouveau-use-i2c-encoder-helper-wrappers.patch
+0231-drm-i2c-give-i2c-it-s-own-Kconfig.patch
+0232-drm-tilcdc-add-TI-LCD-Controller-DRM-driver-v4.patch
+0233-drm-i2c-nxp-tda998x-v3.patch
+0234-drm-tilcdc-add-encoder-slave.patch
+0235-drm-tilcdc-add-support-for-LCD-panels-v5.patch
+0236-drm-lcdc-Power-control-GPIO-support.patch
+0237-drm-tilcdc-Fix-scheduling-while-atomic-from-irq-hand.patch
+0238-add-dvi-pinmuxes-to-am33xx.dtsi.patch
+0239-add-defconfig-file-to-use-as-.config.patch
+0240-am33xx-musb-Add-OF-definitions.patch
+0241-Mark-the-device-as-PRIVATE.patch
+0242-omap_hsmmc-Bug-fixes-pinctl-gpio-reset.patch
+0243-tps65217-bl-Locate-backlight-node-correctly.patch
+0244-arm-Export-cache-flush-management-symbols-when-MULTI.patch
+0245-am335x-bone-dtsi-Clean-up.patch
+0246-am335x-bone-dtsi-Introduce-new-I2C-entries.patch
+0247-am335x-dt-Add-I2C0-pinctrl-entries.patch
+0248-Cleanup-am33xx.dtsi.patch
+0249-Fix-platform-device-resource-linking.patch
+0250-Link-platform-device-resources-properly.patch
+0251-Properly-handle-resources-for-omap_devices.patch
+0252-omap-Avoid-crashes-in-the-case-of-hwmod-misconfigura.patch
+0253-i2c-EEPROM-In-kernel-memory-accessor-interface.patch
+0254-Fix-util_is_printable_string.patch
+0255-fdtdump-properly-handle-multi-string-properties.patch
+0256-dtc-Dynamic-symbols-fixup-support.patch
+0257-dtc-Add-DTCO-rule-for-DTB-objects.patch
+0258-OF-Compile-Device-Tree-sources-with-resolve-option.patch
+0259-firmware-update-.gitignore-with-dtbo-objects.patch
+0260-OF-Introduce-device-tree-node-flag-helpers.patch
+0261-OF-export-of_property_notify.patch
+0262-OF-Export-all-DT-proc-update-functions.patch
+0263-OF-Introduce-utility-helper-functions.patch
+0264-OF-Introduce-Device-Tree-resolve-support.patch
+0265-OF-Introduce-DT-overlay-support.patch
+0266-capemgr-Capemgr-makefiles-and-Kconfig-fragments.patch
+0267-capemgr-Beaglebone-capemanager.patch
+0268-capemgr-Add-beaglebone-s-cape-driver-bindings.patch
+0269-capemgr-am33xx-family-DT-bindings.patch
+0270-bone-geiger-Geiger-bone-driver.patch
+0271-capemgr-firmware-makefiles-for-DT-objects.patch
+0272-capemgr-emmc2-cape-definition.patch
+0273-capemgr-DVI-capes-definitions.patch
+0274-capemgr-Geiger-cape-definition.patch
+0275-capemgr-LCD3-cape-definition.patch
+0276-capemgr-Add-weather-cape-definition.patch
+0277-ehrpwm-add-missing-dts-nodes.patch
+0278-am33xx-DT-Update-am33xx.dsi-with-the-new-PWM-DT-bind.patch
+0279-geiger-cape-Update-to-using-the-new-PWM-interface.patch
+0280-lcd3-cape-Change-into-using-the-lcdc-DRM-driver-inst.patch
+0281-am33xx-Add-default-config.patch
+0282-lcd3-cape-Convert-to-using-the-proper-touchscreen-dr.patch
+0283-geiger-cape-Convert-to-using-the-new-ADC-driver.patch
+0284-cape-dvi-Convert-DVI-capes-to-the-new-LCDC-DRM-drive.patch
+0285-boneblack-Add-default-HDMI-cape.patch
+0286-cape-bone-dvi-Use-720p-mode-as-default.patch
+0287-am33xx.dtsi-Make-the-MUSB-not-crash-on-load.patch
+0288-regulator-DUMMY_REGULATOR-should-work-for-OF-too.patch
+0289-OF-Overlay-Remove-excessive-debugging-crud.patch
+0290-of-i2c-Export-single-device-registration-method.patch
+0291-OF-Overlay-I2C-client-devices-special-handling.patch
+0292-omap-Fix-bug-on-partial-resource-addition.patch
+0293-ASoC-davinci-mcasp-Add-pinctrl-support.patch
+0294-ASoC-Davinci-machine-Add-device-tree-binding.patch
+0295-am33xx-Add-mcasp0-and-mcasp1-device-tree-entries.patch
+0296-ASoC-dts-OMAP2-AM33xx-HACK-Add-missing-dma-info.patch
+0297-ASoC-Davinci-McASP-remove-unused-header-include.patch
+0298-ASoC-AM33XX-Add-support-for-AM33xx-SoC-Audio.patch
+0299-am33xx-mcasp-Add-dma-channel-definitions.patch
+0300-ARM-OMAP2-AM33xx-removed-invalid-McASP-HWMOD-data.patch
+0301-davinci-evm-Header-include-move-fix.patch
+0302-bone-dvi-cape-Add-DT-definition-for-00A2-revision.patch
+0303-bone-dvi-cape-Update-A1-cape-definition-with-sound.patch
+0304-sndsoc-mcasp-Get-DMA-channels-via-byname.patch
+0305-sound-soc-Davinci-Remove-__devinit-__devexit.patch
+0306-st7735fb-Remove-__devinit-__devexit.patch
+0307-capemgr-Remove-__devinit-__devexit.patch
+0308-capes-fw-target-firmware-directory-change.patch
+0309-am33xx-edma-Always-update-unused-channel-list.patch
+0310-defconfig-Update-bone-default-config.patch
+0311-capes-add-dvi-a2-and-lcd3-a2-dts-files.patch
+0312-capemgr-catch-up-with-lcdc-tilcdc-rename.patch
+0313-firmware-fix-dvi-a1-target.patch
+0314-capes-remove-tda-from-hdmi-cape-lcdc-handles-it-by-t.patch
+0315-tilcdc-magic-debug-statement-makes-power-gpio-work-o.patch
+0316-capemgr-add-dts-overlay-for-LCD7-00A2-cape.patch
+0317-HACK-am33xx.dtsi-enable-all-PWMs.patch
+0318-beaglebone-Add-nixie-cape-prototype-driver.patch
+0319-beaglebone-Add-nixie-cape-device-tree-entry.patch
+0320-am335x-bone-common.dtsi-Cleanup-test-remnants.patch
+0321-omap_hsmmc-Add-ti-vcc-aux-disable-is-sleep-DT-proper.patch
+0322-bone-common-ti-vcc-aux-disable-is-sleep-enable.patch
+0323-am33xx-disable-NAPI.patch
+0324-capemgr-Fixed-AIN-name-display-in-error-message.patch
+0325-am33xx.dtsi-remove-duplicate-nodes.patch
+0326-cape-dtbos-update-to-latest-OF-videomode-bindings.patch
+0327-beaglebone-uncomment-eMMC-override.patch
+0328-bone-capes-Update-with-new-tscadc-bindings.patch
+0329-am33xx.dtsi-Update-and-disable-status-of-nodes.patch
+0330-bone-capes-Adapt-to-new-pwms-setup.patch
+0331-tilcdc-introduce-panel-tfp410-power-down-gpio-contro.patch
+0332-bone-dvi-Update-to-new-style-tilcdc-bindings.patch
+0333-tilcdc-tfp410-Rework-power-down-GPIO-logic.patch
+0334-tilcdc-Add-reduced-blanking-mode-checks.patch
+0335-cape-dvi-Switch-all-DVI-capes-to-using-the-TFTP410-p.patch
+0336-beaglebone-switch-eMMC-to-8bit-mode.patch
+0337-Pinmux-helper-driver.patch
+0338-OF-Clear-detach-flag-on-attach.patch
+0339-OF-overlay-Fix-overlay-revert-failure.patch
+0340-bone-capemgr-Make-sure-cape-removal-works.patch
+0341-bone-capemgr-Fix-crash-when-trying-to-remove-non-exi.patch
+0342-beaglebone-LCD7-cape-enable-PWM-and-allow-the-specif.patch
+0343-bone-capemgr-Introduce-pinmux-helper.patch
+0344-bone-geiger-Fix-comment-to-match-the-contents.patch
+0345-of-overlay-Handle-I2C-devices-already-registered-by-.patch
+0346-pinmux-helper-Add-runtime-configuration-capability.patch
+0347-pinmux-helper-Switch-to-using-kmalloc.patch
+0348-i2c-DTify-pca954x-driver.patch
+0349-tty-Add-JHD629-I2C-LCD-Keypad-TTY-driver.patch
+0350-grove-i2c-Add-rudimentary-grove-i2c-motor-control-dr.patch
+0351-tty-jhd629-i2c-Clean-keypad-buffer-when-starting.patch
+0352-am335x-bone-common-Remove-SPI-unused-pinmux-config.patch
+0353-bone-capemgr-Force-a-slot-to-load-unconditionally.patch
+0354-beaglebone-Added-Adafruit-prototype-cape.patch
+0355-tilcdc-Enable-reduced-blanking-check-only-on-DVI-sla.patch
+0356-cape-adafruit-Use-the-correct-spi-bus-spi1-no-spi0.patch
+0357-BBB-tester-Introduce-board-DTS.patch
+0358-BBB-tester-Introduce-cape-describing-the-contents-of.patch
+0359-bone-tester-Add-overrides-for-BB-BONE-TESTER.patch
+0360-cape-tester-Add-uart-specific-default-pinmux-state.patch
+0361-cape-tester-Add-pinmux-helper-for-drvvbus-gpio.patch
+0362-cape-Added-support-for-IIO-helper-cape.patch
+0363-cape-Added-example-IIO-tester-dynamics-overlay.patch
+0364-docs-Added-capemanager-extra_override-usage.patch
+0365-capemgr-Added-module-param-descriptions.patch
+0366-beaglebone-Add-Adafruit-RTC-prototype-cape.patch
+0367-cape-vsense-scale-division-by-zero-check.patch
+0368-capes-add-cape-for-beaglebone-based-Hexy-robot.patch
+0369-Extend-bone-iio-helper.patch
+0370-Update-iio-helper-with-more-channels.patch
+0371-Add-ADC-IIO-helper.patch
+0372-Changing-DT-data-to-make-selection-of-standard-i.e.-.patch
+0373-Enhancing-to-support-extra-device-tree-options-for-t.patch
+0374-add-WIP-support-LCD4-rev-00A4.patch
+0375-add-eMMC-cape-support.patch
+0376-Remove-UART-pins-from-the-expansion-set.patch
+0377-Remove-LCD-pins-from-the-expansion-test-part.patch
+0378-Remove-I2C2-pins-from-expansion-test.patch
+0379-Add-expansion-test-cape-fragment.patch
+0380-tilcdc-added-some-extra-debug-and-softened-the-wordi.patch
+0381-Make-sure-various-timings-fit-within-the-bits-availa.patch
+0382-fix-cape-bone-hexy.patch
+0383-firmware-DT-Fragment-for-MRF24J40-BeagleBone-Cape.patch
+0384-firmware-capes-Update-MRF24J40-cape-to-work-with-lat.patch
+0385-am335x-bone-common-DT-Override-for-MRF24J40-Cape.patch
+0386-beaglebone-black-limit-LDO3-to-1.8V.patch
+0387-beaglebone-black-add-new-fixed-regulator-for-uSD-eMM.patch
+0388-capemgr-Implement-disable-overrides-on-the-cmd-line.patch
+0389-tilcdc-Enable-pinmux-states.patch
+0390-cape-Add-a-simple-cape-for-handling-the-uSD-button.patch
+0391-beaglebone-add-support-for-DVI-00A3.patch
+0392-beaglebone-remove-audio-section-from-DVID-rev-2-and-.patch
+0393-beaglebone-add-dts-for-audio-cape.patch
+0394-cape-bone-hexy-add-iio-helper.patch
+0395-cape-Add-CAPE-BONE-EXPTEST-to-capemaps.patch
+0396-tester-button-cape.patch
+0397-pwm_test-fix-some-issues.patch
+0398-pwm_test-Clean-up-and-make-it-work-on-DT-correctly.patch
+0399-capes-Add-PWM-test-example-cape.patch
+0400-Sync-tester-DTS-with-am335x-common.patch
+0401-Add-in-missing-cape-bone-tester-back-in.patch
+0402-cape-bone-hexy-move-OLED-to-different-reset-gpio.patch
+0403-firmware-capes-added-dts-file-for-every-PWM-pin.patch
+0404-capes-add-LCD7-A3.patch
+0405-capes-add-basic-support-for-LCD4-capes.patch
+0406-OF-overlay-Add-depth-option-for-device-creation.patch
+0407-capes-Add-BB-BONE-GPEVT-cape.patch
+0408-clock-Export-__clock_set_parent.patch
+0409-omap-clk-Add-adjustable-clkout2.patch
+0410-am33xx-Update-DTS-EDMA.patch
+0411-bone-Added-RS232-prototype-cape-DT-object.patch
+0412-Add-support-for-BB-BONE_SERL-01-00A1-CanBus-cape.patch
+0413-capes-Add-virtual-capes-serving-as-examples.patch
+0414-capes-Add-TowerTech-TT3201-CAN-Bus-Cape-TT3201-001-3.patch
+0415-capes-Add-commented-out-example-of-use-of-spi1_cs1.patch
+0416-cape-LCD4-Correct-key-active-polarity.patch
+0417-capes-lcd3-Correct-button-polarity.patch
+0418-cape-Fix-LCD7-keys-polarity.patch
+0419-gpio-Introduce-GPIO-OF-helper.patch
+0420-capes-ADC-GPIO-helper-capes.patch
+0421-capes-RS232-Cape-support-added.patch
+0422-uio-uio_pruss-port-to-AM33xx.patch
+0423-ARM-omap-add-DT-support-for-deasserting-hardware-res.patch
+0424-ARM-dts-AM33xx-PRUSS-support.patch
+0425-uio_pruss-add-dt-support-replicape-00A1.patch
+0426-pruss-Make-sure-it-works-when-no-child-nodes-are-pre.patch
+0427-am33xx-pru-Very-simple-led-cape-via-GPO-of-the-PRU.patch
+0428-PRU-remote-proc-wip.patch
+0429-Add-sysfs-entry-for-DDR-sync.patch
+0430-virtio-ring-Introduce-dma-mapping-for-real-devices.patch
+0431-virtio_console-Simplify-virtio_console-for-h-w-devic.patch
+0432-rpmsg-Make-the-buffers-number-and-size-configurable.patch
+0433-remoteproc-Use-driver-ops-for-allocation-of-virtqueu.patch
+0434-rproc-core-Allow-bootup-without-resources.patch
+0435-tools-virtio-fix-build-for-3.8.patch
+0436-rproc-pru-PRU-remoteproc-updated-to-work-with-virtio.patch
+0437-capes-pru-Update-with-PRU-03-PRU-04.patch
+0438-rproc-PRU-Add-downcall-RPC-capability.patch
+0439-rproc-pru-Implement-a-software-defined-PWM-channel-s.patch
+0440-capes-PRU-PWM-channels-information.patch
+0441-drivers-usb-phy-add-a-new-driver-for-usb-part-of-con.patch
+0442-drivers-usb-start-using-the-control-module-driver.patch
+0443-usb-otg-Add-an-API-to-bind-the-USB-controller-and-PH.patch
+0444-usb-otg-utils-add-facilities-in-phy-lib-to-support-m.patch
+0445-ARM-OMAP-USB-Add-phy-binding-information.patch
+0446-drivers-usb-musb-omap-make-use-of-the-new-PHY-lib-AP.patch
+0447-usb-otg-add-device-tree-support-to-otg-library.patch
+0448-USB-MUSB-OMAP-get-PHY-by-phandle-for-dt-boot.patch
+0449-MUSB-Hack-around-to-make-host-port-to-work.patch
+0450-make-sure-we-register-unregister-the-NOP-xceiver-onl.patch
+0451-ARM-OMAP-am335x-musb-use-250-for-power.patch
+0452-ARM-OMAP2-MUSB-Specify-omap4-has-mailbox.patch
+0453-usb-musb-avoid-stopping-the-session-in-host-mode.patch
+0454-beaglebone-black-1ghz-hack.patch
+0455-ARM-AM33xx-Add-SoC-specific-restart-hook.patch
+0456-iio-common-Add-STMicroelectronics-common-library.patch
+0457-iio-accel-Add-STMicroelectronics-accelerometers-driv.patch
+0458-iio-gyro-Add-STMicroelectronics-gyroscopes-driver.patch
+0459-iio-magnetometer-Add-STMicroelectronics-magnetometer.patch
+0460-iio-magn-Add-sensors_supported-in-st_magn_sensors.patch
+0461-pwm-pca9685-skeleton-i2c-client-driver-for-PCA9685-1.patch
+0462-Invensense-MPU6050-Device-Driver.patch
+0463-iio-imu-inv_mpu6050-depends-on-IIO_BUFFER.patch
+0464-using-kfifo_in_spinlocked-instead-of-separate-code.patch
+0465-W1-w1-gpio-switch-to-using-dev_pm_ops.patch
+0466-W1-w1-gpio-guard-DT-IDs-with-CONFIG_OF.patch
+0467-W1-w1-gpio-rework-handling-of-platform-data.patch
+0468-W1-w1-gpio-switch-to-using-managed-resources-devm.patch
+0469-ARM-OMAP-Clear-GPMC-bits-when-applying-new-setting.patch
+0470-ARM-omap2-gpmc-Mark-local-scoped-functions-static.patch
+0471-ARM-omap2-gpmc-Remove-unused-gpmc_round_ns_to_ticks-.patch
+0472-ARM-omap2-gpmc-Fix-gpmc_cs_reserved-return-value.patch
+0473-ARM-omap2-gpmc-nand-Print-something-useful-on-CS-req.patch
+0474-ARM-omap2-gpmc-onenand-Print-something-useful-on-CS-.patch
+0475-ARM-omap2-gpmc-onenand-Replace-pr_err-with-dev_err.patch
+0476-ARM-omap2-gpmc-onenand-Replace-printk-KERN_ERR-with-.patch
+0477-ARM-omap2-gpmc-Remove-redundant-chip-select-out-of-r.patch
+0478-ARM-OMAP2-Simplify-code-configuring-ONENAND-devices.patch
+0479-ARM-OMAP2-Add-variable-to-store-number-of-GPMC-waitp.patch
+0480-ARM-OMAP2-Add-structure-for-storing-GPMC-settings.patch
+0481-ARM-OMAP2-Add-function-for-configuring-GPMC-settings.patch
+0482-ARM-OMAP2-Convert-ONENAND-to-use-gpmc_cs_program_set.patch
+0483-ARM-OMAP2-Convert-NAND-to-use-gpmc_cs_program_settin.patch
+0484-ARM-OMAP2-Convert-SMC91x-to-use-gpmc_cs_program_sett.patch
+0485-ARM-OMAP2-Convert-TUSB-to-use-gpmc_cs_program_settin.patch
+0486-ARM-OMAP2-Don-t-configure-of-chip-select-options-in-.patch
+0487-ARM-OMAP2-Add-function-to-read-GPMC-settings-from-de.patch
+0488-ARM-OMAP2-Add-additional-GPMC-timing-parameters.patch
+0489-ARM-OMAP2-Add-device-tree-support-for-NOR-flash.patch
+0490-ARM-OMAP2-Convert-NAND-to-retrieve-GPMC-settings-fro.patch
+0491-ARM-OMAP2-Convert-ONENAND-to-retrieve-GPMC-settings-.patch
+0492-ARM-OMAP2-Detect-incorrectly-aligned-GPMC-base-addre.patch
+0493-ARM-OMAP2-Remove-unnecesssary-GPMC-definitions-and-v.patch
+0494-ARM-OMAP2-Allow-GPMC-probe-to-complete-even-if-CS-ma.patch
+0495-ARM-OMAP2-return-ENODEV-if-GPMC-child-device-creatio.patch
+0496-ARM-OMAP2-rename-gpmc_probe_nor_child-to-gpmc_probe_.patch
+0497-ARM-OMAP2-Add-GPMC-DT-support-for-Ethernet-child-nod.patch
+0498-mtd-omap-nand-pass-device_node-in-platform-data.patch
+0499-ARM-OMAP-gpmc-nand-drop-__init-annotation.patch
+0500-ARM-OMAP-gpmc-enable-hwecc-for-AM33xx-SoCs.patch
+0501-ARM-OMAP-gpmc-don-t-create-devices-from-initcall-on-.patch
+0502-ARM-OMAP2-gpmc-onenand-drop-__init-annotation.patch
+0503-gpmc-Add-missing-gpmc-includes.patch
+0504-mtd-omap-onenand-pass-device_node-in-platform-data.patch
+0505-ARM-OMAP2-Convert-ONENAND-to-use-gpmc_cs_program_set.patch
+0506-omap-gpmc-Various-driver-fixes.patch
+0507-gpmc-Add-DT-node-for-gpmc-on-am33xx.patch
+0508-CHROMIUM-Input-atmel_mxt_ts-refactor-i2c-error-handl.patch
+0509-CHROMIUM-Input-atmel_mxt_ts-register-input-device-be.patch
+0510-CHROMIUM-Input-atmel_mxt_ts-refactor-input-device-cr.patch
+0511-CHROMIUM-Input-atmel_mxt_ts-handle-bootloader-mode-a.patch
+0512-CHROMIUM-Input-atmel_mxt_ts-handle-errors-during-fw-.patch
+0513-CHROMIUM-Input-atmel_mxt_ts-destroy-state-before-fw-.patch
+0514-CHROMIUM-Input-atmel_mxt_ts-refactor-bootloader-entr.patch
+0515-CHROMIUM-Input-atmel_mxt_ts-wait-for-CHG-assert-in-m.patch
+0516-CHROMIUM-Input-atmel_mxt_ts-wait-for-CHG-after-bootl.patch
+0517-CHROMIUM-Input-atmel_mxt_ts-change-MXT_BOOT_LOW-to-0.patch
+0518-CHROMIUM-Input-atmel_mxt_ts-Increase-FWRESET_TIME.patch
+0519-CHROMIUM-Input-atmel_mxt_ts-add-calibrate-sysfs-entr.patch
+0520-CHROMIUM-Input-atmel_mxt_ts-add-sysfs-entry-to-read-.patch
+0521-CHROMIUM-Input-atmel_mxt_ts-add-sysfs-entry-to-read-.patch
+0522-CHROMIUM-Input-atmel_mxt_ts-verify-info-block-checks.patch
+0523-CHROMIUM-Input-atmel_mxt_tx-add-matrix_size-sysfs-en.patch
+0524-CHROMIUM-Input-atmel_mxt_ts-define-helper-functions-.patch
+0525-CHROMIUM-Input-atmel_mxt_ts-add-debugfs-infrastructu.patch
+0526-CHROMIUM-Input-atmel_mxt_ts-add-deltas-and-refs-debu.patch
+0527-CHROMIUM-Input-atmel_mxt_ts-add-device-id-for-touchp.patch
+0528-CHROMIUM-Input-atmel_mxt_ts-Read-resolution-from-dev.patch
+0529-CHROMIUM-Input-atmel_mxt_ts-Report-TOUCH-MAJOR-in-te.patch
+0530-CHROMIUM-Input-atmel_mxt_ts-add-new-object-types.patch
+0531-CHROMIUM-INPUT-atmel_mxt_ts-Increase-the-wait-times-.patch
+0532-CHROMIUM-Input-atmel_mxt_ts-dump-mxt_read-write_reg.patch
+0533-CHROMIUM-Input-atmel_mxt_ts-take-an-instance-for-mxt.patch
+0534-CHROMIUM-Input-atmel_mxt_ts-allow-writing-to-object-.patch
+0535-CHROMIUM-Input-atmel_mxt_ts-add-backupnv-sysfs-entry.patch
+0536-CHROMIUM-Input-atmel_mxt_ts-read-num-messages-then-a.patch
+0537-CHROMIUM-Input-atmel_mxt_ts-remove-mxt_make_highchg.patch
+0538-CHROMIUM-Input-atmel_mxt_ts-Remove-matrix-size-updat.patch
+0539-CHROMIUM-Input-atmel_mxt_ts-parse-vector-field-of-da.patch
+0540-CHROMIUM-Input-atmel_mxt_ts-Add-IDLE-DEEP-SLEEP-mode.patch
+0541-CHROMIUM-Input-atmel_mxt_ts-Move-object-from-sysfs-t.patch
+0542-CHROMIUM-Input-atmel_mxt_ts-Set-default-irqflags-whe.patch
+0543-CHROMIUM-Input-atmel_mxt_ts-Support-the-case-with-no.patch
+0544-CHROMIUM-Input-atmel_mxt_ts-Wait-on-auto-calibration.patch
+0545-CHROMIUM-Input-atmel_mxt_ts-Add-sysfs-entry-for-r-w-.patch
+0546-CHROMIUM-Input-atmel_mxt_ts-Add-sysfs-entry-for-r-w-.patch
+0547-CHROMIUM-Input-atmel_mxt_ts-add-sysfs-entry-for-writ.patch
+0548-CHROMIUM-Input-atmel_mxt_ts-make-mxt_initialize-asyn.patch
+0549-CHROMIUM-Input-atmel_mxt_ts-move-backup_nv-to-handle.patch
+0550-CHROMIUM-Input-atmel_mxt_ts-Add-defines-for-T9-Touch.patch
+0551-CHROMIUM-Input-atmel_mxt_ts-disable-reporting-on-sto.patch
+0552-CHROMIUM-Input-atmel_mxt_ts-Suppress-handle-messages.patch
+0553-CHROMIUM-Input-atmel_mxt_ts-save-and-restore-t9_ctrl.patch
+0554-CHROMIUM-Input-atmel_mxt_ts-enable-RPTEN-if-can-wake.patch
+0555-CHROMIUM-Input-atmel_mxt_ts-release-all-fingers-on-r.patch
+0556-CHROMIUM-Input-atmel_mxt_ts-make-suspend-power-acqui.patch
+0557-CHROMIUM-Input-atmel_mxt_ts-recalibrate-on-system-re.patch
+0558-CHROMIUM-Input-atmel_mxt_ts-Use-correct-max-touch_ma.patch
+0559-CHROMIUM-Input-atmel_mxt_ts-Add-support-for-T65-Lens.patch
+0560-CHROMIUM-Input-atmel_mxt_ts-On-Tpads-enable-T42-disa.patch
+0561-CHROMIUM-Input-atmel_mxt_ts-Set-power-wakeup-to-disa.patch
+0562-CHROMIUM-Input-atmel_mxt_ts-mxt_stop-on-lid-close.patch
+0563-CHROMIUM-Input-atmel_mxt_ts-Disable-T9-on-mxt_stop.patch
+0564-CHROMIUM-Input-atmel_mxt_ts-Set-T9-in-mxt_resume-bas.patch
+0565-video-ssd1307fb-Add-support-for-SSD1306-OLED-control.patch
+0566-ssd1307fb-Rework-the-communication-functions.patch
+0567-ssd1307fb-Speed-up-the-communication-with-the-contro.patch
+0568-ssd1307fb-Make-use-of-horizontal-addressing-mode.patch
+0569-SSD1307fb-1Hz-8Hz-defio-updates.patch
+0570-ARM-force-march-armv7a-for-thumb2-builds-http-lists..patch
+0571-headers_install-Fix-build-failures-on-deep-directory.patch
+0572-libtraceevent-Remove-hard-coded-include-to-usr-local.patch
+0573-Make-single-.dtb-targets-also-with-DTC_FLAGS.patch
+0574-video-Add-generic-HDMI-infoframe-helpers.patch
+0575-BeagleBone-Black-TDA998x-Initial-HDMI-Audio-support.patch
+0576-Clean-up-some-formating-and-debug-in-Davinci-MCASP-d.patch
+0577-tilcdc-Prune-modes-that-can-t-support-audio.patch
+0578-Enable-output-of-correct-AVI-Infoframe-type-hdmi.patch
+0579-drm-am335x-add-support-for-2048-lines-vertical.patch
+0580-drm-tda998x-Adding-extra-CEA-mode-for-1920x1080-24.patch
+0581-tilcdc-Remove-superfluous-newlines-from-DBG-messages.patch
+0582-tilcdc-1280x1024x60-bw-1920x1080x24-bw.patch
+0583-tilcdc-Only-support-Audio-on-50-60-Hz-modes.patch
+0584-drm-i2c-nxp-tda998x-fix-EDID-reading-on-TDA19988-dev.patch
+0585-tilcdc-Allow-non-audio-modes-when-we-don-t-support-t.patch
+0586-drm-i2c-nxp-tda998x-ensure-VIP-output-mux-is-properl.patch
+0587-drm-i2c-nxp-tda998x-fix-npix-nline-programming.patch
+0588-drm-tilcdc-Clear-bits-of-register-we-re-going-to-set.patch
+0589-DRM-tda998x-add-missing-include.patch
+0590-drm-i2c-nxp-tda998x-prepare-for-video-input-configur.patch
+0591-WIP-of-new-tda998x-patches.patch
+0592-tilcdc-Slave-panel-settings-read-from-DT-now.patch
+0593-drm-tda998x-Revert-WIP-to-previous-state.patch
+0594-tilcdc-More-refined-audio-mode-compatibility-check.patch
+0595-drm-tilcdc-Implement-whitelist-blacklist-mode-suppor.patch
+0596-boneblack-Remove-default-pinmuxing-for-MMC1.patch
+0597-capemgr-Implement-cape-priorities.patch
+0598-rstctl-Reset-control-subsystem.patch
+0599-omap_hsmmc-Enable-rstctl-bindings.patch
+0600-bone-Add-rstctl-DT-binding-for-beaglebone.patch
+0601-bone-eMMC-Add-rstctl-rstctl-DT-bindings.patch
+0602-capes-Add-testing-capes-for-rstctl.patch
+0603-omap_hsmmc-Bail-out-when-rstctl-error-is-unrecoverab.patch
+0604-bone-Put-priorities-in-built-in-capes.patch
+0605-bone-common-dtsi-remove-reset-cape.patch
+0606-mmc-add-missing-select-RSTCTL-in-MMC_OMAP.patch
+0607-soc_camera-QL-mt9l112-camera-driver-for-the-beaglebo.patch
+0608-capes-Add-BB-BONE-CAM3-cape.patch
+0609-cssp_camera-Correct-license-identifier.patch
+0610-cssp_camera-increase-delays-make-sensor-detection-wo.patch
+0611-mt9t112-forward-port-optimizations-from-Angstrom-3.2.patch
+0612-cssp_camera-Use-flip-if-available.patch
+0613-cssp_camera-Fix-it-for-small-resolutions.patch
+0614-cssp_camera-Increase-delay-after-enabling-clocks-to-.patch
+0615-Debugging-camera-stuff.patch
+0616-cssp_camera-Make-it-work-with-Beaglebone-black.patch
+0617-bone-capemgr-Introduce-simple-resource-tracking.patch
+0618-capes-Add-resources-to-capes.patch
+0619-capes-Update-most-of-the-capes-with-resource-definit.patch
+0620-capes-Update-RS232-CAN-capes-with-resources.patch
+0621-capemgr-Add-enable_partno-parameter.patch
+0622-cape-GPIOHELP-use-correct-part-number.patch
+0623-bbb-Add-a-fall-back-non-audio-HDMI-cape.patch
+0624-capes-HDMI-slaves-need-panel-settings.patch
+0625-capes-boneblack-HDMI-capes-have-blacklisted-modes.patch
+0626-capes-LCD7-Fix-definitions.patch
+0627-capes-LCD7-Fix-enter-key-pinmux.patch
+0628-Fix-timings-for-LCD3-cape.patch
+0629-capes-LCD-capes-updated-with-timing-fixes.patch
+0630-Fix-mmc2-being-enabled-when-eMMC-is-disabled.patch
+0631-capes-LCD7-fix-vsync-len-off-by-one.patch
+0632-LCD-capes-set-default-brightness-to-100.patch
+0633-lcd-capes-update-adc-channels.patch
+0634-bone-renamed-adafruit-RTC-cape.patch
+0635-bone-add-PPS-to-BB-BONE-RTC-cape.patch
+0636-firmware-remove-rule-for-cape-bone-adafruit-lcd-00A0.patch
+0637-tps65217-Enable-KEY_POWER-press-on-AC-loss-PWR_BUT.patch
+0638-dt-bone-common-Add-interrupt-for-PMIC.patch
+0639-drivers-pps-clients-pps-gpio.c-convert-to-module_pla.patch
+0640-drivers-pps-clients-pps-gpio.c-convert-to-devm_-help.patch
+0641-pps-gpio-add-device-tree-binding-and-support.patch
+0642-leds-leds-pwm-Convert-to-use-devm_get_pwm.patch
+0643-leds-leds-pwm-Preparing-the-driver-for-device-tree-s.patch
+0644-leds-leds-pwm-Simplify-cleanup-code.patch
+0645-leds-leds-pwm-Add-device-tree-bindings.patch
+0646-leds-leds-pwm-Defer-led_pwm_set-if-PWM-can-sleep.patch
+0647-leds-pwm-Enable-compilation-on-this-version-of-the-k.patch
+0648-capes-Add-bacon-cape.patch
+0649-cape-bacon-Cosmetic-change-of-the-adc-helper-name.patch
+0650-cape-bacon-educational-edition.patch
+0651-capes-bacon-Update-with-new-ADC-driver-method.patch
+0652-capes-BACON-Educational-cape-with-free-form-muxing.patch
+0653-firmware-add-BeBoPr-cape.patch
+# umpf-release: distrokit/beaglebone/20130720
+# umpf-topic-range: 6fbec96b98a35ba475bb821a60c903566f35a575..cf474a9f0f33aea786d56c1f447d4a837f754a0f
+0701-Release-distrokit-beaglebone-20130720.patch
+# umpf-end
diff --git a/patches/linux-3.8.4/0044-input-ti_am335x_tsc-Step-enable-bits-made-configurab.patch b/patches/linux-3.8.4/0044-input-ti_am335x_tsc-Step-enable-bits-made-configurab.patch
deleted file mode 100644
index c9d8009..0000000
--- a/patches/linux-3.8.4/0044-input-ti_am335x_tsc-Step-enable-bits-made-configurab.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From: "Patil, Rachna" <rachna@ti.com>
-Date: Thu, 24 Jan 2013 03:45:05 +0000
-Subject: [PATCH] input: ti_am335x_tsc: Step enable bits made configurable
-
-Current code has hard coded value written to
-step enable bits. Now the bits are updated based
-on how many steps are needed to be configured got
-from platform data.
-
-The user needs to take care not to exceed
-the count more than 16. While using ADC and TSC
-one should take care to set this parameter correctly.
-
-Signed-off-by: Patil, Rachna <rachna@ti.com>
----
- drivers/input/touchscreen/ti_am335x_tsc.c | 10 ++++++++--
- include/linux/mfd/ti_am335x_tscadc.h | 1 -
- 2 files changed, 8 insertions(+), 3 deletions(-)
-
-diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
-index 51e7b87..da652e0 100644
---- a/drivers/input/touchscreen/ti_am335x_tsc.c
-+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
-@@ -39,6 +39,7 @@ struct titsc {
- unsigned int irq;
- unsigned int wires;
- unsigned int x_plate_resistance;
-+ unsigned int enable_bits;
- bool pen_down;
- int steps_to_configure;
- };
-@@ -57,6 +58,7 @@ static void titsc_writel(struct titsc *tsc, unsigned int reg,
- static void titsc_step_config(struct titsc *ts_dev)
- {
- unsigned int config;
-+ unsigned int stepenable = 0;
- int i, total_steps;
-
- /* Configure the Step registers */
-@@ -128,7 +130,11 @@ static void titsc_step_config(struct titsc *ts_dev)
- titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2),
- STEPCONFIG_OPENDLY);
-
-- titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC);
-+ for (i = 0; i <= (total_steps + 2); i++)
-+ stepenable |= 1 << i;
-+ ts_dev->enable_bits = stepenable;
-+
-+ titsc_writel(ts_dev, REG_SE, ts_dev->enable_bits);
- }
-
- static void titsc_read_coordinates(struct titsc *ts_dev,
-@@ -250,7 +256,7 @@ static irqreturn_t titsc_irq(int irq, void *dev)
-
- titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
-
-- titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC);
-+ titsc_writel(ts_dev, REG_SE, ts_dev->enable_bits);
- return IRQ_HANDLED;
- }
-
-diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
-index c79ad5d..23e4f33 100644
---- a/include/linux/mfd/ti_am335x_tscadc.h
-+++ b/include/linux/mfd/ti_am335x_tscadc.h
-@@ -47,7 +47,6 @@
- #define STEPENB_MASK (0x1FFFF << 0)
- #define STEPENB(val) ((val) << 0)
- #define STPENB_STEPENB STEPENB(0x1FFFF)
--#define STPENB_STEPENB_TC STEPENB(0x1FFF)
-
- /* IRQ enable */
- #define IRQENB_HW_PEN BIT(0)
diff --git a/patches/linux-3.8.4/0047-MFD-ti_am335x_tscadc-add-device-tree-binding-informa.patch b/patches/linux-3.8.4/0047-MFD-ti_am335x_tscadc-add-device-tree-binding-informa.patch
deleted file mode 100644
index c91f079..0000000
--- a/patches/linux-3.8.4/0047-MFD-ti_am335x_tscadc-add-device-tree-binding-informa.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From: "Patil, Rachna" <rachna@ti.com>
-Date: Thu, 24 Jan 2013 03:45:08 +0000
-Subject: [PATCH] MFD: ti_am335x_tscadc: add device tree binding information
-
-Signed-off-by: Patil, Rachna <rachna@ti.com>
----
- .../devicetree/bindings/mfd/ti_am335x_tscadc.txt | 52 ++++++++++++++++++++
- 1 file changed, 52 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/mfd/ti_am335x_tscadc.txt
-
-diff --git a/Documentation/devicetree/bindings/mfd/ti_am335x_tscadc.txt b/Documentation/devicetree/bindings/mfd/ti_am335x_tscadc.txt
-new file mode 100644
-index 0000000..0100771
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mfd/ti_am335x_tscadc.txt
-@@ -0,0 +1,52 @@
-+Texas Instruments - TSC / ADC multi-functional device
-+
-+ti_tscadc is a multi-function device with touchscreen and ADC on chip.
-+This document describes the binding for mfd device.
-+
-+Required properties:
-+- compatible: "ti,ti-tscadc"
-+- reg: Specifies the address of MFD block
-+- interrupts: IRQ line connected to the main SoC
-+- interrupt-parent: The parent interrupt controller
-+
-+Optional properties:
-+- ti,hwmods: Hardware information related to TSC/ADC MFD device
-+
-+Sub-nodes:
-+Device Description
-+------ -----------
-+tsc Touchscreen
-+adc Analog to digital converter
-+
-+Sub-node device required properties:
-+tsc:
-+- ti,wires: 4/5/8 wire touchscreen support on the platform.
-+- ti,x-plate-resistance: X plate resistance.
-+- ti,steps-to-configure: A step is configured to read a single co-ordinate value,
-+ can be applied more number of times for better results.
-+- ti,wire-config: Order for connecting wires on touchscreen.
-+
-+adc:
-+- ti,adc-channels: Number of ADC channels used.
-+
-+Example:
-+
-+ tscadc: tscadc@44e0d000 {
-+ compatible = "ti,ti-tscadc";
-+ reg = <0x44e0d000 0x1000>;
-+
-+ interrupt-parent = <&intc>;
-+ interrupts = <16>;
-+ ti,hwmods = "adc_tsc";
-+
-+ tsc {
-+ ti,wires = <4>;
-+ ti,x-plate-resistance = <200>;
-+ ti,steps-to-configure = <5>;
-+ ti,wire-config = <0x00 0x11 0x22 0x33>;
-+ };
-+
-+ adc {
-+ ti,adc-channels = <4>;
-+ };
-+ };
diff --git a/patches/linux-3.8.4/0049-input-ti_am335x_tsc-Add-DT-support.patch b/patches/linux-3.8.4/0049-input-ti_am335x_tsc-Add-DT-support.patch
deleted file mode 100644
index 2911945..0000000
--- a/patches/linux-3.8.4/0049-input-ti_am335x_tsc-Add-DT-support.patch
+++ /dev/null
@@ -1,139 +0,0 @@
-From: "Patil, Rachna" <rachna@ti.com>
-Date: Thu, 24 Jan 2013 03:45:10 +0000
-Subject: [PATCH] input: ti_am335x_tsc: Add DT support
-
-Add DT support for client touchscreen driver
-
-Signed-off-by: Patil, Rachna <rachna@ti.com>
----
- drivers/input/touchscreen/ti_am335x_tsc.c | 94 +++++++++++++++++++++++++----
- 1 file changed, 81 insertions(+), 13 deletions(-)
-
-diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
-index 064d2b2..6ff5a76 100644
---- a/drivers/input/touchscreen/ti_am335x_tsc.c
-+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
-@@ -26,6 +26,8 @@
- #include <linux/io.h>
- #include <linux/input/ti_am335x_tsc.h>
- #include <linux/delay.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-
- #include <linux/mfd/ti_am335x_tscadc.h>
-
-@@ -366,6 +368,74 @@ static irqreturn_t titsc_irq(int irq, void *dev)
- return IRQ_HANDLED;
- }
-
-+static int titsc_parse_dt(struct ti_tscadc_dev *tscadc_dev,
-+ struct titsc *ts_dev)
-+{
-+ struct device_node *node = tscadc_dev->dev->of_node;
-+ int err, i;
-+ u32 val32, wires_conf[4];
-+
-+ if (!node)
-+ return -EINVAL;
-+ else {
-+ node = of_find_node_by_name(node, "tsc");
-+ if (!node)
-+ return -EINVAL;
-+ else {
-+ err = of_property_read_u32(node, "ti,wires", &val32);
-+ if (err < 0)
-+ goto error_ret;
-+ else
-+ ts_dev->wires = val32;
-+
-+ err = of_property_read_u32(node,
-+ "ti,x-plate-resistance", &val32);
-+ if (err < 0)
-+ goto error_ret;
-+ else
-+ ts_dev->x_plate_resistance = val32;
-+
-+ err = of_property_read_u32(node,
-+ "ti,steps-to-configure", &val32);
-+ if (err < 0)
-+ goto error_ret;
-+ else
-+ ts_dev->steps_to_configure = val32;
-+
-+ err = of_property_read_u32_array(node, "ti,wire-config",
-+ wires_conf, ARRAY_SIZE(wires_conf));
-+ if (err < 0)
-+ goto error_ret;
-+ else {
-+ for (i = 0; i < ARRAY_SIZE(wires_conf); i++)
-+ ts_dev->config_inp[i] = wires_conf[i];
-+ }
-+ }
-+ }
-+ return 0;
-+
-+error_ret:
-+ return err;
-+}
-+
-+static int titsc_parse_pdata(struct ti_tscadc_dev *tscadc_dev,
-+ struct titsc *ts_dev)
-+{
-+ struct mfd_tscadc_board *pdata = tscadc_dev->dev->platform_data;
-+
-+ if (!pdata)
-+ return -EINVAL;
-+
-+ ts_dev->wires = pdata->tsc_init->wires;
-+ ts_dev->x_plate_resistance =
-+ pdata->tsc_init->x_plate_resistance;
-+ ts_dev->steps_to_configure =
-+ pdata->tsc_init->steps_to_configure;
-+ memcpy(ts_dev->config_inp, pdata->tsc_init->wire_config,
-+ sizeof(pdata->tsc_init->wire_config));
-+ return 0;
-+}
-+
- /*
- * The functions for inserting/removing driver as a module.
- */
-@@ -375,16 +445,8 @@ static int titsc_probe(struct platform_device *pdev)
- struct titsc *ts_dev;
- struct input_dev *input_dev;
- struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data;
-- struct mfd_tscadc_board *pdata;
- int err;
-
-- pdata = tscadc_dev->dev->platform_data;
--
-- if (!pdata) {
-- dev_err(&pdev->dev, "Could not find platform data\n");
-- return -EINVAL;
-- }
--
- /* Allocate memory for device */
- ts_dev = kzalloc(sizeof(struct titsc), GFP_KERNEL);
- input_dev = input_allocate_device();
-@@ -398,11 +460,17 @@ static int titsc_probe(struct platform_device *pdev)
- ts_dev->mfd_tscadc = tscadc_dev;
- ts_dev->input = input_dev;
- ts_dev->irq = tscadc_dev->irq;
-- ts_dev->wires = pdata->tsc_init->wires;
-- ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance;
-- ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure;
-- memcpy(ts_dev->config_inp, pdata->tsc_init->wire_config,
-- sizeof(pdata->tsc_init->wire_config));
-+
-+ if (tscadc_dev->dev->platform_data)
-+ err = titsc_parse_pdata(tscadc_dev, ts_dev);
-+ else
-+ err = titsc_parse_dt(tscadc_dev, ts_dev);
-+
-+ if (err) {
-+ dev_err(&pdev->dev, "Could not find platform data\n");
-+ err = -EINVAL;
-+ goto err_free_mem;
-+ }
-
- err = request_irq(ts_dev->irq, titsc_irq,
- 0, pdev->dev.driver->name, ts_dev);
diff --git a/patches/linux-3.8.4/0050-IIO-ti_am335x_adc-Add-DT-support.patch b/patches/linux-3.8.4/0050-IIO-ti_am335x_adc-Add-DT-support.patch
deleted file mode 100644
index e362ce3..0000000
--- a/patches/linux-3.8.4/0050-IIO-ti_am335x_adc-Add-DT-support.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From: "Patil, Rachna" <rachna@ti.com>
-Date: Thu, 24 Jan 2013 03:45:11 +0000
-Subject: [PATCH] IIO: ti_am335x_adc: Add DT support
-
-Add DT support for client ADC driver.
-
-Signed-off-by: Patil, Rachna <rachna@ti.com>
----
- drivers/iio/adc/ti_am335x_adc.c | 26 ++++++++++++++++++++++----
- 1 file changed, 22 insertions(+), 4 deletions(-)
-
-diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
-index cd030e1..8e7b089 100644
---- a/drivers/iio/adc/ti_am335x_adc.c
-+++ b/drivers/iio/adc/ti_am335x_adc.c
-@@ -22,6 +22,8 @@
- #include <linux/platform_device.h>
- #include <linux/io.h>
- #include <linux/iio/iio.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-
- #include <linux/mfd/ti_am335x_tscadc.h>
- #include <linux/platform_data/ti_am335x_adc.h>
-@@ -141,11 +143,12 @@ static int tiadc_probe(struct platform_device *pdev)
- struct iio_dev *indio_dev;
- struct tiadc_device *adc_dev;
- struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data;
-- struct mfd_tscadc_board *pdata;
-+ struct mfd_tscadc_board *pdata = tscadc_dev->dev->platform_data;
-+ struct device_node *node = tscadc_dev->dev->of_node;
- int err;
-+ u32 val32;
-
-- pdata = tscadc_dev->dev->platform_data;
-- if (!pdata || !pdata->adc_init) {
-+ if (!pdata && !node) {
- dev_err(&pdev->dev, "Could not find platform data\n");
- return -EINVAL;
- }
-@@ -159,7 +162,22 @@ static int tiadc_probe(struct platform_device *pdev)
- adc_dev = iio_priv(indio_dev);
-
- adc_dev->mfd_tscadc = tscadc_dev;
-- adc_dev->channels = pdata->adc_init->adc_channels;
-+
-+ if (pdata)
-+ adc_dev->channels = pdata->adc_init->adc_channels;
-+ else {
-+ node = of_find_node_by_name(node, "adc");
-+ if (!node)
-+ return -EINVAL;
-+ else {
-+ err = of_property_read_u32(node,
-+ "ti,adc-channels", &val32);
-+ if (err < 0)
-+ goto err_free_device;
-+ else
-+ adc_dev->channels = val32;
-+ }
-+ }
-
- indio_dev->dev.parent = &pdev->dev;
- indio_dev->name = dev_name(&pdev->dev);
diff --git a/patches/linux-3.8.4/0052-ti_tscadc-Update-with-IIO-map-interface-deal-with-pa.patch b/patches/linux-3.8.4/0052-ti_tscadc-Update-with-IIO-map-interface-deal-with-pa.patch
deleted file mode 100644
index dc5bb9a..0000000
--- a/patches/linux-3.8.4/0052-ti_tscadc-Update-with-IIO-map-interface-deal-with-pa.patch
+++ /dev/null
@@ -1,187 +0,0 @@
-From: Pantelis Antoniou <panto@antoniou-consulting.com>
-Date: Sat, 13 Oct 2012 16:37:24 +0300
-Subject: [PATCH] ti_tscadc: Update with IIO map interface & deal with partial
- activation
-
-Add an IIO map interface that consumers can use.
-While we're here fix the mfd device in the case where a subdevice
-might not be activated.
-
-Conflicts:
- drivers/iio/adc/ti_am335x_adc.c
----
- drivers/iio/adc/ti_am335x_adc.c | 53 ++++++++++++++++++++++++++++------
- drivers/mfd/ti_am335x_tscadc.c | 30 +++++++++++++------
- include/linux/mfd/ti_am335x_tscadc.h | 8 ++---
- 3 files changed, 68 insertions(+), 23 deletions(-)
-
-diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
-index 8e7b089..40e09eb 100644
---- a/drivers/iio/adc/ti_am335x_adc.c
-+++ b/drivers/iio/adc/ti_am335x_adc.c
-@@ -20,10 +20,11 @@
- #include <linux/slab.h>
- #include <linux/interrupt.h>
- #include <linux/platform_device.h>
--#include <linux/io.h>
- #include <linux/iio/iio.h>
- #include <linux/of.h>
- #include <linux/of_device.h>
-+#include <linux/iio/machine.h>
-+#include <linux/iio/driver.h>
-
- #include <linux/mfd/ti_am335x_tscadc.h>
- #include <linux/platform_data/ti_am335x_adc.h>
-@@ -31,6 +32,8 @@
- struct tiadc_device {
- struct ti_tscadc_dev *mfd_tscadc;
- int channels;
-+ char *buf;
-+ struct iio_map *map;
- };
-
- static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
-@@ -77,25 +80,57 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
- static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
- {
- struct iio_chan_spec *chan_array;
-- int i;
--
-- indio_dev->num_channels = channels;
-- chan_array = kcalloc(indio_dev->num_channels,
-- sizeof(struct iio_chan_spec), GFP_KERNEL);
-+ struct iio_chan_spec *chan;
-+ char *s;
-+ int i, len, size, ret;
-
-+ size = indio_dev->num_channels * (sizeof(struct iio_chan_spec) + 6);
-+ chan_array = kzalloc(size, GFP_KERNEL);
- if (chan_array == NULL)
- return -ENOMEM;
-
-- for (i = 0; i < (indio_dev->num_channels); i++) {
-- struct iio_chan_spec *chan = chan_array + i;
-+ /* buffer space is after the array */
-+ s = (char *)(chan_array + indio_dev->num_channels);
-+ chan = chan_array;
-+ for (i = 0; i < indio_dev->num_channels; i++, chan++, s += len + 1) {
-+
-+ len = sprintf(s, "AIN%d", i);
-+
- chan->type = IIO_VOLTAGE;
- chan->indexed = 1;
- chan->channel = i;
-- chan->info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT;
-+ chan->datasheet_name = s;
-+ chan->scan_type.sign = 'u';
-+ chan->scan_type.realbits = 12;
-+ chan->scan_type.storagebits = 32;
-+ chan->scan_type.shift = 0;
- }
-
- indio_dev->channels = chan_array;
-
-+ size = (indio_dev->num_channels + 1) * sizeof(struct iio_map);
-+ adc_dev->map = kzalloc(size, GFP_KERNEL);
-+ if (adc_dev->map == NULL) {
-+ kfree(chan_array);
-+ return -ENOMEM;
-+ }
-+
-+ for (i = 0; i < indio_dev->num_channels; i++) {
-+ adc_dev->map[i].adc_channel_label = chan_array[i].datasheet_name;
-+ adc_dev->map[i].consumer_dev_name = "any";
-+ adc_dev->map[i].consumer_channel = chan_array[i].datasheet_name;
-+ }
-+ adc_dev->map[i].adc_channel_label = NULL;
-+ adc_dev->map[i].consumer_dev_name = NULL;
-+ adc_dev->map[i].consumer_channel = NULL;
-+
-+ ret = iio_map_array_register(indio_dev, adc_dev->map);
-+ if (ret != 0) {
-+ kfree(adc_dev->map);
-+ kfree(chan_array);
-+ return -ENOMEM;
-+ }
-+
- return indio_dev->num_channels;
- }
-
-diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
-index 87b446b..0632d59 100644
---- a/drivers/mfd/ti_am335x_tscadc.c
-+++ b/drivers/mfd/ti_am335x_tscadc.c
-@@ -186,26 +186,38 @@ static int ti_tscadc_probe(struct platform_device *pdev)
- ctrl |= CNTRLREG_TSCSSENB;
- tscadc_writel(tscadc, REG_CTRL, ctrl);
-
-+ tscadc->used_cells = 0;
-+ tscadc->tsc_cell = -1;
-+ tscadc->adc_cell = -1;
-+
- /* TSC Cell */
-- cell = &tscadc->cells[TSC_CELL];
-- cell->name = "tsc";
-- cell->platform_data = tscadc;
-- cell->pdata_size = sizeof(*tscadc);
-+ if (tsc_wires > 0) {
-+ tscadc->tsc_cell = tscadc->used_cells;
-+ cell = &tscadc->cells[tscadc->used_cells++];
-+ cell->name = "tsc";
-+ cell->platform_data = tscadc;
-+ cell->pdata_size = sizeof(*tscadc);
-+ }
-
- /* ADC Cell */
-- cell = &tscadc->cells[ADC_CELL];
-- cell->name = "tiadc";
-- cell->platform_data = tscadc;
-- cell->pdata_size = sizeof(*tscadc);
-+ if (adc_channels > 0) {
-+ tscadc->adc_cell = tscadc->used_cells;
-+ cell = &tscadc->cells[tscadc->used_cells++];
-+ cell->name = "tiadc";
-+ cell->platform_data = tscadc;
-+ cell->pdata_size = sizeof(*tscadc);
-+ }
-
- err = mfd_add_devices(&pdev->dev, pdev->id, tscadc->cells,
-- TSCADC_CELLS, NULL, 0, NULL);
-+ tscadc->used_cells, NULL, 0, NULL);
- if (err < 0)
- goto err_disable_clk;
-
- device_init_wakeup(&pdev->dev, true);
- platform_set_drvdata(pdev, tscadc);
-
-+ dev_info(&pdev->dev, "Initialized OK.\n");
-+
- return 0;
-
- err_disable_clk:
-diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
-index 9624fea..50a245f 100644
---- a/include/linux/mfd/ti_am335x_tscadc.h
-+++ b/include/linux/mfd/ti_am335x_tscadc.h
-@@ -128,11 +128,6 @@
-
- #define TSCADC_CELLS 2
-
--enum tscadc_cells {
-- TSC_CELL,
-- ADC_CELL,
--};
--
- struct mfd_tscadc_board {
- struct tsc_data *tsc_init;
- struct adc_data *adc_init;
-@@ -143,6 +138,9 @@ struct ti_tscadc_dev {
- struct regmap *regmap_tscadc;
- void __iomem *tscadc_base;
- int irq;
-+ int used_cells; /* 0-2 */
-+ int tsc_cell; /* -1 if not used */
-+ int adc_cell; /* -1 if not used */
- struct mfd_cell cells[TSCADC_CELLS];
-
- /* tsc device */
diff --git a/patches/linux-3.8.4/0053-ti_tscadc-Match-mfd-sub-devices-to-regmap-interface.patch b/patches/linux-3.8.4/0053-ti_tscadc-Match-mfd-sub-devices-to-regmap-interface.patch
deleted file mode 100644
index b089315..0000000
--- a/patches/linux-3.8.4/0053-ti_tscadc-Match-mfd-sub-devices-to-regmap-interface.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-From: Pantelis Antoniou <panto@antoniou-consulting.com>
-Date: Fri, 26 Oct 2012 14:01:05 +0300
-Subject: [PATCH] ti_tscadc: Match mfd sub devices to regmap interface
-
-Conflicts:
- drivers/input/touchscreen/ti_am335x_tsc.c
- drivers/mfd/ti_am335x_tscadc.c
----
- drivers/iio/adc/ti_am335x_adc.c | 27 +++++++++++++++++++--------
- drivers/input/touchscreen/ti_am335x_tsc.c | 16 +++++++++++++---
- drivers/mfd/ti_am335x_tscadc.c | 1 +
- 3 files changed, 33 insertions(+), 11 deletions(-)
-
-diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
-index 40e09eb..d8bc836 100644
---- a/drivers/iio/adc/ti_am335x_adc.c
-+++ b/drivers/iio/adc/ti_am335x_adc.c
-@@ -25,7 +25,9 @@
- #include <linux/of_device.h>
- #include <linux/iio/machine.h>
- #include <linux/iio/driver.h>
-+#include <linux/regmap.h>
-
-+#include <linux/io.h>
- #include <linux/mfd/ti_am335x_tscadc.h>
- #include <linux/platform_data/ti_am335x_adc.h>
-
-@@ -38,13 +40,17 @@ struct tiadc_device {
-
- static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
- {
-- return readl(adc->mfd_tscadc->tscadc_base + reg);
-+ unsigned int val;
-+
-+ val = (unsigned int)-1;
-+ regmap_read(adc->mfd_tscadc->regmap_tscadc, reg, &val);
-+ return val;
- }
-
- static void tiadc_writel(struct tiadc_device *adc, unsigned int reg,
- unsigned int val)
- {
-- writel(val, adc->mfd_tscadc->tscadc_base + reg);
-+ regmap_write(adc->mfd_tscadc->regmap_tscadc, reg, val);
- }
-
- static void tiadc_step_config(struct tiadc_device *adc_dev)
-@@ -77,22 +83,24 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
- tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB);
- }
-
--static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
-+static int tiadc_channel_init(struct iio_dev *indio_dev,
-+ struct tiadc_device *adc_dev)
- {
- struct iio_chan_spec *chan_array;
- struct iio_chan_spec *chan;
- char *s;
- int i, len, size, ret;
-+ int channels = adc_dev->channels;
-
-- size = indio_dev->num_channels * (sizeof(struct iio_chan_spec) + 6);
-+ size = channels * (sizeof(struct iio_chan_spec) + 6);
- chan_array = kzalloc(size, GFP_KERNEL);
- if (chan_array == NULL)
- return -ENOMEM;
-
- /* buffer space is after the array */
-- s = (char *)(chan_array + indio_dev->num_channels);
-+ s = (char *)(chan_array + channels);
- chan = chan_array;
-- for (i = 0; i < indio_dev->num_channels; i++, chan++, s += len + 1) {
-+ for (i = 0; i < channels; i++, chan++, s += len + 1) {
-
- len = sprintf(s, "AIN%d", i);
-
-@@ -107,8 +115,9 @@ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
- }
-
- indio_dev->channels = chan_array;
-+ indio_dev->num_channels = channels;
-
-- size = (indio_dev->num_channels + 1) * sizeof(struct iio_map);
-+ size = (channels + 1) * sizeof(struct iio_map);
- adc_dev->map = kzalloc(size, GFP_KERNEL);
- if (adc_dev->map == NULL) {
- kfree(chan_array);
-@@ -221,7 +230,7 @@ static int tiadc_probe(struct platform_device *pdev)
-
- tiadc_step_config(adc_dev);
-
-- err = tiadc_channel_init(indio_dev, adc_dev->channels);
-+ err = tiadc_channel_init(indio_dev, adc_dev);
- if (err < 0)
- goto err_free_device;
-
-@@ -231,6 +240,8 @@ static int tiadc_probe(struct platform_device *pdev)
-
- platform_set_drvdata(pdev, indio_dev);
-
-+ dev_info(&pdev->dev, "Initialized\n");
-+
- return 0;
-
- err_free_channels:
-diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
-index 6ff5a76..edba36b 100644
---- a/drivers/input/touchscreen/ti_am335x_tsc.c
-+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
-@@ -28,6 +28,7 @@
- #include <linux/delay.h>
- #include <linux/of.h>
- #include <linux/of_device.h>
-+#include <linux/regmap.h>
-
- #include <linux/mfd/ti_am335x_tscadc.h>
-
-@@ -62,13 +63,17 @@ struct titsc {
-
- static unsigned int titsc_readl(struct titsc *ts, unsigned int reg)
- {
-- return readl(ts->mfd_tscadc->tscadc_base + reg);
-+ unsigned int val;
-+
-+ val = (unsigned int)-1;
-+ regmap_read(ts->mfd_tscadc->regmap_tscadc, reg, &val);
-+ return val;
- }
-
- static void titsc_writel(struct titsc *tsc, unsigned int reg,
- unsigned int val)
- {
-- writel(val, tsc->mfd_tscadc->tscadc_base + reg);
-+ regmap_write(tsc->mfd_tscadc->regmap_tscadc, reg, val);
- }
-
- /*
-@@ -500,10 +505,15 @@ static int titsc_probe(struct platform_device *pdev)
-
- /* register to the input system */
- err = input_register_device(input_dev);
-- if (err)
-+ if (err) {
-+ dev_err(&pdev->dev, "Failed to register input device\n");
- goto err_free_irq;
-+ }
-
- platform_set_drvdata(pdev, ts_dev);
-+
-+ dev_info(&pdev->dev, "Initialized OK\n");
-+
- return 0;
-
- err_free_irq:
-diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
-index 0632d59..899534d 100644
---- a/drivers/mfd/ti_am335x_tscadc.c
-+++ b/drivers/mfd/ti_am335x_tscadc.c
-@@ -33,6 +33,7 @@ static unsigned int tscadc_readl(struct ti_tscadc_dev *tsadc, unsigned int reg)
- {
- unsigned int val;
-
-+ val = (unsigned int)-1;
- regmap_read(tsadc->regmap_tscadc, reg, &val);
- return val;
- }
diff --git a/patches/linux-3.8.4/0054-input-ti_am335x_tsc-Add-variance-filters.patch b/patches/linux-3.8.4/0054-input-ti_am335x_tsc-Add-variance-filters.patch
deleted file mode 100644
index 8cd7121..0000000
--- a/patches/linux-3.8.4/0054-input-ti_am335x_tsc-Add-variance-filters.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From: "Patil, Rachna" <rachna@ti.com>
-Date: Mon, 22 Oct 2012 10:15:18 +0000
-Subject: [PATCH] input: ti_am335x_tsc: Add variance filters
-
-Only fine tuning variance present in tslib utility
-does not help in removing all the wanted ADC noise.
-This logic of filtering is necessary to get this
-touchscreen to work finely.
-
-Signed-off-by: Patil, Rachna <rachna@ti.com>
-
-Conflicts:
- drivers/input/touchscreen/ti_am335x_tsc.c
----
- drivers/input/touchscreen/ti_am335x_tsc.c | 16 +++++++++++++++-
- 1 file changed, 15 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
-index edba36b..2461631 100644
---- a/drivers/input/touchscreen/ti_am335x_tsc.c
-+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
-@@ -35,6 +35,8 @@
- #define ADCFSM_STEPID 0x10
- #define SEQ_SETTLE 275
- #define MAX_12BIT ((1 << 12) - 1)
-+#define TSCADC_DELTA_X 15
-+#define TSCADC_DELTA_Y 15
-
- /*
- * Refer to function regbit_map() to
-@@ -54,6 +56,8 @@ struct titsc {
- unsigned int wires;
- unsigned int x_plate_resistance;
- unsigned int enable_bits;
-+ unsigned int bckup_x;
-+ unsigned int bckup_y;
- bool pen_down;
- int steps_to_configure;
- int config_inp[20];
-@@ -315,11 +319,18 @@ static irqreturn_t titsc_irq(int irq, void *dev)
- unsigned int x = 0, y = 0;
- unsigned int z1, z2, z;
- unsigned int fsm;
-+ unsigned int diffx = 0, diffy = 0;
-+ int i;
-
- status = titsc_readl(ts_dev, REG_IRQSTATUS);
- if (status & IRQENB_FIFO0THRES) {
- titsc_read_coordinates(ts_dev, &x, &y);
-
-+ diffx = abs(x - (ts_dev->bckup_x));
-+ diffy = abs(y - (ts_dev->bckup_y));
-+ ts_dev->bckup_x = x;
-+ ts_dev->bckup_y = y;
-+
- z1 = titsc_readl(ts_dev, REG_FIFO0) & 0xfff;
- z2 = titsc_readl(ts_dev, REG_FIFO1) & 0xfff;
-
-@@ -335,7 +346,8 @@ static irqreturn_t titsc_irq(int irq, void *dev)
- z /= z1;
- z = (z + 2047) >> 12;
-
-- if (z <= MAX_12BIT) {
-+ if ((diffx < TSCADC_DELTA_X) &&
-+ (diffy < TSCADC_DELTA_Y) && (z <= MAX_12BIT)) {
- input_report_abs(input_dev, ABS_X, x);
- input_report_abs(input_dev, ABS_Y, y);
- input_report_abs(input_dev, ABS_PRESSURE, z);
-@@ -358,6 +370,8 @@ static irqreturn_t titsc_irq(int irq, void *dev)
- fsm = titsc_readl(ts_dev, REG_ADCFSM);
- if (fsm == ADCFSM_STEPID) {
- ts_dev->pen_down = false;
-+ ts_dev->bckup_x = 0;
-+ ts_dev->bckup_y = 0;
- input_report_key(input_dev, BTN_TOUCH, 0);
- input_report_abs(input_dev, ABS_PRESSURE, 0);
- input_sync(input_dev);
diff --git a/patches/linux-3.8.4/0055-am335x-adc-Do-not-use-find_node_by_name-use-get_chil.patch b/patches/linux-3.8.4/0055-am335x-adc-Do-not-use-find_node_by_name-use-get_chil.patch
deleted file mode 100644
index 3a9a0bd..0000000
--- a/patches/linux-3.8.4/0055-am335x-adc-Do-not-use-find_node_by_name-use-get_chil.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From: Pantelis Antoniou <panto@antoniou-consulting.com>
-Date: Wed, 30 Jan 2013 13:29:59 +0200
-Subject: [PATCH] am335x-adc: Do not use find_node_by_name, use
- get_child_by_name
-
-of_find_node_by_name doesn't work with overlays, and it's not
-doing what the caller expected to do anyway. find_node_by_name
-works by a coincidence anyway.
-
-Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
----
- drivers/iio/adc/ti_am335x_adc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
-index d8bc836..ee20c0c9 100644
---- a/drivers/iio/adc/ti_am335x_adc.c
-+++ b/drivers/iio/adc/ti_am335x_adc.c
-@@ -210,7 +210,7 @@ static int tiadc_probe(struct platform_device *pdev)
- if (pdata)
- adc_dev->channels = pdata->adc_init->adc_channels;
- else {
-- node = of_find_node_by_name(node, "adc");
-+ node = of_get_child_by_name(node, "adc");
- if (!node)
- return -EINVAL;
- else {
diff --git a/patches/linux-3.8.4/0056-am335x-tsc-Do-not-use-find_node_by_name-use-get_chil.patch b/patches/linux-3.8.4/0056-am335x-tsc-Do-not-use-find_node_by_name-use-get_chil.patch
deleted file mode 100644
index 7ffe42e..0000000
--- a/patches/linux-3.8.4/0056-am335x-tsc-Do-not-use-find_node_by_name-use-get_chil.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From: Pantelis Antoniou <panto@antoniou-consulting.com>
-Date: Wed, 30 Jan 2013 13:49:12 +0200
-Subject: [PATCH] am335x-tsc: Do not use find_node_by_name, use
- get_child_by_name
-
-of_find_node_by_name doesn't work with overlays, and it's not
-doing what the caller expected to do anyway. find_node_by_name
-works by a coincidence anyway.
-
-Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
----
- drivers/input/touchscreen/ti_am335x_tsc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c
-index 2461631..4fcf72f 100644
---- a/drivers/input/touchscreen/ti_am335x_tsc.c
-+++ b/drivers/input/touchscreen/ti_am335x_tsc.c
-@@ -397,7 +397,7 @@ static int titsc_parse_dt(struct ti_tscadc_dev *tscadc_dev,
- if (!node)
- return -EINVAL;
- else {
-- node = of_find_node_by_name(node, "tsc");
-+ node = of_get_child_by_name(node, "tsc");
- if (!node)
- return -EINVAL;
- else {
diff --git a/patches/linux-3.8.4/0057-am335x-tscadc-Do-not-use-find_node_by_name-use-get_c.patch b/patches/linux-3.8.4/0057-am335x-tscadc-Do-not-use-find_node_by_name-use-get_c.patch
deleted file mode 100644
index 4e35356..0000000
--- a/patches/linux-3.8.4/0057-am335x-tscadc-Do-not-use-find_node_by_name-use-get_c.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From: Pantelis Antoniou <panto@antoniou-consulting.com>
-Date: Wed, 30 Jan 2013 15:13:19 +0200
-Subject: [PATCH] am335x-tscadc: Do not use find_node_by_name, use
- get_child_by_name
-
-of_find_node_by_name doesn't work with overlays, and it's not
-doing what the caller expected to do anyway. find_node_by_name
-works by a coincidence anyway.
-
-Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
----
- drivers/mfd/ti_am335x_tscadc.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
-index 899534d..e28a31d 100644
---- a/drivers/mfd/ti_am335x_tscadc.c
-+++ b/drivers/mfd/ti_am335x_tscadc.c
-@@ -85,10 +85,10 @@ static int ti_tscadc_probe(struct platform_device *pdev)
- if (pdata->adc_init)
- adc_channels = pdata->adc_init->adc_channels;
- } else {
-- node = of_find_node_by_name(pdev->dev.of_node, "tsc");
-+ node = of_get_child_by_name(pdev->dev.of_node, "tsc");
- of_property_read_u32(node, "ti,wires", &tsc_wires);
-
-- node = of_find_node_by_name(pdev->dev.of_node, "adc");
-+ node = of_get_child_by_name(pdev->dev.of_node, "adc");
- of_property_read_u32(node, "ti,adc-channels", &adc_channels);
- }
-
-@@ -284,6 +284,7 @@ static const struct dev_pm_ops tscadc_pm_ops = {
-
- static const struct of_device_id ti_tscadc_dt_ids[] = {
- { .compatible = "ti,ti-tscadc", },
-+ { }
- };
-
- static struct platform_driver ti_tscadc_driver = {
diff --git a/patches/linux-3.8.4/0162-6lowpan-add-a-new-parameter-in-sysfs-to-turn-on-off-.patch b/patches/linux-3.8.4/0162-6lowpan-add-a-new-parameter-in-sysfs-to-turn-on-off-.patch
deleted file mode 100644
index d7e9f0f..0000000
--- a/patches/linux-3.8.4/0162-6lowpan-add-a-new-parameter-in-sysfs-to-turn-on-off-.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Thu, 12 Jul 2012 17:47:39 -0400
-Subject: [PATCH] 6lowpan: add a new parameter in sysfs to turn on/off ACK
- request at MAC layer
-
-Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
----
- net/ieee802154/6lowpan.c | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
-index 665ddcf..a71452e 100644
---- a/net/ieee802154/6lowpan.c
-+++ b/net/ieee802154/6lowpan.c
-@@ -62,6 +62,8 @@
-
- #include "6lowpan.h"
-
-+static bool req_802154_ack;
-+
- /* TTL uncompression values */
- static const u8 lowpan_ttl_values[] = {0, 1, 64, 255};
-
-@@ -596,7 +598,8 @@ static int lowpan_header_create(struct sk_buff *skb,
- memcpy(&(da.hwaddr), daddr, 8);
-
- /* request acknowledgment */
-- mac_cb(skb)->flags |= MAC_CB_FLAG_ACKREQ;
-+ if (req_802154_ack)
-+ mac_cb(skb)->flags |= MAC_CB_FLAG_ACKREQ;
- }
-
- return dev_hard_header(skb, lowpan_dev_info(dev)->real_dev,
-@@ -1367,6 +1370,10 @@ static void __exit lowpan_cleanup_module(void)
- }
-
- module_init(lowpan_init_module);
-+
-+module_param(req_802154_ack, bool, 0644);
-+MODULE_PARM_DESC(req_802154_ack, "request link-layer (i.e. IEEE 802.15.4) acknowledgments");
-+
- module_exit(lowpan_cleanup_module);
- MODULE_LICENSE("GPL");
- MODULE_ALIAS_RTNL_LINK("lowpan");
diff --git a/patches/linux-3.8.4/0165-6lowpan-make-memory-allocation-atomic-during-6lowpan.patch b/patches/linux-3.8.4/0165-6lowpan-make-memory-allocation-atomic-during-6lowpan.patch
deleted file mode 100644
index 88a9a29..0000000
--- a/patches/linux-3.8.4/0165-6lowpan-make-memory-allocation-atomic-during-6lowpan.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Mon, 3 Sep 2012 23:26:27 -0400
-Subject: [PATCH] 6lowpan: make memory allocation atomic during 6lowpan header
- creation
-
-This is prevent various crashes when using the serial driver (not yet in
-the tree).
-
-Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
----
- net/ieee802154/6lowpan.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
-index 7cba1a6..604a902 100644
---- a/net/ieee802154/6lowpan.c
-+++ b/net/ieee802154/6lowpan.c
-@@ -396,7 +396,7 @@ static int lowpan_header_create(struct sk_buff *skb,
- /* TODO:
- * if this package isn't ipv6 one, where should it be routed?
- */
-- head = kzalloc(100, GFP_KERNEL);
-+ head = kzalloc(100, GFP_ATOMIC);
- if (head == NULL)
- return -ENOMEM;
-
diff --git a/patches/linux-3.8.4/0166-mac802154-make-mem-alloc-ATOMIC-to-prevent-schedulin.patch b/patches/linux-3.8.4/0166-mac802154-make-mem-alloc-ATOMIC-to-prevent-schedulin.patch
deleted file mode 100644
index 0b5cb38..0000000
--- a/patches/linux-3.8.4/0166-mac802154-make-mem-alloc-ATOMIC-to-prevent-schedulin.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Tue, 10 Jul 2012 11:36:28 -0400
-Subject: [PATCH] mac802154: make mem alloc ATOMIC to prevent "scheduling
- while atomic" crashes
-
-These crashes occur mainly with the serial driver (not yet in the tree).
-
-Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
----
- net/mac802154/wpan.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c
-index fdf482a..e0d358f 100644
---- a/net/mac802154/wpan.c
-+++ b/net/mac802154/wpan.c
-@@ -143,7 +143,7 @@ static int mac802154_header_create(struct sk_buff *skb,
- if (!daddr)
- return -EINVAL;
-
-- head = kzalloc(MAC802154_FRAME_HARD_HEADER_LEN, GFP_KERNEL);
-+ head = kzalloc(MAC802154_FRAME_HARD_HEADER_LEN, GFP_ATOMIC);
- if (head == NULL)
- return -ENOMEM;
-
diff --git a/patches/linux-3.8.4/0167-mac802154-remove-unnecessary-spinlocks.patch b/patches/linux-3.8.4/0167-mac802154-remove-unnecessary-spinlocks.patch
deleted file mode 100644
index 0bc9c07..0000000
--- a/patches/linux-3.8.4/0167-mac802154-remove-unnecessary-spinlocks.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Thu, 20 Sep 2012 23:44:19 -0400
-Subject: [PATCH] mac802154: remove unnecessary spinlocks
-
-These spinlock protects an int variable, that is always accessible in an
-atomic fashion.
-
-Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
----
- net/mac802154/mib.c | 14 ++------------
- 1 file changed, 2 insertions(+), 12 deletions(-)
-
-diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c
-index f47781a..2339f8d 100644
---- a/net/mac802154/mib.c
-+++ b/net/mac802154/mib.c
-@@ -103,15 +103,10 @@ void mac802154_dev_set_short_addr(struct net_device *dev, u16 val)
- u16 mac802154_dev_get_short_addr(const struct net_device *dev)
- {
- struct mac802154_sub_if_data *priv = netdev_priv(dev);
-- u16 ret;
-
- BUG_ON(dev->type != ARPHRD_IEEE802154);
-
-- spin_lock_bh(&priv->mib_lock);
-- ret = priv->short_addr;
-- spin_unlock_bh(&priv->mib_lock);
--
-- return ret;
-+ return priv->short_addr;
- }
-
- void mac802154_dev_set_ieee_addr(struct net_device *dev)
-@@ -131,15 +126,10 @@ void mac802154_dev_set_ieee_addr(struct net_device *dev)
- u16 mac802154_dev_get_pan_id(const struct net_device *dev)
- {
- struct mac802154_sub_if_data *priv = netdev_priv(dev);
-- u16 ret;
-
- BUG_ON(dev->type != ARPHRD_IEEE802154);
-
-- spin_lock_bh(&priv->mib_lock);
-- ret = priv->pan_id;
-- spin_unlock_bh(&priv->mib_lock);
--
-- return ret;
-+ return priv->pan_id;
- }
-
- void mac802154_dev_set_pan_id(struct net_device *dev, u16 val)
diff --git a/patches/linux-3.8.4/0168-mac802154-re-introduce-MAC-primitives-required-to-se.patch b/patches/linux-3.8.4/0168-mac802154-re-introduce-MAC-primitives-required-to-se.patch
deleted file mode 100644
index 510c783..0000000
--- a/patches/linux-3.8.4/0168-mac802154-re-introduce-MAC-primitives-required-to-se.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Thu, 20 Sep 2012 23:48:11 -0400
-Subject: [PATCH] mac802154: re-introduce MAC primitives required to
- send/receive packets
-
-- mlme_assoc_req() and mlme_assoc_resp() are just place holder for the
- moment (they prevent the two corresponding function pointers in the
- mac802154_mlme_wpan structure to be left uninitialized)
-- mac802514_dev_get_bsn() and mac802514_dev_get_dsn() MAC primitives
- were present in the Linux-Zigbee kernel and are being re-introduced.
-
-Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
----
- net/mac802154/mac802154.h | 2 ++
- net/mac802154/mac_cmd.c | 22 +++++++++++++++++++++-
- net/mac802154/mib.c | 19 +++++++++++++++++++
- 3 files changed, 42 insertions(+), 1 deletion(-)
-
-diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h
-index a4dcaf1..18d4044 100644
---- a/net/mac802154/mac802154.h
-+++ b/net/mac802154/mac802154.h
-@@ -114,5 +114,7 @@ void mac802154_dev_set_ieee_addr(struct net_device *dev);
- u16 mac802154_dev_get_pan_id(const struct net_device *dev);
- void mac802154_dev_set_pan_id(struct net_device *dev, u16 val);
- void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan);
-+u8 mac802154_dev_get_dsn(const struct net_device *dev);
-+u8 mac802154_dev_get_bsn(const struct net_device *dev);
-
- #endif /* MAC802154_H */
-diff --git a/net/mac802154/mac_cmd.c b/net/mac802154/mac_cmd.c
-index d8d2770..8e46e7b 100644
---- a/net/mac802154/mac_cmd.c
-+++ b/net/mac802154/mac_cmd.c
-@@ -33,6 +33,22 @@
-
- #include "mac802154.h"
-
-+static int mac802154_mlme_assoc_req(struct net_device *dev,
-+ struct ieee802154_addr *addr,
-+ u8 channel, u8 page, u8 cap)
-+{
-+ /* TBD */
-+ return 0;
-+}
-+
-+static int mac802154_mlme_assoc_resp(struct net_device *dev,
-+ struct ieee802154_addr *addr,
-+ u16 short_addr, u8 status)
-+{
-+ /* TBD */
-+ return 0;
-+}
-+
- static int mac802154_mlme_start_req(struct net_device *dev,
- struct ieee802154_addr *addr,
- u8 channel, u8 page,
-@@ -70,7 +86,11 @@ struct ieee802154_reduced_mlme_ops mac802154_mlme_reduced = {
-
- struct ieee802154_mlme_ops mac802154_mlme_wpan = {
- .get_phy = mac802154_get_phy,
-- .start_req = mac802154_mlme_start_req,
- .get_pan_id = mac802154_dev_get_pan_id,
- .get_short_addr = mac802154_dev_get_short_addr,
-+ .get_dsn = mac802154_dev_get_dsn,
-+ .get_bsn = mac802154_dev_get_bsn,
-+ .start_req = mac802154_mlme_start_req,
-+ .assoc_req = mac802154_mlme_assoc_req,
-+ .assoc_resp = mac802154_mlme_assoc_resp
- };
-diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c
-index 2339f8d..70ab6ca 100644
---- a/net/mac802154/mib.c
-+++ b/net/mac802154/mib.c
-@@ -149,6 +149,25 @@ void mac802154_dev_set_pan_id(struct net_device *dev, u16 val)
- }
- }
-
-+u8 mac802154_dev_get_dsn(const struct net_device *dev)
-+{
-+ struct mac802154_sub_if_data *priv = netdev_priv(dev);
-+
-+ BUG_ON(dev->type != ARPHRD_IEEE802154);
-+
-+ return priv->dsn++;
-+}
-+
-+u8 mac802154_dev_get_bsn(const struct net_device *dev)
-+{
-+ struct mac802154_sub_if_data *priv = netdev_priv(dev);
-+
-+ BUG_ON(dev->type != ARPHRD_IEEE802154);
-+
-+ return priv->bsn++;
-+}
-+
-+
- static void phy_chan_notify(struct work_struct *work)
- {
- struct phy_chan_notify_work *nw = container_of(work,
diff --git a/patches/linux-3.8.4/0169-serial-initial-import-of-the-IEEE-802.15.4-serial-dr.patch b/patches/linux-3.8.4/0169-serial-initial-import-of-the-IEEE-802.15.4-serial-dr.patch
deleted file mode 100644
index 2d501d8..0000000
--- a/patches/linux-3.8.4/0169-serial-initial-import-of-the-IEEE-802.15.4-serial-dr.patch
+++ /dev/null
@@ -1,1323 +0,0 @@
-From: Tony Cheneau <tony.cheneau@amnesiak.org>
-Date: Tue, 11 Sep 2012 23:42:51 -0400
-Subject: [PATCH] serial: initial import of the IEEE 802.15.4 serial driver
-
-The initial code has been imported from the Linux ZigBee project. It
-supports RedBee Econotag device type.
-
-Patches from Mariano Alvira has been applied against the drivers.
-
-Initialisation of the driver now send CLOSE command before sending OPEN
-command. This effectively re-initiate the devices (empty buffers).
-
-Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
----
- drivers/net/ieee802154/Kconfig | 4 +
- drivers/net/ieee802154/Makefile | 1 +
- drivers/net/ieee802154/serial.c | 1228 +++++++++++++++++++++++++++++++++++++++
- include/linux/nl802154.h | 3 +-
- include/uapi/linux/tty.h | 1 +
- net/ieee802154/6lowpan.c | 2 +
- 6 files changed, 1238 insertions(+), 1 deletion(-)
- create mode 100644 drivers/net/ieee802154/serial.c
-
-diff --git a/drivers/net/ieee802154/Kconfig b/drivers/net/ieee802154/Kconfig
-index 08ae465..c982fa8 100644
---- a/drivers/net/ieee802154/Kconfig
-+++ b/drivers/net/ieee802154/Kconfig
-@@ -45,3 +45,7 @@ config IEEE802154_MRF24J40
-
- This driver can also be built as a module. To do so, say M here.
- the module will be called 'mrf24j40'.
-+
-+config IEEE802154_SERIAL
-+ depends on IEEE802154_DRIVERS && MAC802154
-+ tristate "Simple LR-WPAN UART driver"
-diff --git a/drivers/net/ieee802154/Makefile b/drivers/net/ieee802154/Makefile
-index abb0c08..5c7d9cb 100644
---- a/drivers/net/ieee802154/Makefile
-+++ b/drivers/net/ieee802154/Makefile
-@@ -2,3 +2,4 @@ obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o
- obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o
- obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o
- obj-$(CONFIG_IEEE802154_MRF24J40) += mrf24j40.o
-+obj-$(CONFIG_IEEE802154_SERIAL) += serial.o
-diff --git a/drivers/net/ieee802154/serial.c b/drivers/net/ieee802154/serial.c
-new file mode 100644
-index 0000000..950893a
---- /dev/null
-+++ b/drivers/net/ieee802154/serial.c
-@@ -0,0 +1,1228 @@
-+/*
-+ * ZigBee TTY line discipline.
-+ *
-+ * Provides interface between ZigBee stack and IEEE 802.15.4 compatible
-+ * firmware over serial line. Communication protocol is described below.
-+ *
-+ * Copyright (C) 2007, 2008, 2009 Siemens AG
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2
-+ * as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License along
-+ * with this program; if not, write to the Free Software Foundation, Inc.,
-+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-+ *
-+ * Written by:
-+ * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
-+ * Maxim Osipov <maxim.osipov@siemens.com>
-+ * Sergey Lapin <slapin@ossfans.org>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/completion.h>
-+#include <linux/tty.h>
-+#include <linux/skbuff.h>
-+#include <linux/sched.h>
-+#include <net/mac802154.h>
-+#include <net/wpan-phy.h>
-+
-+
-+/* NOTE: be sure to use here the same values as in the firmware */
-+#define START_BYTE1 'z'
-+#define START_BYTE2 'b'
-+#define MAX_DATA_SIZE 127
-+
-+#define TIMEOUT 1000
-+
-+#define IDLE_MODE 0x00
-+#define RX_MODE 0x02
-+#define TX_MODE 0x03
-+#define FORCE_TRX_OFF 0xF0
-+
-+#define STATUS_SUCCESS 0
-+#define STATUS_RX_ON 1
-+#define STATUS_TX_ON 2
-+#define STATUS_TRX_OFF 3
-+#define STATUS_IDLE 4
-+#define STATUS_BUSY 5
-+#define STATUS_BUSY_RX 6
-+#define STATUS_BUSY_TX 7
-+#define STATUS_ERR 8
-+
-+#define STATUS_WAIT ((u8) -1) /* waiting for the answer */
-+
-+/* We re-use PPP ioctl for our purposes */
-+#define PPPIOCGUNIT _IOR('t', 86, int) /* get ppp unit number */
-+
-+/*
-+ * The following messages are used to control ZigBee firmware.
-+ * All communication has request/response format,
-+ * except of asynchronous incoming data stream (DATA_RECV_* messages).
-+ */
-+enum {
-+ NO_ID = 0, /* means no pending id */
-+
-+ /* Driver to Firmware */
-+ CMD_OPEN = 0x01, /* u8 id */
-+ CMD_CLOSE = 0x02, /* u8 id */
-+ CMD_SET_CHANNEL = 0x04, /* u8 id, u8 channel */
-+ CMD_ED = 0x05, /* u8 id */
-+ CMD_SET_STATE = 0x07, /* u8 id, u8 flag */
-+ DATA_XMIT_BLOCK = 0x09, /* u8 id, u8 len, u8 data[len] */
-+ RESP_RECV_BLOCK = 0x0b, /* u8 id, u8 status */
-+ CMD_ADDRESS = 0x0d, /* u8 id */
-+ CMD_SET_PAN_ID = 0x0f, /* u8 id, u8 u8 panid (MSB first) */
-+ CMD_SET_SHORT_ADDRESS = 0x10, /* u8 id, u8 u8 address (MSB first)*/
-+ CMD_SET_LONG_ADDRESS = 0x11, /* u8 id, u8 u8 u8 u8 u8 u8 u8 u8 address (MSB first) */
-+
-+ /* Firmware to Driver */
-+ RESP_OPEN = 0x81, /* u8 id, u8 status */
-+ RESP_CLOSE = 0x82, /* u8 id, u8 status */
-+ RESP_SET_CHANNEL = 0x84, /* u8 id, u8 status */
-+ RESP_ED = 0x85, /* u8 id, u8 status, u8 level */
-+ RESP_SET_STATE = 0x87, /* u8 id, u8 status */
-+ RESP_XMIT_BLOCK = 0x89, /* u8 id, u8 status */
-+ DATA_RECV_BLOCK = 0x8b, /* u8 id, u8 lq, u8 len, u8 data[len] */
-+ RESP_ADDRESS = 0x8d, /* u8 id, u8 status, u8 u8 u8 u8 u8 u8 u8 u8 address */
-+ RESP_SET_PAN_ID = 0x8f, /* u8 id, u8 status */
-+ RESP_SET_SHORT_ADDRESS = 0x90, /* u8 id, u8 status */
-+ RESP_SET_LONG_ADDRESS = 0x91, /* u8 id, u8 status */
-+};
-+
-+enum {
-+ STATE_WAIT_START1,
-+ STATE_WAIT_START2,
-+ STATE_WAIT_COMMAND,
-+ STATE_WAIT_PARAM1,
-+ STATE_WAIT_PARAM2,
-+ STATE_WAIT_DATA
-+};
-+
-+struct zb_device {
-+ /* Relative devices */
-+ struct tty_struct *tty;
-+ struct ieee802154_dev *dev;
-+
-+ /* locks the ldisc for the command */
-+ struct mutex mutex;
-+
-+ /* command completition */
-+ wait_queue_head_t wq;
-+ u8 status;
-+ u8 ed;
-+
-+ /* Internal state */
-+ struct completion open_done;
-+ struct completion close_done;
-+ unsigned char opened;
-+ u8 pending_id;
-+ unsigned int pending_size;
-+ u8 *pending_data;
-+ /* FIXME: WE NEED LOCKING!!! */
-+
-+ /* Command (rx) processing */
-+ int state;
-+ unsigned char id;
-+ unsigned char param1;
-+ unsigned char param2;
-+ unsigned char index;
-+ unsigned char data[MAX_DATA_SIZE];
-+};
-+
-+/*****************************************************************************
-+ * ZigBee serial device protocol handling
-+ *****************************************************************************/
-+static int _open_dev(struct zb_device *zbdev);
-+static int _close_dev(struct zb_device *zbdev);
-+
-+static void
-+cleanup(struct zb_device *zbdev)
-+{
-+ zbdev->state = STATE_WAIT_START1;
-+ zbdev->id = 0;
-+ zbdev->param1 = 0;
-+ zbdev->param2 = 0;
-+ zbdev->index = 0;
-+ zbdev->pending_id = 0;
-+ zbdev->pending_size = 0;
-+
-+ if (zbdev->pending_data)
-+ {
-+ kfree(zbdev->pending_data);
-+ zbdev->pending_data = NULL;
-+ }
-+}
-+
-+static int
-+_send_pending_data(struct zb_device *zbdev)
-+{
-+ struct tty_struct *tty;
-+
-+ BUG_ON(!zbdev);
-+ tty = zbdev->tty;
-+ if (!tty)
-+ return -ENODEV;
-+
-+ zbdev->status = STATUS_WAIT;
-+
-+ /* Debug info */
-+ printk(KERN_INFO "%s, %d bytes\n", __func__,
-+ zbdev->pending_size);
-+#ifdef DEBUG
-+ print_hex_dump_bytes("send_pending_data ", DUMP_PREFIX_NONE,
-+ zbdev->pending_data, zbdev->pending_size);
-+#endif
-+
-+ if (tty->driver->ops->write(tty, zbdev->pending_data,
-+ zbdev->pending_size) != zbdev->pending_size) {
-+ printk(KERN_ERR "%s: device write failed\n", __func__);
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+send_cmd(struct zb_device *zbdev, u8 id)
-+{
-+ u8 len = 0;
-+ /* 4 because of 2 start bytes, id and optional extra */
-+ u8 buf[4];
-+
-+ /* Check arguments */
-+ BUG_ON(!zbdev);
-+
-+ if (!zbdev->opened) {
-+ if (!_close_dev(zbdev) || !_open_dev(zbdev))
-+ return -EAGAIN;
-+ }
-+
-+ pr_debug("%s(): id = %u\n", __func__, id);
-+ if (zbdev->pending_size) {
-+ printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
-+ __func__, zbdev->pending_id);
-+ //BUG();
-+ cleanup(zbdev);
-+ return -EAGAIN;
-+ }
-+
-+ /* Prepare a message */
-+ buf[len++] = START_BYTE1;
-+ buf[len++] = START_BYTE2;
-+ buf[len++] = id;
-+
-+ zbdev->pending_id = id;
-+ zbdev->pending_size = len;
-+ zbdev->pending_data = kzalloc(zbdev->pending_size, GFP_ATOMIC);
-+ if (!zbdev->pending_data) {
-+ printk(KERN_ERR "%s(): unable to allocate memory\n", __func__);
-+ zbdev->pending_id = 0;
-+ zbdev->pending_size = 0;
-+ return -ENOMEM;
-+ }
-+ memcpy(zbdev->pending_data, buf, len);
-+
-+ return _send_pending_data(zbdev);
-+}
-+
-+static int
-+send_cmd2(struct zb_device *zbdev, u8 id, u8 extra)
-+{
-+ u8 len = 0;
-+ /* 4 because of 2 start bytes, id and optional extra */
-+ u8 buf[4];
-+
-+ /* Check arguments */
-+ BUG_ON(!zbdev);
-+
-+ if (!zbdev->opened) {
-+ if (!_close_dev(zbdev) || !_open_dev(zbdev))
-+ return -EAGAIN;
-+ }
-+
-+ pr_debug("%s(): id = %u\n", __func__, id);
-+ if (zbdev->pending_size) {
-+ printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
-+ __func__, zbdev->pending_id);
-+// BUG();
-+ cleanup(zbdev);
-+ return -EAGAIN;
-+ }
-+
-+ /* Prepare a message */
-+ buf[len++] = START_BYTE1;
-+ buf[len++] = START_BYTE2;
-+ buf[len++] = id;
-+ buf[len++] = extra;
-+
-+ zbdev->pending_id = id;
-+ zbdev->pending_size = len;
-+ zbdev->pending_data = kzalloc(zbdev->pending_size, GFP_ATOMIC);
-+ if (!zbdev->pending_data) {
-+ printk(KERN_ERR "%s(): unable to allocate memory\n", __func__);
-+ zbdev->pending_id = 0;
-+ zbdev->pending_size = 0;
-+ return -ENOMEM;
-+ }
-+ memcpy(zbdev->pending_data, buf, len);
-+
-+ return _send_pending_data(zbdev);
-+}
-+
-+static int
-+send_cmd3(struct zb_device *zbdev, u8 id, u8 extra1, u8 extra2)
-+{
-+ u8 len = 0;
-+ /* 5 because of 2 start bytes, id, extra1, extra2 */
-+ u8 buf[5];
-+
-+ /* Check arguments */
-+ BUG_ON(!zbdev);
-+
-+ if (!zbdev->opened) {
-+ if (!_close_dev(zbdev) || !_open_dev(zbdev))
-+ return -EAGAIN;
-+ }
-+
-+ pr_debug("%s(): id = %u\n", __func__, id);
-+ if (zbdev->pending_size) {
-+ printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
-+ __func__, zbdev->pending_id);
-+// BUG();
-+ cleanup(zbdev);
-+ return -EAGAIN;
-+ }
-+
-+ /* Prepare a message */
-+ buf[len++] = START_BYTE1;
-+ buf[len++] = START_BYTE2;
-+ buf[len++] = id;
-+ buf[len++] = extra1;
-+ buf[len++] = extra2;
-+
-+ zbdev->pending_id = id;
-+ zbdev->pending_size = len;
-+ zbdev->pending_data = kzalloc(zbdev->pending_size, GFP_ATOMIC);
-+ if (!zbdev->pending_data) {
-+ printk(KERN_ERR "%s(): unable to allocate memory\n", __func__);
-+ zbdev->pending_id = 0;
-+ zbdev->pending_size = 0;
-+ return -ENOMEM;
-+ }
-+ memcpy(zbdev->pending_data, buf, len);
-+
-+ return _send_pending_data(zbdev);
-+}
-+
-+static int
-+send_block(struct zb_device *zbdev, u8 len, u8 *data)
-+{
-+ u8 i = 0, buf[4]; /* 4 because of 2 start bytes, id and len */
-+
-+ /* Check arguments */
-+ BUG_ON(!zbdev);
-+
-+ if (!zbdev->opened) {
-+ if (!_close_dev(zbdev) || !_open_dev(zbdev))
-+ return -EAGAIN;
-+ }
-+
-+ pr_debug("%s(): id = %u\n", __func__, DATA_XMIT_BLOCK);
-+ if (zbdev->pending_size) {
-+ printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
-+ __func__, zbdev->pending_id);
-+ //BUG();
-+ cleanup(zbdev);
-+ return -EAGAIN;
-+ }
-+
-+ /* Prepare a message */
-+ buf[i++] = START_BYTE1;
-+ buf[i++] = START_BYTE2;
-+ buf[i++] = DATA_XMIT_BLOCK;
-+ buf[i++] = len;
-+
-+ zbdev->pending_id = DATA_XMIT_BLOCK;
-+ zbdev->pending_size = i + len;
-+ zbdev->pending_data = kzalloc(zbdev->pending_size, GFP_ATOMIC);
-+ if (!zbdev->pending_data) {
-+ printk(KERN_ERR "%s(): unable to allocate memory\n", __func__);
-+ zbdev->pending_id = 0;
-+ zbdev->pending_size = 0;
-+ return -ENOMEM;
-+ }
-+ memcpy(zbdev->pending_data, buf, i);
-+ memcpy(zbdev->pending_data + i, data, len);
-+
-+ return _send_pending_data(zbdev);
-+}
-+
-+
-+static int
-+is_command(unsigned char c)
-+{
-+ switch (c) {
-+ /* ids we can get here: */
-+ case RESP_OPEN:
-+ case RESP_CLOSE:
-+ case RESP_SET_CHANNEL:
-+ case RESP_ED:
-+ case RESP_XMIT_BLOCK:
-+ case DATA_RECV_BLOCK:
-+ case RESP_ADDRESS:
-+ case RESP_SET_PAN_ID:
-+ case RESP_SET_SHORT_ADDRESS:
-+ case RESP_SET_LONG_ADDRESS:
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+static int
-+_match_pending_id(struct zb_device *zbdev)
-+{
-+ return ((CMD_OPEN == zbdev->pending_id &&
-+ RESP_OPEN == zbdev->id) ||
-+ (CMD_CLOSE == zbdev->pending_id &&
-+ RESP_CLOSE == zbdev->id) ||
-+ (CMD_SET_CHANNEL == zbdev->pending_id &&
-+ RESP_SET_CHANNEL == zbdev->id) ||
-+ (CMD_ED == zbdev->pending_id &&
-+ RESP_ED == zbdev->id) ||
-+ (DATA_XMIT_BLOCK == zbdev->pending_id &&
-+ RESP_XMIT_BLOCK == zbdev->id) ||
-+ (DATA_RECV_BLOCK == zbdev->id) ||
-+ (CMD_ADDRESS == zbdev->pending_id &&
-+ RESP_ADDRESS == zbdev->id)) ||
-+ (CMD_SET_PAN_ID == zbdev->pending_id &&
-+ RESP_SET_PAN_ID == zbdev->id) ||
-+ (CMD_SET_SHORT_ADDRESS == zbdev->pending_id &&
-+ RESP_SET_SHORT_ADDRESS == zbdev->id) ||
-+ (CMD_SET_LONG_ADDRESS == zbdev->pending_id &&
-+ RESP_SET_LONG_ADDRESS == zbdev->id);
-+}
-+
-+static void serial_net_rx(struct zb_device *zbdev)
-+{
-+ /* zbdev->param1 is LQI
-+ * zbdev->param2 is length of data
-+ * zbdev->data is data itself
-+ */
-+ struct sk_buff *skb;
-+ skb = alloc_skb(zbdev->param2, GFP_ATOMIC);
-+ skb_put(skb, zbdev->param2);
-+ skb_copy_to_linear_data(skb, zbdev->data, zbdev->param2);
-+ ieee802154_rx_irqsafe(zbdev->dev, skb, zbdev->param1);
-+}
-+
-+static void
-+process_command(struct zb_device *zbdev)
-+{
-+ /* Command processing */
-+ if (!_match_pending_id(zbdev))
-+ {
-+ cleanup(zbdev);
-+ return;
-+ }
-+
-+ if (RESP_OPEN == zbdev->id && STATUS_SUCCESS == zbdev->param1) {
-+ zbdev->opened = 1;
-+ pr_debug("Opened device\n");
-+ complete(&zbdev->open_done);
-+ /* Input is not processed during output, so
-+ * using completion is not possible during output.
-+ * so we need to handle open as any other command
-+ * and hope for best
-+ */
-+ return;
-+ }
-+
-+ if (RESP_CLOSE == zbdev->id && STATUS_SUCCESS == zbdev->param1) {
-+ zbdev->opened = 0;
-+ pr_debug("Closed device\n");
-+ complete(&zbdev->close_done);
-+ /* Input is not processed during output, so
-+ * using completion is not possible during output.
-+ * so we need to handle open as any other command
-+ * and hope for best
-+ */
-+ return;
-+ }
-+
-+ if (!zbdev->opened)
-+ {
-+ cleanup(zbdev);
-+ return;
-+ }
-+
-+
-+ zbdev->pending_id = 0;
-+ kfree(zbdev->pending_data);
-+ zbdev->pending_data = NULL;
-+ zbdev->pending_size = 0;
-+
-+ if (zbdev->id != DATA_RECV_BLOCK) {
-+ /* XXX: w/around for old FW, REMOVE */
-+ if (zbdev->param1 == STATUS_IDLE)
-+ zbdev->status = STATUS_SUCCESS;
-+ else
-+ zbdev->status = zbdev->param1;
-+ }
-+
-+ switch (zbdev->id) {
-+ case RESP_ED:
-+ zbdev->ed = zbdev->param2;
-+ break;
-+ case DATA_RECV_BLOCK:
-+ pr_debug("Received block, lqi %02x, len %02x\n",
-+ zbdev->param1, zbdev->param2);
-+ /* zbdev->param1 is LQ, zbdev->param2 is length */
-+ serial_net_rx(zbdev);
-+ break;
-+ case RESP_ADDRESS:
-+ pr_debug("Received address, %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-+ zbdev->data[0], zbdev->data[1], zbdev->data[2], zbdev->data[3],
-+ zbdev->data[4], zbdev->data[5], zbdev->data[6], zbdev->data[7]);
-+ break;
-+ }
-+
-+ cleanup(zbdev);
-+
-+ wake_up(&zbdev->wq);
-+}
-+
-+static void
-+process_char(struct zb_device *zbdev, unsigned char c)
-+{
-+ /* Data processing */
-+ switch (zbdev->state) {
-+ case STATE_WAIT_START1:
-+ if (START_BYTE1 == c)
-+ zbdev->state = STATE_WAIT_START2;
-+ else
-+ cleanup(zbdev);
-+ break;
-+
-+ case STATE_WAIT_START2:
-+ if (START_BYTE2 == c)
-+ zbdev->state = STATE_WAIT_COMMAND;
-+ else
-+ cleanup(zbdev);
-+ break;
-+
-+ case STATE_WAIT_COMMAND:
-+ if (is_command(c)) {
-+ zbdev->id = c;
-+ zbdev->state = STATE_WAIT_PARAM1;
-+ } else {
-+ cleanup(zbdev);
-+ printk(KERN_ERR "%s, unexpected command id: %x\n",
-+ __func__, c);
-+ }
-+ break;
-+
-+ case STATE_WAIT_PARAM1:
-+ zbdev->param1 = c;
-+ if ((RESP_ED == zbdev->id) || (DATA_RECV_BLOCK == zbdev->id))
-+ zbdev->state = STATE_WAIT_PARAM2;
-+ else if (RESP_ADDRESS == zbdev->id) {
-+ zbdev->param2 = 8;
-+ zbdev->state = STATE_WAIT_DATA;
-+ } else
-+ process_command(zbdev);
-+ break;
-+
-+ case STATE_WAIT_PARAM2:
-+ zbdev->param2 = c;
-+ if (RESP_ED == zbdev->id)
-+ process_command(zbdev);
-+ else if (DATA_RECV_BLOCK == zbdev->id)
-+ zbdev->state = STATE_WAIT_DATA;
-+ else
-+ cleanup(zbdev);
-+ break;
-+
-+ case STATE_WAIT_DATA:
-+ if ((zbdev->index < sizeof(zbdev->data)) &&
-+ (zbdev->param2 <= sizeof(zbdev->data))) {
-+
-+ zbdev->data[zbdev->index] = c;
-+ zbdev->index++;
-+ /*
-+ * Pending data is received,
-+ * param2 is length for DATA_RECV_BLOCK
-+ */
-+ if (zbdev->index == zbdev->param2) {
-+ zbdev->state = STATE_WAIT_START1;
-+ process_command(zbdev);
-+ }
-+ } else {
-+ printk(KERN_ERR "%s(): data size is greater "
-+ "than buffer available\n", __func__);
-+ cleanup(zbdev);
-+ }
-+ break;
-+
-+ default:
-+ cleanup(zbdev);
-+ }
-+}
-+
-+/*****************************************************************************
-+ * Device operations for IEEE 802.15.4 PHY side interface ZigBee stack
-+ *****************************************************************************/
-+
-+static int _open_dev(struct zb_device *zbdev)
-+{
-+ int retries;
-+ u8 len = 0;
-+ /* 4 because of 2 start bytes, id and optional extra */
-+ u8 buf[4];
-+
-+ /* Check arguments */
-+ BUG_ON(!zbdev);
-+ if (zbdev->opened)
-+ return 1;
-+
-+ pr_debug("%s()\n", __func__);
-+ if (zbdev->pending_size) {
-+ printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
-+ __func__, zbdev->pending_id);
-+ //BUG();
-+ cleanup(zbdev);
-+ return -EAGAIN;
-+ }
-+
-+ /* Prepare a message */
-+ buf[len++] = START_BYTE1;
-+ buf[len++] = START_BYTE2;
-+ buf[len++] = CMD_OPEN;
-+
-+
-+ zbdev->pending_id = CMD_OPEN;
-+ zbdev->pending_size = len;
-+ zbdev->pending_data = kzalloc(zbdev->pending_size, GFP_KERNEL);
-+ if (!zbdev->pending_data) {
-+ printk(KERN_ERR "%s(): unable to allocate memory\n", __func__);
-+ zbdev->pending_id = 0;
-+ zbdev->pending_size = 0;
-+ return -ENOMEM;
-+ }
-+ memcpy(zbdev->pending_data, buf, len);
-+
-+ retries = 5;
-+ while (!zbdev->opened && retries) {
-+
-+ if (_send_pending_data(zbdev) != 0)
-+ return 0;
-+
-+ /* 3 second before retransmission */
-+ wait_for_completion_interruptible_timeout(
-+ &zbdev->open_done, msecs_to_jiffies(TIMEOUT));
-+ --retries;
-+ }
-+
-+ cleanup(zbdev);
-+
-+ if (zbdev->opened) {
-+ printk(KERN_INFO "Opened connection to device\n");
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int _close_dev(struct zb_device *zbdev)
-+{
-+ int retries;
-+ u8 len = 0;
-+ /* 4 because of 2 start bytes, id and optional extra */
-+ u8 buf[4];
-+
-+ /* Check arguments */
-+ BUG_ON(!zbdev);
-+
-+ pr_debug("%s()\n", __func__);
-+ if (zbdev->pending_size) {
-+ printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
-+ __func__, zbdev->pending_id);
-+ //BUG();
-+ cleanup(zbdev);
-+ return -EAGAIN;
-+ }
-+
-+ /* Prepare a message */
-+ buf[len++] = START_BYTE1;
-+ buf[len++] = START_BYTE2;
-+ buf[len++] = CMD_CLOSE;
-+
-+ zbdev->pending_id = CMD_CLOSE;
-+ zbdev->pending_size = len;
-+ zbdev->pending_data = kzalloc(zbdev->pending_size, GFP_KERNEL);
-+ if (!zbdev->pending_data) {
-+ printk(KERN_ERR "%s(): unable to allocate memory\n", __func__);
-+ zbdev->pending_id = 0;
-+ zbdev->pending_size = 0;
-+ return -ENOMEM;
-+ }
-+ memcpy(zbdev->pending_data, buf, len);
-+
-+ retries = 5;
-+ do{
-+
-+ if (_send_pending_data(zbdev) !=0)
-+ return 0;
-+
-+ /* 1 second before retransmission */
-+ wait_for_completion_interruptible_timeout(
-+ &zbdev->close_done, msecs_to_jiffies(TIMEOUT));
-+ --retries;
-+ } while (zbdev->opened && retries) ;
-+
-+ cleanup(zbdev);
-+
-+ if (!zbdev->opened)
-+ {
-+ printk(KERN_INFO "Closed connection to device\n");
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+/* Valid channels: 1-16 */
-+static int
-+ieee802154_serial_set_channel(struct ieee802154_dev *dev, int page, int channel)
-+{
-+ struct zb_device *zbdev;
-+ int ret = 0;
-+
-+ pr_debug("%s %d\n", __func__, channel);
-+
-+ zbdev = dev->priv;
-+ if (NULL == zbdev) {
-+ printk(KERN_ERR "%s: wrong phy\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ BUG_ON(page != 0);
-+ /* Our channels are actually from 11 to 26
-+ * We have IEEE802.15.4 channel no from 0 to 26.
-+ * channels 0-10 are not valid for us */
-+ BUG_ON(channel < 11 || channel > 26);
-+ /* ... but our crappy firmware numbers channels from 1 to 16
-+ * which is a mystery. We suould enforce that using PIB API
-+ * but additional checking here won't kill, and gcc will
-+ * optimize this stuff anyway. */
-+ BUG_ON((channel - 10) < 1 && (channel - 10) > 16);
-+ if (mutex_lock_interruptible(&zbdev->mutex))
-+ return -EINTR;
-+ ret = send_cmd2(zbdev, CMD_SET_CHANNEL, channel - 10);
-+ if (ret)
-+ goto out;
-+
-+ if (wait_event_interruptible_timeout(zbdev->wq,
-+ zbdev->status != STATUS_WAIT,
-+ msecs_to_jiffies(TIMEOUT)) > 0) {
-+ if (zbdev->status != STATUS_SUCCESS)
-+ ret = -EBUSY;
-+ } else
-+ ret = -EINTR;
-+
-+ if (!ret)
-+ zbdev->dev->phy->current_channel = channel;
-+out:
-+ mutex_unlock(&zbdev->mutex);
-+ pr_debug("%s end\n", __func__);
-+ return ret;
-+}
-+
-+static int
-+ieee802154_serial_ed(struct ieee802154_dev *dev, u8 *level)
-+{
-+ struct zb_device *zbdev;
-+ int ret = 0;
-+
-+ pr_debug("%s\n", __func__);
-+
-+ zbdev = dev->priv;
-+ if (NULL == zbdev) {
-+ printk(KERN_ERR "%s: wrong phy\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ if (mutex_lock_interruptible(&zbdev->mutex))
-+ return -EINTR;
-+
-+ ret = send_cmd(zbdev, CMD_ED);
-+ if (ret)
-+ goto out;
-+
-+ if (wait_event_interruptible_timeout(zbdev->wq,
-+ zbdev->status != STATUS_WAIT,
-+ msecs_to_jiffies(TIMEOUT)) > 0) {
-+ *level = zbdev->ed;
-+ if (zbdev->status != STATUS_SUCCESS)
-+ ret = -EBUSY;
-+ } else
-+ ret = -ETIMEDOUT;
-+out:
-+
-+ mutex_unlock(&zbdev->mutex);
-+ pr_debug("%s end\n", __func__);
-+ return ret;
-+}
-+
-+static int
-+ieee802154_serial_set_laddr(struct zb_device *zbdev, u8 addr[IEEE802154_ADDR_LEN])
-+{
-+ int ret = 0;
-+ uint8_t len = 0;
-+ /* 11 because of 2 start bytes, id and 8 bytes addr */
-+ uint8_t buf[11];
-+
-+ pr_debug("%s\n", __func__);
-+
-+ if (mutex_lock_interruptible(&zbdev->mutex))
-+ return -EINTR;
-+
-+
-+ if (zbdev->pending_size) {
-+ printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
-+ __func__, zbdev->pending_id);
-+ cleanup(zbdev);
-+ return -EAGAIN;
-+ }
-+
-+ /* Prepare a message */
-+ buf[len++] = START_BYTE1;
-+ buf[len++] = START_BYTE2;
-+ buf[len++] = CMD_SET_LONG_ADDRESS;
-+
-+ memcpy(&buf[len], addr, IEEE802154_ADDR_LEN);
-+
-+ zbdev->pending_id = CMD_SET_LONG_ADDRESS;
-+ zbdev->pending_size = len + IEEE802154_ADDR_LEN;
-+ zbdev->pending_data = kzalloc(zbdev->pending_size, GFP_ATOMIC);
-+ if (!zbdev->pending_data) {
-+ printk(KERN_ERR "%s(): unable to allocate memory\n", __func__);
-+ zbdev->pending_id = 0;
-+ zbdev->pending_size = 0;
-+ return -ENOMEM;
-+ }
-+ memcpy(zbdev->pending_data, buf, len);
-+
-+ ret = _send_pending_data(zbdev);
-+
-+ if (ret)
-+ goto out;
-+
-+ if (wait_event_interruptible_timeout(zbdev->wq,
-+ zbdev->status != STATUS_WAIT,
-+ msecs_to_jiffies(TIMEOUT)) > 0) {
-+ if (zbdev->status != STATUS_SUCCESS)
-+ ret = -EBUSY;
-+ } else
-+ ret = -ETIMEDOUT;
-+
-+out:
-+ mutex_unlock(&zbdev->mutex);
-+ pr_debug("%s end\n", __func__);
-+ return ret;
-+}
-+
-+static int
-+ieee802154_serial_get_laddr(struct ieee802154_dev *dev, u8 addr[IEEE802154_ADDR_LEN])
-+{
-+ struct zb_device *zbdev;
-+ int ret = 0;
-+
-+ pr_debug("%s\n", __func__);
-+
-+ zbdev = dev->priv;
-+ if (NULL == zbdev) {
-+ printk(KERN_ERR "%s: wrong phy\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ if (mutex_lock_interruptible(&zbdev->mutex))
-+ return -EINTR;
-+
-+ ret = send_cmd(zbdev, CMD_ADDRESS);
-+ if (ret)
-+ goto out;
-+
-+ if (wait_event_interruptible_timeout(zbdev->wq,
-+ zbdev->status != STATUS_WAIT,
-+ msecs_to_jiffies(TIMEOUT)) > 0) {
-+ memcpy(addr, zbdev->data, IEEE802154_ADDR_LEN);
-+ if (zbdev->status != STATUS_SUCCESS)
-+ ret = -EBUSY;
-+ } else
-+ ret = -ETIMEDOUT;
-+out:
-+
-+ mutex_unlock(&zbdev->mutex);
-+ pr_debug("%s end\n", __func__);
-+ return ret;
-+}
-+
-+static int
-+ieee802154_serial_set_hw_addr_filt(struct ieee802154_dev *dev,
-+ struct ieee802154_hw_addr_filt *filt,
-+ unsigned long changed)
-+{
-+ struct zb_device *zbdev;
-+ int ret = 0;
-+
-+ pr_debug("%s\n", __func__);
-+
-+ zbdev = dev->priv;
-+
-+ if (NULL == zbdev) {
-+ printk(KERN_ERR "%s: wrong phy\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ if (mutex_lock_interruptible(&zbdev->mutex))
-+ return -EINTR;
-+
-+ switch (changed)
-+ {
-+ case IEEE802515_AFILT_SADDR_CHANGED:
-+ send_cmd3(zbdev, CMD_SET_SHORT_ADDRESS, filt->short_addr & 0xff, filt->short_addr >> 8);
-+ break;
-+ case IEEE802515_AFILT_PANID_CHANGED:
-+ send_cmd3(zbdev, CMD_SET_PAN_ID, filt->pan_id & 0xff, filt->pan_id >> 8);
-+ break;
-+ case IEEE802515_AFILT_IEEEADDR_CHANGED:
-+ ret = ieee802154_serial_set_laddr(zbdev, filt->ieee_addr);
-+ break;
-+ default:
-+ printk(KERN_ERR "%s: unable to apply change, not supported\n", __func__);
-+ break;
-+ }
-+
-+ mutex_unlock(&zbdev->mutex);
-+ pr_debug("%s end\n", __func__);
-+ return ret;
-+}
-+
-+static int
-+ieee802154_serial_start(struct ieee802154_dev *dev)
-+{
-+ struct zb_device *zbdev;
-+ int ret = 0;
-+
-+ pr_debug("%s\n", __func__);
-+
-+ zbdev = dev->priv;
-+ if (NULL == zbdev) {
-+ printk(KERN_ERR "%s: wrong phy\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ pr_debug("%s end (retval: %d)\n", __func__, ret);
-+ return ret;
-+}
-+
-+static void
-+ieee802154_serial_stop(struct ieee802154_dev *dev)
-+{
-+ struct zb_device *zbdev;
-+ pr_debug("%s\n", __func__);
-+
-+ zbdev = dev->priv;
-+ if (NULL == zbdev) {
-+ printk(KERN_ERR "%s: wrong phy\n", __func__);
-+ return;
-+ }
-+
-+ pr_debug("%s end\n", __func__);
-+}
-+
-+static int
-+ieee802154_serial_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
-+{
-+ struct zb_device *zbdev;
-+ int ret;
-+
-+ pr_debug("%s\n", __func__);
-+
-+ zbdev = dev->priv;
-+ if (NULL == zbdev) {
-+ printk(KERN_ERR "%s: wrong phy\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ if (mutex_lock_interruptible(&zbdev->mutex))
-+ return -EINTR;
-+
-+ ret = send_block(zbdev, skb->len, skb->data);
-+ if (ret)
-+ goto out;
-+
-+ if (wait_event_interruptible_timeout(zbdev->wq,
-+ zbdev->status != STATUS_WAIT,
-+ msecs_to_jiffies(TIMEOUT)) > 0) {
-+ if (zbdev->status != STATUS_SUCCESS) {
-+ ret = -EBUSY;
-+ goto out;
-+ }
-+ } else {
-+ ret = -ETIMEDOUT;
-+ goto out;
-+ }
-+
-+out:
-+
-+ mutex_unlock(&zbdev->mutex);
-+ pr_debug("%s end\n", __func__);
-+ return ret;
-+}
-+
-+/*****************************************************************************
-+ * Line discipline interface for IEEE 802.15.4 serial device
-+ *****************************************************************************/
-+
-+static struct ieee802154_ops serial_ops = {
-+ .owner = THIS_MODULE,
-+ .xmit = ieee802154_serial_xmit,
-+ .ed = ieee802154_serial_ed,
-+ .set_channel = ieee802154_serial_set_channel,
-+ .start = ieee802154_serial_start,
-+ .stop = ieee802154_serial_stop,
-+// .set_hw_addr_filt = ieee802154_serial_set_hw_addr_filt,
-+ .ieee_addr = ieee802154_serial_get_laddr,
-+};
-+
-+/*
-+ * Called when a tty is put into ZB line discipline. Called in process context.
-+ * Returns 0 on success.
-+ */
-+static int
-+ieee802154_tty_open(struct tty_struct *tty)
-+{
-+ struct zb_device *zbdev = tty->disc_data;
-+ struct ieee802154_dev *dev;
-+ int err;
-+
-+ pr_debug("Openning ldisc\n");
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EPERM;
-+
-+ if (tty->disc_data)
-+ return -EBUSY;
-+
-+ dev = ieee802154_alloc_device(sizeof(*zbdev), &serial_ops);
-+ if (!dev)
-+ return -ENOMEM;
-+
-+ zbdev = dev->priv;
-+ zbdev->dev = dev;
-+
-+ mutex_init(&zbdev->mutex);
-+ init_completion(&zbdev->open_done);
-+ init_completion(&zbdev->close_done);
-+ init_waitqueue_head(&zbdev->wq);
-+
-+ dev->extra_tx_headroom = 0;
-+ /* only 2.4 GHz band */
-+ dev->phy->channels_supported[0] = 0x7fff800;
-+
-+ dev->flags = IEEE802154_HW_OMIT_CKSUM;
-+
-+ dev->parent = tty->dev;
-+
-+ zbdev->tty = tty_kref_get(tty);
-+
-+ cleanup(zbdev);
-+
-+ tty->disc_data = zbdev;
-+ tty->receive_room = MAX_DATA_SIZE;
-+ // TC: why was it removed ?
-+ // why does it crash one of my computer each times, and the other one is fine
-+ // tty->low_latency = 1;
-+
-+ /* FIXME: why is this needed. Note don't use ldisc_ref here as the
-+ open path is before the ldisc is referencable */
-+
-+ if (tty->ldisc->ops->flush_buffer)
-+ tty->ldisc->ops->flush_buffer(tty);
-+ tty_driver_flush_buffer(tty);
-+
-+ err = ieee802154_register_device(dev);
-+ if (err) {
-+ printk(KERN_ERR "%s: device register failed\n", __func__);
-+ goto out_free;
-+ }
-+
-+ return 0;
-+
-+
-+out_free:
-+ tty->disc_data = NULL;
-+ tty_kref_put(tty);
-+ zbdev->tty = NULL;
-+
-+ ieee802154_unregister_device(zbdev->dev);
-+ ieee802154_free_device(zbdev->dev);
-+
-+ return err;
-+}
-+
-+/*
-+ * Called when the tty is put into another line discipline or it hangs up. We
-+ * have to wait for any cpu currently executing in any of the other zb_tty_*
-+ * routines to finish before we can call zb_tty_close and free the
-+ * zb_serial_dev struct. This routine must be called from process context, not
-+ * interrupt or softirq context.
-+ */
-+static void
-+ieee802154_tty_close(struct tty_struct *tty)
-+{
-+ struct zb_device *zbdev;
-+
-+ zbdev = tty->disc_data;
-+ if (NULL == zbdev) {
-+ printk(KERN_WARNING "%s: match is not found\n", __func__);
-+ return;
-+ }
-+
-+ tty->disc_data = NULL;
-+ tty_kref_put(tty);
-+ zbdev->tty = NULL;
-+ mutex_destroy(&zbdev->mutex);
-+
-+ ieee802154_unregister_device(zbdev->dev);
-+
-+ tty_ldisc_flush(tty);
-+ tty_driver_flush_buffer(tty);
-+
-+ ieee802154_free_device(zbdev->dev);
-+}
-+
-+/*
-+ * Called on tty hangup in process context.
-+ */
-+static int
-+ieee802154_tty_hangup(struct tty_struct *tty)
-+{
-+ ieee802154_tty_close(tty);
-+ return 0;
-+}
-+
-+/*
-+ * Called in process context only. May be re-entered
-+ * by multiple ioctl calling threads.
-+ */
-+static int
-+ieee802154_tty_ioctl(struct tty_struct *tty, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ struct zb_device *zbdev;
-+
-+ pr_debug("cmd = 0x%x\n", cmd);
-+
-+ zbdev = tty->disc_data;
-+ if (NULL == zbdev) {
-+ pr_debug("match is not found\n");
-+ return -EINVAL;
-+ }
-+
-+ switch (cmd) {
-+ case TCFLSH:
-+ return tty_perform_flush(tty, arg);
-+ default:
-+ /* Try the mode commands */
-+ return tty_mode_ioctl(tty, file, cmd, arg);
-+ }
-+}
-+
-+
-+/*
-+ * This can now be called from hard interrupt level as well
-+ * as soft interrupt level or mainline.
-+ */
-+static void
-+ieee802154_tty_receive(struct tty_struct *tty, const unsigned char *buf,
-+ char *cflags, int count)
-+{
-+ struct zb_device *zbdev;
-+ int i;
-+
-+ /* Debug info */
-+ printk(KERN_INFO "%s, received %d bytes\n", __func__,
-+ count);
-+#ifdef DEBUG
-+ print_hex_dump_bytes("ieee802154_tty_receive ", DUMP_PREFIX_NONE,
-+ buf, count);
-+#endif
-+
-+ /* Actual processing */
-+ zbdev = tty->disc_data;
-+ if (NULL == zbdev) {
-+ printk(KERN_ERR "%s(): record for tty is not found\n",
-+ __func__);
-+ return;
-+ }
-+ for (i = 0; i < count; ++i)
-+ process_char(zbdev, buf[i]);
-+#if 0
-+ if (tty->driver->flush_chars)
-+ tty->driver->flush_chars(tty);
-+#endif
-+ tty_unthrottle(tty);
-+}
-+
-+/*
-+ * Line discipline device structure
-+ */
-+static struct tty_ldisc_ops ieee802154_ldisc = {
-+ .owner = THIS_MODULE,
-+ .magic = TTY_LDISC_MAGIC,
-+ .name = "ieee802154-ldisc",
-+ .open = ieee802154_tty_open,
-+ .close = ieee802154_tty_close,
-+ .hangup = ieee802154_tty_hangup,
-+ .receive_buf = ieee802154_tty_receive,
-+ .ioctl = ieee802154_tty_ioctl,
-+};
-+
-+/*****************************************************************************
-+ * Module service routinues
-+ *****************************************************************************/
-+
-+static int __init ieee802154_serial_init(void)
-+{
-+ printk(KERN_INFO "Initializing ZigBee TTY interface\n");
-+
-+ if (tty_register_ldisc(N_IEEE802154, &ieee802154_ldisc) != 0) {
-+ printk(KERN_ERR "%s: line discipline register failed\n",
-+ __func__);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static void __exit ieee802154_serial_cleanup(void)
-+{
-+ if (tty_unregister_ldisc(N_IEEE802154) != 0)
-+ printk(KERN_CRIT
-+ "failed to unregister ZigBee line discipline.\n");
-+}
-+
-+module_init(ieee802154_serial_init);
-+module_exit(ieee802154_serial_cleanup);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS_LDISC(N_IEEE802154);
-diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h
-index fd4f2d1..25ed3ec 100644
---- a/include/linux/nl802154.h
-+++ b/include/linux/nl802154.h
-@@ -21,6 +21,8 @@
- #ifndef NL802154_H
- #define NL802154_H
-
-+#include <net/netlink.h>
-+
- #define IEEE802154_NL_NAME "802.15.4 MAC"
- #define IEEE802154_MCAST_COORD_NAME "coordinator"
- #define IEEE802154_MCAST_BEACON_NAME "beacon"
-@@ -132,7 +134,6 @@ enum {
-
- IEEE802154_DEV_WPAN,
- IEEE802154_DEV_MONITOR,
--
- __IEEE802154_DEV_MAX,
- };
-
-diff --git a/include/uapi/linux/tty.h b/include/uapi/linux/tty.h
-index dac199a..96233b1 100644
---- a/include/uapi/linux/tty.h
-+++ b/include/uapi/linux/tty.h
-@@ -34,5 +34,6 @@
- #define N_TI_WL 22 /* for TI's WL BT, FM, GPS combo chips */
- #define N_TRACESINK 23 /* Trace data routing for MIPI P1149.7 */
- #define N_TRACEROUTER 24 /* Trace data routing for MIPI P1149.7 */
-+#define N_IEEE802154 25 /* Serial / USB serial IEEE802154.4 devices */
-
- #endif /* _UAPI_LINUX_TTY_H */
-diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
-index 604a902..5a1cf5a 100644
---- a/net/ieee802154/6lowpan.c
-+++ b/net/ieee802154/6lowpan.c
-@@ -59,6 +59,8 @@
- #include <net/ieee802154.h>
- #include <net/ieee802154_netdev.h>
- #include <net/ipv6.h>
-+#include <net/mac802154.h>
-+
-
- #include "6lowpan.h"
-
diff --git a/patches/linux-3.8.4/0385-ARM-OMAP-gpmc-add-DT-bindings-for-GPMC-timings-and-N.patch b/patches/linux-3.8.4/0385-ARM-OMAP-gpmc-add-DT-bindings-for-GPMC-timings-and-N.patch
deleted file mode 100644
index 66d97e7..0000000
--- a/patches/linux-3.8.4/0385-ARM-OMAP-gpmc-add-DT-bindings-for-GPMC-timings-and-N.patch
+++ /dev/null
@@ -1,408 +0,0 @@
-From: Daniel Mack <zonque@gmail.com>
-Date: Fri, 14 Dec 2012 10:36:44 +0000
-Subject: [PATCH] ARM: OMAP: gpmc: add DT bindings for GPMC timings and NAND
-
-This patch adds basic DT bindings for OMAP GPMC.
-
-The actual peripherals are instantiated from child nodes within the GPMC
-node, and the only type of device that is currently supported is NAND.
-
-Code was added to parse the generic GPMC timing parameters and some
-documentation with examples on how to use them.
-
-Successfully tested on an AM33xx board.
-
-Signed-off-by: Daniel Mack <zonque@gmail.com>
-Acked-by: Grant Likely <grant.likely@secretlab.ca>
----
- Documentation/devicetree/bindings/bus/ti-gpmc.txt | 84 ++++++++++
- .../devicetree/bindings/mtd/gpmc-nand.txt | 76 +++++++++
- arch/arm/mach-omap2/gpmc.c | 173 ++++++++++++++++++++
- 3 files changed, 333 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/bus/ti-gpmc.txt
- create mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nand.txt
-
-diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
-new file mode 100644
-index 0000000..5ddb2e9
---- /dev/null
-+++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
-@@ -0,0 +1,84 @@
-+Device tree bindings for OMAP general purpose memory controllers (GPMC)
-+
-+The actual devices are instantiated from the child nodes of a GPMC node.
-+
-+Required properties:
-+
-+ - compatible: Should be set to one of the following:
-+
-+ ti,omap2420-gpmc (omap2420)
-+ ti,omap2430-gpmc (omap2430)
-+ ti,omap3430-gpmc (omap3430 & omap3630)
-+ ti,omap4430-gpmc (omap4430 & omap4460 & omap543x)
-+ ti,am3352-gpmc (am335x devices)
-+
-+ - reg: A resource specifier for the register space
-+ (see the example below)
-+ - ti,hwmods: Should be set to "ti,gpmc" until the DT transition is
-+ completed.
-+ - #address-cells: Must be set to 2 to allow memory address translation
-+ - #size-cells: Must be set to 1 to allow CS address passing
-+ - gpmc,num-cs: The maximum number of chip-select lines that controller
-+ can support.
-+ - gpmc,num-waitpins: The maximum number of wait pins that controller can
-+ support.
-+ - ranges: Must be set up to reflect the memory layout with four
-+ integer values for each chip-select line in use:
-+
-+ <cs-number> 0 <physical address of mapping> <size>
-+
-+ Currently, calculated values derived from the contents
-+ of the per-CS register GPMC_CONFIG7 (as set up by the
-+ bootloader) are used for the physical address decoding.
-+ As this will change in the future, filling correct
-+ values here is a requirement.
-+
-+Timing properties for child nodes. All are optional and default to 0.
-+
-+ - gpmc,sync-clk: Minimum clock period for synchronous mode, in picoseconds
-+
-+ Chip-select signal timings corresponding to GPMC_CONFIG2:
-+ - gpmc,cs-on: Assertion time
-+ - gpmc,cs-rd-off: Read deassertion time
-+ - gpmc,cs-wr-off: Write deassertion time
-+
-+ ADV signal timings corresponding to GPMC_CONFIG3:
-+ - gpmc,adv-on: Assertion time
-+ - gpmc,adv-rd-off: Read deassertion time
-+ - gpmc,adv-wr-off: Write deassertion time
-+
-+ WE signals timings corresponding to GPMC_CONFIG4:
-+ - gpmc,we-on: Assertion time
-+ - gpmc,we-off: Deassertion time
-+
-+ OE signals timings corresponding to GPMC_CONFIG4:
-+ - gpmc,oe-on: Assertion time
-+ - gpmc,oe-off: Deassertion time
-+
-+ Access time and cycle time timings corresponding to GPMC_CONFIG5:
-+ - gpmc,page-burst-access: Multiple access word delay
-+ - gpmc,access: Start-cycle to first data valid delay
-+ - gpmc,rd-cycle: Total read cycle time
-+ - gpmc,wr-cycle: Total write cycle time
-+
-+The following are only applicable to OMAP3+ and AM335x:
-+ - gpmc,wr-access
-+ - gpmc,wr-data-mux-bus
-+
-+
-+Example for an AM33xx board:
-+
-+ gpmc: gpmc@50000000 {
-+ compatible = "ti,am3352-gpmc";
-+ ti,hwmods = "gpmc";
-+ reg = <0x50000000 0x2000>;
-+ interrupts = <100>;
-+
-+ gpmc,num-cs = <8>;
-+ gpmc,num-waitpins = <2>;
-+ #address-cells = <2>;
-+ #size-cells = <1>;
-+ ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */
-+
-+ /* child nodes go here */
-+ };
-diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
-new file mode 100644
-index 0000000..9f464f9
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
-@@ -0,0 +1,76 @@
-+Device tree bindings for GPMC connected NANDs
-+
-+GPMC connected NAND (found on OMAP boards) are represented as child nodes of
-+the GPMC controller with a name of "nand".
-+
-+All timing relevant properties as well as generic gpmc child properties are
-+explained in a separate documents - please refer to
-+Documentation/devicetree/bindings/bus/ti-gpmc.txt
-+
-+For NAND specific properties such as ECC modes or bus width, please refer to
-+Documentation/devicetree/bindings/mtd/nand.txt
-+
-+
-+Required properties:
-+
-+ - reg: The CS line the peripheral is connected to
-+
-+Optional properties:
-+
-+ - nand-bus-width: Set this numeric value to 16 if the hardware
-+ is wired that way. If not specified, a bus
-+ width of 8 is assumed.
-+
-+ - ti,nand-ecc-opt: A string setting the ECC layout to use. One of:
-+
-+ "sw" Software method (default)
-+ "hw" Hardware method
-+ "hw-romcode" gpmc hamming mode method & romcode layout
-+ "bch4" 4-bit BCH ecc code
-+ "bch8" 8-bit BCH ecc code
-+
-+For inline partiton table parsing (optional):
-+
-+ - #address-cells: should be set to 1
-+ - #size-cells: should be set to 1
-+
-+Example for an AM33xx board:
-+
-+ gpmc: gpmc@50000000 {
-+ compatible = "ti,am3352-gpmc";
-+ ti,hwmods = "gpmc";
-+ reg = <0x50000000 0x1000000>;
-+ interrupts = <100>;
-+ gpmc,num-cs = <8>;
-+ gpmc,num-waitpins = <2>;
-+ #address-cells = <2>;
-+ #size-cells = <1>;
-+ ranges = <0 0 0x08000000 0x2000>; /* CS0: NAND */
-+
-+ nand@0,0 {
-+ reg = <0 0 0>; /* CS0, offset 0 */
-+ nand-bus-width = <16>;
-+ ti,nand-ecc-opt = "bch8";
-+
-+ gpmc,sync-clk = <0>;
-+ gpmc,cs-on = <0>;
-+ gpmc,cs-rd-off = <44>;
-+ gpmc,cs-wr-off = <44>;
-+ gpmc,adv-on = <6>;
-+ gpmc,adv-rd-off = <34>;
-+ gpmc,adv-wr-off = <44>;
-+ gpmc,we-off = <40>;
-+ gpmc,oe-off = <54>;
-+ gpmc,access = <64>;
-+ gpmc,rd-cycle = <82>;
-+ gpmc,wr-cycle = <82>;
-+ gpmc,wr-access = <40>;
-+ gpmc,wr-data-mux-bus = <0>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ /* partitions go here */
-+ };
-+ };
-+
-diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
-index 1f0ec79..a37e1c9 100644
---- a/arch/arm/mach-omap2/gpmc.c
-+++ b/arch/arm/mach-omap2/gpmc.c
-@@ -25,6 +25,10 @@
- #include <linux/module.h>
- #include <linux/interrupt.h>
- #include <linux/platform_device.h>
-+#include <linux/of.h>
-+#include <linux/of_mtd.h>
-+#include <linux/of_device.h>
-+#include <linux/mtd/nand.h>
-
- #include <linux/platform_data/mtd-nand-omap2.h>
-
-@@ -34,6 +38,7 @@
- #include "common.h"
- #include "omap_device.h"
- #include "gpmc.h"
-+#include "gpmc-nand.h"
-
- #define DEVICE_NAME "omap-gpmc"
-
-@@ -1121,6 +1126,165 @@ int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
- return 0;
- }
-
-+#ifdef CONFIG_OF
-+static struct of_device_id gpmc_dt_ids[] = {
-+ { .compatible = "ti,omap2420-gpmc" },
-+ { .compatible = "ti,omap2430-gpmc" },
-+ { .compatible = "ti,omap3430-gpmc" }, /* omap3430 & omap3630 */
-+ { .compatible = "ti,omap4430-gpmc" }, /* omap4430 & omap4460 & omap543x */
-+ { .compatible = "ti,am3352-gpmc" }, /* am335x devices */
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, gpmc_dt_ids);
-+
-+static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
-+ struct gpmc_timings *gpmc_t)
-+{
-+ u32 val;
-+
-+ memset(gpmc_t, 0, sizeof(*gpmc_t));
-+
-+ /* minimum clock period for syncronous mode */
-+ if (!of_property_read_u32(np, "gpmc,sync-clk", &val))
-+ gpmc_t->sync_clk = val;
-+
-+ /* chip select timtings */
-+ if (!of_property_read_u32(np, "gpmc,cs-on", &val))
-+ gpmc_t->cs_on = val;
-+
-+ if (!of_property_read_u32(np, "gpmc,cs-rd-off", &val))
-+ gpmc_t->cs_rd_off = val;
-+
-+ if (!of_property_read_u32(np, "gpmc,cs-wr-off", &val))
-+ gpmc_t->cs_wr_off = val;
-+
-+ /* ADV signal timings */
-+ if (!of_property_read_u32(np, "gpmc,adv-on", &val))
-+ gpmc_t->adv_on = val;
-+
-+ if (!of_property_read_u32(np, "gpmc,adv-rd-off", &val))
-+ gpmc_t->adv_rd_off = val;
-+
-+ if (!of_property_read_u32(np, "gpmc,adv-wr-off", &val))
-+ gpmc_t->adv_wr_off = val;
-+
-+ /* WE signal timings */
-+ if (!of_property_read_u32(np, "gpmc,we-on", &val))
-+ gpmc_t->we_on = val;
-+
-+ if (!of_property_read_u32(np, "gpmc,we-off", &val))
-+ gpmc_t->we_off = val;
-+
-+ /* OE signal timings */
-+ if (!of_property_read_u32(np, "gpmc,oe-on", &val))
-+ gpmc_t->oe_on = val;
-+
-+ if (!of_property_read_u32(np, "gpmc,oe-off", &val))
-+ gpmc_t->oe_off = val;
-+
-+ /* access and cycle timings */
-+ if (!of_property_read_u32(np, "gpmc,page-burst-access", &val))
-+ gpmc_t->page_burst_access = val;
-+
-+ if (!of_property_read_u32(np, "gpmc,access", &val))
-+ gpmc_t->access = val;
-+
-+ if (!of_property_read_u32(np, "gpmc,rd-cycle", &val))
-+ gpmc_t->rd_cycle = val;
-+
-+ if (!of_property_read_u32(np, "gpmc,wr-cycle", &val))
-+ gpmc_t->wr_cycle = val;
-+
-+ /* only for OMAP3430 */
-+ if (!of_property_read_u32(np, "gpmc,wr-access", &val))
-+ gpmc_t->wr_access = val;
-+
-+ if (!of_property_read_u32(np, "gpmc,wr-data-mux-bus", &val))
-+ gpmc_t->wr_data_mux_bus = val;
-+}
-+
-+#ifdef CONFIG_MTD_NAND
-+
-+static const char *nand_ecc_opts[] = {
-+ [OMAP_ECC_HAMMING_CODE_DEFAULT] = "sw",
-+ [OMAP_ECC_HAMMING_CODE_HW] = "hw",
-+ [OMAP_ECC_HAMMING_CODE_HW_ROMCODE] = "hw-romcode",
-+ [OMAP_ECC_BCH4_CODE_HW] = "bch4",
-+ [OMAP_ECC_BCH8_CODE_HW] = "bch8",
-+};
-+
-+static int gpmc_probe_nand_child(struct platform_device *pdev,
-+ struct device_node *child)
-+{
-+ u32 val;
-+ const char *s;
-+ struct gpmc_timings gpmc_t;
-+ struct omap_nand_platform_data *gpmc_nand_data;
-+
-+ if (of_property_read_u32(child, "reg", &val) < 0) {
-+ dev_err(&pdev->dev, "%s has no 'reg' property\n",
-+ child->full_name);
-+ return -ENODEV;
-+ }
-+
-+ gpmc_nand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_nand_data),
-+ GFP_KERNEL);
-+ if (!gpmc_nand_data)
-+ return -ENOMEM;
-+
-+ gpmc_nand_data->cs = val;
-+ gpmc_nand_data->of_node = child;
-+
-+ if (!of_property_read_string(child, "ti,nand-ecc-opt", &s))
-+ for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++)
-+ if (!strcasecmp(s, nand_ecc_opts[val])) {
-+ gpmc_nand_data->ecc_opt = val;
-+ break;
-+ }
-+
-+ val = of_get_nand_bus_width(child);
-+ if (val == 16)
-+ gpmc_nand_data->devsize = NAND_BUSWIDTH_16;
-+
-+ gpmc_read_timings_dt(child, &gpmc_t);
-+ gpmc_nand_init(gpmc_nand_data, &gpmc_t);
-+
-+ return 0;
-+}
-+#else
-+static int gpmc_probe_nand_child(struct platform_device *pdev,
-+ struct device_node *child)
-+{
-+ return 0;
-+}
-+#endif
-+
-+static int gpmc_probe_dt(struct platform_device *pdev)
-+{
-+ int ret;
-+ struct device_node *child;
-+ const struct of_device_id *of_id =
-+ of_match_device(gpmc_dt_ids, &pdev->dev);
-+
-+ if (!of_id)
-+ return 0;
-+
-+ for_each_node_by_name(child, "nand") {
-+ ret = gpmc_probe_nand_child(pdev, child);
-+ of_node_put(child);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+#else
-+static int gpmc_probe_dt(struct platform_device *pdev)
-+{
-+ return 0;
-+}
-+#endif
-+
- static int gpmc_probe(struct platform_device *pdev)
- {
- int rc;
-@@ -1174,6 +1338,14 @@ static int gpmc_probe(struct platform_device *pdev)
- if (IS_ERR_VALUE(gpmc_setup_irq()))
- dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
-
-+ rc = gpmc_probe_dt(pdev);
-+ if (rc < 0) {
-+ clk_disable_unprepare(gpmc_l3_clk);
-+ clk_put(gpmc_l3_clk);
-+ dev_err(gpmc_dev, "failed to probe DT parameters\n");
-+ return rc;
-+ }
-+
- return 0;
- }
-
-@@ -1191,6 +1363,7 @@ static struct platform_driver gpmc_driver = {
- .driver = {
- .name = DEVICE_NAME,
- .owner = THIS_MODULE,
-+ .of_match_table = of_match_ptr(gpmc_dt_ids),
- },
- };
-
diff --git a/patches/linux-3.8.4/0401-Release-distrokit-beaglebone-20130329.patch b/patches/linux-3.8.4/0401-Release-distrokit-beaglebone-20130329.patch
deleted file mode 100644
index 1eac056..0000000
--- a/patches/linux-3.8.4/0401-Release-distrokit-beaglebone-20130329.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Jan Luebbe <jluebbe@debian.org>
-Date: Fri, 29 Mar 2013 13:40:36 +0100
-Subject: [PATCH] Release distrokit/beaglebone/20130329
-
-Signed-off-by: Jan Luebbe <jluebbe@debian.org>
----
- Makefile | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/Makefile b/Makefile
-index e20f162..ac5933b 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1,7 +1,7 @@
- VERSION = 3
- PATCHLEVEL = 8
- SUBLEVEL = 4
--EXTRAVERSION =
-+EXTRAVERSION =-20130329
- NAME = Unicycling Gorilla
-
- # *DOCUMENTATION*
diff --git a/patches/linux-3.8.4/series b/patches/linux-3.8.4/series
deleted file mode 100644
index a00bc4f..0000000
--- a/patches/linux-3.8.4/series
+++ /dev/null
@@ -1,395 +0,0 @@
-# umpf-base: v3.8.4
-# umpf-name: distrokit/beaglebone
-# umpf-version: distrokit/beaglebone/20130329
-# umpf-topic: topic/distrokit/beaglebone/board
-# umpf-hashinfo: ba2a5857fbffb2aad09012e9fd22a235fc7c7671
-# umpf-topic-range: 405acc3402a3df8df967d1848947dc58f0059664..ba2a5857fbffb2aad09012e9fd22a235fc7c7671
-0001-Without-MACH_-option-Early-printk-DEBUG_LL.patch
-0002-ARM-OMAP-Hack-AM33xx-clock-data-to-allow-JTAG-use.patch
-0003-video-st7735fb-add-st7735-framebuffer-driver.patch
-0004-dmaengine-add-helper-function-to-request-a-slave-DMA.patch
-0005-of-Add-generic-device-tree-DMA-helpers.patch
-0006-of-dma-fix-build-break-for-CONFIG_OF.patch
-0007-of-dma-fix-typos-in-generic-dma-binding-definition.patch
-0008-dmaengine-fix-build-failure-due-to-missing-semi-colo.patch
-0009-dmaengine-edma-fix-slave-config-dependency-on-direct.patch
-0010-dmaengine-add-dma_get_channel_caps.patch
-0011-dma-edma-add-device_channel_caps-support.patch
-0012-mmc-davinci-get-SG-segment-limits-with-dma_get_chann.patch
-0013-ARM-davinci-move-private-EDMA-API-to-arm-common.patch
-0014-ARM-edma-remove-unused-transfer-controller-handlers.patch
-0015-ARM-edma-add-AM33XX-support-to-the-private-EDMA-API.patch
-0016-dmaengine-edma-enable-build-for-AM33XX.patch
-0017-dmaengine-edma-Add-TI-EDMA-device-tree-binding.patch
-0018-ARM-dts-add-AM33XX-EDMA-support.patch
-0019-dmaengine-add-dma_request_slave_channel_compat.patch
-0020-mmc-omap_hsmmc-convert-to-dma_request_slave_channel_.patch
-0021-mmc-omap_hsmmc-set-max_segs-based-on-dma-engine-limi.patch
-0022-mmc-omap_hsmmc-add-generic-DMA-request-support-to-th.patch
-0023-ARM-dts-add-AM33XX-MMC-support.patch
-0024-spi-omap2-mcspi-convert-to-dma_request_slave_channel.patch
-0025-spi-omap2-mcspi-add-generic-DMA-request-support-to-t.patch
-0026-ARM-dts-add-AM33XX-SPI-DMA-support.patch
-0027-ARM-dts-Add-SPI-Flash-support-to-am335x-evm.patch
-0028-Documentation-bindings-add-spansion.patch
-0029-ARM-dts-enable-spi1-node-and-pinmux-on-BeagleBone.patch
-0030-ARM-dts-add-BeagleBone-Adafruit-1.8-LCD-support.patch
-0031-misc-add-gpevt-driver.patch
-0032-ARM-dts-add-BeagleBone-gpevt-support.patch
-0033-ARM-configs-working-dmaengine-configs-for-da8xx-and-.patch
-0034-ARM-dts-Add-UART4-support-to-BeagleBone.patch
-0035-ARM-OMAP2-am33xx-hwmod-Fix-register-offset-NULL-chec.patch
-0036-rtc-OMAP-Add-system-pm_power_off-to-rtc-driver.patch
-0037-ARM-dts-AM33XX-Set-pmic-shutdown-controller-for-Beag.patch
-0038-ARM-dts-AM33XX-Enable-system-power-off-control-in-am.patch
-0039-i2c-pinctrl-ify-i2c-omap.c.patch
-0040-arm-dts-AM33XX-Configure-pinmuxs-for-user-leds-contr.patch
-0041-beaglebone-DT-set-default-triggers-for-LEDS.patch
-0042-beaglebone-add-a-cpu-led-trigger.patch
-0043-am33xx-DT-add-commented-out-OPP-values-for-ES2.0.patch
-0044-input-ti_am335x_tsc-Step-enable-bits-made-configurab.patch
-0045-input-ti_am335x_tsc-Order-of-TSC-wires-made-configur.patch
-0046-input-touchscreen-ti_tsc-remove-unwanted-fifo-flush.patch
-0047-MFD-ti_am335x_tscadc-add-device-tree-binding-informa.patch
-0048-MFD-ti_am335x_tscadc-Add-DT-support.patch
-0049-input-ti_am335x_tsc-Add-DT-support.patch
-0050-IIO-ti_am335x_adc-Add-DT-support.patch
-0051-arm-dts-AM335x-evm-Add-TSC-ADC-MFD-device-support.patch
-0052-ti_tscadc-Update-with-IIO-map-interface-deal-with-pa.patch
-0053-ti_tscadc-Match-mfd-sub-devices-to-regmap-interface.patch
-0054-input-ti_am335x_tsc-Add-variance-filters.patch
-0055-am335x-adc-Do-not-use-find_node_by_name-use-get_chil.patch
-0056-am335x-tsc-Do-not-use-find_node_by_name-use-get_chil.patch
-0057-am335x-tscadc-Do-not-use-find_node_by_name-use-get_c.patch
-0058-pinctrl-pinctrl-single-must-be-initialized-early.patch
-0059-Bone-DTS-working-i2c2-i2c3-in-the-tree.patch
-0060-am33xx-Convert-I2C-from-omap-to-am33xx-names.patch
-0061-am335x-evm-hack-around-i2c-node-names.patch
-0062-viafb-rename-display_timing-to-via_display_timing.patch
-0063-video-add-display_timing-and-videomode.patch
-0064-video-add-of-helper-for-display-timings-videomode.patch
-0065-fbmon-add-videomode-helpers.patch
-0066-fbmon-add-of_videomode-helpers.patch
-0067-drm_modes-add-videomode-helpers.patch
-0068-drm_modes-add-of_videomode-helpers.patch
-0069-fbmon-fix-build-error.patch
-0070-of-display-timings-use-of_get_child_by_name.patch
-0071-da8xx-Allow-use-by-am33xx-based-devices.patch
-0072-video-da8xx-fb-fb_check_var-enhancement.patch
-0073-video-da8xx-fb-simplify-lcd_reset.patch
-0074-video-da8xx-fb-use-modedb-helper-to-update-var.patch
-0075-video-da8xx-fb-remove-unneeded-var-initialization.patch
-0076-video-da8xx-fb-store-current-display-information.patch
-0077-video-da8xx-fb-store-clk-rate-even-if-CPUFREQ.patch
-0078-video-da8xx-fb-pix-clk-and-clk-div-handling-cleanup.patch
-0079-video-da8xx-fb-store-struct-device.patch
-0080-video-da8xx-fb-report-correct-pixclock.patch
-0081-video-da8xx-fb-fb_set_par-support.patch
-0082-ARM-dts-AM33XX-Add-lcdc-node.patch
-0083-ARM-dts-AM33XX-Add-am335x-evm-lcdc-panel-timings.patch
-0084-ARM-dts-AM33XX-Add-am335x-evm-lcdc-pincontrol-info.patch
-0085-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-panel-timings.patch
-0086-ARM-dts-AM33XX-Add-am335x-evmsk-lcdc-pincontrol-info.patch
-0087-ARM-OMAP-AM33xx-hwmod-Corrects-PWM-subsystem-HWMOD-e.patch
-0088-ARM-OMAP-AM33xx-hwmod-Add-parent-child-relationship-.patch
-0089-ARM-dts-AM33XX-Add-PWMSS-device-tree-nodes.patch
-0090-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch
-0091-ARM-dts-AM33XX-Add-PWM-backlight-DT-data-to-am335x-e.patch
-0092-clk-divider-prepare-for-minimum-divider.patch
-0093-clk-divider-handle-minimum-divider.patch
-0094-ARM-OMAP2-dpll-round-rate-to-closest-value.patch
-0095-ARM-OMAP2-dpll-am335x-avoid-freqsel.patch
-0096-ARM-OMAP2-clock-DEFINE_STRUCT_CLK_FLAGS-helper.patch
-0097-ARM-AM33XX-clock-SET_RATE_PARENT-in-lcd-path.patch
-0098-video-da8xx-fb-make-io-operations-safe.patch
-0099-video-da8xx-fb-fix-24bpp-raster-configuration.patch
-0100-video-da8xx-fb-enable-sync-lost-intr-for-v2-ip.patch
-0101-video-da8xx-fb-use-devres.patch
-0102-video-da8xx-fb-ensure-non-null-cfg-in-pdata.patch
-0103-video-da8xx-fb-reorganize-panel-detection.patch
-0104-video-da8xx-fb-minimal-dt-support.patch
-0105-video-da8xx-fb-invoke-platform-callback-safely.patch
-0106-video-da8xx-fb-obtain-fb_videomode-info-from-dt.patch
-0107-video-da8xx-fb-ensure-pdata-only-for-non-dt.patch
-0108-video-da8xx-fb-setup-struct-lcd_ctrl_config-for-dt.patch
-0109-video-da8xx-fb-CCF-clock-divider-handling.patch
-0110-pwm_backlight-Add-device-tree-support-for-Low-Thresh.patch
-0111-Control-module-EHRPWM-clk-enabling.patch
-0112-pwm-pwm_test-Driver-support-for-PWM-module-testing.patch
-0113-ARM-OMAP2-PWM-limit-am33xx_register_ehrpwm-to-soc_is.patch
-0114-pwm-export-of_pwm_request.patch
-0115-pwm-pwm-tiehrpwm-Update-the-clock-handling-of-pwm-ti.patch
-0116-ARM-AM33XX-clk-Add-clock-node-for-EHRPWM-TBCLK.patch
-0117-HACK-am33xx.dtsi-turn-on-all-PWMs.patch
-0118-am33xx.dtsi-enable-MMC-HSPE-bit-for-all-3-controller.patch
-0119-omap-hsmmc-Correct-usage-of-of_find_node_by_name.patch
-0120-ARM-OMAP2xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch
-0121-ARM-OMAP2xxx-hwmod-Add-DMA-support-for-SHAM-module.patch
-0122-ARM-OMAP3xxx-hwmod-Convert-SHAM-crypto-device-data-t.patch
-0123-ARM-OMAP2-Remove-unnecessary-message-when-no-SHA-IP-.patch
-0124-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch
-0125-ARM-AM33XX-Add-sha0-crypto-clock-data.patch
-0126-ARM-AM33XX-hwmod-Update-and-uncomment-SHA0-module-da.patch
-0127-ARM-dts-Add-SHAM-data-and-documentation-for-AM33XX.patch
-0128-ARM-OMAP2xxx-hwmod-Convert-AES-crypto-devcie-data-to.patch
-0129-ARM-OMAP3xxx-hwmod-Convert-AES-crypto-device-data-to.patch
-0130-ARM-OMAP2-Remove-unnecessary-message-when-no-AES-IP-.patch
-0131-ARM-OMAP2-Only-manually-add-hwmod-data-when-DT-not-u.patch
-0132-ARM-AM33XX-Add-aes0-crypto-clock-data.patch
-0133-ARM-AM33XX-hwmod-Update-and-uncomment-AES0-module-da.patch
-0134-ARM-dts-Add-AES-data-and-documentation-for-AM33XX.patch
-0135-crypto-omap-sham-Remove-unnecessary-pr_info-noise.patch
-0136-crypto-omap-sham-Convert-to-use-pm_runtime-API.patch
-0137-crypto-omap-sham-Add-suspend-resume-support.patch
-0138-crypto-omap-sham-Add-code-to-use-dmaengine-API.patch
-0139-crypto-omap-sham-Remove-usage-of-private-DMA-API.patch
-0140-crypto-omap-sham-Add-Device-Tree-Support.patch
-0141-crypto-omap-sham-Convert-to-dma_request_slave_channe.patch
-0142-crypto-omap-sham-Add-OMAP4-AM33XX-SHAM-Support.patch
-0143-crypto-omap-sham-Add-SHA224-and-SHA256-Support.patch
-0144-crypto-omap-aes-Remmove-unnecessary-pr_info-noise.patch
-0145-crypto-omap-aes-Don-t-reset-controller-for-every-ope.patch
-0146-crypto-omap-aes-Convert-to-use-pm_runtime-API.patch
-0147-crypto-omap-aes-Add-suspend-resume-support.patch
-0148-crypto-omap-aes-Add-code-to-use-dmaengine-API.patch
-0149-crypto-omap-aes-Remove-usage-of-private-DMA-API.patch
-0150-crypto-omap-aes-Add-Device-Tree-Support.patch
-0151-crypto-omap-aes-Convert-to-dma_request_slave_channel.patch
-0152-crypto-omap-aes-Add-OMAP4-AM33XX-AES-Support.patch
-0153-crypto-omap-aes-Add-CTR-algorithm-Support.patch
-0154-6lowpan-lowpan_is_iid_16_bit_compressable-does-not-d.patch
-0155-6lowpan-next-header-is-not-properly-set-upon-decompr.patch
-0156-6lowpan-always-enable-link-layer-acknowledgments.patch
-0157-mac802154-turn-on-ACK-when-enabled-by-the-upper-laye.patch
-0158-6lowpan-use-short-IEEE-802.15.4-addresses-for-broadc.patch
-0159-6lowpan-fix-first-fragment-FRAG1-handling.patch
-0160-6lowpan-store-fragment-tag-values-per-device-instead.patch
-0161-6lowpan-obtain-IEEE802.15.4-sequence-number-from-the.patch
-0162-6lowpan-add-a-new-parameter-in-sysfs-to-turn-on-off-.patch
-0163-6lowpan-use-the-PANID-provided-by-the-device-instead.patch
-0164-6lowpan-modify-udp-compression-uncompression-to-matc.patch
-0165-6lowpan-make-memory-allocation-atomic-during-6lowpan.patch
-0166-mac802154-make-mem-alloc-ATOMIC-to-prevent-schedulin.patch
-0167-mac802154-remove-unnecessary-spinlocks.patch
-0168-mac802154-re-introduce-MAC-primitives-required-to-se.patch
-0169-serial-initial-import-of-the-IEEE-802.15.4-serial-dr.patch
-0170-gpio-keys-Pinctrl-fy.patch
-0171-tps65217-Allow-placement-elsewhere-than-parent-mfd-d.patch
-0172-pwm-backlight-Pinctrl-fy.patch
-0173-ARM-CUSTOM-Build-a-uImage-with-dtb-already-appended.patch
-0174-beaglebone-create-a-shared-dtsi-for-beaglebone-based.patch
-0175-beaglebone-enable-emmc-for-bonelt.patch
-0176-Fix-appended-dtb-rule.patch
-0177-deb-pkg-Simplify-architecture-matching-for-cross-bui.patch
-0178-Without-MACH_-option-Early-printk-DEBUG_LL.patch
-0179-regulator-core-if-voltage-scaling-fails-restore-orig.patch
-0180-omap2-twl-common-Add-default-power-configuration.patch
-0181-OMAP-DSS2-add-bootarg-for-selecting-svideo.patch
-0182-video-add-timings-for-hd720.patch
-0183-Beagle-expansion-add-buddy-param-for-expansionboard-.patch
-0184-Beagle-expansion-add-zippy.patch
-0185-Beagle-expansion-add-zippy2.patch
-0186-Beagle-expansion-add-trainer.patch
-0187-Beagle-expansion-add-CircuitCo-ulcd-Support.patch
-0188-Beagle-expansion-add-wifi.patch
-0189-Beagle-expansion-add-beaglefpga.patch
-0190-Beagle-expansion-add-spidev.patch
-0191-Beagle-expansion-add-Aptina-li5m03-camera.patch
-0192-Beagle-expansion-add-LSR-COM6L-Adapter-Board.patch
-0193-meego-modedb-add-Toshiba-LTA070B220F-800x480-support.patch
-0194-backlight-Add-TLC59108-backlight-control-driver.patch
-0195-tlc59108-adjust-for-beagleboard-uLCD7.patch
-0196-zeroMAP-Open-your-eyes.patch
-0197-ARM-OMAP-Beagle-use-TWL4030-generic-reset-script.patch
-0198-am33xx-cpsw-default-to-ethernet-hwaddr-from-efuse-if.patch
-0199-Attempted-SMC911x-BQL-patch.patch
-0200-cpsw-Fix-interrupt-storm-among-other-things.patch
-0201-am33xx-Add-clock-for-the-lcdc-DRM-driver.patch
-0202-drm-small-fix-in-drm_send_vblank_event.patch
-0203-drm-cma-add-debugfs-helpers.patch
-0204-drm-i2c-encoder-helper-wrappers.patch
-0205-drm-nouveau-use-i2c-encoder-helper-wrappers.patch
-0206-drm-i2c-give-i2c-it-s-own-Kconfig.patch
-0207-drm-tilcdc-add-TI-LCD-Controller-DRM-driver-v4.patch
-0208-drm-i2c-nxp-tda998x-v3.patch
-0209-drm-tilcdc-add-encoder-slave.patch
-0210-drm-tilcdc-add-support-for-LCD-panels-v5.patch
-0211-drm-lcdc-Power-control-GPIO-support.patch
-0212-add-dvi-pinmuxes-to-am33xx.dtsi.patch
-0213-add-defconfig-file-to-use-as-.config.patch
-0214-am33xx-musb-Add-OF-definitions.patch
-0215-Mark-the-device-as-PRIVATE.patch
-0216-omap_hsmmc-Bug-fixes-pinctl-gpio-reset.patch
-0217-tps65217-bl-Locate-backlight-node-correctly.patch
-0218-arm-Export-cache-flush-management-symbols-when-MULTI.patch
-0219-am335x-bone-dtsi-Clean-up.patch
-0220-am335x-bone-dtsi-Introduce-new-I2C-entries.patch
-0221-am335x-dt-Add-I2C0-pinctrl-entries.patch
-0222-Cleanup-am33xx.dtsi.patch
-0223-Fix-platform-device-resource-linking.patch
-0224-Link-platform-device-resources-properly.patch
-0225-Properly-handle-resources-for-omap_devices.patch
-0226-omap-Avoid-crashes-in-the-case-of-hwmod-misconfigura.patch
-0227-i2c-EEPROM-In-kernel-memory-accessor-interface.patch
-0228-Fix-util_is_printable_string.patch
-0229-fdtdump-properly-handle-multi-string-properties.patch
-0230-dtc-Dynamic-symbols-fixup-support.patch
-0231-dtc-Add-DTCO-rule-for-DTB-objects.patch
-0232-OF-Compile-Device-Tree-sources-with-resolve-option.patch
-0233-firmware-update-.gitignore-with-dtbo-objects.patch
-0234-OF-Introduce-device-tree-node-flag-helpers.patch
-0235-OF-export-of_property_notify.patch
-0236-OF-Export-all-DT-proc-update-functions.patch
-0237-OF-Introduce-utility-helper-functions.patch
-0238-OF-Introduce-Device-Tree-resolve-support.patch
-0239-OF-Introduce-DT-overlay-support.patch
-0240-capemgr-Capemgr-makefiles-and-Kconfig-fragments.patch
-0241-capemgr-Beaglebone-capemanager.patch
-0242-capemgr-Add-beaglebone-s-cape-driver-bindings.patch
-0243-capemgr-am33xx-family-DT-bindings.patch
-0244-bone-geiger-Geiger-bone-driver.patch
-0245-capemgr-firmware-makefiles-for-DT-objects.patch
-0246-capemgr-emmc2-cape-definition.patch
-0247-capemgr-DVI-capes-definitions.patch
-0248-capemgr-Geiger-cape-definition.patch
-0249-capemgr-LCD3-cape-definition.patch
-0250-capemgr-Add-weather-cape-definition.patch
-0251-ehrpwm-add-missing-dts-nodes.patch
-0252-am33xx-DT-Update-am33xx.dsi-with-the-new-PWM-DT-bind.patch
-0253-geiger-cape-Update-to-using-the-new-PWM-interface.patch
-0254-lcd3-cape-Change-into-using-the-lcdc-DRM-driver-inst.patch
-0255-am33xx-Add-default-config.patch
-0256-lcd3-cape-Convert-to-using-the-proper-touchscreen-dr.patch
-0257-geiger-cape-Convert-to-using-the-new-ADC-driver.patch
-0258-cape-dvi-Convert-DVI-capes-to-the-new-LCDC-DRM-drive.patch
-0259-boneblack-Add-default-HDMI-cape.patch
-0260-cape-bone-dvi-Use-720p-mode-as-default.patch
-0261-am33xx.dtsi-Make-the-MUSB-not-crash-on-load.patch
-0262-regulator-DUMMY_REGULATOR-should-work-for-OF-too.patch
-0263-OF-Overlay-Remove-excessive-debugging-crud.patch
-0264-of-i2c-Export-single-device-registration-method.patch
-0265-OF-Overlay-I2C-client-devices-special-handling.patch
-0266-omap-Fix-bug-on-partial-resource-addition.patch
-0267-ASoC-davinci-mcasp-Add-pinctrl-support.patch
-0268-ASoC-Davinci-machine-Add-device-tree-binding.patch
-0269-am33xx-Add-mcasp0-and-mcasp1-device-tree-entries.patch
-0270-ASoC-dts-OMAP2-AM33xx-HACK-Add-missing-dma-info.patch
-0271-ASoC-Davinci-McASP-remove-unused-header-include.patch
-0272-ASoC-AM33XX-Add-support-for-AM33xx-SoC-Audio.patch
-0273-am33xx-mcasp-Add-dma-channel-definitions.patch
-0274-ARM-OMAP2-AM33xx-removed-invalid-McASP-HWMOD-data.patch
-0275-davinci-evm-Header-include-move-fix.patch
-0276-bone-dvi-cape-Add-DT-definition-for-00A2-revision.patch
-0277-bone-dvi-cape-Update-A1-cape-definition-with-sound.patch
-0278-sndsoc-mcasp-Get-DMA-channels-via-byname.patch
-0279-sound-soc-Davinci-Remove-__devinit-__devexit.patch
-0280-st7735fb-Remove-__devinit-__devexit.patch
-0281-capemgr-Remove-__devinit-__devexit.patch
-0282-capes-fw-target-firmware-directory-change.patch
-0283-am33xx-edma-Always-update-unused-channel-list.patch
-0284-defconfig-Update-bone-default-config.patch
-0285-capes-add-dvi-a2-and-lcd3-a2-dts-files.patch
-0286-capemgr-catch-up-with-lcdc-tilcdc-rename.patch
-0287-firmware-fix-dvi-a1-target.patch
-0288-capes-remove-tda-from-hdmi-cape-lcdc-handles-it-by-t.patch
-0289-tilcdc-magic-debug-statement-makes-power-gpio-work-o.patch
-0290-capemgr-add-dts-overlay-for-LCD7-00A2-cape.patch
-0291-HACK-am33xx.dtsi-enable-all-PWMs.patch
-0292-beaglebone-Add-nixie-cape-prototype-driver.patch
-0293-beaglebone-Add-nixie-cape-device-tree-entry.patch
-0294-am335x-bone-common.dtsi-Cleanup-test-remnants.patch
-0295-omap_hsmmc-Add-ti-vcc-aux-disable-is-sleep-DT-proper.patch
-0296-bone-common-ti-vcc-aux-disable-is-sleep-enable.patch
-0297-am33xx-disable-NAPI.patch
-0298-capemgr-Fixed-AIN-name-display-in-error-message.patch
-0299-am33xx.dtsi-remove-duplicate-nodes.patch
-0300-cape-dtbos-update-to-latest-OF-videomode-bindings.patch
-0301-beaglebone-uncomment-eMMC-override.patch
-0302-bone-capes-Update-with-new-tscadc-bindings.patch
-0303-am33xx.dtsi-Update-and-disable-status-of-nodes.patch
-0304-bone-capes-Adapt-to-new-pwms-setup.patch
-0305-tilcdc-introduce-panel-tfp410-power-down-gpio-contro.patch
-0306-bone-dvi-Update-to-new-style-tilcdc-bindings.patch
-0307-tilcdc-tfp410-Rework-power-down-GPIO-logic.patch
-0308-tilcdc-Add-reduced-blanking-mode-checks.patch
-0309-cape-dvi-Switch-all-DVI-capes-to-using-the-TFTP410-p.patch
-0310-beaglebone-switch-eMMC-to-8bit-mode.patch
-0311-Pinmux-helper-driver.patch
-0312-OF-Clear-detach-flag-on-attach.patch
-0313-OF-overlay-Fix-overlay-revert-failure.patch
-0314-bone-capemgr-Make-sure-cape-removal-works.patch
-0315-bone-capemgr-Fix-crash-when-trying-to-remove-non-exi.patch
-0316-beaglebone-LCD7-cape-enable-PWM-and-allow-the-specif.patch
-0317-bone-capemgr-Introduce-pinmux-helper.patch
-0318-bone-geiger-Fix-comment-to-match-the-contents.patch
-0319-of-overlay-Handle-I2C-devices-already-registered-by-.patch
-0320-pinmux-helper-Add-runtime-configuration-capability.patch
-0321-pinmux-helper-Switch-to-using-kmalloc.patch
-0322-i2c-DTify-pca954x-driver.patch
-0323-tty-Add-JHD629-I2C-LCD-Keypad-TTY-driver.patch
-0324-grove-i2c-Add-rudimentary-grove-i2c-motor-control-dr.patch
-0325-tty-jhd629-i2c-Clean-keypad-buffer-when-starting.patch
-0326-am335x-bone-common-Remove-SPI-unused-pinmux-config.patch
-0327-bone-capemgr-Force-a-slot-to-load-unconditionally.patch
-0328-beaglebone-Added-Adafruit-prototype-cape.patch
-0329-tilcdc-Enable-reduced-blanking-check-only-on-DVI-sla.patch
-0330-cape-adafruit-Use-the-correct-spi-bus-spi1-no-spi0.patch
-0331-BBB-tester-Introduce-board-DTS.patch
-0332-BBB-tester-Introduce-cape-describing-the-contents-of.patch
-0333-bone-tester-Add-overrides-for-BB-BONE-TESTER.patch
-0334-cape-tester-Add-uart-specific-default-pinmux-state.patch
-0335-cape-tester-Add-pinmux-helper-for-drvvbus-gpio.patch
-0336-cape-Added-support-for-IIO-helper-cape.patch
-0337-cape-Added-example-IIO-tester-dynamics-overlay.patch
-0338-docs-Added-capemanager-extra_override-usage.patch
-0339-capemgr-Added-module-param-descriptions.patch
-0340-beaglebone-Add-Adafruit-RTC-prototype-cape.patch
-0341-cape-vsense-scale-division-by-zero-check.patch
-0342-capes-add-cape-for-beaglebone-based-Hexy-robot.patch
-0343-Extend-bone-iio-helper.patch
-0344-Update-iio-helper-with-more-channels.patch
-0345-Add-ADC-IIO-helper.patch
-0346-Changing-DT-data-to-make-selection-of-standard-i.e.-.patch
-0347-Enhancing-to-support-extra-device-tree-options-for-t.patch
-0348-add-WIP-support-LCD4-rev-00A4.patch
-0349-add-eMMC-cape-support.patch
-0350-Remove-UART-pins-from-the-expansion-set.patch
-0351-Remove-LCD-pins-from-the-expansion-test-part.patch
-0352-Remove-I2C2-pins-from-expansion-test.patch
-0353-Add-expansion-test-cape-fragment.patch
-0354-tilcdc-added-some-extra-debug-and-softened-the-wordi.patch
-0355-Make-sure-various-timings-fit-within-the-bits-availa.patch
-0356-uio-uio_pruss-port-to-AM33xx.patch
-0357-ARM-omap-add-DT-support-for-deasserting-hardware-res.patch
-0358-ARM-dts-AM33xx-PRUSS-support.patch
-0359-drivers-usb-phy-add-a-new-driver-for-usb-part-of-con.patch
-0360-drivers-usb-start-using-the-control-module-driver.patch
-0361-usb-otg-Add-an-API-to-bind-the-USB-controller-and-PH.patch
-0362-usb-otg-utils-add-facilities-in-phy-lib-to-support-m.patch
-0363-ARM-OMAP-USB-Add-phy-binding-information.patch
-0364-drivers-usb-musb-omap-make-use-of-the-new-PHY-lib-AP.patch
-0365-usb-otg-add-device-tree-support-to-otg-library.patch
-0366-USB-MUSB-OMAP-get-PHY-by-phandle-for-dt-boot.patch
-0367-MUSB-Hack-around-to-make-host-port-to-work.patch
-0368-make-sure-we-register-unregister-the-NOP-xceiver-onl.patch
-0369-beaglebone-black-1ghz-hack.patch
-0370-ARM-AM33xx-Add-SoC-specific-restart-hook.patch
-0371-iio-common-Add-STMicroelectronics-common-library.patch
-0372-iio-accel-Add-STMicroelectronics-accelerometers-driv.patch
-0373-iio-gyro-Add-STMicroelectronics-gyroscopes-driver.patch
-0374-iio-magnetometer-Add-STMicroelectronics-magnetometer.patch
-0375-iio-magn-Add-sensors_supported-in-st_magn_sensors.patch
-0376-pwm-pca9685-skeleton-i2c-client-driver-for-PCA9685-1.patch
-0377-W1-w1-gpio-switch-to-using-dev_pm_ops.patch
-0378-W1-w1-gpio-guard-DT-IDs-with-CONFIG_OF.patch
-0379-W1-w1-gpio-rework-handling-of-platform-data.patch
-0380-W1-w1-gpio-switch-to-using-managed-resources-devm.patch
-0381-ARM-OMAP-gpmc-don-t-create-devices-from-initcall-on-.patch
-0382-mtd-omap-nand-pass-device_node-in-platform-data.patch
-0383-ARM-OMAP-gpmc-nand-drop-__init-annotation.patch
-0384-ARM-OMAP-gpmc-enable-hwecc-for-AM33xx-SoCs.patch
-0385-ARM-OMAP-gpmc-add-DT-bindings-for-GPMC-timings-and-N.patch
-# umpf-release: distrokit/beaglebone/20130329
-# umpf-topic-range: ba2a5857fbffb2aad09012e9fd22a235fc7c7671..5732e204486c993fb86ec1d85bb17f8f03c9a6c4
-0401-Release-distrokit-beaglebone-20130329.patch
-# umpf-end
diff --git a/platformconfig b/platformconfig
index 010f69e..a5dcac9 100644
--- a/platformconfig
+++ b/platformconfig
@@ -97,8 +97,8 @@ PTXCONF_KERNEL_INSTALL=y
PTXCONF_KERNEL_MODULES=y
PTXCONF_KERNEL_MODULES_INSTALL=y
PTXCONF_KERNEL_MODULES_BUILD="modules"
-PTXCONF_KERNEL_VERSION="3.8.4"
-PTXCONF_KERNEL_MD5="ad19f1be181408124a7f9d8cf57b97b4"
+PTXCONF_KERNEL_VERSION="3.8.13"
+PTXCONF_KERNEL_MD5="2af19d06cd47ec459519159cdd10542d"
PTXCONF_KERNEL_ARCH_STRING="arm"
# PTXCONF_KERNEL_IMAGE_BZ is not set
# PTXCONF_KERNEL_IMAGE_Z is not set