aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-12-03 15:02:06 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-12-03 15:02:06 -0800
commit12e057530821c9839d0d0272cdda555fb36869d1 (patch)
tree77409404febc6c3fd10027cd34d4ff869853b54f
parent4b1f40738f349875cd568ca6aa9a099659d8b718 (diff)
downloadltsi-kernel-12e057530821c9839d0d0272cdda555fb36869d1.tar.gz
3.4: Armadillo 800 and Marzen patches added
-rw-r--r--patches.armadillo800/0001-ARM-shmobile-add-common-DMAEngine-definitions.patch115
-rw-r--r--patches.armadillo800/0002-ARM-shmobile-soc-core-add-R-mobile-PM-domain-common-.patch260
-rw-r--r--patches.armadillo800/0003-media-V4L2-sh_mobile_ceu-manage-lower-8bit-bus.patch55
-rw-r--r--patches.armadillo800/0004-regulator-support-multiple-dummy-fixed-regulators.patch96
-rw-r--r--patches.armadillo800/0005-regulator-extend-the-fixed-dummy-voltage-regulator-t.patch70
-rw-r--r--patches.armadillo800/0006-Input-gpio_keys-remove-useless-reinitialization-of-p.patch32
-rw-r--r--patches.armadillo800/0007-Input-st1232-add-device-tree-support.patch49
-rw-r--r--patches.armadillo800/0008-Input-st1232-switch-to-using-SIMPLE_DEV_PM_OPS.patch57
-rw-r--r--patches.armadillo800/0009-net-sh_eth-add-support-R8A7740.patch209
-rw-r--r--patches.armadillo800/0010-net-sh_eth-fix-the-rxdesc-pointer-when-rx-descriptor.patch48
-rw-r--r--patches.armadillo800/0011-net-sh_eth-fix-the-condition-to-fix-the-cur_tx-dirty.patch65
-rw-r--r--patches.armadillo800/0012-net-sh-eth-Add-support-selecting-MII-function-for-SH.patch196
-rw-r--r--patches.armadillo800/0013-net-sh-eth-Check-return-value-of-sh_eth_reset-when-c.patch215
-rw-r--r--patches.armadillo800/0014-net-sh_eth-remove-unnecessary-function.patch94
-rw-r--r--patches.armadillo800/0015-net-sh_eth-remove-unnecessary-members-definitions.patch140
-rw-r--r--patches.armadillo800/0016-net-sh_eth-fix-up-the-buffer-pointers.patch94
-rw-r--r--patches.armadillo800/0017-net-sh_eth-add-support-for-set_ringparam-get_ringpar.patch407
-rw-r--r--patches.armadillo800/0018-net-sh_eth-Add-eth-support-for-R8A7779-device.patch71
-rw-r--r--patches.armadillo800/0019-ASoC-add-generic-simple-card-support.patch239
-rw-r--r--patches.armadillo800/0020-ASoC-sh-fsi-use-simple-card-instead-of-fsi-ak4642.patch358
-rw-r--r--patches.armadillo800/0021-ASoC-sh-fsi-use-simple-card-instead-of-fsi-hdmi.patch246
-rw-r--r--patches.armadillo800/0022-ASoC-sh-fsi-use-simple-card-instead-of-fsi-da7210.patch210
-rw-r--r--patches.armadillo800/0023-ASoC-sh-fsi-use-register-field-macro-name-on-IN-OUT_.patch27
-rw-r--r--patches.armadillo800/0024-ASoC-sh-fsi-add-fsi_version-and-removed-meaningless-.patch105
-rw-r--r--patches.armadillo800/0025-ASoC-sh-fsi-use-same-format-for-IN-OUT.patch83
-rw-r--r--patches.armadillo800/0026-ASoC-sh-fsi-call-fsi_hw_startup-shutdown-from-fsi_da.patch53
-rw-r--r--patches.armadillo800/0027-ASoC-sh-fsi-enable-chip-specific-data-transfer-mode.patch334
-rw-r--r--patches.armadillo800/0028-ASoC-fsi-bugfix-enable-master-clock-control-on-DMA-s.patch34
-rw-r--r--patches.armadillo800/0029-ASoC-fsi-bugfix-correct-dma-area.patch66
-rw-r--r--patches.armadillo800/0030-ASoC-fsi-bugfix-ensure-dma-is-terminated.patch28
-rw-r--r--patches.armadillo800/0031-ASoC-fsi-use-dmaengine-helper-functions.patch74
-rw-r--r--patches.armadillo800/0032-ASoC-fsi-use-PIO-handler-if-DMA-handler-was-invalid.patch97
-rw-r--r--patches.armadillo800/0033-ASoC-fsi-prepare-for-conversion-to-the-shdma-base-li.patch35
-rw-r--r--patches.armadillo800/0034-fbdev-sh_mobile_hdmi-add-hdmi_bit_set-function.patch86
-rw-r--r--patches.armadillo800/0035-fbdev-sh_mobile_hdmi-add-interrupt-output-option.patch64
-rw-r--r--patches.armadillo800/0036-fbdev-sh_mobile_hdmi-32bit-register-access-support.patch115
-rw-r--r--patches.armadillo800/0037-fbdev-sh_mobile_hdmi-add-HDMI-Control-Register-suppo.patch264
-rw-r--r--patches.armadillo800/0038-fbdev-sh_mipi_dsi-fix-a-section-mismatch.patch53
-rw-r--r--patches.armadillo800/0039-fbdev-sh_mobile_lcdc-Constify-sh_mobile_lcdc_fix-str.patch31
-rw-r--r--patches.armadillo800/0040-fbdev-sh_mobile_lcdc-Rename-fb-operation-handlers-wi.patch168
-rw-r--r--patches.armadillo800/0041-fbdev-sh_mobile_lcdc-Implement-overlays-support.patch1137
-rw-r--r--patches.armadillo800/0042-sh_mobile_meram-Rename-operations-to-cache_-alloc-fr.patch425
-rw-r--r--patches.armadillo800/0043-sh_mobile_meram-Use-direct-function-calls-for-the-pu.patch265
-rw-r--r--patches.armadillo800/0044-sh_mobile_meram-Add-direct-MERAM-allocation-API.patch129
-rw-r--r--patches.armadillo800/0045-fbdev-sh_mobile_lcdc-Destroy-mutex-at-remove-time.patch37
-rw-r--r--patches.armadillo800/0046-fbdev-sh_mobile_lcdc-Fix-line-pitch-computation.patch72
-rw-r--r--patches.armadillo800/0047-fbdev-sh_mobile_lcdc-Use-channel-configuration-to-in.patch53
-rw-r--r--patches.armadillo800/0048-fbdev-sh_mobile_lcdc-Support-horizontal-panning.patch72
-rw-r--r--patches.armadillo800/0049-fbdev-sh_mobile_lcdc-Fix-overlay-registers-update-du.patch41
-rw-r--r--patches.armadillo800/0050-fbdev-sh_mobile_lcdc-Fix-pan-offset-computation-in-Y.patch241
-rw-r--r--patches.armadillo800/0051-fbdev-sh_mobile_lcdc-Fix-vertical-panning-step.patch55
-rw-r--r--patches.armadillo800/0052-ARM-mach-shmobile-r8a7740-add-gpio_irq-support.patch83
-rw-r--r--patches.armadillo800/0053-ARM-mach-shmobile-r8a7740-cleanup-I2C-workaround-met.patch48
-rw-r--r--patches.armadillo800/0054-ARM-mach-shmobile-clock-r8a7740-add-FSI-clock.patch47
-rw-r--r--patches.armadillo800/0055-ARM-mach-shmobile-clock-r8a7740-add-USB-clock.patch208
-rw-r--r--patches.armadillo800/0056-ARM-mach-shmobile-clock-r8a7740-add-SDHI-clock.patch57
-rw-r--r--patches.armadillo800/0057-ARM-mach-shmobile-clock-r8a7740-add-MMCIF-clock.patch48
-rw-r--r--patches.armadillo800/0058-ARM-mach-shmobile-clock-r8a7740-use-followparent_rec.patch48
-rw-r--r--patches.armadillo800/0059-ARM-mach-shmobile-add-armadillo800eva-board-support.patch232
-rw-r--r--patches.armadillo800/0060-ARM-mach-shmobile-armadillo800eva-add-defconfig.patch169
-rw-r--r--patches.armadillo800/0061-ARM-mach-shmobile-armadillo800eva-add-support-LCDC0.patch160
-rw-r--r--patches.armadillo800/0062-ARM-mach-shmobile-armadillo800eva-add-support-gpio_k.patch70
-rw-r--r--patches.armadillo800/0063-ARM-mach-shmobile-armadillo800eva-add-support-sh_eth.patch109
-rw-r--r--patches.armadillo800/0064-ARM-mach-shmobile-armadillo800eva-add-support-ST1232.patch59
-rw-r--r--patches.armadillo800/0065-ARM-mach-shmobile-armadillo800eva-add-USB-function-s.patch326
-rw-r--r--patches.armadillo800/0066-ARM-mach-shmobile-armadillo800eva-add-SDHI0-support.patch129
-rw-r--r--patches.armadillo800/0067-ARM-mach-shmobile-armadillo800eva-add-SDHI1-support.patch113
-rw-r--r--patches.armadillo800/0068-ARM-mach-shmobile-armadillo800eva-add-MMCIF-support.patch108
-rw-r--r--patches.armadillo800/0069-ARM-mach-shmobile-r8a7740-reserve-DMA-memory-for-the.patch47
-rw-r--r--patches.armadillo800/0070-ARM-mach-shmobile-clock-r8a7740-add-sh-eth-clock.patch64
-rw-r--r--patches.armadillo800/0071-ARM-mach-shmobile-armadillo800eva-defconfig-update.patch87
-rw-r--r--patches.armadillo800/0072-ARM-mach-shmobile-Use-DT_MACHINE-for-armadillo-800-e.patch88
-rw-r--r--patches.armadillo800/0073-ARM-shmobile-r8a7740-add-HDMI-interrupt-support.patch82
-rw-r--r--patches.armadillo800/0074-ARM-shmobile-r8a7740-add-HDMI-clock-support.patch146
-rw-r--r--patches.armadillo800/0075-ARM-shmobile-r8a7740-add-HDMI-GPIO-support.patch76
-rw-r--r--patches.armadillo800/0076-ARM-shmobile-r8a7740-add-MERAM-work-around.patch34
-rw-r--r--patches.armadillo800/0077-ARM-shmobile-r8a7740-add-CEU-clock-support.patch101
-rw-r--r--patches.armadillo800/0078-ARM-shmobile-r8a7740-add-FSI-parent-clock-support.patch125
-rw-r--r--patches.armadillo800/0079-ARM-shmobile-r8a7740-add-FSI-B-for-HDMI-GPIO-support.patch97
-rw-r--r--patches.armadillo800/0080-ARM-shmobile-armadillo800eva-enable-HDMI.patch197
-rw-r--r--patches.armadillo800/0081-ARM-mach-shmobile-armadillo800eva-Use-late-init-mach.patch35
-rw-r--r--patches.armadillo800/0082-ARM-shmobile-armadillo800eva-enable-camera.patch192
-rw-r--r--patches.armadillo800/0083-ARM-shmobile-r8a7740-add-DMAEngine-support-for-FSI.patch299
-rw-r--r--patches.armadillo800/0084-ARM-shmobile-r8a7740-add-DMAEngine-support-for-SDHI.patch80
-rw-r--r--patches.armadillo800/0085-ARM-shmobile-r8a7740-add-DMAEngine-support-for-USB.patch170
-rw-r--r--patches.armadillo800/0086-ARM-shmobile-use-common-DMAEngine-definitions-on-r8a.patch139
-rw-r--r--patches.armadillo800/0087-ARM-shmobile-armadillo800eva-enable-FSI-WM8978-sound.patch184
-rw-r--r--patches.armadillo800/0088-ARM-shmobile-armadillo800eva-enable-FSI-HDMI-sound.patch176
-rw-r--r--patches.armadillo800/0089-ARM-shmobile-armadillo800eva-enable-DMAEngine-on-FSI.patch54
-rw-r--r--patches.armadillo800/0090-ARM-shmobile-armadillo800eva-enable-DMAEngine-on-SDH.patch43
-rw-r--r--patches.armadillo800/0091-ARM-shmobile-armadillo800eva-enable-DMAEngine-on-USB.patch34
-rw-r--r--patches.armadillo800/0092-ARM-shmobile-use-common-extra-gpio-functions-on-arma.patch60
-rw-r--r--patches.armadillo800/0093-ARM-mach-shmobile-add-fixed-voltage-regulators-to-ar.patch61
-rw-r--r--patches.armadillo800/0094-ARM-mach-shmobile-Convert-sh_clk_mstp32_register-to-.patch107
-rw-r--r--patches.armadillo800/0095-ARM-shmobile-r8a7740-fixup-MSEL1CR-7bit-control.patch45
-rw-r--r--patches.armadillo800/0096-ARM-shmobile-r8a7740-add-A4S-pm-domain-support.patch122
-rw-r--r--patches.armadillo800/0097-ARM-shmobile-r8a7740-add-A3SP-pm-domain-support.patch107
-rw-r--r--patches.armadillo800/0098-ARM-shmobile-r8a7740-add-A4LC-pm-domain-support.patch63
-rw-r--r--patches.armadillo800/0099-ARM-shmobile-armadillo800eva-USB-Func-enables-extern.patch130
-rw-r--r--patches.armadillo800/0100-ARM-shmobile-armadillo800eva-A4LC-domain-includes-LC.patch35
-rw-r--r--patches.armadillo800/0101-ARM-shmobile-armadillo800eva-A3SP-domain-includes-US.patch55
-rw-r--r--patches.armadillo800/0102-ARM-mach-shmobile-r8a7740-generic-board-support-via-.patch118
-rw-r--r--patches.armadillo800/0103-ARM-mach-shmobile-armadillo800eva-defconfig-Allow-us.patch43
-rw-r--r--patches.armadillo800/0104-ARM-mach-shmobile-armadillo800eva-Fix-GPIO-buttons-d.patch40
-rw-r--r--patches.armadillo800/0105-ARM-mach-shmobile-armadillo800eva-Enable-power-butto.patch37
-rw-r--r--patches.armadillo800/0106-ARM-shmobile-armadillo800eva-fixup-sound-card-detect.patch43
-rw-r--r--patches.armadillo800/0107-ARM-shmobile-armadillo800eva-enable-rw-rootfs-mount.patch39
-rw-r--r--patches.marzen/0001-sh-clkfwk-Support-variable-size-accesses-for-MSTP-cl.patch154
-rw-r--r--patches.marzen/0002-sh-clkfwk-Support-variable-size-accesses-for-div4-di.patch202
-rw-r--r--patches.marzen/0003-sh-clkfwk-Move-to-common-clk_div_table-accessors-for.patch169
-rw-r--r--patches.marzen/0004-sh-clkfwk-Introduce-a-div_mask-for-variable-div-type.patch117
-rw-r--r--patches.marzen/0005-sh-clkfwk-Use-shared-sh_clk_div_recalc.patch167
-rw-r--r--patches.marzen/0006-sh-clkfwk-Use-shared-sh_clk_div_set_rate.patch151
-rw-r--r--patches.marzen/0007-sh-clkfwk-Use-shared-sh_clk_div_enable-disable.patch186
-rw-r--r--patches.marzen/0008-sh-clkfwk-Consolidate-div6-div4-clk_ops-definitions.patch106
-rw-r--r--patches.marzen/0009-sh-clkfwk-Consolidate-div-clk-registration-helper.patch245
-rw-r--r--patches.marzen/0010-irqdomain-Support-removal-of-IRQ-domains.patch128
-rw-r--r--patches.marzen/0011-irqdomain-Export-remaining-public-API-symbols.patch109
-rw-r--r--patches.marzen/0012-irqdomain-Make-irq_domain_simple_map-static.patch38
-rw-r--r--patches.marzen/0013-irqdomain-Kill-off-duplicate-definitions.patch35
-rw-r--r--patches.marzen/0014-irqdomain-trivial-pr_fmt-conversion.patch142
-rw-r--r--patches.marzen/0015-irqdomain-Document-size-parameter-of-irq_domain_add_.patch29
-rw-r--r--patches.marzen/0016-devicetree-add-helper-inline-for-retrieving-a-node-s.patch232
-rw-r--r--patches.marzen/0017-irqdomain-Simple-NUMA-awareness.patch132
-rw-r--r--patches.marzen/0018-irqdomain-Remove-unnecessary-test-for-IRQ_DOMAIN_MAP.patch39
-rw-r--r--patches.marzen/0019-irqdomain-Make-ops-map-hook-optional.patch69
-rw-r--r--patches.marzen/0020-irq_domain-Standardise-legacy-linear-domain-selectio.patch109
-rw-r--r--patches.marzen/0021-irq_domain-correct-a-minor-wrong-comment-for-linear-.patch32
-rw-r--r--patches.marzen/0022-irqdomain-Always-update-revmap-when-setting-up-a-vir.patch63
-rw-r--r--patches.marzen/0023-irqdomain-Split-disassociating-code-into-separate-fu.patch125
-rw-r--r--patches.marzen/0024-irqdomain-Support-for-static-IRQ-mapping-and-associa.patch239
-rw-r--r--patches.marzen/0025-irqdomain-Eliminate-dedicated-radix-lookup-functions.patch146
-rw-r--r--patches.marzen/0026-irqdomain-Fix-irq_create_direct_mapping-to-test-irq_.patch39
-rw-r--r--patches.marzen/0027-irqdomain-eliminate-slow-path-revmap-lookups.patch142
-rw-r--r--patches.marzen/0028-irqdomain-Improve-diagnostics-when-a-domain-mapping-.patch56
-rw-r--r--patches.marzen/0029-ARM-mach-shmobile-Introduce-INTC_IRQ_PINS_16H.patch83
-rw-r--r--patches.marzen/0030-sh-intc-Kill-off-special-reservation-interface.patch72
-rw-r--r--patches.marzen/0031-sh-intc-Allocate-subgroup-virq-backing-desc-directly.patch41
-rw-r--r--patches.marzen/0032-sh-intc-initial-irqdomain-support.patch195
-rw-r--r--patches.marzen/0033-sh-intc-Handle-domain-association-for-sparseirq-pre-.patch76
-rw-r--r--patches.marzen/0034-sh-intc-Fix-up-multi-evt-irq-association.patch32
-rw-r--r--patches.marzen/0035-ARM-mach-shmobile-Introduce-shmobile_setup_delay.patch70
-rw-r--r--patches.marzen/0036-ARM-mach-shmobile-Use-0x3400-as-INTCS-vector-offset.patch43
-rw-r--r--patches.marzen/0037-ARM-provide-a-late_initcall-hook-for-platform-initia.patch55
-rw-r--r--patches.marzen/0038-ARM-shmobile-use-machine-specific-hook-for-late-init.patch219
-rw-r--r--patches.marzen/0039-ARM-mach-shmobile-Use-preset_lpj-with-calibrate_dela.patch46
-rw-r--r--patches.marzen/0040-ARM-shmobile-r8a7740-add-MERAM-work-around.patch72
-rw-r--r--patches.marzen/0041-ARM-shmobile-add-common-extra-gpio-functions.patch73
-rw-r--r--patches.marzen/0042-ARM-mach-shmobile-add-fixed-voltage-regulators-to-ma.patch55
-rw-r--r--patches.marzen/0043-ARM-shmobile-marzen-fixup-smsc911x-id-for-regulator.patch33
-rw-r--r--patches.marzen/0044-ARM-shmobile-r8a7779-Route-all-interrupts-to-ARM.patch46
-rw-r--r--patches.marzen/0045-dmaengine-Fixup-dmaengine_prep_slave_single-to-be-ac.patch52
-rw-r--r--patches.marzen/0046-dma-dmaengine-add-slave-req-id-in-slave_config.patch47
-rw-r--r--patches.marzen/0047-dmaengine-Add-wrapper-for-device_tx_status-callback.patch42
-rw-r--r--patches.marzen/0048-dma-move-shdma-driver-to-an-own-directory.patch66
-rw-r--r--patches.marzen/0049-dmaengine-add-an-shdma-base-library.patch1036
-rw-r--r--patches.marzen/0050-dma-shdma-prepare-for-conversion-to-the-shdma-base-l.patch44
-rw-r--r--patches.marzen/0051-ASoC-fsi-prepare-for-conversion-to-the-shdma-base-li.patch30
-rw-r--r--patches.marzen/0052-usb-renesas_usbhs-prepare-for-conversion-to-the-shdm.patch55
-rw-r--r--patches.marzen/0053-dma-shdma-convert-to-the-shdma-base-library.patch1561
-rw-r--r--patches.marzen/0054-dmaengine-shdma-prepare-to-stop-using-struct-dma_cha.patch183
-rw-r--r--patches.marzen/0055-dmaengine-shdma-cosmetic-simplify-a-static-function.patch58
-rw-r--r--patches.marzen/0056-dma-sh-use-an-integer-slave-ID-to-improve-API-compat.patch220
-rw-r--r--patches.marzen/0057-dma-sh-provide-a-migration-path-for-slave-drivers-to.patch231
-rw-r--r--patches.marzen/0058-dmaengine-shdma-restore-partial-transfer-calculation.patch101
-rw-r--r--patches.marzen/0059-serial-sh-sci-modify-sci_break_ctl.patch77
-rw-r--r--patches.marzen/0060-serial-sh-sci-Update-break_ctl-handling-for-all-SCSP.patch77
-rw-r--r--patches.marzen/0061-serial-sh-sci-Fix-for-port-types-without-BRI-interru.patch63
-rw-r--r--patches.marzen/0062-serial-sh-sci-Fix-probe-error-paths.patch102
-rw-r--r--patches.marzen/0063-serial-sh-sci-Make-probe-fail-for-ports-that-exceed-.patch39
-rw-r--r--patches.marzen/0064-serial-sh-sci-prepare-for-conversion-to-the-shdma-ba.patch53
-rw-r--r--patches.marzen/0065-serial-sh-sci-fix-compilation-breakage-when-DMA-is-e.patch51
-rw-r--r--patches.marzen/0066-net-smsc911x-Repair-broken-failure-paths.patch53
-rw-r--r--patches.marzen/0067-smsc911x.c-encapsulate-enable-irq-calls.patch70
-rw-r--r--patches.marzen/0068-clocksource-sh_tmu-Convert-timer-lock-to-raw-spinloc.patch47
-rw-r--r--patches.marzen/0069-mmc-tmio-use-MMC-opcode-defines-instead-of-numbers.patch52
-rw-r--r--patches.marzen/0070-mmc-cd-gpio-pass-IRQF_ONESHOT-to-request_threaded_ir.patch43
-rw-r--r--patches.marzen/0071-mmc-extend-and-rename-cd-gpio-helpers-to-handle-more.patch199
-rw-r--r--patches.marzen/0072-mmc-tmio-Don-t-access-hardware-registers-after-stopp.patch66
-rw-r--r--patches.marzen/0073-mmc-tmio-don-t-needlessly-enable-interrupts-during-p.patch60
-rw-r--r--patches.marzen/0074-mmc-sdhi-implement-tmio-mmc-clock-enable-update-and-.patch66
-rw-r--r--patches.marzen/0075-mmc-tmio-add-callbacks-to-enable-update-and-disable-.patch120
-rw-r--r--patches.marzen/0076-mmc-sdhi-do-not-install-dummy-callbacks.patch62
-rw-r--r--patches.marzen/0077-mmc-add-a-function-to-get-regulators-supplying-card-.patch112
-rw-r--r--patches.marzen/0078-mmc-tmio-add-regulator-support.patch95
-rw-r--r--patches.marzen/0079-mmc-tmio-remove-a-duplicated-comment-line.patch29
-rw-r--r--patches.marzen/0080-mmc-tmio-support-caps2-flags.patch45
-rw-r--r--patches.marzen/0081-mmc-sh_mobile_sdhi-support-caps2-flags.patch44
-rw-r--r--patches.marzen/0082-mmc-sdhi-add-OF-support-make-platform-data-optional.patch121
-rw-r--r--patches.marzen/0083-mmc-core-use-a-more-generic-name-for-slot-function-t.patch100
-rw-r--r--patches.marzen/0084-mmc-add-two-capability-flags-for-CD-and-WP-signal-po.patch33
-rw-r--r--patches.marzen/0085-mmc-add-CD-GPIO-polling-support-to-slot-functions.patch141
-rw-r--r--patches.marzen/0086-mmc-core-convert-slot-functions-to-managed-allocatio.patch161
-rw-r--r--patches.marzen/0087-mmc-core-add-WP-pin-handler-to-slot-functions.patch132
-rw-r--r--patches.marzen/0088-mmc-tmio-use-generic-GPIO-CD-and-WP-handlers.patch45
-rw-r--r--patches.marzen/0089-mmc-sh_mobile_sdhi-prepare-for-conversion-to-the-shd.patch37
-rw-r--r--patches.marzen/0090-mmc-sh_mmcif-remove-unneeded-struct-sh_mmcif_dma-pre.patch94
-rw-r--r--patches.marzen/0091-mmc-sh_mmcif-switch-to-the-new-DMA-channel-allocatio.patch138
-rw-r--r--patches.marzen/0092-mmc-sh_mmcif-Support-MMC_SLEEP_AWAKE-command.patch53
-rw-r--r--patches.marzen/0093-mmc-sh_mmcif-simplify-and-use-meaningful-label-names.patch126
-rw-r--r--patches.marzen/0094-mmc-sh_mmcif-fix-clock-management.patch160
-rw-r--r--patches.marzen/0095-mmc-sh_mmcif-re-read-the-clock-frequency-every-time-.patch73
-rw-r--r--patches.marzen/0096-mmc-sh_mmcif-remove-redundant-.down_pwr-callback.patch39
-rw-r--r--patches.marzen/0097-mmc-sh_mmcif-add-regulator-support.patch108
-rw-r--r--patches.marzen/0098-mmc-sh-mmcif-add-OF-support-make-platform-data-optio.patch127
-rw-r--r--patches.marzen/0099-mmc-sh_mmcif-support-generic-card-detection.patch92
-rw-r--r--series208
207 files changed, 25190 insertions, 0 deletions
diff --git a/patches.armadillo800/0001-ARM-shmobile-add-common-DMAEngine-definitions.patch b/patches.armadillo800/0001-ARM-shmobile-add-common-DMAEngine-definitions.patch
new file mode 100644
index 0000000000000..5316285a382f3
--- /dev/null
+++ b/patches.armadillo800/0001-ARM-shmobile-add-common-DMAEngine-definitions.patch
@@ -0,0 +1,115 @@
+From 4d3626f914a2b4023a3edf428640e578527ac0c8 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 25 Jun 2012 03:43:00 -0700
+Subject: ARM: shmobile: add common DMAEngine definitions
+
+Current shmobile have DMAEngine specific settings on each CPU code,
+but SH-ARM DMAC use same value.
+
+This patch adds new dma-register.h header to share definitions
+and reduce a waste of code on SH-ARM architecture.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 5ca1d44f6a99b29ab164a06f4ec71950d6939fb5)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/include/mach/dma-register.h | 84 ++++++++++++++++++++++
+ 1 file changed, 84 insertions(+)
+ create mode 100644 arch/arm/mach-shmobile/include/mach/dma-register.h
+
+diff --git a/arch/arm/mach-shmobile/include/mach/dma-register.h b/arch/arm/mach-shmobile/include/mach/dma-register.h
+new file mode 100644
+index 0000000..97c40bd
+--- /dev/null
++++ b/arch/arm/mach-shmobile/include/mach/dma-register.h
+@@ -0,0 +1,84 @@
++/*
++ * SH-ARM CPU-specific DMA definitions, used by both DMA drivers
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp
++ *
++ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
++ *
++ * Based on arch/sh/include/cpu-sh4/cpu/dma-register.h
++ * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef DMA_REGISTER_H
++#define DMA_REGISTER_H
++
++/*
++ * Direct Memory Access Controller
++ */
++
++/* Transmit sizes and respective CHCR register values */
++enum {
++ XMIT_SZ_8BIT = 0,
++ XMIT_SZ_16BIT = 1,
++ XMIT_SZ_32BIT = 2,
++ XMIT_SZ_64BIT = 7,
++ XMIT_SZ_128BIT = 3,
++ XMIT_SZ_256BIT = 4,
++ XMIT_SZ_512BIT = 5,
++};
++
++/* log2(size / 8) - used to calculate number of transfers */
++static const unsigned int dma_ts_shift[] = {
++ [XMIT_SZ_8BIT] = 0,
++ [XMIT_SZ_16BIT] = 1,
++ [XMIT_SZ_32BIT] = 2,
++ [XMIT_SZ_64BIT] = 3,
++ [XMIT_SZ_128BIT] = 4,
++ [XMIT_SZ_256BIT] = 5,
++ [XMIT_SZ_512BIT] = 6,
++};
++
++#define TS_LOW_BIT 0x3 /* --xx */
++#define TS_HI_BIT 0xc /* xx-- */
++
++#define TS_LOW_SHIFT (3)
++#define TS_HI_SHIFT (20 - 2) /* 2 bits for shifted low TS */
++
++#define TS_INDEX2VAL(i) \
++ ((((i) & TS_LOW_BIT) << TS_LOW_SHIFT) |\
++ (((i) & TS_HI_BIT) << TS_HI_SHIFT))
++
++#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz)))
++#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz)))
++
++
++/*
++ * USB High-Speed DMAC
++ */
++/* Transmit sizes and respective CHCR register values */
++enum {
++ USBTS_XMIT_SZ_8BYTE = 0,
++ USBTS_XMIT_SZ_16BYTE = 1,
++ USBTS_XMIT_SZ_32BYTE = 2,
++};
++
++/* log2(size / 8) - used to calculate number of transfers */
++static const unsigned int dma_usbts_shift[] = {
++ [USBTS_XMIT_SZ_8BYTE] = 3,
++ [USBTS_XMIT_SZ_16BYTE] = 4,
++ [USBTS_XMIT_SZ_32BYTE] = 5,
++};
++
++#define USBTS_LOW_BIT 0x3 /* --xx */
++#define USBTS_HI_BIT 0x0 /* ---- */
++
++#define USBTS_LOW_SHIFT 6
++#define USBTS_HI_SHIFT 0
++
++#define USBTS_INDEX2VAL(i) (((i) & 3) << 6)
++
++#endif /* DMA_REGISTER_H */
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0002-ARM-shmobile-soc-core-add-R-mobile-PM-domain-common-.patch b/patches.armadillo800/0002-ARM-shmobile-soc-core-add-R-mobile-PM-domain-common-.patch
new file mode 100644
index 0000000000000..2acaf3de704cf
--- /dev/null
+++ b/patches.armadillo800/0002-ARM-shmobile-soc-core-add-R-mobile-PM-domain-common-.patch
@@ -0,0 +1,260 @@
+From c13b4e8e39cad46f37b794ba12b8a97569767e25 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 5 Jul 2012 01:24:46 -0700
+Subject: ARM: shmobile: soc-core: add R-mobile PM domain common APIs
+
+This patch adds Renesas R-mobile series common PM domain APIs.
+R-mobile CPU can use/switch this API
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 8f45b112fc66ef6869ccca4c3966976982f496a9)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/Makefile | 1 +
+ arch/arm/mach-shmobile/include/mach/pm-rmobile.h | 44 ++++++
+ arch/arm/mach-shmobile/pm-rmobile.c | 167 +++++++++++++++++++++++
+ 3 files changed, 212 insertions(+)
+ create mode 100644 arch/arm/mach-shmobile/include/mach/pm-rmobile.h
+ create mode 100644 arch/arm/mach-shmobile/pm-rmobile.c
+
+diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
+index e7c2590..53846a1e 100644
+--- a/arch/arm/mach-shmobile/Makefile
++++ b/arch/arm/mach-shmobile/Makefile
+@@ -37,6 +37,7 @@ obj-$(CONFIG_ARCH_R8A7740) += entry-intc.o
+ # PM objects
+ obj-$(CONFIG_SUSPEND) += suspend.o
+ obj-$(CONFIG_CPU_IDLE) += cpuidle.o
++obj-$(CONFIG_ARCH_SHMOBILE) += pm-rmobile.o
+ obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o
+ obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o
+
+diff --git a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h
+new file mode 100644
+index 0000000..5a40284
+--- /dev/null
++++ b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h
+@@ -0,0 +1,44 @@
++/*
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ *
++ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License. See the file "COPYING" in the main directory of this archive
++ * for more details.
++ */
++#ifndef PM_RMOBILE_H
++#define PM_RMOBILE_H
++
++#include <linux/pm_domain.h>
++
++struct platform_device;
++
++struct rmobile_pm_domain {
++ struct generic_pm_domain genpd;
++ struct dev_power_governor *gov;
++ int (*suspend)(void);
++ void (*resume)(void);
++ unsigned int bit_shift;
++ bool no_debug;
++};
++
++static inline
++struct rmobile_pm_domain *to_rmobile_pd(struct generic_pm_domain *d)
++{
++ return container_of(d, struct rmobile_pm_domain, genpd);
++}
++
++#ifdef CONFIG_PM
++extern void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd);
++extern void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd,
++ struct platform_device *pdev);
++extern void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd,
++ struct rmobile_pm_domain *rmobile_sd);
++#else
++#define rmobile_init_pm_domain(pd) do { } while (0)
++#define rmobile_add_device_to_domain(pd, pdev) do { } while (0)
++#define rmobile_pm_add_subdomain(pd, sd) do { } while (0)
++#endif /* CONFIG_PM */
++
++#endif /* PM_RMOBILE_H */
+diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c
+new file mode 100644
+index 0000000..a856254
+--- /dev/null
++++ b/arch/arm/mach-shmobile/pm-rmobile.c
+@@ -0,0 +1,167 @@
++/*
++ * rmobile power management support
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
++ *
++ * based on pm-sh7372.c
++ * Copyright (C) 2011 Magnus Damm
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License. See the file "COPYING" in the main directory of this archive
++ * for more details.
++ */
++#include <linux/console.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++#include <linux/pm.h>
++#include <linux/pm_clock.h>
++#include <asm/io.h>
++#include <mach/pm-rmobile.h>
++
++/* SYSC */
++#define SPDCR 0xe6180008
++#define SWUCR 0xe6180014
++#define PSTR 0xe6180080
++
++#define PSTR_RETRIES 100
++#define PSTR_DELAY_US 10
++
++#ifdef CONFIG_PM
++static int rmobile_pd_power_down(struct generic_pm_domain *genpd)
++{
++ struct rmobile_pm_domain *rmobile_pd = to_rmobile_pd(genpd);
++ unsigned int mask = 1 << rmobile_pd->bit_shift;
++
++ if (rmobile_pd->suspend) {
++ int ret = rmobile_pd->suspend();
++
++ if (ret)
++ return ret;
++ }
++
++ if (__raw_readl(PSTR) & mask) {
++ unsigned int retry_count;
++ __raw_writel(mask, SPDCR);
++
++ for (retry_count = PSTR_RETRIES; retry_count; retry_count--) {
++ if (!(__raw_readl(SPDCR) & mask))
++ break;
++ cpu_relax();
++ }
++ }
++
++ if (!rmobile_pd->no_debug)
++ pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n",
++ genpd->name, mask, __raw_readl(PSTR));
++
++ return 0;
++}
++
++static int __rmobile_pd_power_up(struct rmobile_pm_domain *rmobile_pd,
++ bool do_resume)
++{
++ unsigned int mask = 1 << rmobile_pd->bit_shift;
++ unsigned int retry_count;
++ int ret = 0;
++
++ if (__raw_readl(PSTR) & mask)
++ goto out;
++
++ __raw_writel(mask, SWUCR);
++
++ for (retry_count = 2 * PSTR_RETRIES; retry_count; retry_count--) {
++ if (!(__raw_readl(SWUCR) & mask))
++ break;
++ if (retry_count > PSTR_RETRIES)
++ udelay(PSTR_DELAY_US);
++ else
++ cpu_relax();
++ }
++ if (!retry_count)
++ ret = -EIO;
++
++ if (!rmobile_pd->no_debug)
++ pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n",
++ rmobile_pd->genpd.name, mask, __raw_readl(PSTR));
++
++out:
++ if (ret == 0 && rmobile_pd->resume && do_resume)
++ rmobile_pd->resume();
++
++ return ret;
++}
++
++static int rmobile_pd_power_up(struct generic_pm_domain *genpd)
++{
++ return __rmobile_pd_power_up(to_rmobile_pd(genpd), true);
++}
++
++static bool rmobile_pd_active_wakeup(struct device *dev)
++{
++ bool (*active_wakeup)(struct device *dev);
++
++ active_wakeup = dev_gpd_data(dev)->ops.active_wakeup;
++ return active_wakeup ? active_wakeup(dev) : true;
++}
++
++static int rmobile_pd_stop_dev(struct device *dev)
++{
++ int (*stop)(struct device *dev);
++
++ stop = dev_gpd_data(dev)->ops.stop;
++ if (stop) {
++ int ret = stop(dev);
++ if (ret)
++ return ret;
++ }
++ return pm_clk_suspend(dev);
++}
++
++static int rmobile_pd_start_dev(struct device *dev)
++{
++ int (*start)(struct device *dev);
++ int ret;
++
++ ret = pm_clk_resume(dev);
++ if (ret)
++ return ret;
++
++ start = dev_gpd_data(dev)->ops.start;
++ if (start)
++ ret = start(dev);
++
++ return ret;
++}
++
++void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
++{
++ struct generic_pm_domain *genpd = &rmobile_pd->genpd;
++ struct dev_power_governor *gov = rmobile_pd->gov;
++
++ pm_genpd_init(genpd, gov ? : &simple_qos_governor, false);
++ genpd->dev_ops.stop = rmobile_pd_stop_dev;
++ genpd->dev_ops.start = rmobile_pd_start_dev;
++ genpd->dev_ops.active_wakeup = rmobile_pd_active_wakeup;
++ genpd->dev_irq_safe = true;
++ genpd->power_off = rmobile_pd_power_down;
++ genpd->power_on = rmobile_pd_power_up;
++ __rmobile_pd_power_up(rmobile_pd, false);
++}
++
++void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd,
++ struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++
++ pm_genpd_add_device(&rmobile_pd->genpd, dev);
++ if (pm_clk_no_clocks(dev))
++ pm_clk_add(dev, NULL);
++}
++
++void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd,
++ struct rmobile_pm_domain *rmobile_sd)
++{
++ pm_genpd_add_subdomain(&rmobile_pd->genpd, &rmobile_sd->genpd);
++}
++#endif /* CONFIG_PM */
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0003-media-V4L2-sh_mobile_ceu-manage-lower-8bit-bus.patch b/patches.armadillo800/0003-media-V4L2-sh_mobile_ceu-manage-lower-8bit-bus.patch
new file mode 100644
index 0000000000000..e133ecf33aa80
--- /dev/null
+++ b/patches.armadillo800/0003-media-V4L2-sh_mobile_ceu-manage-lower-8bit-bus.patch
@@ -0,0 +1,55 @@
+From 657ed37c21c4b58b2ce736343d1c653a842f7299 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 8 May 2012 00:00:07 -0300
+Subject: [media] V4L2: sh_mobile_ceu: manage lower 8bit bus
+
+CAMCR::DTIF feild controls camera bus as upper8bit/16bit/lower8bit.
+This patch manages unmanaged lower 8bit bus
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+(cherry picked from commit 2564f67bc8d56e5c7fc2970f80f41f2d38db3e21)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/media/video/sh_mobile_ceu_camera.c | 8 +++++---
+ include/media/sh_mobile_ceu.h | 1 +
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
+index 424dfac..4e0b654 100644
+--- a/drivers/media/video/sh_mobile_ceu_camera.c
++++ b/drivers/media/video/sh_mobile_ceu_camera.c
+@@ -881,11 +881,13 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd)
+
+ value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
+ value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
+- value |= pcdev->is_16bit ? 1 << 12 : 0;
+
+- /* CSI2 mode */
+- if (pcdev->pdata->csi2)
++ if (pcdev->pdata->csi2) /* CSI2 mode */
+ value |= 3 << 12;
++ else if (pcdev->is_16bit)
++ value |= 1 << 12;
++ else if (pcdev->pdata->flags & SH_CEU_FLAG_LOWER_8BIT)
++ value |= 2 << 12;
+
+ ceu_write(pcdev, CAMCR, value);
+
+diff --git a/include/media/sh_mobile_ceu.h b/include/media/sh_mobile_ceu.h
+index a90a765..6fdb6ad 100644
+--- a/include/media/sh_mobile_ceu.h
++++ b/include/media/sh_mobile_ceu.h
+@@ -5,6 +5,7 @@
+ #define SH_CEU_FLAG_USE_16BIT_BUS (1 << 1) /* use 16bit bus width */
+ #define SH_CEU_FLAG_HSYNC_LOW (1 << 2) /* default High if possible */
+ #define SH_CEU_FLAG_VSYNC_LOW (1 << 3) /* default High if possible */
++#define SH_CEU_FLAG_LOWER_8BIT (1 << 4) /* default upper 8bit */
+
+ struct device;
+ struct resource;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0004-regulator-support-multiple-dummy-fixed-regulators.patch b/patches.armadillo800/0004-regulator-support-multiple-dummy-fixed-regulators.patch
new file mode 100644
index 0000000000000..fb5e5111c4832
--- /dev/null
+++ b/patches.armadillo800/0004-regulator-support-multiple-dummy-fixed-regulators.patch
@@ -0,0 +1,96 @@
+From 5d792a5a2daa8e2d397c0b5f45ac76c9e0d175ff Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Tue, 19 Jun 2012 17:43:56 +0200
+Subject: regulator: support multiple dummy fixed regulators
+
+Currently regulator_register_fixed() uses a constant name to register a
+fixed dummy regulator. This is sufficient in principle, since there is no
+reason to register multiple such regulators. The user can simply supply all
+consumers in one array and use it to initialise such a regulator. However,
+in some cases it can be convenient to register multiple such regulators.
+This is also a prerequisite for the upcoming patch, that will add a voltage
+parameter to this function. The original function is provided as a wrapper
+macro.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit dfad84aeab5f71b33a12e6803a809f698bdef5a2)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/regulator/fixed-helper.c | 14 +++++++++++---
+ include/linux/regulator/fixed.h | 7 +++++--
+ 2 files changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/regulator/fixed-helper.c b/drivers/regulator/fixed-helper.c
+index cacd33c..3aa268d 100644
+--- a/drivers/regulator/fixed-helper.c
++++ b/drivers/regulator/fixed-helper.c
+@@ -1,4 +1,5 @@
+ #include <linux/slab.h>
++#include <linux/string.h>
+ #include <linux/platform_device.h>
+ #include <linux/regulator/machine.h>
+ #include <linux/regulator/fixed.h>
+@@ -13,16 +14,18 @@ static void regulator_fixed_release(struct device *dev)
+ {
+ struct fixed_regulator_data *data = container_of(dev,
+ struct fixed_regulator_data, pdev.dev);
++ kfree(data->cfg.supply_name);
+ kfree(data);
+ }
+
+ /**
+- * regulator_register_fixed - register a no-op fixed regulator
++ * regulator_register_fixed_name - register a no-op fixed regulator
+ * @id: platform device id
++ * @name: name to be used for the regulator
+ * @supplies: consumers for this regulator
+ * @num_supplies: number of consumers
+ */
+-struct platform_device *regulator_register_fixed(int id,
++struct platform_device *regulator_register_always_on(int id, const char *name,
+ struct regulator_consumer_supply *supplies, int num_supplies)
+ {
+ struct fixed_regulator_data *data;
+@@ -31,7 +34,12 @@ struct platform_device *regulator_register_fixed(int id,
+ if (!data)
+ return NULL;
+
+- data->cfg.supply_name = "fixed-dummy";
++ data->cfg.supply_name = kstrdup(name, GFP_KERNEL);
++ if (!data->cfg.supply_name) {
++ kfree(data);
++ return NULL;
++ }
++
+ data->cfg.microvolts = 0;
+ data->cfg.gpio = -EINVAL;
+ data->cfg.enabled_at_boot = 1;
+diff --git a/include/linux/regulator/fixed.h b/include/linux/regulator/fixed.h
+index 936a7d8..7bb456c 100644
+--- a/include/linux/regulator/fixed.h
++++ b/include/linux/regulator/fixed.h
+@@ -51,14 +51,17 @@ struct fixed_voltage_config {
+ struct regulator_consumer_supply;
+
+ #if IS_ENABLED(CONFIG_REGULATOR)
+-struct platform_device *regulator_register_fixed(int id,
++struct platform_device *regulator_register_always_on(int id, const char *name,
+ struct regulator_consumer_supply *supplies, int num_supplies);
+ #else
+-static inline struct platform_device *regulator_register_fixed(int id,
++static inline struct platform_device *regulator_register_always_on(int id, const char *name,
+ struct regulator_consumer_supply *supplies, int num_supplies)
+ {
+ return NULL;
+ }
+ #endif
+
++#define regulator_register_fixed(id, s, ns) regulator_register_always_on(id, \
++ "fixed-dummy", s, ns)
++
+ #endif
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0005-regulator-extend-the-fixed-dummy-voltage-regulator-t.patch b/patches.armadillo800/0005-regulator-extend-the-fixed-dummy-voltage-regulator-t.patch
new file mode 100644
index 0000000000000..dccde558658f1
--- /dev/null
+++ b/patches.armadillo800/0005-regulator-extend-the-fixed-dummy-voltage-regulator-t.patch
@@ -0,0 +1,70 @@
+From c5249f06fd57ea88ef47b750dc11a6f683bd5e5d Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Tue, 19 Jun 2012 17:44:39 +0200
+Subject: regulator: extend the fixed dummy voltage regulator to accept voltage
+
+Trivially extend the regulator_register_always_on() helper function to be
+even more useful by adding a voltage parameter to it.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 15719ccc274981b19ad8fe9ac20c94249de8a257)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/regulator/fixed-helper.c | 5 +++--
+ include/linux/regulator/fixed.h | 6 +++---
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/regulator/fixed-helper.c b/drivers/regulator/fixed-helper.c
+index 3aa268d..f9d0279 100644
+--- a/drivers/regulator/fixed-helper.c
++++ b/drivers/regulator/fixed-helper.c
+@@ -24,9 +24,10 @@ static void regulator_fixed_release(struct device *dev)
+ * @name: name to be used for the regulator
+ * @supplies: consumers for this regulator
+ * @num_supplies: number of consumers
++ * @uv: voltage in microvolts
+ */
+ struct platform_device *regulator_register_always_on(int id, const char *name,
+- struct regulator_consumer_supply *supplies, int num_supplies)
++ struct regulator_consumer_supply *supplies, int num_supplies, int uv)
+ {
+ struct fixed_regulator_data *data;
+
+@@ -40,7 +41,7 @@ struct platform_device *regulator_register_always_on(int id, const char *name,
+ return NULL;
+ }
+
+- data->cfg.microvolts = 0;
++ data->cfg.microvolts = uv;
+ data->cfg.gpio = -EINVAL;
+ data->cfg.enabled_at_boot = 1;
+ data->cfg.init_data = &data->init_data;
+diff --git a/include/linux/regulator/fixed.h b/include/linux/regulator/fixed.h
+index 7bb456c..f6372ee 100644
+--- a/include/linux/regulator/fixed.h
++++ b/include/linux/regulator/fixed.h
+@@ -52,16 +52,16 @@ struct regulator_consumer_supply;
+
+ #if IS_ENABLED(CONFIG_REGULATOR)
+ struct platform_device *regulator_register_always_on(int id, const char *name,
+- struct regulator_consumer_supply *supplies, int num_supplies);
++ struct regulator_consumer_supply *supplies, int num_supplies, int uv);
+ #else
+ static inline struct platform_device *regulator_register_always_on(int id, const char *name,
+- struct regulator_consumer_supply *supplies, int num_supplies)
++ struct regulator_consumer_supply *supplies, int num_supplies, int uv)
+ {
+ return NULL;
+ }
+ #endif
+
+ #define regulator_register_fixed(id, s, ns) regulator_register_always_on(id, \
+- "fixed-dummy", s, ns)
++ "fixed-dummy", s, ns, 0)
+
+ #endif
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0006-Input-gpio_keys-remove-useless-reinitialization-of-p.patch b/patches.armadillo800/0006-Input-gpio_keys-remove-useless-reinitialization-of-p.patch
new file mode 100644
index 0000000000000..0f2761ddaffb0
--- /dev/null
+++ b/patches.armadillo800/0006-Input-gpio_keys-remove-useless-reinitialization-of-p.patch
@@ -0,0 +1,32 @@
+From 5f0a6815e3a7c5e73486b7b0a7ffffcf78b81cee Mon Sep 17 00:00:00 2001
+From: Tobias Klauser <tklauser@distanz.ch>
+Date: Mon, 11 Jun 2012 23:55:32 -0700
+Subject: Input: gpio_keys - remove useless reinitialization of pdata->nbuttons
+
+pdata is zeroed using memset just a few lines before, so there is no
+need to set the nbuttons member to 0 again.
+
+Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
+Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
+(cherry picked from commit 4eceb14f669cb9e9d189019e8fcbf73577fe77a7)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/input/keyboard/gpio_keys.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
+index 62bfce4..cbb1add 100644
+--- a/drivers/input/keyboard/gpio_keys.c
++++ b/drivers/input/keyboard/gpio_keys.c
+@@ -559,7 +559,6 @@ static int gpio_keys_get_devtree_pdata(struct device *dev,
+ pdata->rep = !!of_get_property(node, "autorepeat", NULL);
+
+ /* First count the subnodes */
+- pdata->nbuttons = 0;
+ pp = NULL;
+ while ((pp = of_get_next_child(node, pp)))
+ pdata->nbuttons++;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0007-Input-st1232-add-device-tree-support.patch b/patches.armadillo800/0007-Input-st1232-add-device-tree-support.patch
new file mode 100644
index 0000000000000..d0a9ee2bf9618
--- /dev/null
+++ b/patches.armadillo800/0007-Input-st1232-add-device-tree-support.patch
@@ -0,0 +1,49 @@
+From ccbea8cbb6f976a4ed42dfba5648bfb543f520d1 Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Tue, 3 Apr 2012 11:30:28 -0700
+Subject: Input: st1232 - add device tree support
+
+This patch enables DT support for the st1232 driver
+which is primarily used on the sh7372 Mackerel board.
+
+[dtor@mail.ru: chnaged to use CONFIG_OF and of_match_ptr]
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
+(cherry picked from commit e6293d2f8a6cd427a1ef4ddecb16b1d5ae1929cd)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/input/touchscreen/st1232.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c
+index cbbf71b..216fabb 100644
+--- a/drivers/input/touchscreen/st1232.c
++++ b/drivers/input/touchscreen/st1232.c
+@@ -255,6 +255,14 @@ static const struct i2c_device_id st1232_ts_id[] = {
+ };
+ MODULE_DEVICE_TABLE(i2c, st1232_ts_id);
+
++#ifdef CONFIG_OF
++static const struct of_device_id st1232_ts_dt_ids[] __devinitconst = {
++ { .compatible = "sitronix,st1232", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, st1232_ts_dt_ids);
++#endif
++
+ static struct i2c_driver st1232_ts_driver = {
+ .probe = st1232_ts_probe,
+ .remove = __devexit_p(st1232_ts_remove),
+@@ -262,6 +270,7 @@ static struct i2c_driver st1232_ts_driver = {
+ .driver = {
+ .name = ST1232_TS_NAME,
+ .owner = THIS_MODULE,
++ .of_match_table = of_match_ptr(st1232_ts_dt_ids),
+ #ifdef CONFIG_PM
+ .pm = &st1232_ts_pm_ops,
+ #endif
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0008-Input-st1232-switch-to-using-SIMPLE_DEV_PM_OPS.patch b/patches.armadillo800/0008-Input-st1232-switch-to-using-SIMPLE_DEV_PM_OPS.patch
new file mode 100644
index 0000000000000..95252d1ed1bb0
--- /dev/null
+++ b/patches.armadillo800/0008-Input-st1232-switch-to-using-SIMPLE_DEV_PM_OPS.patch
@@ -0,0 +1,57 @@
+From 456b9180124a8edec6c90cbd4d2b3f7c8a09a6f7 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Tue, 3 Apr 2012 11:30:28 -0700
+Subject: Input: st1232 - switch to using SIMPLE_DEV_PM_OPS
+
+Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
+Reviewed-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
+(cherry picked from commit b3571400395e318306165eabbfbe05a4c3e4366c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/input/touchscreen/st1232.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c
+index 216fabb..6cb68a1 100644
+--- a/drivers/input/touchscreen/st1232.c
++++ b/drivers/input/touchscreen/st1232.c
+@@ -218,7 +218,7 @@ static int __devexit st1232_ts_remove(struct i2c_client *client)
+ return 0;
+ }
+
+-#ifdef CONFIG_PM
++#ifdef CONFIG_PM_SLEEP
+ static int st1232_ts_suspend(struct device *dev)
+ {
+ struct i2c_client *client = to_i2c_client(dev);
+@@ -243,12 +243,11 @@ static int st1232_ts_resume(struct device *dev)
+ return 0;
+ }
+
+-static const struct dev_pm_ops st1232_ts_pm_ops = {
+- .suspend = st1232_ts_suspend,
+- .resume = st1232_ts_resume,
+-};
+ #endif
+
++static SIMPLE_DEV_PM_OPS(st1232_ts_pm_ops,
++ st1232_ts_suspend, st1232_ts_resume);
++
+ static const struct i2c_device_id st1232_ts_id[] = {
+ { ST1232_TS_NAME, 0 },
+ { }
+@@ -271,9 +270,7 @@ static struct i2c_driver st1232_ts_driver = {
+ .name = ST1232_TS_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(st1232_ts_dt_ids),
+-#ifdef CONFIG_PM
+ .pm = &st1232_ts_pm_ops,
+-#endif
+ },
+ };
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0009-net-sh_eth-add-support-R8A7740.patch b/patches.armadillo800/0009-net-sh_eth-add-support-R8A7740.patch
new file mode 100644
index 0000000000000..24501ce745b1b
--- /dev/null
+++ b/patches.armadillo800/0009-net-sh_eth-add-support-R8A7740.patch
@@ -0,0 +1,209 @@
+From 38480ba305384441ebefad2684028756f7eab8b2 Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Wed, 4 Apr 2012 18:37:10 +0000
+Subject: net: sh_eth: add support R8A7740
+
+The R8A7740 has a Gigabit Ethernet MAC. This patch supports it.
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Tested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 73a0d907301ece200d32b4e8ba2da2ca296b507f)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/net/ethernet/renesas/Kconfig | 7 ++-
+ drivers/net/ethernet/renesas/sh_eth.c | 114 +++++++++++++++++++++++++++++++++-
+ drivers/net/ethernet/renesas/sh_eth.h | 5 +-
+ 3 files changed, 120 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/Kconfig b/drivers/net/ethernet/renesas/Kconfig
+index 3fb2355..46df3a0 100644
+--- a/drivers/net/ethernet/renesas/Kconfig
++++ b/drivers/net/ethernet/renesas/Kconfig
+@@ -4,11 +4,11 @@
+
+ config SH_ETH
+ tristate "Renesas SuperH Ethernet support"
+- depends on SUPERH && \
++ depends on (SUPERH || ARCH_SHMOBILE) && \
+ (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
+ CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
+ CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7734 || \
+- CPU_SUBTYPE_SH7757)
++ CPU_SUBTYPE_SH7757 || ARCH_R8A7740)
+ select CRC32
+ select NET_CORE
+ select MII
+@@ -17,4 +17,5 @@ config SH_ETH
+ ---help---
+ Renesas SuperH Ethernet device driver.
+ This driver supporting CPUs are:
+- - SH7619, SH7710, SH7712, SH7724, SH7734, SH7763 and SH7757.
++ - SH7619, SH7710, SH7712, SH7724, SH7734, SH7763, SH7757,
++ and R8A7740.
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index d63e09b..be3c221 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -386,6 +386,114 @@ static void sh_eth_reset_hw_crc(struct net_device *ndev)
+ sh_eth_write(ndev, 0x0, CSMR);
+ }
+
++#elif defined(CONFIG_ARCH_R8A7740)
++#define SH_ETH_HAS_TSU 1
++static void sh_eth_chip_reset(struct net_device *ndev)
++{
++ struct sh_eth_private *mdp = netdev_priv(ndev);
++ unsigned long mii;
++
++ /* reset device */
++ sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR);
++ mdelay(1);
++
++ switch (mdp->phy_interface) {
++ case PHY_INTERFACE_MODE_GMII:
++ mii = 2;
++ break;
++ case PHY_INTERFACE_MODE_MII:
++ mii = 1;
++ break;
++ case PHY_INTERFACE_MODE_RMII:
++ default:
++ mii = 0;
++ break;
++ }
++ sh_eth_write(ndev, mii, RMII_MII);
++}
++
++static void sh_eth_reset(struct net_device *ndev)
++{
++ int cnt = 100;
++
++ sh_eth_write(ndev, EDSR_ENALL, EDSR);
++ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
++ while (cnt > 0) {
++ if (!(sh_eth_read(ndev, EDMR) & 0x3))
++ break;
++ mdelay(1);
++ cnt--;
++ }
++ if (cnt == 0)
++ printk(KERN_ERR "Device reset fail\n");
++
++ /* Table Init */
++ sh_eth_write(ndev, 0x0, TDLAR);
++ sh_eth_write(ndev, 0x0, TDFAR);
++ sh_eth_write(ndev, 0x0, TDFXR);
++ sh_eth_write(ndev, 0x0, TDFFR);
++ sh_eth_write(ndev, 0x0, RDLAR);
++ sh_eth_write(ndev, 0x0, RDFAR);
++ sh_eth_write(ndev, 0x0, RDFXR);
++ sh_eth_write(ndev, 0x0, RDFFR);
++}
++
++static void sh_eth_set_duplex(struct net_device *ndev)
++{
++ struct sh_eth_private *mdp = netdev_priv(ndev);
++
++ if (mdp->duplex) /* Full */
++ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
++ else /* Half */
++ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
++}
++
++static void sh_eth_set_rate(struct net_device *ndev)
++{
++ struct sh_eth_private *mdp = netdev_priv(ndev);
++
++ switch (mdp->speed) {
++ case 10: /* 10BASE */
++ sh_eth_write(ndev, GECMR_10, GECMR);
++ break;
++ case 100:/* 100BASE */
++ sh_eth_write(ndev, GECMR_100, GECMR);
++ break;
++ case 1000: /* 1000BASE */
++ sh_eth_write(ndev, GECMR_1000, GECMR);
++ break;
++ default:
++ break;
++ }
++}
++
++/* R8A7740 */
++static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
++ .chip_reset = sh_eth_chip_reset,
++ .set_duplex = sh_eth_set_duplex,
++ .set_rate = sh_eth_set_rate,
++
++ .ecsr_value = ECSR_ICD | ECSR_MPD,
++ .ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
++ .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
++
++ .tx_check = EESR_TC1 | EESR_FTC,
++ .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \
++ EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \
++ EESR_ECI,
++ .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
++ EESR_TFE,
++
++ .apr = 1,
++ .mpr = 1,
++ .tpauser = 1,
++ .bculr = 1,
++ .hw_swap = 1,
++ .no_trimd = 1,
++ .no_ade = 1,
++ .tsu = 1,
++};
++
+ #elif defined(CONFIG_CPU_SUBTYPE_SH7619)
+ #define SH_ETH_RESET_DEFAULT 1
+ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+@@ -443,7 +551,7 @@ static void sh_eth_reset(struct net_device *ndev)
+ }
+ #endif
+
+-#if defined(CONFIG_CPU_SH4)
++#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
+ static void sh_eth_set_receive_align(struct sk_buff *skb)
+ {
+ int reserve;
+@@ -919,6 +1027,10 @@ static int sh_eth_rx(struct net_device *ndev)
+ desc_status = edmac_to_cpu(mdp, rxdesc->status);
+ pkt_len = rxdesc->frame_length;
+
++#if defined(CONFIG_ARCH_R8A7740)
++ desc_status >>= 16;
++#endif
++
+ if (--boguscnt < 0)
+ break;
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
+index 0fa14afc..57b8e1f 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.h
++++ b/drivers/net/ethernet/renesas/sh_eth.h
+@@ -372,7 +372,7 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
+ };
+
+ /* Driver's parameters */
+-#if defined(CONFIG_CPU_SH4)
++#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
+ #define SH4_SKB_RX_ALIGN 32
+ #else
+ #define SH2_SH3_SKB_RX_ALIGN 2
+@@ -381,7 +381,8 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
+ /*
+ * Register's bits
+ */
+-#if defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763)
++#if defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763) ||\
++ defined(CONFIG_ARCH_R8A7740)
+ /* EDSR */
+ enum EDSR_BIT {
+ EDSR_ENT = 0x01, EDSR_ENR = 0x02,
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0010-net-sh_eth-fix-the-rxdesc-pointer-when-rx-descriptor.patch b/patches.armadillo800/0010-net-sh_eth-fix-the-rxdesc-pointer-when-rx-descriptor.patch
new file mode 100644
index 0000000000000..f06a9706150d8
--- /dev/null
+++ b/patches.armadillo800/0010-net-sh_eth-fix-the-rxdesc-pointer-when-rx-descriptor.patch
@@ -0,0 +1,48 @@
+From 02098572c84a88121b0baeb2b96cea47f17f2e3e Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Mon, 28 May 2012 23:07:55 +0000
+Subject: net: sh_eth: fix the rxdesc pointer when rx descriptor empty happens
+
+When Receive Descriptor Empty happens, rxdesc pointer of the driver
+and actual next descriptor of the controller may be mismatch.
+This patch fixes it.
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 79fba9f51755c704c0a7d7b7f0df10874dc0a744)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index be3c221..667169b 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -1101,8 +1101,12 @@ static int sh_eth_rx(struct net_device *ndev)
+
+ /* Restart Rx engine if stopped. */
+ /* If we don't need to check status, don't. -KDU */
+- if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R))
++ if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) {
++ /* fix the values for the next receiving */
++ mdp->cur_rx = mdp->dirty_rx = (sh_eth_read(ndev, RDFAR) -
++ sh_eth_read(ndev, RDLAR)) >> 4;
+ sh_eth_write(ndev, EDRRR_R, EDRRR);
++ }
+
+ return 0;
+ }
+@@ -1199,8 +1203,6 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
+ /* Receive Descriptor Empty int */
+ ndev->stats.rx_over_errors++;
+
+- if (sh_eth_read(ndev, EDRRR) ^ EDRRR_R)
+- sh_eth_write(ndev, EDRRR_R, EDRRR);
+ if (netif_msg_rx_err(mdp))
+ dev_err(&ndev->dev, "Receive Descriptor Empty\n");
+ }
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0011-net-sh_eth-fix-the-condition-to-fix-the-cur_tx-dirty.patch b/patches.armadillo800/0011-net-sh_eth-fix-the-condition-to-fix-the-cur_tx-dirty.patch
new file mode 100644
index 0000000000000..9d3e463e2e06b
--- /dev/null
+++ b/patches.armadillo800/0011-net-sh_eth-fix-the-condition-to-fix-the-cur_tx-dirty.patch
@@ -0,0 +1,65 @@
+From 1c70638e065f5a6bba99f0e27a3b4a4931c77681 Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Wed, 20 Jun 2012 15:26:34 +0000
+Subject: net: sh_eth: fix the condition to fix the cur_tx/dirty_rx
+
+The following commit couldn't work if the RMCR is not set to 1.
+
+"net: sh_eth: fix the rxdesc pointer when rx descriptor empty happens"
+commit id 79fba9f51755c704c0a7d7b7f0df10874dc0a744
+
+If RMCR is not set, the controller will clear the EDRRR after it received
+a frame. In this case, the driver doesn't need to fix the value of
+cur_rx/dirty_rx. The driver only needs it when the controll detects
+receive descriptors are empty.
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Tested-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit a18e08bdcf845efb7344cea146e683df746bbfb4)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index 667169b..79bf09b 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -1011,7 +1011,7 @@ static int sh_eth_txfree(struct net_device *ndev)
+ }
+
+ /* Packet receive function */
+-static int sh_eth_rx(struct net_device *ndev)
++static int sh_eth_rx(struct net_device *ndev, u32 intr_status)
+ {
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ struct sh_eth_rxdesc *rxdesc;
+@@ -1102,9 +1102,11 @@ static int sh_eth_rx(struct net_device *ndev)
+ /* Restart Rx engine if stopped. */
+ /* If we don't need to check status, don't. -KDU */
+ if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) {
+- /* fix the values for the next receiving */
+- mdp->cur_rx = mdp->dirty_rx = (sh_eth_read(ndev, RDFAR) -
+- sh_eth_read(ndev, RDLAR)) >> 4;
++ /* fix the values for the next receiving if RDE is set */
++ if (intr_status & EESR_RDE)
++ mdp->cur_rx = mdp->dirty_rx =
++ (sh_eth_read(ndev, RDFAR) -
++ sh_eth_read(ndev, RDLAR)) >> 4;
+ sh_eth_write(ndev, EDRRR_R, EDRRR);
+ }
+
+@@ -1273,7 +1275,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
+ EESR_RTSF | /* short frame recv */
+ EESR_PRE | /* PHY-LSI recv error */
+ EESR_CERF)){ /* recv frame CRC error */
+- sh_eth_rx(ndev);
++ sh_eth_rx(ndev, intr_status);
+ }
+
+ /* Tx Check */
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0012-net-sh-eth-Add-support-selecting-MII-function-for-SH.patch b/patches.armadillo800/0012-net-sh-eth-Add-support-selecting-MII-function-for-SH.patch
new file mode 100644
index 0000000000000..66b1134781ac5
--- /dev/null
+++ b/patches.armadillo800/0012-net-sh-eth-Add-support-selecting-MII-function-for-SH.patch
@@ -0,0 +1,196 @@
+From a9d45f3559e2b48428446114ae6817f8a4883de8 Mon Sep 17 00:00:00 2001
+From: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+Date: Mon, 25 Jun 2012 17:34:14 +0000
+Subject: net/sh-eth: Add support selecting MII function for SH7734 and R8A7740
+
+Ethernet IP of SH7734 and R8A7740 has selecting MII register.
+The user needs to change a value according to MII to be used.
+This adds the function to change the value of this register.
+
+Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 5e7a76be0e48217aff6b6f34bdcce4725db999e2)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 108 ++++++++++++++++++++--------------
+ drivers/net/ethernet/renesas/sh_eth.h | 1 +
+ 2 files changed, 66 insertions(+), 43 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index 79bf09b..8d696e0 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -49,6 +49,34 @@
+ NETIF_MSG_RX_ERR| \
+ NETIF_MSG_TX_ERR)
+
++#if defined(CONFIG_CPU_SUBTYPE_SH7734) || \
++ defined(CONFIG_CPU_SUBTYPE_SH7763) || \
++ defined(CONFIG_ARCH_R8A7740)
++static void sh_eth_select_mii(struct net_device *ndev)
++{
++ u32 value = 0x0;
++ struct sh_eth_private *mdp = netdev_priv(ndev);
++
++ switch (mdp->phy_interface) {
++ case PHY_INTERFACE_MODE_GMII:
++ value = 0x2;
++ break;
++ case PHY_INTERFACE_MODE_MII:
++ value = 0x1;
++ break;
++ case PHY_INTERFACE_MODE_RMII:
++ value = 0x0;
++ break;
++ default:
++ pr_warn("PHY interface mode was not setup. Set to MII.\n");
++ value = 0x1;
++ break;
++ }
++
++ sh_eth_write(ndev, value, RMII_MII);
++}
++#endif
++
+ /* There is CPU dependent code */
+ #if defined(CONFIG_CPU_SUBTYPE_SH7724)
+ #define SH_ETH_RESET_DEFAULT 1
+@@ -283,6 +311,7 @@ static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp)
+ #elif defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763)
+ #define SH_ETH_HAS_TSU 1
+ static void sh_eth_reset_hw_crc(struct net_device *ndev);
++
+ static void sh_eth_chip_reset(struct net_device *ndev)
+ {
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+@@ -292,35 +321,6 @@ static void sh_eth_chip_reset(struct net_device *ndev)
+ mdelay(1);
+ }
+
+-static void sh_eth_reset(struct net_device *ndev)
+-{
+- int cnt = 100;
+-
+- sh_eth_write(ndev, EDSR_ENALL, EDSR);
+- sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
+- while (cnt > 0) {
+- if (!(sh_eth_read(ndev, EDMR) & 0x3))
+- break;
+- mdelay(1);
+- cnt--;
+- }
+- if (cnt == 0)
+- printk(KERN_ERR "Device reset fail\n");
+-
+- /* Table Init */
+- sh_eth_write(ndev, 0x0, TDLAR);
+- sh_eth_write(ndev, 0x0, TDFAR);
+- sh_eth_write(ndev, 0x0, TDFXR);
+- sh_eth_write(ndev, 0x0, TDFFR);
+- sh_eth_write(ndev, 0x0, RDLAR);
+- sh_eth_write(ndev, 0x0, RDFAR);
+- sh_eth_write(ndev, 0x0, RDFXR);
+- sh_eth_write(ndev, 0x0, RDFFR);
+-
+- /* Reset HW CRC register */
+- sh_eth_reset_hw_crc(ndev);
+-}
+-
+ static void sh_eth_set_duplex(struct net_device *ndev)
+ {
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+@@ -377,9 +377,43 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+ .tsu = 1,
+ #if defined(CONFIG_CPU_SUBTYPE_SH7734)
+ .hw_crc = 1,
++ .select_mii = 1,
+ #endif
+ };
+
++static void sh_eth_reset(struct net_device *ndev)
++{
++ int cnt = 100;
++
++ sh_eth_write(ndev, EDSR_ENALL, EDSR);
++ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
++ while (cnt > 0) {
++ if (!(sh_eth_read(ndev, EDMR) & 0x3))
++ break;
++ mdelay(1);
++ cnt--;
++ }
++ if (cnt == 0)
++ printk(KERN_ERR "Device reset fail\n");
++
++ /* Table Init */
++ sh_eth_write(ndev, 0x0, TDLAR);
++ sh_eth_write(ndev, 0x0, TDFAR);
++ sh_eth_write(ndev, 0x0, TDFXR);
++ sh_eth_write(ndev, 0x0, TDFFR);
++ sh_eth_write(ndev, 0x0, RDLAR);
++ sh_eth_write(ndev, 0x0, RDFAR);
++ sh_eth_write(ndev, 0x0, RDFXR);
++ sh_eth_write(ndev, 0x0, RDFFR);
++
++ /* Reset HW CRC register */
++ sh_eth_reset_hw_crc(ndev);
++
++ /* Select MII mode */
++ if (sh_eth_my_cpu_data.select_mii)
++ sh_eth_select_mii(ndev);
++}
++
+ static void sh_eth_reset_hw_crc(struct net_device *ndev)
+ {
+ if (sh_eth_my_cpu_data.hw_crc)
+@@ -391,25 +425,12 @@ static void sh_eth_reset_hw_crc(struct net_device *ndev)
+ static void sh_eth_chip_reset(struct net_device *ndev)
+ {
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+- unsigned long mii;
+
+ /* reset device */
+ sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR);
+ mdelay(1);
+
+- switch (mdp->phy_interface) {
+- case PHY_INTERFACE_MODE_GMII:
+- mii = 2;
+- break;
+- case PHY_INTERFACE_MODE_MII:
+- mii = 1;
+- break;
+- case PHY_INTERFACE_MODE_RMII:
+- default:
+- mii = 0;
+- break;
+- }
+- sh_eth_write(ndev, mii, RMII_MII);
++ sh_eth_select_mii(ndev);
+ }
+
+ static void sh_eth_reset(struct net_device *ndev)
+@@ -492,6 +513,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+ .no_trimd = 1,
+ .no_ade = 1,
+ .tsu = 1,
++ .select_mii = 1,
+ };
+
+ #elif defined(CONFIG_CPU_SUBTYPE_SH7619)
+diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
+index 57b8e1f..d6763b1392 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.h
++++ b/drivers/net/ethernet/renesas/sh_eth.h
+@@ -757,6 +757,7 @@ struct sh_eth_cpu_data {
+ unsigned no_trimd:1; /* E-DMAC DO NOT have TRIMD */
+ unsigned no_ade:1; /* E-DMAC DO NOT have ADE bit in EESR */
+ unsigned hw_crc:1; /* E-DMAC have CSMR */
++ unsigned select_mii:1; /* EtherC have RMII_MII (MII select register) */
+ };
+
+ struct sh_eth_private {
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0013-net-sh-eth-Check-return-value-of-sh_eth_reset-when-c.patch b/patches.armadillo800/0013-net-sh-eth-Check-return-value-of-sh_eth_reset-when-c.patch
new file mode 100644
index 0000000000000..1cca1a6b8fa9a
--- /dev/null
+++ b/patches.armadillo800/0013-net-sh-eth-Check-return-value-of-sh_eth_reset-when-c.patch
@@ -0,0 +1,215 @@
+From d9b780ce68b329aa745868803ec0419a3fd6975f Mon Sep 17 00:00:00 2001
+From: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+Date: Mon, 25 Jun 2012 17:35:12 +0000
+Subject: net/sh-eth: Check return value of sh_eth_reset when chip reset fail
+
+The sh_eth_reset function resets chip, but this performs nothing when failed.
+This changes sh_eth_reset return an error, when this failed in reset.
+
+Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 5cee1d37c9f565f1aa515408863dbb13db67dab9)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 88 ++++++++++++++++++++++-------------
+ 1 file changed, 56 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index 8d696e0..326cb91 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -130,6 +130,8 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+ #elif defined(CONFIG_CPU_SUBTYPE_SH7757)
+ #define SH_ETH_HAS_BOTH_MODULES 1
+ #define SH_ETH_HAS_TSU 1
++static int sh_eth_check_reset(struct net_device *ndev);
++
+ static void sh_eth_set_duplex(struct net_device *ndev)
+ {
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+@@ -204,23 +206,19 @@ static void sh_eth_chip_reset_giga(struct net_device *ndev)
+ }
+
+ static int sh_eth_is_gether(struct sh_eth_private *mdp);
+-static void sh_eth_reset(struct net_device *ndev)
++static int sh_eth_reset(struct net_device *ndev)
+ {
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+- int cnt = 100;
++ int ret = 0;
+
+ if (sh_eth_is_gether(mdp)) {
+ sh_eth_write(ndev, 0x03, EDSR);
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER,
+ EDMR);
+- while (cnt > 0) {
+- if (!(sh_eth_read(ndev, EDMR) & 0x3))
+- break;
+- mdelay(1);
+- cnt--;
+- }
+- if (cnt < 0)
+- printk(KERN_ERR "Device reset fail\n");
++
++ ret = sh_eth_check_reset(ndev);
++ if (ret)
++ goto out;
+
+ /* Table Init */
+ sh_eth_write(ndev, 0x0, TDLAR);
+@@ -238,6 +236,9 @@ static void sh_eth_reset(struct net_device *ndev)
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER,
+ EDMR);
+ }
++
++out:
++ return ret;
+ }
+
+ static void sh_eth_set_duplex_giga(struct net_device *ndev)
+@@ -310,6 +311,7 @@ static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp)
+
+ #elif defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763)
+ #define SH_ETH_HAS_TSU 1
++static int sh_eth_check_reset(struct net_device *ndev);
+ static void sh_eth_reset_hw_crc(struct net_device *ndev);
+
+ static void sh_eth_chip_reset(struct net_device *ndev)
+@@ -381,20 +383,16 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+ #endif
+ };
+
+-static void sh_eth_reset(struct net_device *ndev)
++static int sh_eth_reset(struct net_device *ndev)
+ {
+- int cnt = 100;
++ int ret = 0;
+
+ sh_eth_write(ndev, EDSR_ENALL, EDSR);
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
+- while (cnt > 0) {
+- if (!(sh_eth_read(ndev, EDMR) & 0x3))
+- break;
+- mdelay(1);
+- cnt--;
+- }
+- if (cnt == 0)
+- printk(KERN_ERR "Device reset fail\n");
++
++ ret = sh_eth_check_reset(ndev);
++ if (ret)
++ goto out;
+
+ /* Table Init */
+ sh_eth_write(ndev, 0x0, TDLAR);
+@@ -412,6 +410,8 @@ static void sh_eth_reset(struct net_device *ndev)
+ /* Select MII mode */
+ if (sh_eth_my_cpu_data.select_mii)
+ sh_eth_select_mii(ndev);
++out:
++ return ret;
+ }
+
+ static void sh_eth_reset_hw_crc(struct net_device *ndev)
+@@ -422,6 +422,8 @@ static void sh_eth_reset_hw_crc(struct net_device *ndev)
+
+ #elif defined(CONFIG_ARCH_R8A7740)
+ #define SH_ETH_HAS_TSU 1
++static int sh_eth_check_reset(struct net_device *ndev);
++
+ static void sh_eth_chip_reset(struct net_device *ndev)
+ {
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+@@ -433,20 +435,16 @@ static void sh_eth_chip_reset(struct net_device *ndev)
+ sh_eth_select_mii(ndev);
+ }
+
+-static void sh_eth_reset(struct net_device *ndev)
++static int sh_eth_reset(struct net_device *ndev)
+ {
+- int cnt = 100;
++ int ret = 0;
+
+ sh_eth_write(ndev, EDSR_ENALL, EDSR);
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
+- while (cnt > 0) {
+- if (!(sh_eth_read(ndev, EDMR) & 0x3))
+- break;
+- mdelay(1);
+- cnt--;
+- }
+- if (cnt == 0)
+- printk(KERN_ERR "Device reset fail\n");
++
++ ret = sh_eth_check_reset(ndev);
++ if (ret)
++ goto out;
+
+ /* Table Init */
+ sh_eth_write(ndev, 0x0, TDLAR);
+@@ -457,6 +455,9 @@ static void sh_eth_reset(struct net_device *ndev)
+ sh_eth_write(ndev, 0x0, RDFAR);
+ sh_eth_write(ndev, 0x0, RDFXR);
+ sh_eth_write(ndev, 0x0, RDFFR);
++
++out:
++ return ret;
+ }
+
+ static void sh_eth_set_duplex(struct net_device *ndev)
+@@ -565,11 +566,31 @@ static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
+
+ #if defined(SH_ETH_RESET_DEFAULT)
+ /* Chip Reset */
+-static void sh_eth_reset(struct net_device *ndev)
++static int sh_eth_reset(struct net_device *ndev)
+ {
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER, EDMR);
+ mdelay(3);
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER, EDMR);
++
++ return 0;
++}
++#else
++static int sh_eth_check_reset(struct net_device *ndev)
++{
++ int ret = 0;
++ int cnt = 100;
++
++ while (cnt > 0) {
++ if (!(sh_eth_read(ndev, EDMR) & 0x3))
++ break;
++ mdelay(1);
++ cnt--;
++ }
++ if (cnt < 0) {
++ printk(KERN_ERR "Device reset fail\n");
++ ret = -ETIMEDOUT;
++ }
++ return ret;
+ }
+ #endif
+
+@@ -924,7 +945,9 @@ static int sh_eth_dev_init(struct net_device *ndev)
+ u32 val;
+
+ /* Soft Reset */
+- sh_eth_reset(ndev);
++ ret = sh_eth_reset(ndev);
++ if (ret)
++ goto out;
+
+ /* Descriptor format */
+ sh_eth_ring_format(ndev);
+@@ -998,6 +1021,7 @@ static int sh_eth_dev_init(struct net_device *ndev)
+
+ netif_start_queue(ndev);
+
++out:
+ return ret;
+ }
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0014-net-sh_eth-remove-unnecessary-function.patch b/patches.armadillo800/0014-net-sh_eth-remove-unnecessary-function.patch
new file mode 100644
index 0000000000000..029365f01b9be
--- /dev/null
+++ b/patches.armadillo800/0014-net-sh_eth-remove-unnecessary-function.patch
@@ -0,0 +1,94 @@
+From da239ac021220b753bc1f21495ed187275f935aa Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Tue, 26 Jun 2012 19:59:51 +0000
+Subject: net: sh_eth: remove unnecessary function
+
+The sh_eth_timer() called mod_timer() for itself. So, this patch
+removes the function.
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit c26502680e59af556211fc3fd3ae0f2aa5d98440)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 22 ----------------------
+ drivers/net/ethernet/renesas/sh_eth.h | 1 -
+ 2 files changed, 23 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index 326cb91..cf0bc31 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -1339,14 +1339,6 @@ other_irq:
+ return ret;
+ }
+
+-static void sh_eth_timer(unsigned long data)
+-{
+- struct net_device *ndev = (struct net_device *)data;
+- struct sh_eth_private *mdp = netdev_priv(ndev);
+-
+- mod_timer(&mdp->timer, jiffies + (10 * HZ));
+-}
+-
+ /* PHY state control function */
+ static void sh_eth_adjust_link(struct net_device *ndev)
+ {
+@@ -1594,11 +1586,6 @@ static int sh_eth_open(struct net_device *ndev)
+ if (ret)
+ goto out_free_irq;
+
+- /* Set the timer to check for link beat. */
+- init_timer(&mdp->timer);
+- mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */
+- setup_timer(&mdp->timer, sh_eth_timer, (unsigned long)ndev);
+-
+ return ret;
+
+ out_free_irq:
+@@ -1623,9 +1610,6 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
+ /* tx_errors count up */
+ ndev->stats.tx_errors++;
+
+- /* timer off */
+- del_timer_sync(&mdp->timer);
+-
+ /* Free all the skbuffs in the Rx queue. */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ rxdesc = &mdp->rx_ring[i];
+@@ -1643,10 +1627,6 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
+
+ /* device init */
+ sh_eth_dev_init(ndev);
+-
+- /* timer on */
+- mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */
+- add_timer(&mdp->timer);
+ }
+
+ /* Packet transmit function */
+@@ -1719,8 +1699,6 @@ static int sh_eth_close(struct net_device *ndev)
+
+ free_irq(ndev->irq, ndev);
+
+- del_timer_sync(&mdp->timer);
+-
+ /* Free all the skbuffs in the Rx queue. */
+ sh_eth_ring_free(ndev);
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
+index d6763b1392..5af3f2a 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.h
++++ b/drivers/net/ethernet/renesas/sh_eth.h
+@@ -772,7 +772,6 @@ struct sh_eth_private {
+ struct sh_eth_txdesc *tx_ring;
+ struct sk_buff **rx_skbuff;
+ struct sk_buff **tx_skbuff;
+- struct timer_list timer;
+ spinlock_t lock;
+ u32 cur_rx, dirty_rx; /* Producer/consumer ring indices */
+ u32 cur_tx, dirty_tx;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0015-net-sh_eth-remove-unnecessary-members-definitions.patch b/patches.armadillo800/0015-net-sh_eth-remove-unnecessary-members-definitions.patch
new file mode 100644
index 0000000000000..95923c02d6925
--- /dev/null
+++ b/patches.armadillo800/0015-net-sh_eth-remove-unnecessary-members-definitions.patch
@@ -0,0 +1,140 @@
+From c0de8fd97587b151f04aeb92c1946d30e04b3f8a Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Tue, 26 Jun 2012 19:59:58 +0000
+Subject: net: sh_eth: remove unnecessary members/definitions
+
+This patch removes unnecessary members in sh_th_private.
+This patch also removes unnecessary definitions in sh_eth.h
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 2ecbb783c3bf5a63f555c39deef308dcc1902b7f)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 7 +---
+ drivers/net/ethernet/renesas/sh_eth.h | 69 -----------------------------------
+ 2 files changed, 1 insertion(+), 75 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index cf0bc31..43e76d2 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -941,7 +941,6 @@ static int sh_eth_dev_init(struct net_device *ndev)
+ {
+ int ret = 0;
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+- u_int32_t rx_int_var, tx_int_var;
+ u32 val;
+
+ /* Soft Reset */
+@@ -971,9 +970,7 @@ static int sh_eth_dev_init(struct net_device *ndev)
+ /* Frame recv control */
+ sh_eth_write(ndev, mdp->cd->rmcr_value, RMCR);
+
+- rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5;
+- tx_int_var = mdp->tx_int_var = DESC_I_TINT2;
+- sh_eth_write(ndev, rx_int_var | tx_int_var, TRSCER);
++ sh_eth_write(ndev, DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2, TRSCER);
+
+ if (mdp->cd->bculr)
+ sh_eth_write(ndev, 0x800, BCULR); /* Burst sycle set */
+@@ -2336,8 +2333,6 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
+
+ /* debug message level */
+ mdp->msg_enable = SH_ETH_DEF_MSG_ENABLE;
+- mdp->post_rx = POST_RX >> (devno << 1);
+- mdp->post_fw = POST_FW >> (devno << 1);
+
+ /* read and set MAC address */
+ read_mac_address(ndev, pd->mac_addr);
+diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
+index 5af3f2a..37a0702 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.h
++++ b/drivers/net/ethernet/renesas/sh_eth.h
+@@ -585,71 +585,6 @@ enum RPADIR_BIT {
+ /* FDR */
+ #define DEFAULT_FDR_INIT 0x00000707
+
+-enum phy_offsets {
+- PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3,
+- PHY_ANA = 4, PHY_ANL = 5, PHY_ANE = 6,
+- PHY_16 = 16,
+-};
+-
+-/* PHY_CTRL */
+-enum PHY_CTRL_BIT {
+- PHY_C_RESET = 0x8000, PHY_C_LOOPBK = 0x4000, PHY_C_SPEEDSL = 0x2000,
+- PHY_C_ANEGEN = 0x1000, PHY_C_PWRDN = 0x0800, PHY_C_ISO = 0x0400,
+- PHY_C_RANEG = 0x0200, PHY_C_DUPLEX = 0x0100, PHY_C_COLT = 0x0080,
+-};
+-#define DM9161_PHY_C_ANEGEN 0 /* auto nego special */
+-
+-/* PHY_STAT */
+-enum PHY_STAT_BIT {
+- PHY_S_100T4 = 0x8000, PHY_S_100X_F = 0x4000, PHY_S_100X_H = 0x2000,
+- PHY_S_10T_F = 0x1000, PHY_S_10T_H = 0x0800, PHY_S_ANEGC = 0x0020,
+- PHY_S_RFAULT = 0x0010, PHY_S_ANEGA = 0x0008, PHY_S_LINK = 0x0004,
+- PHY_S_JAB = 0x0002, PHY_S_EXTD = 0x0001,
+-};
+-
+-/* PHY_ANA */
+-enum PHY_ANA_BIT {
+- PHY_A_NP = 0x8000, PHY_A_ACK = 0x4000, PHY_A_RF = 0x2000,
+- PHY_A_FCS = 0x0400, PHY_A_T4 = 0x0200, PHY_A_FDX = 0x0100,
+- PHY_A_HDX = 0x0080, PHY_A_10FDX = 0x0040, PHY_A_10HDX = 0x0020,
+- PHY_A_SEL = 0x001e,
+-};
+-/* PHY_ANL */
+-enum PHY_ANL_BIT {
+- PHY_L_NP = 0x8000, PHY_L_ACK = 0x4000, PHY_L_RF = 0x2000,
+- PHY_L_FCS = 0x0400, PHY_L_T4 = 0x0200, PHY_L_FDX = 0x0100,
+- PHY_L_HDX = 0x0080, PHY_L_10FDX = 0x0040, PHY_L_10HDX = 0x0020,
+- PHY_L_SEL = 0x001f,
+-};
+-
+-/* PHY_ANE */
+-enum PHY_ANE_BIT {
+- PHY_E_PDF = 0x0010, PHY_E_LPNPA = 0x0008, PHY_E_NPA = 0x0004,
+- PHY_E_PRX = 0x0002, PHY_E_LPANEGA = 0x0001,
+-};
+-
+-/* DM9161 */
+-enum PHY_16_BIT {
+- PHY_16_BP4B45 = 0x8000, PHY_16_BPSCR = 0x4000, PHY_16_BPALIGN = 0x2000,
+- PHY_16_BP_ADPOK = 0x1000, PHY_16_Repeatmode = 0x0800,
+- PHY_16_TXselect = 0x0400,
+- PHY_16_Rsvd = 0x0200, PHY_16_RMIIEnable = 0x0100,
+- PHY_16_Force100LNK = 0x0080,
+- PHY_16_APDLED_CTL = 0x0040, PHY_16_COLLED_CTL = 0x0020,
+- PHY_16_RPDCTR_EN = 0x0010,
+- PHY_16_ResetStMch = 0x0008, PHY_16_PreamSupr = 0x0004,
+- PHY_16_Sleepmode = 0x0002,
+- PHY_16_RemoteLoopOut = 0x0001,
+-};
+-
+-#define POST_RX 0x08
+-#define POST_FW 0x04
+-#define POST0_RX (POST_RX)
+-#define POST0_FW (POST_FW)
+-#define POST1_RX (POST_RX >> 2)
+-#define POST1_FW (POST_FW >> 2)
+-#define POST_ALL (POST0_RX | POST0_FW | POST1_RX | POST1_FW)
+-
+ /* ARSTR */
+ enum ARSTR_BIT { ARSTR_ARSTR = 0x00000001, };
+
+@@ -786,10 +721,6 @@ struct sh_eth_private {
+ int msg_enable;
+ int speed;
+ int duplex;
+- u32 rx_int_var, tx_int_var; /* interrupt control variables */
+- char post_rx; /* POST receive */
+- char post_fw; /* POST forward */
+- struct net_device_stats tsu_stats; /* TSU forward status */
+ int port; /* for TSU */
+ int vlan_num_ids; /* for VLAN tag filter */
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0016-net-sh_eth-fix-up-the-buffer-pointers.patch b/patches.armadillo800/0016-net-sh_eth-fix-up-the-buffer-pointers.patch
new file mode 100644
index 0000000000000..5e09276e07266
--- /dev/null
+++ b/patches.armadillo800/0016-net-sh_eth-fix-up-the-buffer-pointers.patch
@@ -0,0 +1,94 @@
+From ec575069aff289fc8d05d09b897bb05e55e90adf Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Tue, 26 Jun 2012 20:00:01 +0000
+Subject: net: sh_eth: fix up the buffer pointers
+
+After freeing the buffer, the driver should change the value of
+the pointer to NULL.
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 91c77550000a7d888aaf9f9ac13e3e3485d18560)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 31 ++++++++++++++++++++++++-------
+ 1 file changed, 24 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index 43e76d2..2dd2ff5 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -788,6 +788,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
+ }
+ }
+ kfree(mdp->rx_skbuff);
++ mdp->rx_skbuff = NULL;
+
+ /* Free Tx skb ringbuffer */
+ if (mdp->tx_skbuff) {
+@@ -797,6 +798,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
+ }
+ }
+ kfree(mdp->tx_skbuff);
++ mdp->tx_skbuff = NULL;
+ }
+
+ /* format skb and descriptor buffer */
+@@ -933,10 +935,31 @@ desc_ring_free:
+ skb_ring_free:
+ /* Free Rx and Tx skb ring buffer */
+ sh_eth_ring_free(ndev);
++ mdp->tx_ring = NULL;
++ mdp->rx_ring = NULL;
+
+ return ret;
+ }
+
++static void sh_eth_free_dma_buffer(struct sh_eth_private *mdp)
++{
++ int ringsize;
++
++ if (mdp->rx_ring) {
++ ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
++ dma_free_coherent(NULL, ringsize, mdp->rx_ring,
++ mdp->rx_desc_dma);
++ mdp->rx_ring = NULL;
++ }
++
++ if (mdp->tx_ring) {
++ ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
++ dma_free_coherent(NULL, ringsize, mdp->tx_ring,
++ mdp->tx_desc_dma);
++ mdp->tx_ring = NULL;
++ }
++}
++
+ static int sh_eth_dev_init(struct net_device *ndev)
+ {
+ int ret = 0;
+@@ -1677,7 +1700,6 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ static int sh_eth_close(struct net_device *ndev)
+ {
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+- int ringsize;
+
+ netif_stop_queue(ndev);
+
+@@ -1700,12 +1722,7 @@ static int sh_eth_close(struct net_device *ndev)
+ sh_eth_ring_free(ndev);
+
+ /* free DMA buffer */
+- ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
+- dma_free_coherent(NULL, ringsize, mdp->rx_ring, mdp->rx_desc_dma);
+-
+- /* free DMA buffer */
+- ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
+- dma_free_coherent(NULL, ringsize, mdp->tx_ring, mdp->tx_desc_dma);
++ sh_eth_free_dma_buffer(mdp);
+
+ pm_runtime_put_sync(&mdp->pdev->dev);
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0017-net-sh_eth-add-support-for-set_ringparam-get_ringpar.patch b/patches.armadillo800/0017-net-sh_eth-add-support-for-set_ringparam-get_ringpar.patch
new file mode 100644
index 0000000000000..d1a976c408bd4
--- /dev/null
+++ b/patches.armadillo800/0017-net-sh_eth-add-support-for-set_ringparam-get_ringpar.patch
@@ -0,0 +1,407 @@
+From 53432c5cc072269a7e3ac40d2731da16434a24b2 Mon Sep 17 00:00:00 2001
+From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Date: Tue, 26 Jun 2012 20:00:03 +0000
+Subject: net: sh_eth: add support for set_ringparam/get_ringparam
+
+This patch supports the ethtool's set_ringparam() and get_ringparam().
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 525b8075edda9c2ab4b81e210505bd7487ea6e56)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 139 ++++++++++++++++++++++++++--------
+ drivers/net/ethernet/renesas/sh_eth.h | 6 ++
+ 2 files changed, 112 insertions(+), 33 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index 2dd2ff5..af0b867 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -782,7 +782,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
+
+ /* Free Rx skb ringbuffer */
+ if (mdp->rx_skbuff) {
+- for (i = 0; i < RX_RING_SIZE; i++) {
++ for (i = 0; i < mdp->num_rx_ring; i++) {
+ if (mdp->rx_skbuff[i])
+ dev_kfree_skb(mdp->rx_skbuff[i]);
+ }
+@@ -792,7 +792,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
+
+ /* Free Tx skb ringbuffer */
+ if (mdp->tx_skbuff) {
+- for (i = 0; i < TX_RING_SIZE; i++) {
++ for (i = 0; i < mdp->num_tx_ring; i++) {
+ if (mdp->tx_skbuff[i])
+ dev_kfree_skb(mdp->tx_skbuff[i]);
+ }
+@@ -809,8 +809,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
+ struct sk_buff *skb;
+ struct sh_eth_rxdesc *rxdesc = NULL;
+ struct sh_eth_txdesc *txdesc = NULL;
+- int rx_ringsize = sizeof(*rxdesc) * RX_RING_SIZE;
+- int tx_ringsize = sizeof(*txdesc) * TX_RING_SIZE;
++ int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring;
++ int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring;
+
+ mdp->cur_rx = mdp->cur_tx = 0;
+ mdp->dirty_rx = mdp->dirty_tx = 0;
+@@ -818,7 +818,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
+ memset(mdp->rx_ring, 0, rx_ringsize);
+
+ /* build Rx ring buffer */
+- for (i = 0; i < RX_RING_SIZE; i++) {
++ for (i = 0; i < mdp->num_rx_ring; i++) {
+ /* skb */
+ mdp->rx_skbuff[i] = NULL;
+ skb = netdev_alloc_skb(ndev, mdp->rx_buf_sz);
+@@ -844,7 +844,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
+ }
+ }
+
+- mdp->dirty_rx = (u32) (i - RX_RING_SIZE);
++ mdp->dirty_rx = (u32) (i - mdp->num_rx_ring);
+
+ /* Mark the last entry as wrapping the ring. */
+ rxdesc->status |= cpu_to_edmac(mdp, RD_RDEL);
+@@ -852,7 +852,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
+ memset(mdp->tx_ring, 0, tx_ringsize);
+
+ /* build Tx ring buffer */
+- for (i = 0; i < TX_RING_SIZE; i++) {
++ for (i = 0; i < mdp->num_tx_ring; i++) {
+ mdp->tx_skbuff[i] = NULL;
+ txdesc = &mdp->tx_ring[i];
+ txdesc->status = cpu_to_edmac(mdp, TD_TFP);
+@@ -886,7 +886,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
+ mdp->rx_buf_sz += NET_IP_ALIGN;
+
+ /* Allocate RX and TX skb rings */
+- mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * RX_RING_SIZE,
++ mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * mdp->num_rx_ring,
+ GFP_KERNEL);
+ if (!mdp->rx_skbuff) {
+ dev_err(&ndev->dev, "Cannot allocate Rx skb\n");
+@@ -894,7 +894,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
+ return ret;
+ }
+
+- mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * TX_RING_SIZE,
++ mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * mdp->num_tx_ring,
+ GFP_KERNEL);
+ if (!mdp->tx_skbuff) {
+ dev_err(&ndev->dev, "Cannot allocate Tx skb\n");
+@@ -903,7 +903,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
+ }
+
+ /* Allocate all Rx descriptors. */
+- rx_ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
++ rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
+ mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma,
+ GFP_KERNEL);
+
+@@ -917,7 +917,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
+ mdp->dirty_rx = 0;
+
+ /* Allocate all Tx descriptors. */
+- tx_ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
++ tx_ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
+ mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma,
+ GFP_KERNEL);
+ if (!mdp->tx_ring) {
+@@ -946,21 +946,21 @@ static void sh_eth_free_dma_buffer(struct sh_eth_private *mdp)
+ int ringsize;
+
+ if (mdp->rx_ring) {
+- ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE;
++ ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
+ dma_free_coherent(NULL, ringsize, mdp->rx_ring,
+ mdp->rx_desc_dma);
+ mdp->rx_ring = NULL;
+ }
+
+ if (mdp->tx_ring) {
+- ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
++ ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
+ dma_free_coherent(NULL, ringsize, mdp->tx_ring,
+ mdp->tx_desc_dma);
+ mdp->tx_ring = NULL;
+ }
+ }
+
+-static int sh_eth_dev_init(struct net_device *ndev)
++static int sh_eth_dev_init(struct net_device *ndev, bool start)
+ {
+ int ret = 0;
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+@@ -1008,7 +1008,8 @@ static int sh_eth_dev_init(struct net_device *ndev)
+ RFLR);
+
+ sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR);
+- sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
++ if (start)
++ sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
+
+ /* PAUSE Prohibition */
+ val = (sh_eth_read(ndev, ECMR) & ECMR_DM) |
+@@ -1023,7 +1024,8 @@ static int sh_eth_dev_init(struct net_device *ndev)
+ sh_eth_write(ndev, mdp->cd->ecsr_value, ECSR);
+
+ /* E-MAC Interrupt Enable register */
+- sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR);
++ if (start)
++ sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR);
+
+ /* Set MAC address */
+ update_mac_address(ndev);
+@@ -1036,10 +1038,12 @@ static int sh_eth_dev_init(struct net_device *ndev)
+ if (mdp->cd->tpauser)
+ sh_eth_write(ndev, TPAUSER_UNLIMITED, TPAUSER);
+
+- /* Setting the Rx mode will start the Rx process. */
+- sh_eth_write(ndev, EDRRR_R, EDRRR);
++ if (start) {
++ /* Setting the Rx mode will start the Rx process. */
++ sh_eth_write(ndev, EDRRR_R, EDRRR);
+
+- netif_start_queue(ndev);
++ netif_start_queue(ndev);
++ }
+
+ out:
+ return ret;
+@@ -1054,7 +1058,7 @@ static int sh_eth_txfree(struct net_device *ndev)
+ int entry = 0;
+
+ for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
+- entry = mdp->dirty_tx % TX_RING_SIZE;
++ entry = mdp->dirty_tx % mdp->num_tx_ring;
+ txdesc = &mdp->tx_ring[entry];
+ if (txdesc->status & cpu_to_edmac(mdp, TD_TACT))
+ break;
+@@ -1067,7 +1071,7 @@ static int sh_eth_txfree(struct net_device *ndev)
+ freeNum++;
+ }
+ txdesc->status = cpu_to_edmac(mdp, TD_TFP);
+- if (entry >= TX_RING_SIZE - 1)
++ if (entry >= mdp->num_tx_ring - 1)
+ txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
+
+ ndev->stats.tx_packets++;
+@@ -1082,8 +1086,8 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status)
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ struct sh_eth_rxdesc *rxdesc;
+
+- int entry = mdp->cur_rx % RX_RING_SIZE;
+- int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx;
++ int entry = mdp->cur_rx % mdp->num_rx_ring;
++ int boguscnt = (mdp->dirty_rx + mdp->num_rx_ring) - mdp->cur_rx;
+ struct sk_buff *skb;
+ u16 pkt_len = 0;
+ u32 desc_status;
+@@ -1134,13 +1138,13 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status)
+ ndev->stats.rx_bytes += pkt_len;
+ }
+ rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
+- entry = (++mdp->cur_rx) % RX_RING_SIZE;
++ entry = (++mdp->cur_rx) % mdp->num_rx_ring;
+ rxdesc = &mdp->rx_ring[entry];
+ }
+
+ /* Refill the Rx ring buffers. */
+ for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) {
+- entry = mdp->dirty_rx % RX_RING_SIZE;
++ entry = mdp->dirty_rx % mdp->num_rx_ring;
+ rxdesc = &mdp->rx_ring[entry];
+ /* The size of the buffer is 16 byte boundary. */
+ rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
+@@ -1157,7 +1161,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status)
+ skb_checksum_none_assert(skb);
+ rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
+ }
+- if (entry >= RX_RING_SIZE - 1)
++ if (entry >= mdp->num_rx_ring - 1)
+ rxdesc->status |=
+ cpu_to_edmac(mdp, RD_RACT | RD_RFP | RD_RDEL);
+ else
+@@ -1557,6 +1561,71 @@ static void sh_eth_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
+ }
+ }
+
++static void sh_eth_get_ringparam(struct net_device *ndev,
++ struct ethtool_ringparam *ring)
++{
++ struct sh_eth_private *mdp = netdev_priv(ndev);
++
++ ring->rx_max_pending = RX_RING_MAX;
++ ring->tx_max_pending = TX_RING_MAX;
++ ring->rx_pending = mdp->num_rx_ring;
++ ring->tx_pending = mdp->num_tx_ring;
++}
++
++static int sh_eth_set_ringparam(struct net_device *ndev,
++ struct ethtool_ringparam *ring)
++{
++ struct sh_eth_private *mdp = netdev_priv(ndev);
++ int ret;
++
++ if (ring->tx_pending > TX_RING_MAX ||
++ ring->rx_pending > RX_RING_MAX ||
++ ring->tx_pending < TX_RING_MIN ||
++ ring->rx_pending < RX_RING_MIN)
++ return -EINVAL;
++ if (ring->rx_mini_pending || ring->rx_jumbo_pending)
++ return -EINVAL;
++
++ if (netif_running(ndev)) {
++ netif_tx_disable(ndev);
++ /* Disable interrupts by clearing the interrupt mask. */
++ sh_eth_write(ndev, 0x0000, EESIPR);
++ /* Stop the chip's Tx and Rx processes. */
++ sh_eth_write(ndev, 0, EDTRR);
++ sh_eth_write(ndev, 0, EDRRR);
++ synchronize_irq(ndev->irq);
++ }
++
++ /* Free all the skbuffs in the Rx queue. */
++ sh_eth_ring_free(ndev);
++ /* Free DMA buffer */
++ sh_eth_free_dma_buffer(mdp);
++
++ /* Set new parameters */
++ mdp->num_rx_ring = ring->rx_pending;
++ mdp->num_tx_ring = ring->tx_pending;
++
++ ret = sh_eth_ring_init(ndev);
++ if (ret < 0) {
++ dev_err(&ndev->dev, "%s: sh_eth_ring_init failed.\n", __func__);
++ return ret;
++ }
++ ret = sh_eth_dev_init(ndev, false);
++ if (ret < 0) {
++ dev_err(&ndev->dev, "%s: sh_eth_dev_init failed.\n", __func__);
++ return ret;
++ }
++
++ if (netif_running(ndev)) {
++ sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
++ /* Setting the Rx mode will start the Rx process. */
++ sh_eth_write(ndev, EDRRR_R, EDRRR);
++ netif_wake_queue(ndev);
++ }
++
++ return 0;
++}
++
+ static const struct ethtool_ops sh_eth_ethtool_ops = {
+ .get_settings = sh_eth_get_settings,
+ .set_settings = sh_eth_set_settings,
+@@ -1567,6 +1636,8 @@ static const struct ethtool_ops sh_eth_ethtool_ops = {
+ .get_strings = sh_eth_get_strings,
+ .get_ethtool_stats = sh_eth_get_ethtool_stats,
+ .get_sset_count = sh_eth_get_sset_count,
++ .get_ringparam = sh_eth_get_ringparam,
++ .set_ringparam = sh_eth_set_ringparam,
+ };
+
+ /* network device open function */
+@@ -1597,7 +1668,7 @@ static int sh_eth_open(struct net_device *ndev)
+ goto out_free_irq;
+
+ /* device init */
+- ret = sh_eth_dev_init(ndev);
++ ret = sh_eth_dev_init(ndev, true);
+ if (ret)
+ goto out_free_irq;
+
+@@ -1631,7 +1702,7 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
+ ndev->stats.tx_errors++;
+
+ /* Free all the skbuffs in the Rx queue. */
+- for (i = 0; i < RX_RING_SIZE; i++) {
++ for (i = 0; i < mdp->num_rx_ring; i++) {
+ rxdesc = &mdp->rx_ring[i];
+ rxdesc->status = 0;
+ rxdesc->addr = 0xBADF00D0;
+@@ -1639,14 +1710,14 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
+ dev_kfree_skb(mdp->rx_skbuff[i]);
+ mdp->rx_skbuff[i] = NULL;
+ }
+- for (i = 0; i < TX_RING_SIZE; i++) {
++ for (i = 0; i < mdp->num_tx_ring; i++) {
+ if (mdp->tx_skbuff[i])
+ dev_kfree_skb(mdp->tx_skbuff[i]);
+ mdp->tx_skbuff[i] = NULL;
+ }
+
+ /* device init */
+- sh_eth_dev_init(ndev);
++ sh_eth_dev_init(ndev, true);
+ }
+
+ /* Packet transmit function */
+@@ -1658,7 +1729,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ unsigned long flags;
+
+ spin_lock_irqsave(&mdp->lock, flags);
+- if ((mdp->cur_tx - mdp->dirty_tx) >= (TX_RING_SIZE - 4)) {
++ if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
+ if (!sh_eth_txfree(ndev)) {
+ if (netif_msg_tx_queued(mdp))
+ dev_warn(&ndev->dev, "TxFD exhausted.\n");
+@@ -1669,7 +1740,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ }
+ spin_unlock_irqrestore(&mdp->lock, flags);
+
+- entry = mdp->cur_tx % TX_RING_SIZE;
++ entry = mdp->cur_tx % mdp->num_tx_ring;
+ mdp->tx_skbuff[entry] = skb;
+ txdesc = &mdp->tx_ring[entry];
+ /* soft swap. */
+@@ -1683,7 +1754,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ else
+ txdesc->buffer_length = skb->len;
+
+- if (entry >= TX_RING_SIZE - 1)
++ if (entry >= mdp->num_tx_ring - 1)
+ txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE);
+ else
+ txdesc->status |= cpu_to_edmac(mdp, TD_TACT);
+@@ -2313,6 +2384,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
+ ether_setup(ndev);
+
+ mdp = netdev_priv(ndev);
++ mdp->num_tx_ring = TX_RING_SIZE;
++ mdp->num_rx_ring = RX_RING_SIZE;
+ mdp->addr = ioremap(res->start, resource_size(res));
+ if (mdp->addr == NULL) {
+ ret = -ENOMEM;
+diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
+index 37a0702..bae84fd 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.h
++++ b/drivers/net/ethernet/renesas/sh_eth.h
+@@ -27,6 +27,10 @@
+ #define TX_TIMEOUT (5*HZ)
+ #define TX_RING_SIZE 64 /* Tx ring size */
+ #define RX_RING_SIZE 64 /* Rx ring size */
++#define TX_RING_MIN 64
++#define RX_RING_MIN 64
++#define TX_RING_MAX 1024
++#define RX_RING_MAX 1024
+ #define ETHERSMALL 60
+ #define PKT_BUF_SZ 1538
+ #define SH_ETH_TSU_TIMEOUT_MS 500
+@@ -701,6 +705,8 @@ struct sh_eth_private {
+ const u16 *reg_offset;
+ void __iomem *addr;
+ void __iomem *tsu_addr;
++ u32 num_rx_ring;
++ u32 num_tx_ring;
+ dma_addr_t rx_desc_dma;
+ dma_addr_t tx_desc_dma;
+ struct sh_eth_rxdesc *rx_ring;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0018-net-sh_eth-Add-eth-support-for-R8A7779-device.patch b/patches.armadillo800/0018-net-sh_eth-Add-eth-support-for-R8A7779-device.patch
new file mode 100644
index 0000000000000..91821e19678b7
--- /dev/null
+++ b/patches.armadillo800/0018-net-sh_eth-Add-eth-support-for-R8A7779-device.patch
@@ -0,0 +1,71 @@
+From 404932d6f9282b0b5acf10d854fd65611f884521 Mon Sep 17 00:00:00 2001
+From: Phil Edworthy <PHIL.EDWORTHY@renesas.com>
+Date: Tue, 14 Aug 2012 20:33:29 +0000
+Subject: net: sh_eth: Add eth support for R8A7779 device
+
+Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit d0418bb7123f44b23d69ac349eec7daf9103472f)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/net/ethernet/renesas/Kconfig | 4 ++--
+ drivers/net/ethernet/renesas/sh_eth.c | 11 ++++++++---
+ 2 files changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/renesas/Kconfig b/drivers/net/ethernet/renesas/Kconfig
+index 46df3a0..24c2305 100644
+--- a/drivers/net/ethernet/renesas/Kconfig
++++ b/drivers/net/ethernet/renesas/Kconfig
+@@ -8,7 +8,7 @@ config SH_ETH
+ (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
+ CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
+ CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7734 || \
+- CPU_SUBTYPE_SH7757 || ARCH_R8A7740)
++ CPU_SUBTYPE_SH7757 || ARCH_R8A7740 || ARCH_R8A7779)
+ select CRC32
+ select NET_CORE
+ select MII
+@@ -18,4 +18,4 @@ config SH_ETH
+ Renesas SuperH Ethernet device driver.
+ This driver supporting CPUs are:
+ - SH7619, SH7710, SH7712, SH7724, SH7734, SH7763, SH7757,
+- and R8A7740.
++ R8A7740 and R8A7779.
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index af0b867..bad8f2e 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -78,7 +78,7 @@ static void sh_eth_select_mii(struct net_device *ndev)
+ #endif
+
+ /* There is CPU dependent code */
+-#if defined(CONFIG_CPU_SUBTYPE_SH7724)
++#if defined(CONFIG_CPU_SUBTYPE_SH7724) || defined(CONFIG_ARCH_R8A7779)
+ #define SH_ETH_RESET_DEFAULT 1
+ static void sh_eth_set_duplex(struct net_device *ndev)
+ {
+@@ -93,13 +93,18 @@ static void sh_eth_set_duplex(struct net_device *ndev)
+ static void sh_eth_set_rate(struct net_device *ndev)
+ {
+ struct sh_eth_private *mdp = netdev_priv(ndev);
++ unsigned int bits = ECMR_RTM;
++
++#if defined(CONFIG_ARCH_R8A7779)
++ bits |= ECMR_ELB;
++#endif
+
+ switch (mdp->speed) {
+ case 10: /* 10BASE */
+- sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR);
++ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~bits, ECMR);
+ break;
+ case 100:/* 100BASE */
+- sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR);
++ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | bits, ECMR);
+ break;
+ default:
+ break;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0019-ASoC-add-generic-simple-card-support.patch b/patches.armadillo800/0019-ASoC-add-generic-simple-card-support.patch
new file mode 100644
index 0000000000000..23ec1ddda3048
--- /dev/null
+++ b/patches.armadillo800/0019-ASoC-add-generic-simple-card-support.patch
@@ -0,0 +1,239 @@
+From e824e077a91eecb30f3a4124516811ffc382b5a8 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 8 Apr 2012 21:17:50 -0700
+Subject: ASoC: add generic simple-card support
+
+Current ASoC requires card.c file to each platforms in order to
+specifies its CPU and Codecs pair.
+But the differences between these were only value/strings of setting.
+In order to reduce duplicate driver, this patch adds generic/simple-card.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit f2390880ec0264a0ed26b32c23bc23435b4297da)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/sound/simple_card.h | 38 ++++++++++++++
+ sound/soc/Kconfig | 3 ++
+ sound/soc/Makefile | 1 +
+ sound/soc/generic/Kconfig | 4 ++
+ sound/soc/generic/Makefile | 3 ++
+ sound/soc/generic/simple-card.c | 114 ++++++++++++++++++++++++++++++++++++++++
+ 6 files changed, 163 insertions(+)
+ create mode 100644 include/sound/simple_card.h
+ create mode 100644 sound/soc/generic/Kconfig
+ create mode 100644 sound/soc/generic/Makefile
+ create mode 100644 sound/soc/generic/simple-card.c
+
+diff --git a/include/sound/simple_card.h b/include/sound/simple_card.h
+new file mode 100644
+index 0000000..4b62b8d
+--- /dev/null
++++ b/include/sound/simple_card.h
+@@ -0,0 +1,38 @@
++/*
++ * ASoC simple sound card support
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __SIMPLE_CARD_H
++#define __SIMPLE_CARD_H
++
++#include <sound/soc.h>
++
++struct asoc_simple_dai_init_info {
++ unsigned int fmt;
++ unsigned int cpu_daifmt;
++ unsigned int codec_daifmt;
++ unsigned int sysclk;
++};
++
++struct asoc_simple_card_info {
++ const char *name;
++ const char *card;
++ const char *cpu_dai;
++ const char *codec;
++ const char *platform;
++ const char *codec_dai;
++ struct asoc_simple_dai_init_info *init; /* for snd_link.init */
++
++ /* used in simple-card.c */
++ struct snd_soc_dai_link snd_link;
++ struct snd_soc_card snd_card;
++};
++
++#endif /* __SIMPLE_CARD_H */
+diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
+index 91c9855..38be639 100644
+--- a/sound/soc/Kconfig
++++ b/sound/soc/Kconfig
+@@ -52,5 +52,8 @@ source "sound/soc/txx9/Kconfig"
+ # Supported codecs
+ source "sound/soc/codecs/Kconfig"
+
++# generic frame-work
++source "sound/soc/generic/Kconfig"
++
+ endif # SND_SOC
+
+diff --git a/sound/soc/Makefile b/sound/soc/Makefile
+index 2feaf37..b55db9c 100644
+--- a/sound/soc/Makefile
++++ b/sound/soc/Makefile
+@@ -6,6 +6,7 @@ obj-$(CONFIG_SND_SOC_DMAENGINE_PCM) += snd-soc-dmaengine-pcm.o
+
+ obj-$(CONFIG_SND_SOC) += snd-soc-core.o
+ obj-$(CONFIG_SND_SOC) += codecs/
++obj-$(CONFIG_SND_SOC) += generic/
+ obj-$(CONFIG_SND_SOC) += atmel/
+ obj-$(CONFIG_SND_SOC) += au1x/
+ obj-$(CONFIG_SND_SOC) += blackfin/
+diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig
+new file mode 100644
+index 0000000..610f612
+--- /dev/null
++++ b/sound/soc/generic/Kconfig
+@@ -0,0 +1,4 @@
++config SND_SIMPLE_CARD
++ tristate "ASoC Simple sound card support"
++ help
++ This option enables generic simple sound card support
+diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile
+new file mode 100644
+index 0000000..9c3b246
+--- /dev/null
++++ b/sound/soc/generic/Makefile
+@@ -0,0 +1,3 @@
++snd-soc-simple-card-objs := simple-card.o
++
++obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o
+diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
+new file mode 100644
+index 0000000..b4b4cab
+--- /dev/null
++++ b/sound/soc/generic/simple-card.c
+@@ -0,0 +1,114 @@
++/*
++ * ASoC simple sound card support
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.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/platform_device.h>
++#include <linux/module.h>
++#include <sound/simple_card.h>
++
++#define asoc_simple_get_card_info(p) \
++ container_of(p->dai_link, struct asoc_simple_card_info, snd_link)
++
++static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
++{
++ struct asoc_simple_card_info *cinfo = asoc_simple_get_card_info(rtd);
++ struct asoc_simple_dai_init_info *iinfo = cinfo->init;
++ struct snd_soc_dai *codec = rtd->codec_dai;
++ struct snd_soc_dai *cpu = rtd->cpu_dai;
++ unsigned int cpu_daifmt = iinfo->fmt | iinfo->cpu_daifmt;
++ unsigned int codec_daifmt = iinfo->fmt | iinfo->codec_daifmt;
++ int ret;
++
++ if (codec_daifmt) {
++ ret = snd_soc_dai_set_fmt(codec, codec_daifmt);
++ if (ret < 0)
++ return ret;
++ }
++
++ if (iinfo->sysclk) {
++ ret = snd_soc_dai_set_sysclk(codec, 0, iinfo->sysclk, 0);
++ if (ret < 0)
++ return ret;
++ }
++
++ if (cpu_daifmt) {
++ ret = snd_soc_dai_set_fmt(cpu, cpu_daifmt);
++ if (ret < 0)
++ return ret;
++ }
++
++ return 0;
++}
++
++static int asoc_simple_card_probe(struct platform_device *pdev)
++{
++ struct asoc_simple_card_info *cinfo = pdev->dev.platform_data;
++
++ if (!cinfo) {
++ dev_err(&pdev->dev, "no info for asoc-simple-card\n");
++ return -EINVAL;
++ }
++
++ if (!cinfo->name ||
++ !cinfo->card ||
++ !cinfo->cpu_dai ||
++ !cinfo->codec ||
++ !cinfo->platform ||
++ !cinfo->codec_dai) {
++ dev_err(&pdev->dev, "insufficient asoc_simple_card_info settings\n");
++ return -EINVAL;
++ }
++
++ /*
++ * init snd_soc_dai_link
++ */
++ cinfo->snd_link.name = cinfo->name;
++ cinfo->snd_link.stream_name = cinfo->name;
++ cinfo->snd_link.cpu_dai_name = cinfo->cpu_dai;
++ cinfo->snd_link.platform_name = cinfo->platform;
++ cinfo->snd_link.codec_name = cinfo->codec;
++ cinfo->snd_link.codec_dai_name = cinfo->codec_dai;
++
++ /* enable snd_link.init if cinfo has settings */
++ if (cinfo->init)
++ cinfo->snd_link.init = asoc_simple_card_dai_init;
++
++ /*
++ * init snd_soc_card
++ */
++ cinfo->snd_card.name = cinfo->card;
++ cinfo->snd_card.owner = THIS_MODULE;
++ cinfo->snd_card.dai_link = &cinfo->snd_link;
++ cinfo->snd_card.num_links = 1;
++ cinfo->snd_card.dev = &pdev->dev;
++
++ return snd_soc_register_card(&cinfo->snd_card);
++}
++
++static int asoc_simple_card_remove(struct platform_device *pdev)
++{
++ struct asoc_simple_card_info *cinfo = pdev->dev.platform_data;
++
++ return snd_soc_unregister_card(&cinfo->snd_card);
++}
++
++static struct platform_driver asoc_simple_card = {
++ .driver = {
++ .name = "asoc-simple-card",
++ },
++ .probe = asoc_simple_card_probe,
++ .remove = asoc_simple_card_remove,
++};
++
++module_platform_driver(asoc_simple_card);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("ASoC Simple Sound Card");
++MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0020-ASoC-sh-fsi-use-simple-card-instead-of-fsi-ak4642.patch b/patches.armadillo800/0020-ASoC-sh-fsi-use-simple-card-instead-of-fsi-ak4642.patch
new file mode 100644
index 0000000000000..a6129227a8f34
--- /dev/null
+++ b/patches.armadillo800/0020-ASoC-sh-fsi-use-simple-card-instead-of-fsi-ak4642.patch
@@ -0,0 +1,358 @@
+From 69dbe4e265126dd9dcd679d7f707c73fa86b88ef Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 8 Apr 2012 21:18:28 -0700
+Subject: ASoC: sh: fsi: use simple-card instead of fsi-ak4642
+
+This patch uses simple-card driver instead of fsi-ak4642 on each board.
+To select AK4642 driver, each boards select it on Kconfig.
+
+This patch removes fsi-ak4642 driver which is no longer needed
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit af8a2fe12fae1b59178dc96e396e5665bcbea7da)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/Kconfig | 2 +
+ arch/arm/mach-shmobile/board-ap4evb.c | 15 ++++-
+ arch/arm/mach-shmobile/board-mackerel.c | 15 ++++-
+ arch/sh/boards/Kconfig | 1 +
+ arch/sh/boards/mach-se/7724/setup.c | 15 ++++-
+ include/sound/sh_fsi.h | 12 ----
+ sound/soc/sh/Kconfig | 8 ---
+ sound/soc/sh/Makefile | 2 -
+ sound/soc/sh/fsi-ak4642.c | 108 --------------------------------
+ 9 files changed, 39 insertions(+), 139 deletions(-)
+ delete mode 100644 sound/soc/sh/fsi-ak4642.c
+
+diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
+index 34560ca..2cda0c2 100644
+--- a/arch/arm/mach-shmobile/Kconfig
++++ b/arch/arm/mach-shmobile/Kconfig
+@@ -58,6 +58,7 @@ config MACH_AP4EVB
+ depends on ARCH_SH7372
+ select ARCH_REQUIRE_GPIOLIB
+ select SH_LCD_MIPI_DSI
++ select SND_SOC_AK4642 if SND_SIMPLE_CARD
+
+ choice
+ prompt "AP4EVB LCD panel selection"
+@@ -82,6 +83,7 @@ config MACH_MACKEREL
+ bool "mackerel board"
+ depends on ARCH_SH7372
+ select ARCH_REQUIRE_GPIOLIB
++ select SND_SOC_AK4642 if SND_SIMPLE_CARD
+
+ config MACH_KOTA2
+ bool "KOTA2 board"
+diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
+index b56dde2..b397512 100644
+--- a/arch/arm/mach-shmobile/board-ap4evb.c
++++ b/arch/arm/mach-shmobile/board-ap4evb.c
+@@ -50,6 +50,7 @@
+ #include <media/soc_camera.h>
+
+ #include <sound/sh_fsi.h>
++#include <sound/simple_card.h>
+
+ #include <video/sh_mobile_hdmi.h>
+ #include <video/sh_mobile_lcdc.h>
+@@ -785,17 +786,25 @@ static struct platform_device fsi_device = {
+ },
+ };
+
+-static struct fsi_ak4642_info fsi2_ak4643_info = {
++static struct asoc_simple_dai_init_info fsi2_ak4643_init_info = {
++ .fmt = SND_SOC_DAIFMT_LEFT_J,
++ .codec_daifmt = SND_SOC_DAIFMT_CBM_CFM,
++ .cpu_daifmt = SND_SOC_DAIFMT_CBS_CFS,
++ .sysclk = 11289600,
++};
++
++static struct asoc_simple_card_info fsi2_ak4643_info = {
+ .name = "AK4643",
+ .card = "FSI2A-AK4643",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi2",
+- .id = FSI_PORT_A,
++ .codec_dai = "ak4642-hifi",
++ .init = &fsi2_ak4643_init_info,
+ };
+
+ static struct platform_device fsi_ak4643_device = {
+- .name = "fsi-ak4642-audio",
++ .name = "asoc-simple-card",
+ .dev = {
+ .platform_data = &fsi2_ak4643_info,
+ },
+diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
+index 8c6202b..b63de55 100644
+--- a/arch/arm/mach-shmobile/board-mackerel.c
++++ b/arch/arm/mach-shmobile/board-mackerel.c
+@@ -53,6 +53,7 @@
+ #include <media/soc_camera.h>
+ #include <media/soc_camera_platform.h>
+ #include <sound/sh_fsi.h>
++#include <sound/simple_card.h>
+
+ #include <mach/common.h>
+ #include <mach/irqs.h>
+@@ -941,17 +942,25 @@ static struct platform_device fsi_device = {
+ },
+ };
+
+-static struct fsi_ak4642_info fsi2_ak4643_info = {
++static struct asoc_simple_dai_init_info fsi2_ak4643_init_info = {
++ .fmt = SND_SOC_DAIFMT_LEFT_J,
++ .codec_daifmt = SND_SOC_DAIFMT_CBM_CFM,
++ .cpu_daifmt = SND_SOC_DAIFMT_CBS_CFS,
++ .sysclk = 11289600,
++};
++
++static struct asoc_simple_card_info fsi2_ak4643_info = {
+ .name = "AK4643",
+ .card = "FSI2A-AK4643",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0013",
+ .platform = "sh_fsi2",
+- .id = FSI_PORT_A,
++ .codec_dai = "ak4642-hifi",
++ .init = &fsi2_ak4643_init_info,
+ };
+
+ static struct platform_device fsi_ak4643_device = {
+- .name = "fsi-ak4642-audio",
++ .name = "asoc-simple-card",
+ .dev = {
+ .platform_data = &fsi2_ak4643_info,
+ },
+diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
+index d893411..0da49f3 100644
+--- a/arch/sh/boards/Kconfig
++++ b/arch/sh/boards/Kconfig
+@@ -54,6 +54,7 @@ config SH_7724_SOLUTION_ENGINE
+ select SOLUTION_ENGINE
+ depends on CPU_SUBTYPE_SH7724
+ select ARCH_REQUIRE_GPIOLIB
++ select SND_SOC_AK4642 if SND_SIMPLE_CARD
+ help
+ Select 7724 SolutionEngine if configuring for a Hitachi SH7724
+ evaluation board.
+diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
+index c540b16..5cc5ed4 100644
+--- a/arch/sh/boards/mach-se/7724/setup.c
++++ b/arch/sh/boards/mach-se/7724/setup.c
+@@ -28,6 +28,7 @@
+ #include <video/sh_mobile_lcdc.h>
+ #include <media/sh_mobile_ceu.h>
+ #include <sound/sh_fsi.h>
++#include <sound/simple_card.h>
+ #include <asm/io.h>
+ #include <asm/heartbeat.h>
+ #include <asm/clock.h>
+@@ -304,17 +305,25 @@ static struct platform_device fsi_device = {
+ },
+ };
+
+-static struct fsi_ak4642_info fsi_ak4642_info = {
++static struct asoc_simple_dai_init_info fsi2_ak4642_init_info = {
++ .fmt = SND_SOC_DAIFMT_LEFT_J,
++ .codec_daifmt = SND_SOC_DAIFMT_CBM_CFM,
++ .cpu_daifmt = SND_SOC_DAIFMT_CBS_CFS,
++ .sysclk = 11289600,
++};
++
++static struct asoc_simple_card_info fsi_ak4642_info = {
+ .name = "AK4642",
+ .card = "FSIA-AK4642",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi.0",
+- .id = FSI_PORT_A,
++ .codec_dai = "ak4642-hifi",
++ .init = &fsi2_ak4642_init_info,
+ };
+
+ static struct platform_device fsi_ak4642_device = {
+- .name = "fsi-ak4642-audio",
++ .name = "asoc-simple-card",
+ .dev = {
+ .platform_data = &fsi_ak4642_info,
+ },
+diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h
+index b457e87..956e30e 100644
+--- a/include/sound/sh_fsi.h
++++ b/include/sound/sh_fsi.h
+@@ -84,16 +84,4 @@ struct sh_fsi_platform_info {
+ struct sh_fsi_port_info port_b;
+ };
+
+-/*
+- * for fsi-ak4642
+- */
+-struct fsi_ak4642_info {
+- const char *name;
+- const char *card;
+- const char *cpu_dai;
+- const char *codec;
+- const char *platform;
+- int id;
+-};
+-
+ #endif /* __SOUND_FSI_H */
+diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
+index d8e06a6..c68b90b 100644
+--- a/sound/soc/sh/Kconfig
++++ b/sound/soc/sh/Kconfig
+@@ -46,14 +46,6 @@ config SND_SH7760_AC97
+ This option enables generic sound support for the first
+ AC97 unit of the SH7760.
+
+-config SND_FSI_AK4642
+- tristate "FSI-AK4642 sound support"
+- depends on SND_SOC_SH4_FSI && I2C
+- select SND_SOC_AK4642
+- help
+- This option enables generic sound support for the
+- FSI - AK4642 unit
+-
+ config SND_FSI_DA7210
+ tristate "FSI-DA7210 sound support"
+ depends on SND_SOC_SH4_FSI && I2C
+diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile
+index 94476d4..01808cd 100644
+--- a/sound/soc/sh/Makefile
++++ b/sound/soc/sh/Makefile
+@@ -14,13 +14,11 @@ obj-$(CONFIG_SND_SOC_SH4_SIU) += snd-soc-siu.o
+
+ ## boards
+ snd-soc-sh7760-ac97-objs := sh7760-ac97.o
+-snd-soc-fsi-ak4642-objs := fsi-ak4642.o
+ snd-soc-fsi-da7210-objs := fsi-da7210.o
+ snd-soc-fsi-hdmi-objs := fsi-hdmi.o
+ snd-soc-migor-objs := migor.o
+
+ obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o
+-obj-$(CONFIG_SND_FSI_AK4642) += snd-soc-fsi-ak4642.o
+ obj-$(CONFIG_SND_FSI_DA7210) += snd-soc-fsi-da7210.o
+ obj-$(CONFIG_SND_FSI_HDMI) += snd-soc-fsi-hdmi.o
+ obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o
+diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
+deleted file mode 100644
+index 97f540a..0000000
+--- a/sound/soc/sh/fsi-ak4642.c
++++ /dev/null
+@@ -1,108 +0,0 @@
+-/*
+- * FSI-AK464x sound support for ms7724se
+- *
+- * Copyright (C) 2009 Renesas Solutions Corp.
+- * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+- *
+- * This file is subject to the terms and conditions of the GNU General Public
+- * License. See the file "COPYING" in the main directory of this archive
+- * for more details.
+- */
+-
+-#include <linux/platform_device.h>
+-#include <linux/module.h>
+-#include <sound/sh_fsi.h>
+-
+-struct fsi_ak4642_data {
+- const char *name;
+- const char *card;
+- const char *cpu_dai;
+- const char *codec;
+- const char *platform;
+- int id;
+-};
+-
+-static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
+-{
+- struct snd_soc_dai *codec = rtd->codec_dai;
+- struct snd_soc_dai *cpu = rtd->cpu_dai;
+- int ret;
+-
+- ret = snd_soc_dai_set_fmt(codec, SND_SOC_DAIFMT_LEFT_J |
+- SND_SOC_DAIFMT_CBM_CFM);
+- if (ret < 0)
+- return ret;
+-
+- ret = snd_soc_dai_set_sysclk(codec, 0, 11289600, 0);
+- if (ret < 0)
+- return ret;
+-
+- ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_LEFT_J |
+- SND_SOC_DAIFMT_CBS_CFS);
+-
+- return ret;
+-}
+-
+-static struct snd_soc_dai_link fsi_dai_link = {
+- .codec_dai_name = "ak4642-hifi",
+- .init = fsi_ak4642_dai_init,
+-};
+-
+-static struct snd_soc_card fsi_soc_card = {
+- .owner = THIS_MODULE,
+- .dai_link = &fsi_dai_link,
+- .num_links = 1,
+-};
+-
+-static struct platform_device *fsi_snd_device;
+-
+-static int fsi_ak4642_probe(struct platform_device *pdev)
+-{
+- int ret = -ENOMEM;
+- struct fsi_ak4642_info *pinfo = pdev->dev.platform_data;
+-
+- if (!pinfo) {
+- dev_err(&pdev->dev, "no info for fsi ak4642\n");
+- goto out;
+- }
+-
+- fsi_snd_device = platform_device_alloc("soc-audio", pinfo->id);
+- if (!fsi_snd_device)
+- goto out;
+-
+- fsi_dai_link.name = pinfo->name;
+- fsi_dai_link.stream_name = pinfo->name;
+- fsi_dai_link.cpu_dai_name = pinfo->cpu_dai;
+- fsi_dai_link.platform_name = pinfo->platform;
+- fsi_dai_link.codec_name = pinfo->codec;
+- fsi_soc_card.name = pinfo->card;
+-
+- platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
+- ret = platform_device_add(fsi_snd_device);
+-
+- if (ret)
+- platform_device_put(fsi_snd_device);
+-
+-out:
+- return ret;
+-}
+-
+-static int fsi_ak4642_remove(struct platform_device *pdev)
+-{
+- platform_device_unregister(fsi_snd_device);
+- return 0;
+-}
+-
+-static struct platform_driver fsi_ak4642 = {
+- .driver = {
+- .name = "fsi-ak4642-audio",
+- },
+- .probe = fsi_ak4642_probe,
+- .remove = fsi_ak4642_remove,
+-};
+-
+-module_platform_driver(fsi_ak4642);
+-
+-MODULE_LICENSE("GPL");
+-MODULE_DESCRIPTION("Generic SH4 FSI-AK4642 sound card");
+-MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0021-ASoC-sh-fsi-use-simple-card-instead-of-fsi-hdmi.patch b/patches.armadillo800/0021-ASoC-sh-fsi-use-simple-card-instead-of-fsi-hdmi.patch
new file mode 100644
index 0000000000000..704a5a6ce8e5b
--- /dev/null
+++ b/patches.armadillo800/0021-ASoC-sh-fsi-use-simple-card-instead-of-fsi-hdmi.patch
@@ -0,0 +1,246 @@
+From bd1e0d9b157b61d6a283ab31f175f6bab4277cfe Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 8 Apr 2012 21:18:58 -0700
+Subject: ASoC: sh: fsi: use simple-card instead of fsi-hdmi
+
+This patch uses simple-card driver instead of fsi-hdmi on each board.
+This patch removes fsi-hdmi driver which is no longer needed
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit fa063b48046c1f30cb06898559bb34935ade74e1)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-ap4evb.c | 20 +++++-
+ arch/arm/mach-shmobile/board-mackerel.c | 20 +++++-
+ sound/soc/sh/Kconfig | 7 --
+ sound/soc/sh/Makefile | 2 -
+ sound/soc/sh/fsi-hdmi.c | 118 --------------------------------
+ 5 files changed, 38 insertions(+), 129 deletions(-)
+ delete mode 100644 sound/soc/sh/fsi-hdmi.c
+
+diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
+index b397512..8302265 100644
+--- a/arch/arm/mach-shmobile/board-ap4evb.c
++++ b/arch/arm/mach-shmobile/board-ap4evb.c
+@@ -909,8 +909,26 @@ static struct platform_device lcdc1_device = {
+ },
+ };
+
++static struct asoc_simple_dai_init_info fsi2_hdmi_init_info = {
++ .cpu_daifmt = SND_SOC_DAIFMT_CBM_CFM,
++};
++
++static struct asoc_simple_card_info fsi2_hdmi_info = {
++ .name = "HDMI",
++ .card = "FSI2B-HDMI",
++ .cpu_dai = "fsib-dai",
++ .codec = "sh-mobile-hdmi",
++ .platform = "sh_fsi2",
++ .codec_dai = "sh_mobile_hdmi-hifi",
++ .init = &fsi2_hdmi_init_info,
++};
++
+ static struct platform_device fsi_hdmi_device = {
+- .name = "sh_fsi2_b_hdmi",
++ .name = "asoc-simple-card",
++ .id = 1,
++ .dev = {
++ .platform_data = &fsi2_hdmi_info,
++ },
+ };
+
+ static struct gpio_led ap4evb_leds[] = {
+diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
+index b63de55..fb27bac 100644
+--- a/arch/arm/mach-shmobile/board-mackerel.c
++++ b/arch/arm/mach-shmobile/board-mackerel.c
+@@ -503,8 +503,26 @@ static struct platform_device hdmi_lcdc_device = {
+ },
+ };
+
++static struct asoc_simple_dai_init_info fsi2_hdmi_init_info = {
++ .cpu_daifmt = SND_SOC_DAIFMT_CBM_CFM,
++};
++
++static struct asoc_simple_card_info fsi2_hdmi_info = {
++ .name = "HDMI",
++ .card = "FSI2B-HDMI",
++ .cpu_dai = "fsib-dai",
++ .codec = "sh-mobile-hdmi",
++ .platform = "sh_fsi2",
++ .codec_dai = "sh_mobile_hdmi-hifi",
++ .init = &fsi2_hdmi_init_info,
++};
++
+ static struct platform_device fsi_hdmi_device = {
+- .name = "sh_fsi2_b_hdmi",
++ .name = "asoc-simple-card",
++ .id = 1,
++ .dev = {
++ .platform_data = &fsi2_hdmi_info,
++ },
+ };
+
+ static void __init hdmi_init_pm_clock(void)
+diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
+index c68b90b..9ef49c8 100644
+--- a/sound/soc/sh/Kconfig
++++ b/sound/soc/sh/Kconfig
+@@ -54,13 +54,6 @@ config SND_FSI_DA7210
+ This option enables generic sound support for the
+ FSI - DA7210 unit
+
+-config SND_FSI_HDMI
+- tristate "FSI-HDMI sound support"
+- depends on SND_SOC_SH4_FSI && FB_SH_MOBILE_HDMI
+- help
+- This option enables generic sound support for the
+- FSI - HDMI unit
+-
+ config SND_SIU_MIGOR
+ tristate "SIU sound support on Migo-R"
+ depends on SH_MIGOR
+diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile
+index 01808cd..f37fc3a 100644
+--- a/sound/soc/sh/Makefile
++++ b/sound/soc/sh/Makefile
+@@ -15,10 +15,8 @@ obj-$(CONFIG_SND_SOC_SH4_SIU) += snd-soc-siu.o
+ ## boards
+ snd-soc-sh7760-ac97-objs := sh7760-ac97.o
+ snd-soc-fsi-da7210-objs := fsi-da7210.o
+-snd-soc-fsi-hdmi-objs := fsi-hdmi.o
+ snd-soc-migor-objs := migor.o
+
+ obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o
+ obj-$(CONFIG_SND_FSI_DA7210) += snd-soc-fsi-da7210.o
+-obj-$(CONFIG_SND_FSI_HDMI) += snd-soc-fsi-hdmi.o
+ obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o
+diff --git a/sound/soc/sh/fsi-hdmi.c b/sound/soc/sh/fsi-hdmi.c
+deleted file mode 100644
+index 6e41908..0000000
+--- a/sound/soc/sh/fsi-hdmi.c
++++ /dev/null
+@@ -1,118 +0,0 @@
+-/*
+- * FSI - HDMI sound support
+- *
+- * Copyright (C) 2010 Renesas Solutions Corp.
+- * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+- *
+- * This file is subject to the terms and conditions of the GNU General Public
+- * License. See the file "COPYING" in the main directory of this archive
+- * for more details.
+- */
+-
+-#include <linux/platform_device.h>
+-#include <linux/module.h>
+-#include <sound/sh_fsi.h>
+-
+-struct fsi_hdmi_data {
+- const char *cpu_dai;
+- const char *card;
+- int id;
+-};
+-
+-static int fsi_hdmi_dai_init(struct snd_soc_pcm_runtime *rtd)
+-{
+- struct snd_soc_dai *cpu = rtd->cpu_dai;
+- int ret;
+-
+- ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_CBM_CFM);
+-
+- return ret;
+-}
+-
+-static struct snd_soc_dai_link fsi_dai_link = {
+- .name = "HDMI",
+- .stream_name = "HDMI",
+- .codec_dai_name = "sh_mobile_hdmi-hifi",
+- .platform_name = "sh_fsi2",
+- .codec_name = "sh-mobile-hdmi",
+- .init = fsi_hdmi_dai_init,
+-};
+-
+-static struct snd_soc_card fsi_soc_card = {
+- .owner = THIS_MODULE,
+- .dai_link = &fsi_dai_link,
+- .num_links = 1,
+-};
+-
+-static struct platform_device *fsi_snd_device;
+-
+-static int fsi_hdmi_probe(struct platform_device *pdev)
+-{
+- int ret = -ENOMEM;
+- const struct platform_device_id *id_entry;
+- struct fsi_hdmi_data *pdata;
+-
+- id_entry = pdev->id_entry;
+- if (!id_entry) {
+- dev_err(&pdev->dev, "unknown fsi hdmi\n");
+- return -ENODEV;
+- }
+-
+- pdata = (struct fsi_hdmi_data *)id_entry->driver_data;
+-
+- fsi_snd_device = platform_device_alloc("soc-audio", pdata->id);
+- if (!fsi_snd_device)
+- goto out;
+-
+- fsi_dai_link.cpu_dai_name = pdata->cpu_dai;
+- fsi_soc_card.name = pdata->card;
+-
+- platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
+- ret = platform_device_add(fsi_snd_device);
+-
+- if (ret)
+- platform_device_put(fsi_snd_device);
+-
+-out:
+- return ret;
+-}
+-
+-static int fsi_hdmi_remove(struct platform_device *pdev)
+-{
+- platform_device_unregister(fsi_snd_device);
+- return 0;
+-}
+-
+-static struct fsi_hdmi_data fsi2_a_hdmi = {
+- .cpu_dai = "fsia-dai",
+- .card = "FSI2A-HDMI",
+- .id = FSI_PORT_A,
+-};
+-
+-static struct fsi_hdmi_data fsi2_b_hdmi = {
+- .cpu_dai = "fsib-dai",
+- .card = "FSI2B-HDMI",
+- .id = FSI_PORT_B,
+-};
+-
+-static struct platform_device_id fsi_id_table[] = {
+- /* FSI 2 */
+- { "sh_fsi2_a_hdmi", (kernel_ulong_t)&fsi2_a_hdmi },
+- { "sh_fsi2_b_hdmi", (kernel_ulong_t)&fsi2_b_hdmi },
+- {},
+-};
+-
+-static struct platform_driver fsi_hdmi = {
+- .driver = {
+- .name = "fsi-hdmi-audio",
+- },
+- .probe = fsi_hdmi_probe,
+- .remove = fsi_hdmi_remove,
+- .id_table = fsi_id_table,
+-};
+-
+-module_platform_driver(fsi_hdmi);
+-
+-MODULE_LICENSE("GPL");
+-MODULE_DESCRIPTION("Generic SH4 FSI-HDMI sound card");
+-MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0022-ASoC-sh-fsi-use-simple-card-instead-of-fsi-da7210.patch b/patches.armadillo800/0022-ASoC-sh-fsi-use-simple-card-instead-of-fsi-da7210.patch
new file mode 100644
index 0000000000000..037ab31121ecf
--- /dev/null
+++ b/patches.armadillo800/0022-ASoC-sh-fsi-use-simple-card-instead-of-fsi-da7210.patch
@@ -0,0 +1,210 @@
+From 0baa4d444616c8bd593aaf36ca25639d66da129a Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 8 Apr 2012 21:19:25 -0700
+Subject: ASoC: sh: fsi: use simple-card instead of fsi-da7210
+
+This patch uses simple-card driver instead of fsi-da7210 on each board.
+To select DA7210 driver, each boards select it on Kconfig.
+
+This patch removes fsi-da7210 driver which is no longer needed
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 064bfada66779d95686cacdcbb17551e2c0bf66b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/sh/boards/Kconfig | 1 +
+ arch/sh/boards/mach-ecovec24/setup.c | 26 ++++++++++++
+ sound/soc/sh/Kconfig | 8 ----
+ sound/soc/sh/Makefile | 2 -
+ sound/soc/sh/fsi-da7210.c | 81 ------------------------------------
+ 5 files changed, 27 insertions(+), 91 deletions(-)
+ delete mode 100644 sound/soc/sh/fsi-da7210.c
+
+diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
+index 0da49f3..c0241bd 100644
+--- a/arch/sh/boards/Kconfig
++++ b/arch/sh/boards/Kconfig
+@@ -224,6 +224,7 @@ config SH_ECOVEC
+ bool "EcoVec"
+ depends on CPU_SUBTYPE_SH7724
+ select ARCH_REQUIRE_GPIOLIB
++ select SND_SOC_DA7210 if SND_SIMPLE_CARD
+ help
+ Renesas "R0P7724LC0011/21RL (EcoVec)" support.
+
+diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
+index d12fe9d..299a40a 100644
+--- a/arch/sh/boards/mach-ecovec24/setup.c
++++ b/arch/sh/boards/mach-ecovec24/setup.c
+@@ -32,6 +32,7 @@
+ #include <linux/videodev2.h>
+ #include <video/sh_mobile_lcdc.h>
+ #include <sound/sh_fsi.h>
++#include <sound/simple_card.h>
+ #include <media/sh_mobile_ceu.h>
+ #include <media/soc_camera.h>
+ #include <media/tw9910.h>
+@@ -809,6 +810,30 @@ static struct platform_device fsi_device = {
+ },
+ };
+
++static struct asoc_simple_dai_init_info fsi_da7210_init_info = {
++ .fmt = SND_SOC_DAIFMT_I2S,
++ .codec_daifmt = SND_SOC_DAIFMT_CBM_CFM,
++ .cpu_daifmt = SND_SOC_DAIFMT_CBS_CFS,
++};
++
++static struct asoc_simple_card_info fsi_da7210_info = {
++ .name = "DA7210",
++ .card = "FSIB-DA7210",
++ .cpu_dai = "fsib-dai",
++ .codec = "da7210.0-001a",
++ .platform = "sh_fsi.0",
++ .codec_dai = "da7210-hifi",
++ .init = &fsi_da7210_init_info,
++};
++
++static struct platform_device fsi_da7210_device = {
++ .name = "asoc-simple-card",
++ .dev = {
++ .platform_data = &fsi_da7210_info,
++ },
++};
++
++
+ /* IrDA */
+ static struct resource irda_resources[] = {
+ [0] = {
+@@ -945,6 +970,7 @@ static struct platform_device *ecovec_devices[] __initdata = {
+ &camera_devices[1],
+ &camera_devices[2],
+ &fsi_device,
++ &fsi_da7210_device,
+ &irda_device,
+ &vou_device,
+ #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE)
+diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
+index 9ef49c8..c9fdf63 100644
+--- a/sound/soc/sh/Kconfig
++++ b/sound/soc/sh/Kconfig
+@@ -46,14 +46,6 @@ config SND_SH7760_AC97
+ This option enables generic sound support for the first
+ AC97 unit of the SH7760.
+
+-config SND_FSI_DA7210
+- tristate "FSI-DA7210 sound support"
+- depends on SND_SOC_SH4_FSI && I2C
+- select SND_SOC_DA7210
+- help
+- This option enables generic sound support for the
+- FSI - DA7210 unit
+-
+ config SND_SIU_MIGOR
+ tristate "SIU sound support on Migo-R"
+ depends on SH_MIGOR
+diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile
+index f37fc3a..849b387 100644
+--- a/sound/soc/sh/Makefile
++++ b/sound/soc/sh/Makefile
+@@ -14,9 +14,7 @@ obj-$(CONFIG_SND_SOC_SH4_SIU) += snd-soc-siu.o
+
+ ## boards
+ snd-soc-sh7760-ac97-objs := sh7760-ac97.o
+-snd-soc-fsi-da7210-objs := fsi-da7210.o
+ snd-soc-migor-objs := migor.o
+
+ obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o
+-obj-$(CONFIG_SND_FSI_DA7210) += snd-soc-fsi-da7210.o
+ obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o
+diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
+deleted file mode 100644
+index 1dd3354..0000000
+--- a/sound/soc/sh/fsi-da7210.c
++++ /dev/null
+@@ -1,81 +0,0 @@
+-/*
+- * fsi-da7210.c
+- *
+- * Copyright (C) 2009 Renesas Solutions Corp.
+- * Kuninori Morimoto <morimoto.kuninori@renesas.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.
+- */
+-
+-#include <linux/platform_device.h>
+-#include <linux/module.h>
+-#include <sound/sh_fsi.h>
+-
+-static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd)
+-{
+- struct snd_soc_dai *codec = rtd->codec_dai;
+- struct snd_soc_dai *cpu = rtd->cpu_dai;
+- int ret;
+-
+- ret = snd_soc_dai_set_fmt(codec,
+- SND_SOC_DAIFMT_I2S |
+- SND_SOC_DAIFMT_CBM_CFM);
+- if (ret < 0)
+- return ret;
+-
+- ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_I2S |
+- SND_SOC_DAIFMT_CBS_CFS);
+-
+- return ret;
+-}
+-
+-static struct snd_soc_dai_link fsi_da7210_dai = {
+- .name = "DA7210",
+- .stream_name = "DA7210",
+- .cpu_dai_name = "fsib-dai", /* FSI B */
+- .codec_dai_name = "da7210-hifi",
+- .platform_name = "sh_fsi.0",
+- .codec_name = "da7210-codec.0-001a",
+- .init = fsi_da7210_init,
+-};
+-
+-static struct snd_soc_card fsi_soc_card = {
+- .name = "FSI-DA7210",
+- .owner = THIS_MODULE,
+- .dai_link = &fsi_da7210_dai,
+- .num_links = 1,
+-};
+-
+-static struct platform_device *fsi_da7210_snd_device;
+-
+-static int __init fsi_da7210_sound_init(void)
+-{
+- int ret;
+-
+- fsi_da7210_snd_device = platform_device_alloc("soc-audio", FSI_PORT_B);
+- if (!fsi_da7210_snd_device)
+- return -ENOMEM;
+-
+- platform_set_drvdata(fsi_da7210_snd_device, &fsi_soc_card);
+- ret = platform_device_add(fsi_da7210_snd_device);
+- if (ret)
+- platform_device_put(fsi_da7210_snd_device);
+-
+- return ret;
+-}
+-
+-static void __exit fsi_da7210_sound_exit(void)
+-{
+- platform_device_unregister(fsi_da7210_snd_device);
+-}
+-
+-module_init(fsi_da7210_sound_init);
+-module_exit(fsi_da7210_sound_exit);
+-
+-/* Module information */
+-MODULE_DESCRIPTION("ALSA SoC FSI DA2710");
+-MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
+-MODULE_LICENSE("GPL");
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0023-ASoC-sh-fsi-use-register-field-macro-name-on-IN-OUT_.patch b/patches.armadillo800/0023-ASoC-sh-fsi-use-register-field-macro-name-on-IN-OUT_.patch
new file mode 100644
index 0000000000000..56622e1385d2f
--- /dev/null
+++ b/patches.armadillo800/0023-ASoC-sh-fsi-use-register-field-macro-name-on-IN-OUT_.patch
@@ -0,0 +1,27 @@
+From 09e74410c4effeb137a0aa05425057b740deb997 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 17 May 2012 17:33:49 -0700
+Subject: ASoC: sh: fsi: use register field macro name on IN/OUT_DMAC
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 4d62ec125be98f5a446444e4ce53f4f4e2e1baff)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -1218,8 +1218,8 @@ static int fsi_hw_startup(struct fsi_pri
+ * FSI2 chip can select it.
+ */
+ if (fsi_ver >= 2) {
+- fsi_reg_write(fsi, OUT_DMAC, (1 << 4));
+- fsi_reg_write(fsi, IN_DMAC, (1 << 4));
++ fsi_reg_write(fsi, OUT_DMAC, VDMD_BACK);
++ fsi_reg_write(fsi, IN_DMAC, VDMD_BACK);
+ }
+
+ /* irq clear */
diff --git a/patches.armadillo800/0024-ASoC-sh-fsi-add-fsi_version-and-removed-meaningless-.patch b/patches.armadillo800/0024-ASoC-sh-fsi-add-fsi_version-and-removed-meaningless-.patch
new file mode 100644
index 0000000000000..71fc21e87acee
--- /dev/null
+++ b/patches.armadillo800/0024-ASoC-sh-fsi-add-fsi_version-and-removed-meaningless-.patch
@@ -0,0 +1,105 @@
+From 9bc6d811db2dfc4f27805bc62d39e1bc319653e0 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 17 May 2012 17:34:16 -0700
+Subject: ASoC: sh: fsi: add fsi_version() and removed meaningless version
+ check
+
+This patch adds fsi_version() function for accessing version.
+
+And there were some meaningless version check which never hit.
+This patch removed it.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 284c6f6547dd08d8f26e12f4014ec298faa7da03)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 26 ++++++++------------------
+ 1 file changed, 8 insertions(+), 18 deletions(-)
+
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -322,6 +322,10 @@ static void _fsi_master_mask_set(struct
+ /*
+ * basic function
+ */
++static int fsi_version(struct fsi_master *master)
++{
++ return master->core->ver;
++}
+
+ static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
+ {
+@@ -630,11 +634,6 @@ static void fsi_spdif_clk_ctrl(struct fs
+ struct fsi_master *master = fsi_get_master(fsi);
+ u32 mask, val;
+
+- if (master->core->ver < 2) {
+- pr_err("fsi: register access err (%s)\n", __func__);
+- return;
+- }
+-
+ mask = BP | SE;
+ val = enable ? mask : 0;
+
+@@ -649,9 +648,7 @@ static void fsi_spdif_clk_ctrl(struct fs
+ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
+ long rate, int enable)
+ {
+- struct fsi_master *master = fsi_get_master(fsi);
+ set_rate_func set_rate = fsi_get_info_set_rate(fsi);
+- int fsi_ver = master->core->ver;
+ int ret;
+
+ if (!set_rate)
+@@ -683,10 +680,7 @@ static int fsi_set_master_clk(struct dev
+ data |= (0x3 << 12);
+ break;
+ case SH_FSI_ACKMD_32:
+- if (fsi_ver < 2)
+- dev_err(dev, "unsupported ACKMD\n");
+- else
+- data |= (0x4 << 12);
++ data |= (0x4 << 12);
+ break;
+ }
+
+@@ -709,10 +703,7 @@ static int fsi_set_master_clk(struct dev
+ data |= (0x4 << 8);
+ break;
+ case SH_FSI_BPFMD_16:
+- if (fsi_ver < 2)
+- dev_err(dev, "unsupported ACKMD\n");
+- else
+- data |= (0x7 << 8);
++ data |= (0x7 << 8);
+ break;
+ }
+
+@@ -1178,7 +1169,6 @@ static int fsi_hw_startup(struct fsi_pri
+ struct device *dev)
+ {
+ struct fsi_master *master = fsi_get_master(fsi);
+- int fsi_ver = master->core->ver;
+ u32 flags = fsi_get_info_flags(fsi);
+ u32 data = 0;
+
+@@ -1217,7 +1207,7 @@ static int fsi_hw_startup(struct fsi_pri
+ * FSI driver assumed that data package is in-back.
+ * FSI2 chip can select it.
+ */
+- if (fsi_ver >= 2) {
++ if (fsi_version(master) >= 2) {
+ fsi_reg_write(fsi, OUT_DMAC, VDMD_BACK);
+ fsi_reg_write(fsi, IN_DMAC, VDMD_BACK);
+ }
+@@ -1307,7 +1297,7 @@ static int fsi_set_fmt_spdif(struct fsi_
+ struct fsi_master *master = fsi_get_master(fsi);
+ u32 data = 0;
+
+- if (master->core->ver < 2)
++ if (fsi_version(master) < 2)
+ return -EINVAL;
+
+ data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
diff --git a/patches.armadillo800/0025-ASoC-sh-fsi-use-same-format-for-IN-OUT.patch b/patches.armadillo800/0025-ASoC-sh-fsi-use-same-format-for-IN-OUT.patch
new file mode 100644
index 0000000000000..9d9fe53798c8f
--- /dev/null
+++ b/patches.armadillo800/0025-ASoC-sh-fsi-use-same-format-for-IN-OUT.patch
@@ -0,0 +1,83 @@
+From e41d8c0d85612475f270a3f0318570d4974f148f Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 17 May 2012 17:34:53 -0700
+Subject: ASoC: sh: fsi: use same format for IN/OUT
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 9c59dd342e4dd3c0bab5a9cad1aca7ed9501cbf8)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 22 ++++++----------------
+ 1 file changed, 6 insertions(+), 16 deletions(-)
+
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -212,8 +212,7 @@ struct fsi_priv {
+ struct fsi_stream playback;
+ struct fsi_stream capture;
+
+- u32 do_fmt;
+- u32 di_fmt;
++ u32 fmt;
+
+ int chan_num:16;
+ int clk_master:1;
+@@ -1192,8 +1191,8 @@ static int fsi_hw_startup(struct fsi_pri
+ fsi_reg_write(fsi, CKG2, data);
+
+ /* set format */
+- fsi_reg_write(fsi, DO_FMT, fsi->do_fmt);
+- fsi_reg_write(fsi, DI_FMT, fsi->di_fmt);
++ fsi_reg_write(fsi, DO_FMT, fsi->fmt);
++ fsi_reg_write(fsi, DI_FMT, fsi->fmt);
+
+ /* spdif ? */
+ if (fsi_is_spdif(fsi)) {
+@@ -1271,42 +1270,33 @@ static int fsi_dai_trigger(struct snd_pc
+
+ static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt)
+ {
+- u32 data = 0;
+-
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+- data = CR_I2S;
++ fsi->fmt = CR_I2S;
+ fsi->chan_num = 2;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+- data = CR_PCM;
++ fsi->fmt = CR_PCM;
+ fsi->chan_num = 2;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+- fsi->do_fmt = data;
+- fsi->di_fmt = data;
+-
+ return 0;
+ }
+
+ static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
+ {
+ struct fsi_master *master = fsi_get_master(fsi);
+- u32 data = 0;
+
+ if (fsi_version(master) < 2)
+ return -EINVAL;
+
+- data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
++ fsi->fmt = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
+ fsi->chan_num = 2;
+ fsi->spdif = 1;
+
+- fsi->do_fmt = data;
+- fsi->di_fmt = data;
+-
+ return 0;
+ }
+
diff --git a/patches.armadillo800/0026-ASoC-sh-fsi-call-fsi_hw_startup-shutdown-from-fsi_da.patch b/patches.armadillo800/0026-ASoC-sh-fsi-call-fsi_hw_startup-shutdown-from-fsi_da.patch
new file mode 100644
index 0000000000000..9d371ffffc786
--- /dev/null
+++ b/patches.armadillo800/0026-ASoC-sh-fsi-call-fsi_hw_startup-shutdown-from-fsi_da.patch
@@ -0,0 +1,53 @@
+From 30a251b30f73fdfa25d8e260c389bd688951b010 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 17 May 2012 17:35:34 -0700
+Subject: ASoC: sh: fsi: call fsi_hw_startup/shutdown from fsi_dai_trigger()
+
+fsi_hw_startup/shutdown() needs the setup of bus width,
+but it is impossible to get parameter of snd_pcm_runtime at this timing.
+So, these functions are changed so that be called from fsi_dai_trigger().
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit f33238e96f619d9888713c07dcd92e4518879282)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -1233,7 +1233,9 @@ static int fsi_dai_startup(struct snd_pc
+ {
+ struct fsi_priv *fsi = fsi_get_priv(substream);
+
+- return fsi_hw_startup(fsi, fsi_stream_get(fsi, substream), dai->dev);
++ fsi->rate = 0;
++
++ return 0;
+ }
+
+ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
+@@ -1241,7 +1243,6 @@ static void fsi_dai_shutdown(struct snd_
+ {
+ struct fsi_priv *fsi = fsi_get_priv(substream);
+
+- fsi_hw_shutdown(fsi, dai->dev);
+ fsi->rate = 0;
+ }
+
+@@ -1255,11 +1256,13 @@ static int fsi_dai_trigger(struct snd_pc
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ fsi_stream_init(fsi, io, substream);
++ fsi_hw_startup(fsi, io, dai->dev);
+ ret = fsi_stream_transfer(io);
+ if (0 == ret)
+ fsi_stream_start(fsi, io);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
++ fsi_hw_shutdown(fsi, dai->dev);
+ fsi_stream_stop(fsi, io);
+ fsi_stream_quit(fsi, io);
+ break;
diff --git a/patches.armadillo800/0027-ASoC-sh-fsi-enable-chip-specific-data-transfer-mode.patch b/patches.armadillo800/0027-ASoC-sh-fsi-enable-chip-specific-data-transfer-mode.patch
new file mode 100644
index 0000000000000..278811038c4ae
--- /dev/null
+++ b/patches.armadillo800/0027-ASoC-sh-fsi-enable-chip-specific-data-transfer-mode.patch
@@ -0,0 +1,334 @@
+From 603569524ecf479df58238d5c3556bb0882361b1 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 17 May 2012 17:36:47 -0700
+Subject: ASoC: sh: fsi: enable chip specific data transfer mode
+
+SupherH FSI2 can use special data transfer,
+but it depends on CPU-FSI2 connection style.
+
+We can use 16bit data stream mode if it was valid connection,
+and it is required for 16bit data DMA transfer / SPDIF sound output.
+We can use 24bit data transfer if it was invalid connection.
+
+We can select connection type if CPU is SH7372,
+and it is always valid connection if latest SuperH.
+
+This patch adds new bus_option and fsi_bus_setup()
+for supporting these feature.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 766812e6d5e2e23be1e212cf84902d5e834dd865)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/sound/sh_fsi.h | 6 +
+ sound/soc/sh/fsi.c | 177 +++++++++++++++++++++++++++++++++++++++----------
+ 2 files changed, 148 insertions(+), 35 deletions(-)
+
+--- a/include/sound/sh_fsi.h
++++ b/include/sound/sh_fsi.h
+@@ -21,10 +21,11 @@
+ /*
+ * flags format
+ *
+- * 0x000000BA
++ * 0x00000CBA
+ *
+ * A: inversion
+ * B: format mode
++ * C: chip specific
+ */
+
+ /* A: clock inversion */
+@@ -39,6 +40,9 @@
+ #define SH_FSI_FMT_DAI (0 << 4)
+ #define SH_FSI_FMT_SPDIF (1 << 4)
+
++/* C: chip specific */
++#define SH_FSI_OPTION_MASK 0x00000F00
++#define SH_FSI_ENABLE_STREAM_MODE (1 << 8) /* for 16bit data */
+
+ /*
+ * set_rate return value
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -133,6 +133,25 @@
+ typedef int (*set_rate_func)(struct device *dev, int rate, int enable);
+
+ /*
++ * bus options
++ *
++ * 0x000000BA
++ *
++ * A : sample widtht 16bit setting
++ * B : sample widtht 24bit setting
++ */
++
++#define SHIFT_16DATA 0
++#define SHIFT_24DATA 4
++
++#define PACKAGE_24BITBUS_BACK 0
++#define PACKAGE_24BITBUS_FRONT 1
++#define PACKAGE_16BITBUS_STREAM 2
++
++#define BUSOP_SET(s, a) ((a) << SHIFT_ ## s ## DATA)
++#define BUSOP_GET(s, a) (((a) >> SHIFT_ ## s ## DATA) & 0xF)
++
++/*
+ * FSI driver use below type name for variable
+ *
+ * xxx_num : number of data
+@@ -190,6 +209,11 @@ struct fsi_stream {
+ int oerr_num;
+
+ /*
++ * bus options
++ */
++ u32 bus_option;
++
++ /*
+ * thse are initialized by fsi_handler_init()
+ */
+ struct fsi_stream_handler *handler;
+@@ -499,6 +523,7 @@ static void fsi_stream_init(struct fsi_p
+ io->period_samples = fsi_frame2sample(fsi, runtime->period_size);
+ io->period_pos = 0;
+ io->sample_width = samples_to_bytes(runtime, 1);
++ io->bus_option = 0;
+ io->oerr_num = -1; /* ignore 1st err */
+ io->uerr_num = -1; /* ignore 1st err */
+ fsi_stream_handler_call(io, init, fsi, io);
+@@ -526,6 +551,7 @@ static void fsi_stream_quit(struct fsi_p
+ io->period_samples = 0;
+ io->period_pos = 0;
+ io->sample_width = 0;
++ io->bus_option = 0;
+ io->oerr_num = 0;
+ io->uerr_num = 0;
+ spin_unlock_irqrestore(&master->lock, flags);
+@@ -585,6 +611,53 @@ static int fsi_stream_remove(struct fsi_
+ }
+
+ /*
++ * format/bus/dma setting
++ */
++static void fsi_format_bus_setup(struct fsi_priv *fsi, struct fsi_stream *io,
++ u32 bus, struct device *dev)
++{
++ struct fsi_master *master = fsi_get_master(fsi);
++ int is_play = fsi_stream_is_play(fsi, io);
++ u32 fmt = fsi->fmt;
++
++ if (fsi_version(master) >= 2) {
++ u32 dma = 0;
++
++ /*
++ * FSI2 needs DMA/Bus setting
++ */
++ switch (bus) {
++ case PACKAGE_24BITBUS_FRONT:
++ fmt |= CR_BWS_24;
++ dma |= VDMD_FRONT;
++ dev_dbg(dev, "24bit bus / package in front\n");
++ break;
++ case PACKAGE_16BITBUS_STREAM:
++ fmt |= CR_BWS_16;
++ dma |= VDMD_STREAM;
++ dev_dbg(dev, "16bit bus / stream mode\n");
++ break;
++ case PACKAGE_24BITBUS_BACK:
++ default:
++ fmt |= CR_BWS_24;
++ dma |= VDMD_BACK;
++ dev_dbg(dev, "24bit bus / package in back\n");
++ break;
++ }
++
++ if (is_play)
++ fsi_reg_write(fsi, OUT_DMAC, dma);
++ else
++ fsi_reg_write(fsi, IN_DMAC, dma);
++ }
++
++ if (is_play)
++ fsi_reg_write(fsi, DO_FMT, fmt);
++ else
++ fsi_reg_write(fsi, DI_FMT, fmt);
++}
++
++/*
+ * irq function
+ */
+
+@@ -719,11 +792,26 @@ static int fsi_set_master_clk(struct dev
+ */
+ static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples)
+ {
+- u16 *buf = (u16 *)_buf;
++ u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE;
+ int i;
+
+- for (i = 0; i < samples; i++)
+- fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8));
++ if (enable_stream) {
++ /*
++ * stream mode
++ * see
++ * fsi_pio_push_init()
++ */
++ u32 *buf = (u32 *)_buf;
++
++ for (i = 0; i < samples / 2; i++)
++ fsi_reg_write(fsi, DODT, buf[i]);
++ } else {
++ /* normal mode */
++ u16 *buf = (u16 *)_buf;
++
++ for (i = 0; i < samples; i++)
++ fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8));
++ }
+ }
+
+ static void fsi_pio_pop16(struct fsi_priv *fsi, u8 *_buf, int samples)
+@@ -863,12 +951,44 @@ static void fsi_pio_start_stop(struct fs
+ fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
+ }
+
++static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io)
++{
++ u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE;
++
++ /*
++ * we can use 16bit stream mode
++ * when "playback" and "16bit data"
++ * and platform allows "stream mode"
++ * see
++ * fsi_pio_push16()
++ */
++ if (enable_stream)
++ io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) |
++ BUSOP_SET(16, PACKAGE_16BITBUS_STREAM);
++ else
++ io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) |
++ BUSOP_SET(16, PACKAGE_24BITBUS_BACK);
++ return 0;
++}
++
++static int fsi_pio_pop_init(struct fsi_priv *fsi, struct fsi_stream *io)
++{
++ /*
++ * always 24bit bus, package back when "capture"
++ */
++ io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) |
++ BUSOP_SET(16, PACKAGE_24BITBUS_BACK);
++ return 0;
++}
++
+ static struct fsi_stream_handler fsi_pio_push_handler = {
++ .init = fsi_pio_push_init,
+ .transfer = fsi_pio_push,
+ .start_stop = fsi_pio_start_stop,
+ };
+
+ static struct fsi_stream_handler fsi_pio_pop_handler = {
++ .init = fsi_pio_pop_init,
+ .transfer = fsi_pio_pop,
+ .start_stop = fsi_pio_start_stop,
+ };
+@@ -910,6 +1030,13 @@ static int fsi_dma_init(struct fsi_priv
+ enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
+ DMA_TO_DEVICE : DMA_FROM_DEVICE;
+
++ /*
++ * 24bit data : 24bit bus / package in back
++ * 16bit data : 16bit bus / stream mode
++ */
++ io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) |
++ BUSOP_SET(16, PACKAGE_16BITBUS_STREAM);
++
+ io->dma = dma_map_single(dai->dev, runtime->dma_area,
+ snd_pcm_lib_buffer_bytes(io->substream), dir);
+ return 0;
+@@ -1046,25 +1173,9 @@ static int fsi_dma_transfer(struct fsi_p
+ static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
+ int start)
+ {
+- u32 bws;
+- u32 dma;
++ u32 enable = start ? DMA_ON : 0;
+
+- switch (io->sample_width * start) {
+- case 2:
+- bws = CR_BWS_16;
+- dma = VDMD_STREAM | DMA_ON;
+- break;
+- case 4:
+- bws = CR_BWS_24;
+- dma = VDMD_BACK | DMA_ON;
+- break;
+- default:
+- bws = 0;
+- dma = 0;
+- }
+-
+- fsi_reg_mask_set(fsi, DO_FMT, CR_BWS_MASK, bws);
+- fsi_reg_write(fsi, OUT_DMAC, dma);
++ fsi_reg_mask_set(fsi, OUT_DMAC, DMA_ON, enable);
+ }
+
+ static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io)
+@@ -1167,7 +1278,6 @@ static int fsi_hw_startup(struct fsi_pri
+ struct fsi_stream *io,
+ struct device *dev)
+ {
+- struct fsi_master *master = fsi_get_master(fsi);
+ u32 flags = fsi_get_info_flags(fsi);
+ u32 data = 0;
+
+@@ -1190,10 +1300,6 @@ static int fsi_hw_startup(struct fsi_pri
+
+ fsi_reg_write(fsi, CKG2, data);
+
+- /* set format */
+- fsi_reg_write(fsi, DO_FMT, fsi->fmt);
+- fsi_reg_write(fsi, DI_FMT, fsi->fmt);
+-
+ /* spdif ? */
+ if (fsi_is_spdif(fsi)) {
+ fsi_spdif_clk_ctrl(fsi, 1);
+@@ -1201,15 +1307,18 @@ static int fsi_hw_startup(struct fsi_pri
+ }
+
+ /*
+- * FIXME
+- *
+- * FSI driver assumed that data package is in-back.
+- * FSI2 chip can select it.
++ * get bus settings
+ */
+- if (fsi_version(master) >= 2) {
+- fsi_reg_write(fsi, OUT_DMAC, VDMD_BACK);
+- fsi_reg_write(fsi, IN_DMAC, VDMD_BACK);
++ data = 0;
++ switch (io->sample_width) {
++ case 2:
++ data = BUSOP_GET(16, io->bus_option);
++ break;
++ case 4:
++ data = BUSOP_GET(24, io->bus_option);
++ break;
+ }
++ fsi_format_bus_setup(fsi, io, data, dev);
+
+ /* irq clear */
+ fsi_irq_disable(fsi, io);
+@@ -1296,7 +1405,7 @@ static int fsi_set_fmt_spdif(struct fsi_
+ if (fsi_version(master) < 2)
+ return -EINVAL;
+
+- fsi->fmt = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
++ fsi->fmt = CR_DTMD_SPDIF_PCM | CR_PCM;
+ fsi->chan_num = 2;
+ fsi->spdif = 1;
+
diff --git a/patches.armadillo800/0028-ASoC-fsi-bugfix-enable-master-clock-control-on-DMA-s.patch b/patches.armadillo800/0028-ASoC-fsi-bugfix-enable-master-clock-control-on-DMA-s.patch
new file mode 100644
index 0000000000000..380aeb5460603
--- /dev/null
+++ b/patches.armadillo800/0028-ASoC-fsi-bugfix-enable-master-clock-control-on-DMA-s.patch
@@ -0,0 +1,34 @@
+From 8dedb2aa24856018132764d9c3411c7600087b3e Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 24 May 2012 23:55:11 -0700
+Subject: ASoC: fsi: bugfix: enable master clock control on DMA stream
+
+DMA stream handler didn't care about master clock.
+This patch fixes it up.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit e42bb9bfbb43366cd1899c9564d043c41ebd8852)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -1173,9 +1173,14 @@ static int fsi_dma_transfer(struct fsi_p
+ static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
+ int start)
+ {
++ struct fsi_master *master = fsi_get_master(fsi);
++ u32 clk = fsi_is_port_a(fsi) ? CRA : CRB;
+ u32 enable = start ? DMA_ON : 0;
+
+ fsi_reg_mask_set(fsi, OUT_DMAC, DMA_ON, enable);
++
++ if (fsi_is_clk_master(fsi))
++ fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
+ }
+
+ static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io)
diff --git a/patches.armadillo800/0029-ASoC-fsi-bugfix-correct-dma-area.patch b/patches.armadillo800/0029-ASoC-fsi-bugfix-correct-dma-area.patch
new file mode 100644
index 0000000000000..dcbbc64a78354
--- /dev/null
+++ b/patches.armadillo800/0029-ASoC-fsi-bugfix-correct-dma-area.patch
@@ -0,0 +1,66 @@
+From ce1ff80d007ef6f5c64c65fd0d44b587657ae0c6 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 28 May 2012 23:27:49 -0700
+Subject: ASoC: fsi: bugfix: correct dma area
+
+FSI driver is using dma_sync_single_xxx(),
+but the dma area was not correct.
+This patch fix it up.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 4a1b09b79b07cf70c72a091e8fe0660f68541f30)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -1053,6 +1053,13 @@ static int fsi_dma_quit(struct fsi_priv
+ return 0;
+ }
+
++static dma_addr_t fsi_dma_get_area(struct fsi_stream *io)
++{
++ struct snd_pcm_runtime *runtime = io->substream->runtime;
++
++ return io->dma + samples_to_bytes(runtime, io->buff_sample_pos);
++}
++
+ static void fsi_dma_complete(void *data)
+ {
+ struct fsi_stream *io = (struct fsi_stream *)data;
+@@ -1062,7 +1069,7 @@ static void fsi_dma_complete(void *data)
+ enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
+ DMA_TO_DEVICE : DMA_FROM_DEVICE;
+
+- dma_sync_single_for_cpu(dai->dev, io->dma,
++ dma_sync_single_for_cpu(dai->dev, fsi_dma_get_area(io),
+ samples_to_bytes(runtime, io->period_samples), dir);
+
+ io->buff_sample_pos += io->period_samples;
+@@ -1079,13 +1086,6 @@ static void fsi_dma_complete(void *data)
+ snd_pcm_period_elapsed(io->substream);
+ }
+
+-static dma_addr_t fsi_dma_get_area(struct fsi_stream *io)
+-{
+- struct snd_pcm_runtime *runtime = io->substream->runtime;
+-
+- return io->dma + samples_to_bytes(runtime, io->buff_sample_pos);
+-}
+-
+ static void fsi_dma_do_work(struct work_struct *work)
+ {
+ struct fsi_stream *io = container_of(work, struct fsi_stream, work);
+@@ -1111,7 +1111,7 @@ static void fsi_dma_do_work(struct work_
+ len = samples_to_bytes(runtime, io->period_samples);
+ buf = fsi_dma_get_area(io);
+
+- dma_sync_single_for_device(dai->dev, io->dma, len, dir);
++ dma_sync_single_for_device(dai->dev, buf, len, dir);
+
+ sg_init_table(&sg, 1);
+ sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)),
diff --git a/patches.armadillo800/0030-ASoC-fsi-bugfix-ensure-dma-is-terminated.patch b/patches.armadillo800/0030-ASoC-fsi-bugfix-ensure-dma-is-terminated.patch
new file mode 100644
index 0000000000000..a392175faca90
--- /dev/null
+++ b/patches.armadillo800/0030-ASoC-fsi-bugfix-ensure-dma-is-terminated.patch
@@ -0,0 +1,28 @@
+From d94ab970e6055b3e6f7cab54a405431e47445ae4 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 28 May 2012 23:28:22 -0700
+Subject: ASoC: fsi: bugfix: ensure dma is terminated
+
+FSI DMAEngine has to be stopped certainly at the start/stop time.
+Without this patch, it will include noise on playback.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit fbe42f66c66c279b4ed9b8f515058a09bc731c49)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -1179,6 +1179,8 @@ static void fsi_dma_push_start_stop(stru
+
+ fsi_reg_mask_set(fsi, OUT_DMAC, DMA_ON, enable);
+
++ dmaengine_terminate_all(io->chan);
++
+ if (fsi_is_clk_master(fsi))
+ fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
+ }
diff --git a/patches.armadillo800/0031-ASoC-fsi-use-dmaengine-helper-functions.patch b/patches.armadillo800/0031-ASoC-fsi-use-dmaengine-helper-functions.patch
new file mode 100644
index 0000000000000..8c331203fecaf
--- /dev/null
+++ b/patches.armadillo800/0031-ASoC-fsi-use-dmaengine-helper-functions.patch
@@ -0,0 +1,74 @@
+From 341b5a7a28c7b1404b9875366b2b2c1dabd06ee8 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 28 May 2012 23:29:36 -0700
+Subject: ASoC: fsi: use dmaengine helper functions
+
+This patch used dmaengine helper functions instead of using hand setting.
+And reduced local variables
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 5514efdfe0384576ef38c66b1672b6826696fbf3)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 19 ++++---------------
+ 1 file changed, 4 insertions(+), 15 deletions(-)
+
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -1090,13 +1090,10 @@ static void fsi_dma_do_work(struct work_
+ {
+ struct fsi_stream *io = container_of(work, struct fsi_stream, work);
+ struct fsi_priv *fsi = fsi_stream_to_priv(io);
+- struct dma_chan *chan;
+ struct snd_soc_dai *dai;
+ struct dma_async_tx_descriptor *desc;
+- struct scatterlist sg;
+ struct snd_pcm_runtime *runtime;
+ enum dma_data_direction dir;
+- dma_cookie_t cookie;
+ int is_play = fsi_stream_is_play(fsi, io);
+ int len;
+ dma_addr_t buf;
+@@ -1105,7 +1102,6 @@ static void fsi_dma_do_work(struct work_
+ return;
+
+ dai = fsi_get_dai(io->substream);
+- chan = io->chan;
+ runtime = io->substream->runtime;
+ dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+ len = samples_to_bytes(runtime, io->period_samples);
+@@ -1113,14 +1109,8 @@ static void fsi_dma_do_work(struct work_
+
+ dma_sync_single_for_device(dai->dev, buf, len, dir);
+
+- sg_init_table(&sg, 1);
+- sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)),
+- len , offset_in_page(buf));
+- sg_dma_address(&sg) = buf;
+- sg_dma_len(&sg) = len;
+-
+- desc = dmaengine_prep_slave_sg(chan, &sg, 1, dir,
+- DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
++ desc = dmaengine_prep_slave_single(io->chan, buf, len, dir,
++ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc) {
+ dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n");
+ return;
+@@ -1129,13 +1119,12 @@ static void fsi_dma_do_work(struct work_
+ desc->callback = fsi_dma_complete;
+ desc->callback_param = io;
+
+- cookie = desc->tx_submit(desc);
+- if (cookie < 0) {
++ if (dmaengine_submit(desc) < 0) {
+ dev_err(dai->dev, "tx_submit() fail\n");
+ return;
+ }
+
+- dma_async_issue_pending(chan);
++ dma_async_issue_pending(io->chan);
+
+ /*
+ * FIXME
diff --git a/patches.armadillo800/0032-ASoC-fsi-use-PIO-handler-if-DMA-handler-was-invalid.patch b/patches.armadillo800/0032-ASoC-fsi-use-PIO-handler-if-DMA-handler-was-invalid.patch
new file mode 100644
index 0000000000000..4d8ccec3cbbba
--- /dev/null
+++ b/patches.armadillo800/0032-ASoC-fsi-use-PIO-handler-if-DMA-handler-was-invalid.patch
@@ -0,0 +1,97 @@
+From 2c50008416a53374914d047b290c1f28842ce4b3 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 24 May 2012 23:56:19 -0700
+Subject: ASoC: fsi: use PIO handler if DMA handler was invalid
+
+PIO handler is not good performance, but works on all platform.
+So, switch to PIO handler if DMA handler was invalid case.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit b1226dc59d55ecde7fc9a338d8cb2a313821fac0)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 29 ++++++++++++++++++++---------
+ 1 file changed, 20 insertions(+), 9 deletions(-)
+
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -248,7 +248,7 @@ struct fsi_priv {
+ struct fsi_stream_handler {
+ int (*init)(struct fsi_priv *fsi, struct fsi_stream *io);
+ int (*quit)(struct fsi_priv *fsi, struct fsi_stream *io);
+- int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io);
++ int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev);
+ int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io);
+ int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io);
+ void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io,
+@@ -572,16 +572,16 @@ static int fsi_stream_transfer(struct fs
+ #define fsi_stream_stop(fsi, io)\
+ fsi_stream_handler_call(io, start_stop, fsi, io, 0)
+
+-static int fsi_stream_probe(struct fsi_priv *fsi)
++static int fsi_stream_probe(struct fsi_priv *fsi, struct device *dev)
+ {
+ struct fsi_stream *io;
+ int ret1, ret2;
+
+ io = &fsi->playback;
+- ret1 = fsi_stream_handler_call(io, probe, fsi, io);
++ ret1 = fsi_stream_handler_call(io, probe, fsi, io, dev);
+
+ io = &fsi->capture;
+- ret2 = fsi_stream_handler_call(io, probe, fsi, io);
++ ret2 = fsi_stream_handler_call(io, probe, fsi, io, dev);
+
+ if (ret1 < 0)
+ return ret1;
+@@ -1174,7 +1174,7 @@ static void fsi_dma_push_start_stop(stru
+ fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
+ }
+
+-static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io)
++static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev)
+ {
+ dma_cap_mask_t mask;
+
+@@ -1182,8 +1182,19 @@ static int fsi_dma_probe(struct fsi_priv
+ dma_cap_set(DMA_SLAVE, mask);
+
+ io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave);
+- if (!io->chan)
+- return -EIO;
++ if (!io->chan) {
++
++ /* switch to PIO handler */
++ if (fsi_stream_is_play(fsi, io))
++ fsi->playback.handler = &fsi_pio_push_handler;
++ else
++ fsi->capture.handler = &fsi_pio_pop_handler;
++
++ dev_info(dev, "switch handler (dma => pio)\n");
++
++ /* probe again */
++ return fsi_stream_probe(fsi, dev);
++ }
+
+ INIT_WORK(&io->work, fsi_dma_do_work);
+
+@@ -1673,7 +1684,7 @@ static int fsi_probe(struct platform_dev
+ master->fsia.master = master;
+ master->fsia.info = &info->port_a;
+ fsi_handler_init(&master->fsia);
+- ret = fsi_stream_probe(&master->fsia);
++ ret = fsi_stream_probe(&master->fsia, &pdev->dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "FSIA stream probe failed\n");
+ goto exit_iounmap;
+@@ -1684,7 +1695,7 @@ static int fsi_probe(struct platform_dev
+ master->fsib.master = master;
+ master->fsib.info = &info->port_b;
+ fsi_handler_init(&master->fsib);
+- ret = fsi_stream_probe(&master->fsib);
++ ret = fsi_stream_probe(&master->fsib, &pdev->dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "FSIB stream probe failed\n");
+ goto exit_fsia;
diff --git a/patches.armadillo800/0033-ASoC-fsi-prepare-for-conversion-to-the-shdma-base-li.patch b/patches.armadillo800/0033-ASoC-fsi-prepare-for-conversion-to-the-shdma-base-li.patch
new file mode 100644
index 0000000000000..23f861ebc5a00
--- /dev/null
+++ b/patches.armadillo800/0033-ASoC-fsi-prepare-for-conversion-to-the-shdma-base-li.patch
@@ -0,0 +1,35 @@
+From 223018081111b56755835850e5dbc7a122f5f1b5 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 9 May 2012 17:09:20 +0200
+Subject: ASoC: fsi: prepare for conversion to the shdma base library
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Cc: Liam Girdwood <lrg@ti.com>
+Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit b8373147ed3ca01a968d81f22688f2836a9aeb6b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 53486ff..0540408 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -1631,8 +1631,8 @@ static void fsi_handler_init(struct fsi_priv *fsi)
+ fsi->capture.priv = fsi;
+
+ if (fsi->info->tx_id) {
+- fsi->playback.slave.slave_id = fsi->info->tx_id;
+- fsi->playback.handler = &fsi_dma_push_handler;
++ fsi->playback.slave.shdma_slave.slave_id = fsi->info->tx_id;
++ fsi->playback.handler = &fsi_dma_push_handler;
+ }
+ }
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0034-fbdev-sh_mobile_hdmi-add-hdmi_bit_set-function.patch b/patches.armadillo800/0034-fbdev-sh_mobile_hdmi-add-hdmi_bit_set-function.patch
new file mode 100644
index 0000000000000..9e9dfefc9143c
--- /dev/null
+++ b/patches.armadillo800/0034-fbdev-sh_mobile_hdmi-add-hdmi_bit_set-function.patch
@@ -0,0 +1,86 @@
+From 575ef93e0d64ff352f0bafc5038468b13796104b Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 7 May 2012 21:06:54 -0700
+Subject: fbdev: sh_mobile_hdmi: add hdmi_bit_set() function
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
+(cherry picked from commit 3f521abd6cf1320d65a49cf9fc327b82168b5ba0)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_hdmi.c | 22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
+index eafb19d..e201d6f 100644
+--- a/drivers/video/sh_mobile_hdmi.c
++++ b/drivers/video/sh_mobile_hdmi.c
+@@ -236,6 +236,16 @@ static u8 hdmi_read(struct sh_hdmi *hdmi, u8 reg)
+ return ioread8(hdmi->base + reg);
+ }
+
++static void hdmi_bit_set(struct sh_hdmi *hdmi, u8 mask, u8 data, u8 reg)
++{
++ u8 val = hdmi_read(hdmi, reg);
++
++ val &= ~mask;
++ val |= (data & mask);
++
++ hdmi_write(hdmi, val, reg);
++}
++
+ /*
+ * HDMI sound
+ */
+@@ -693,11 +703,11 @@ static void sh_hdmi_configure(struct sh_hdmi *hdmi)
+ msleep(10);
+
+ /* PS mode b->d, reset PLLA and PLLB */
+- hdmi_write(hdmi, 0x4C, HDMI_SYSTEM_CTRL);
++ hdmi_bit_set(hdmi, 0xFC, 0x4C, HDMI_SYSTEM_CTRL);
+
+ udelay(10);
+
+- hdmi_write(hdmi, 0x40, HDMI_SYSTEM_CTRL);
++ hdmi_bit_set(hdmi, 0xFC, 0x40, HDMI_SYSTEM_CTRL);
+ }
+
+ static unsigned long sh_hdmi_rate_error(struct sh_hdmi *hdmi,
+@@ -917,13 +927,13 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
+ u8 status1, status2, mask1, mask2;
+
+ /* mode_b and PLLA and PLLB reset */
+- hdmi_write(hdmi, 0x2C, HDMI_SYSTEM_CTRL);
++ hdmi_bit_set(hdmi, 0xFC, 0x2C, HDMI_SYSTEM_CTRL);
+
+ /* How long shall reset be held? */
+ udelay(10);
+
+ /* mode_b and PLLA and PLLB reset release */
+- hdmi_write(hdmi, 0x20, HDMI_SYSTEM_CTRL);
++ hdmi_bit_set(hdmi, 0xFC, 0x20, HDMI_SYSTEM_CTRL);
+
+ status1 = hdmi_read(hdmi, HDMI_INTERRUPT_STATUS_1);
+ status2 = hdmi_read(hdmi, HDMI_INTERRUPT_STATUS_2);
+@@ -1001,7 +1011,7 @@ static int sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity)
+ */
+ if (hdmi->hp_state == HDMI_HOTPLUG_EDID_DONE) {
+ /* PS mode d->e. All functions are active */
+- hdmi_write(hdmi, 0x80, HDMI_SYSTEM_CTRL);
++ hdmi_bit_set(hdmi, 0xFC, 0x80, HDMI_SYSTEM_CTRL);
+ dev_dbg(hdmi->dev, "HDMI running\n");
+ }
+
+@@ -1016,7 +1026,7 @@ static void sh_hdmi_display_off(struct sh_mobile_lcdc_entity *entity)
+
+ dev_dbg(hdmi->dev, "%s(%p)\n", __func__, hdmi);
+ /* PS mode e->a */
+- hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL);
++ hdmi_bit_set(hdmi, 0xFC, 0x10, HDMI_SYSTEM_CTRL);
+ }
+
+ static const struct sh_mobile_lcdc_entity_ops sh_hdmi_ops = {
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0035-fbdev-sh_mobile_hdmi-add-interrupt-output-option.patch b/patches.armadillo800/0035-fbdev-sh_mobile_hdmi-add-interrupt-output-option.patch
new file mode 100644
index 0000000000000..e03a1158ef387
--- /dev/null
+++ b/patches.armadillo800/0035-fbdev-sh_mobile_hdmi-add-interrupt-output-option.patch
@@ -0,0 +1,64 @@
+From 1f09b960ec16950e3791ba297de136bedc56be51 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 7 May 2012 21:07:20 -0700
+Subject: fbdev: sh_mobile_hdmi: add interrupt output option
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
+(cherry picked from commit e0defc86423d1b5652826c9317c36dfb6af1cd48)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_hdmi.c | 7 +++++++
+ include/video/sh_mobile_hdmi.h | 8 +++++++-
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
+index e201d6f..0bc39bc 100644
+--- a/drivers/video/sh_mobile_hdmi.c
++++ b/drivers/video/sh_mobile_hdmi.c
+@@ -1186,6 +1186,13 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+
++ /* init interrupt polarity */
++ if (pdata->flags & HDMI_OUTPUT_PUSH_PULL)
++ hdmi_bit_set(hdmi, 0x02, 0x02, HDMI_SYSTEM_CTRL);
++
++ if (pdata->flags & HDMI_OUTPUT_POLARITY_HI)
++ hdmi_bit_set(hdmi, 0x01, 0x01, HDMI_SYSTEM_CTRL);
++
+ /* Product and revision IDs are 0 in sh-mobile version */
+ dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n",
+ hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID));
+diff --git a/include/video/sh_mobile_hdmi.h b/include/video/sh_mobile_hdmi.h
+index 728f9de..2699635 100644
+--- a/include/video/sh_mobile_hdmi.h
++++ b/include/video/sh_mobile_hdmi.h
+@@ -18,9 +18,10 @@ struct clk;
+ /*
+ * flags format
+ *
+- * 0x0000000A
++ * 0x000000BA
+ *
+ * A: Audio source select
++ * B: Int output option
+ */
+
+ /* Audio source select */
+@@ -30,6 +31,11 @@ struct clk;
+ #define HDMI_SND_SRC_DSD (2 << 0)
+ #define HDMI_SND_SRC_HBR (3 << 0)
+
++/* Int output option */
++#define HDMI_OUTPUT_PUSH_PULL (1 << 4) /* System control : output mode */
++#define HDMI_OUTPUT_POLARITY_HI (1 << 5) /* System control : output polarity */
++
++
+ struct sh_mobile_hdmi_info {
+ unsigned int flags;
+ long (*clk_optimize_parent)(unsigned long target, unsigned long *best_freq,
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0036-fbdev-sh_mobile_hdmi-32bit-register-access-support.patch b/patches.armadillo800/0036-fbdev-sh_mobile_hdmi-32bit-register-access-support.patch
new file mode 100644
index 0000000000000..d5517c4fda3d6
--- /dev/null
+++ b/patches.armadillo800/0036-fbdev-sh_mobile_hdmi-32bit-register-access-support.patch
@@ -0,0 +1,115 @@
+From 6fb22732c461a0efc337cc6cd03fda18e0b2d1cf Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 7 May 2012 21:07:49 -0700
+Subject: fbdev: sh_mobile_hdmi: 32bit register access support
+
+Latest SuperH HDMI allows 32bit access only.
+But the data is 8bit. So, we can keep compatibility by switching 8/32 bit access.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
+(cherry picked from commit db6668d83a265a15ffd79dbc8432598808b34bb4)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_hdmi.c | 38 ++++++++++++++++++++++++++++++++++++--
+ include/video/sh_mobile_hdmi.h | 5 ++++-
+ 2 files changed, 40 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
+index 0bc39bc..4d48a80 100644
+--- a/drivers/video/sh_mobile_hdmi.c
++++ b/drivers/video/sh_mobile_hdmi.c
+@@ -222,20 +222,45 @@ struct sh_hdmi {
+ struct delayed_work edid_work;
+ struct fb_videomode mode;
+ struct fb_monspecs monspec;
++
++ /* register access functions */
++ void (*write)(struct sh_hdmi *hdmi, u8 data, u8 reg);
++ u8 (*read)(struct sh_hdmi *hdmi, u8 reg);
+ };
+
+ #define entity_to_sh_hdmi(e) container_of(e, struct sh_hdmi, entity)
+
+-static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
++static void __hdmi_write8(struct sh_hdmi *hdmi, u8 data, u8 reg)
+ {
+ iowrite8(data, hdmi->base + reg);
+ }
+
+-static u8 hdmi_read(struct sh_hdmi *hdmi, u8 reg)
++static u8 __hdmi_read8(struct sh_hdmi *hdmi, u8 reg)
+ {
+ return ioread8(hdmi->base + reg);
+ }
+
++static void __hdmi_write32(struct sh_hdmi *hdmi, u8 data, u8 reg)
++{
++ iowrite32((u32)data, hdmi->base + (reg * 4));
++ udelay(100);
++}
++
++static u8 __hdmi_read32(struct sh_hdmi *hdmi, u8 reg)
++{
++ return (u8)ioread32(hdmi->base + (reg * 4));
++}
++
++static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
++{
++ hdmi->write(hdmi, data, reg);
++}
++
++static u8 hdmi_read(struct sh_hdmi *hdmi, u8 reg)
++{
++ return hdmi->read(hdmi, reg);
++}
++
+ static void hdmi_bit_set(struct sh_hdmi *hdmi, u8 mask, u8 data, u8 reg)
+ {
+ u8 val = hdmi_read(hdmi, reg);
+@@ -1148,6 +1173,15 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
+ goto egetclk;
+ }
+
++ /* select register access functions */
++ if (pdata->flags & HDMI_32BIT_REG) {
++ hdmi->write = __hdmi_write32;
++ hdmi->read = __hdmi_read32;
++ } else {
++ hdmi->write = __hdmi_write8;
++ hdmi->read = __hdmi_read8;
++ }
++
+ /* An arbitrary relaxed pixclock just to get things started: from standard 480p */
+ rate = clk_round_rate(hdmi->hdmi_clk, PICOS2KHZ(37037));
+ if (rate > 0)
+diff --git a/include/video/sh_mobile_hdmi.h b/include/video/sh_mobile_hdmi.h
+index 2699635..ce8a540 100644
+--- a/include/video/sh_mobile_hdmi.h
++++ b/include/video/sh_mobile_hdmi.h
+@@ -18,10 +18,11 @@ struct clk;
+ /*
+ * flags format
+ *
+- * 0x000000BA
++ * 0x00000CBA
+ *
+ * A: Audio source select
+ * B: Int output option
++ * C: Chip specific option
+ */
+
+ /* Audio source select */
+@@ -35,6 +36,8 @@ struct clk;
+ #define HDMI_OUTPUT_PUSH_PULL (1 << 4) /* System control : output mode */
+ #define HDMI_OUTPUT_POLARITY_HI (1 << 5) /* System control : output polarity */
+
++/* Chip specific option */
++#define HDMI_32BIT_REG (1 << 8)
+
+ struct sh_mobile_hdmi_info {
+ unsigned int flags;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0037-fbdev-sh_mobile_hdmi-add-HDMI-Control-Register-suppo.patch b/patches.armadillo800/0037-fbdev-sh_mobile_hdmi-add-HDMI-Control-Register-suppo.patch
new file mode 100644
index 0000000000000..93db80ca9980c
--- /dev/null
+++ b/patches.armadillo800/0037-fbdev-sh_mobile_hdmi-add-HDMI-Control-Register-suppo.patch
@@ -0,0 +1,264 @@
+From ccd4120f4b46b4f6c043108aa6f5bbb8f63f959e Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 7 May 2012 21:08:17 -0700
+Subject: fbdev: sh_mobile_hdmi: add HDMI Control Register support
+
+Latest SuperH HDMI uses not only HDMI Core Register (HTOP0)
+but also HDMI Control Register (HTOP1).
+This patch adds HDMI Control Register support.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
+(cherry picked from commit c932b2731116f99a660817e8fa718c9da0798a9c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_hdmi.c | 152 ++++++++++++++++++++++++++++++++++++++++-
+ include/video/sh_mobile_hdmi.h | 1 +
+ 2 files changed, 152 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
+index 4d48a80..930e550 100644
+--- a/drivers/video/sh_mobile_hdmi.c
++++ b/drivers/video/sh_mobile_hdmi.c
+@@ -31,6 +31,7 @@
+
+ #include "sh_mobile_lcdcfb.h"
+
++/* HDMI Core Control Register (HTOP0) */
+ #define HDMI_SYSTEM_CTRL 0x00 /* System control */
+ #define HDMI_L_R_DATA_SWAP_CTRL_RPKT 0x01 /* L/R data swap control,
+ bits 19..16 of 20-bit N for Audio Clock Regeneration packet */
+@@ -201,6 +202,68 @@
+ #define HDMI_REVISION_ID 0xF1 /* Revision ID */
+ #define HDMI_TEST_MODE 0xFE /* Test mode */
+
++/* HDMI Control Register (HTOP1) */
++#define HDMI_HTOP1_TEST_MODE 0x0000 /* Test mode */
++#define HDMI_HTOP1_VIDEO_INPUT 0x0008 /* VideoInput */
++#define HDMI_HTOP1_CORE_RSTN 0x000C /* CoreResetn */
++#define HDMI_HTOP1_PLLBW 0x0018 /* PLLBW */
++#define HDMI_HTOP1_CLK_TO_PHY 0x001C /* Clk to Phy */
++#define HDMI_HTOP1_VIDEO_INPUT2 0x0020 /* VideoInput2 */
++#define HDMI_HTOP1_TISEMP0_1 0x0024 /* tisemp0-1 */
++#define HDMI_HTOP1_TISEMP2_C 0x0028 /* tisemp2-c */
++#define HDMI_HTOP1_TISIDRV 0x002C /* tisidrv */
++#define HDMI_HTOP1_TISEN 0x0034 /* tisen */
++#define HDMI_HTOP1_TISDREN 0x0038 /* tisdren */
++#define HDMI_HTOP1_CISRANGE 0x003C /* cisrange */
++#define HDMI_HTOP1_ENABLE_SELECTOR 0x0040 /* Enable Selector */
++#define HDMI_HTOP1_MACRO_RESET 0x0044 /* Macro reset */
++#define HDMI_HTOP1_PLL_CALIBRATION 0x0048 /* PLL calibration */
++#define HDMI_HTOP1_RE_CALIBRATION 0x004C /* Re-calibration */
++#define HDMI_HTOP1_CURRENT 0x0050 /* Current */
++#define HDMI_HTOP1_PLL_LOCK_DETECT 0x0054 /* PLL lock detect */
++#define HDMI_HTOP1_PHY_TEST_MODE 0x0058 /* PHY Test Mode */
++#define HDMI_HTOP1_CLK_SET 0x0080 /* Clock Set */
++#define HDMI_HTOP1_DDC_FAIL_SAFE 0x0084 /* DDC fail safe */
++#define HDMI_HTOP1_PRBS 0x0088 /* PRBS */
++#define HDMI_HTOP1_EDID_AINC_CONTROL 0x008C /* EDID ainc Control */
++#define HDMI_HTOP1_HTOP_DCL_MODE 0x00FC /* Deep Coloer Mode */
++#define HDMI_HTOP1_HTOP_DCL_FRC_COEF0 0x0100 /* Deep Color:FRC COEF0 */
++#define HDMI_HTOP1_HTOP_DCL_FRC_COEF1 0x0104 /* Deep Color:FRC COEF1 */
++#define HDMI_HTOP1_HTOP_DCL_FRC_COEF2 0x0108 /* Deep Color:FRC COEF2 */
++#define HDMI_HTOP1_HTOP_DCL_FRC_COEF3 0x010C /* Deep Color:FRC COEF3 */
++#define HDMI_HTOP1_HTOP_DCL_FRC_COEF0_C 0x0110 /* Deep Color:FRC COEF0C */
++#define HDMI_HTOP1_HTOP_DCL_FRC_COEF1_C 0x0114 /* Deep Color:FRC COEF1C */
++#define HDMI_HTOP1_HTOP_DCL_FRC_COEF2_C 0x0118 /* Deep Color:FRC COEF2C */
++#define HDMI_HTOP1_HTOP_DCL_FRC_COEF3_C 0x011C /* Deep Color:FRC COEF3C */
++#define HDMI_HTOP1_HTOP_DCL_FRC_MODE 0x0120 /* Deep Color:FRC Mode */
++#define HDMI_HTOP1_HTOP_DCL_RECT_START1 0x0124 /* Deep Color:Rect Start1 */
++#define HDMI_HTOP1_HTOP_DCL_RECT_SIZE1 0x0128 /* Deep Color:Rect Size1 */
++#define HDMI_HTOP1_HTOP_DCL_RECT_START2 0x012C /* Deep Color:Rect Start2 */
++#define HDMI_HTOP1_HTOP_DCL_RECT_SIZE2 0x0130 /* Deep Color:Rect Size2 */
++#define HDMI_HTOP1_HTOP_DCL_RECT_START3 0x0134 /* Deep Color:Rect Start3 */
++#define HDMI_HTOP1_HTOP_DCL_RECT_SIZE3 0x0138 /* Deep Color:Rect Size3 */
++#define HDMI_HTOP1_HTOP_DCL_RECT_START4 0x013C /* Deep Color:Rect Start4 */
++#define HDMI_HTOP1_HTOP_DCL_RECT_SIZE4 0x0140 /* Deep Color:Rect Size4 */
++#define HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y1_1 0x0144 /* Deep Color:Fil Para Y1_1 */
++#define HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y1_2 0x0148 /* Deep Color:Fil Para Y1_2 */
++#define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB1_1 0x014C /* Deep Color:Fil Para CB1_1 */
++#define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB1_2 0x0150 /* Deep Color:Fil Para CB1_2 */
++#define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR1_1 0x0154 /* Deep Color:Fil Para CR1_1 */
++#define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR1_2 0x0158 /* Deep Color:Fil Para CR1_2 */
++#define HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y2_1 0x015C /* Deep Color:Fil Para Y2_1 */
++#define HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y2_2 0x0160 /* Deep Color:Fil Para Y2_2 */
++#define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB2_1 0x0164 /* Deep Color:Fil Para CB2_1 */
++#define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB2_2 0x0168 /* Deep Color:Fil Para CB2_2 */
++#define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR2_1 0x016C /* Deep Color:Fil Para CR2_1 */
++#define HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR2_2 0x0170 /* Deep Color:Fil Para CR2_2 */
++#define HDMI_HTOP1_HTOP_DCL_COR_PARA_Y1 0x0174 /* Deep Color:Cor Para Y1 */
++#define HDMI_HTOP1_HTOP_DCL_COR_PARA_CB1 0x0178 /* Deep Color:Cor Para CB1 */
++#define HDMI_HTOP1_HTOP_DCL_COR_PARA_CR1 0x017C /* Deep Color:Cor Para CR1 */
++#define HDMI_HTOP1_HTOP_DCL_COR_PARA_Y2 0x0180 /* Deep Color:Cor Para Y2 */
++#define HDMI_HTOP1_HTOP_DCL_COR_PARA_CB2 0x0184 /* Deep Color:Cor Para CB2 */
++#define HDMI_HTOP1_HTOP_DCL_COR_PARA_CR2 0x0188 /* Deep Color:Cor Para CR2 */
++#define HDMI_HTOP1_EDID_DATA_READ 0x0200 /* EDID Data Read 128Byte:0x03FC */
++
+ enum hotplug_state {
+ HDMI_HOTPLUG_DISCONNECTED,
+ HDMI_HOTPLUG_CONNECTED,
+@@ -211,6 +274,7 @@ struct sh_hdmi {
+ struct sh_mobile_lcdc_entity entity;
+
+ void __iomem *base;
++ void __iomem *htop1;
+ enum hotplug_state hp_state; /* hot-plug status */
+ u8 preprogrammed_vic; /* use a pre-programmed VIC or
+ the external mode */
+@@ -271,6 +335,17 @@ static void hdmi_bit_set(struct sh_hdmi *hdmi, u8 mask, u8 data, u8 reg)
+ hdmi_write(hdmi, val, reg);
+ }
+
++static void hdmi_htop1_write(struct sh_hdmi *hdmi, u32 data, u32 reg)
++{
++ iowrite32(data, hdmi->htop1 + reg);
++ udelay(100);
++}
++
++static u32 hdmi_htop1_read(struct sh_hdmi *hdmi, u32 reg)
++{
++ return ioread32(hdmi->htop1 + reg);
++}
++
+ /*
+ * HDMI sound
+ */
+@@ -781,7 +856,9 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
+ /* Read EDID */
+ dev_dbg(hdmi->dev, "Read back EDID code:");
+ for (i = 0; i < 128; i++) {
+- edid[i] = hdmi_read(hdmi, HDMI_EDID_KSV_FIFO_ACCESS_WINDOW);
++ edid[i] = (hdmi->htop1) ?
++ (u8)hdmi_htop1_read(hdmi, HDMI_HTOP1_EDID_DATA_READ + (i * 4)) :
++ hdmi_read(hdmi, HDMI_EDID_KSV_FIFO_ACCESS_WINDOW);
+ #ifdef DEBUG
+ if ((i % 16) == 0) {
+ printk(KERN_CONT "\n");
+@@ -1145,10 +1222,58 @@ out:
+ dev_dbg(hdmi->dev, "%s(%p): end\n", __func__, hdmi);
+ }
+
++static void sh_hdmi_htop1_init(struct sh_hdmi *hdmi)
++{
++ hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_HTOP_DCL_MODE);
++ hdmi_htop1_write(hdmi, 0x0000000b, 0x0010);
++ hdmi_htop1_write(hdmi, 0x00006710, HDMI_HTOP1_HTOP_DCL_FRC_MODE);
++ hdmi_htop1_write(hdmi, 0x01020406, HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y1_1);
++ hdmi_htop1_write(hdmi, 0x07080806, HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y1_2);
++ hdmi_htop1_write(hdmi, 0x01020406, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB1_1);
++ hdmi_htop1_write(hdmi, 0x07080806, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB1_2);
++ hdmi_htop1_write(hdmi, 0x01020406, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR1_1);
++ hdmi_htop1_write(hdmi, 0x07080806, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR1_2);
++ hdmi_htop1_write(hdmi, 0x01020406, HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y2_1);
++ hdmi_htop1_write(hdmi, 0x07080806, HDMI_HTOP1_HTOP_DCL_FIL_PARA_Y2_2);
++ hdmi_htop1_write(hdmi, 0x01020406, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB2_1);
++ hdmi_htop1_write(hdmi, 0x07080806, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CB2_2);
++ hdmi_htop1_write(hdmi, 0x01020406, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR2_1);
++ hdmi_htop1_write(hdmi, 0x07080806, HDMI_HTOP1_HTOP_DCL_FIL_PARA_CR2_2);
++ hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_HTOP_DCL_COR_PARA_Y1);
++ hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_HTOP_DCL_COR_PARA_CB1);
++ hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_HTOP_DCL_COR_PARA_CR1);
++ hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_HTOP_DCL_COR_PARA_Y2);
++ hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_HTOP_DCL_COR_PARA_CB2);
++ hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_HTOP_DCL_COR_PARA_CR2);
++ hdmi_htop1_write(hdmi, 0x00000008, HDMI_HTOP1_CURRENT);
++ hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_TISEMP0_1);
++ hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_TISEMP2_C);
++ hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_PHY_TEST_MODE);
++ hdmi_htop1_write(hdmi, 0x00000081, HDMI_HTOP1_TISIDRV);
++ hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_PLLBW);
++ hdmi_htop1_write(hdmi, 0x0000000f, HDMI_HTOP1_TISEN);
++ hdmi_htop1_write(hdmi, 0x0000000f, HDMI_HTOP1_TISDREN);
++ hdmi_htop1_write(hdmi, 0x00000003, HDMI_HTOP1_ENABLE_SELECTOR);
++ hdmi_htop1_write(hdmi, 0x00000001, HDMI_HTOP1_MACRO_RESET);
++ hdmi_htop1_write(hdmi, 0x00000016, HDMI_HTOP1_CISRANGE);
++ msleep(100);
++ hdmi_htop1_write(hdmi, 0x00000001, HDMI_HTOP1_ENABLE_SELECTOR);
++ msleep(100);
++ hdmi_htop1_write(hdmi, 0x00000003, HDMI_HTOP1_ENABLE_SELECTOR);
++ hdmi_htop1_write(hdmi, 0x00000001, HDMI_HTOP1_MACRO_RESET);
++ hdmi_htop1_write(hdmi, 0x0000000f, HDMI_HTOP1_TISEN);
++ hdmi_htop1_write(hdmi, 0x0000000f, HDMI_HTOP1_TISDREN);
++ hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_VIDEO_INPUT);
++ hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_CLK_TO_PHY);
++ hdmi_htop1_write(hdmi, 0x00000000, HDMI_HTOP1_VIDEO_INPUT2);
++ hdmi_htop1_write(hdmi, 0x0000000a, HDMI_HTOP1_CLK_SET);
++}
++
+ static int __init sh_hdmi_probe(struct platform_device *pdev)
+ {
+ struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ struct resource *htop1_res;
+ int irq = platform_get_irq(pdev, 0), ret;
+ struct sh_hdmi *hdmi;
+ long rate;
+@@ -1156,6 +1281,15 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
+ if (!res || !pdata || irq < 0)
+ return -ENODEV;
+
++ htop1_res = NULL;
++ if (pdata->flags & HDMI_HAS_HTOP1) {
++ htop1_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++ if (!htop1_res) {
++ dev_err(&pdev->dev, "htop1 needs register base\n");
++ return -EINVAL;
++ }
++ }
++
+ hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL);
+ if (!hdmi) {
+ dev_err(&pdev->dev, "Cannot allocate device data\n");
+@@ -1227,6 +1361,17 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
+ if (pdata->flags & HDMI_OUTPUT_POLARITY_HI)
+ hdmi_bit_set(hdmi, 0x01, 0x01, HDMI_SYSTEM_CTRL);
+
++ /* enable htop1 register if needed */
++ if (htop1_res) {
++ hdmi->htop1 = ioremap(htop1_res->start, resource_size(htop1_res));
++ if (!hdmi->htop1) {
++ dev_err(&pdev->dev, "control register region already claimed\n");
++ ret = -ENOMEM;
++ goto emap_htop1;
++ }
++ sh_hdmi_htop1_init(hdmi);
++ }
++
+ /* Product and revision IDs are 0 in sh-mobile version */
+ dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n",
+ hdmi_read(hdmi, HDMI_PRODUCT_ID), hdmi_read(hdmi, HDMI_REVISION_ID));
+@@ -1250,6 +1395,9 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
+ ecodec:
+ free_irq(irq, hdmi);
+ ereqirq:
++ if (hdmi->htop1)
++ iounmap(hdmi->htop1);
++emap_htop1:
+ pm_runtime_put(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ iounmap(hdmi->base);
+@@ -1281,6 +1429,8 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
+ pm_runtime_disable(&pdev->dev);
+ clk_disable(hdmi->hdmi_clk);
+ clk_put(hdmi->hdmi_clk);
++ if (hdmi->htop1)
++ iounmap(hdmi->htop1);
+ iounmap(hdmi->base);
+ release_mem_region(res->start, resource_size(res));
+ kfree(hdmi);
+diff --git a/include/video/sh_mobile_hdmi.h b/include/video/sh_mobile_hdmi.h
+index ce8a540..63d20ef 100644
+--- a/include/video/sh_mobile_hdmi.h
++++ b/include/video/sh_mobile_hdmi.h
+@@ -38,6 +38,7 @@ struct clk;
+
+ /* Chip specific option */
+ #define HDMI_32BIT_REG (1 << 8)
++#define HDMI_HAS_HTOP1 (1 << 9)
+
+ struct sh_mobile_hdmi_info {
+ unsigned int flags;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0038-fbdev-sh_mipi_dsi-fix-a-section-mismatch.patch b/patches.armadillo800/0038-fbdev-sh_mipi_dsi-fix-a-section-mismatch.patch
new file mode 100644
index 0000000000000..ce1fee549114c
--- /dev/null
+++ b/patches.armadillo800/0038-fbdev-sh_mipi_dsi-fix-a-section-mismatch.patch
@@ -0,0 +1,53 @@
+From 46a0acbafe13b92d4ea16ca47414ac22579f9827 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 14 Jun 2012 09:53:33 +0200
+Subject: fbdev: sh_mipi_dsi: fix a section mismatch
+
+sh_mipi_setup() is called from a .text function, therefore it cannot be
+__init. Additionally, sh_mipi_remove() can be moved to the .devexit.text
+section.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+(cherry picked from commit e6765ffa6897f7fb84469bab2e1be885c57ea519)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mipi_dsi.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
+index 4c6b844..3951fda 100644
+--- a/drivers/video/sh_mipi_dsi.c
++++ b/drivers/video/sh_mipi_dsi.c
+@@ -127,8 +127,7 @@ static void sh_mipi_shutdown(struct platform_device *pdev)
+ sh_mipi_dsi_enable(mipi, false);
+ }
+
+-static int __init sh_mipi_setup(struct sh_mipi *mipi,
+- struct sh_mipi_dsi_info *pdata)
++static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata)
+ {
+ void __iomem *base = mipi->base;
+ struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan;
+@@ -551,7 +550,7 @@ efindslot:
+ return ret;
+ }
+
+-static int __exit sh_mipi_remove(struct platform_device *pdev)
++static int __devexit sh_mipi_remove(struct platform_device *pdev)
+ {
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+@@ -592,7 +591,7 @@ static int __exit sh_mipi_remove(struct platform_device *pdev)
+ }
+
+ static struct platform_driver sh_mipi_driver = {
+- .remove = __exit_p(sh_mipi_remove),
++ .remove = __devexit_p(sh_mipi_remove),
+ .shutdown = sh_mipi_shutdown,
+ .driver = {
+ .name = "sh-mipi-dsi",
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0039-fbdev-sh_mobile_lcdc-Constify-sh_mobile_lcdc_fix-str.patch b/patches.armadillo800/0039-fbdev-sh_mobile_lcdc-Constify-sh_mobile_lcdc_fix-str.patch
new file mode 100644
index 0000000000000..353350200bbce
--- /dev/null
+++ b/patches.armadillo800/0039-fbdev-sh_mobile_lcdc-Constify-sh_mobile_lcdc_fix-str.patch
@@ -0,0 +1,31 @@
+From 285591af450384157206e46d4b676f8a5d095c4a Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Tue, 22 Nov 2011 00:56:58 +0100
+Subject: fbdev: sh_mobile_lcdc: Constify sh_mobile_lcdc_fix structure
+
+The structure is only read, make it const.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+(cherry picked from commit 3281e54c80195b90ed12a5b6cddef4ab42e656e1)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_lcdcfb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
+index e672698..5461abe 100644
+--- a/drivers/video/sh_mobile_lcdcfb.c
++++ b/drivers/video/sh_mobile_lcdcfb.c
+@@ -1003,7 +1003,7 @@ static int sh_mobile_lcdc_setcolreg(u_int regno,
+ return 0;
+ }
+
+-static struct fb_fix_screeninfo sh_mobile_lcdc_fix = {
++static const struct fb_fix_screeninfo sh_mobile_lcdc_fix = {
+ .id = "SH Mobile LCDC",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_TRUECOLOR,
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0040-fbdev-sh_mobile_lcdc-Rename-fb-operation-handlers-wi.patch b/patches.armadillo800/0040-fbdev-sh_mobile_lcdc-Rename-fb-operation-handlers-wi.patch
new file mode 100644
index 0000000000000..015ce4eaafe4f
--- /dev/null
+++ b/patches.armadillo800/0040-fbdev-sh_mobile_lcdc-Rename-fb-operation-handlers-wi.patch
@@ -0,0 +1,168 @@
+From 2a41d02255f596307db8e41902cfec9877bfe493 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Tue, 22 Nov 2011 00:56:58 +0100
+Subject: fbdev: sh_mobile_lcdc: Rename fb operation handlers with a common
+ prefix
+
+Make all fb operation handlers start with sh_mobile_lcdc_ in preparation
+for the multi-plane support.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+(cherry picked from commit d7ad33421863308fe7ddf865737d4d83b64e5b81)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_lcdcfb.c | 48 +++++++++++++++++++++-------------------
+ 1 file changed, 25 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
+index 5461abe..799f871 100644
+--- a/drivers/video/sh_mobile_lcdcfb.c
++++ b/drivers/video/sh_mobile_lcdcfb.c
+@@ -384,8 +384,8 @@ sh_mobile_lcdc_must_reconfigure(struct sh_mobile_lcdc_chan *ch,
+ return true;
+ }
+
+-static int sh_mobile_check_var(struct fb_var_screeninfo *var,
+- struct fb_info *info);
++static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var,
++ struct fb_info *info);
+
+ static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch,
+ enum sh_mobile_lcdc_entity_event event,
+@@ -439,7 +439,7 @@ static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch,
+ fb_videomode_to_var(&var, mode);
+ var.bits_per_pixel = info->var.bits_per_pixel;
+ var.grayscale = info->var.grayscale;
+- ret = sh_mobile_check_var(&var, info);
++ ret = sh_mobile_lcdc_check_var(&var, info);
+ break;
+ }
+
+@@ -585,7 +585,7 @@ static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
+ return IRQ_HANDLED;
+ }
+
+-static int sh_mobile_wait_for_vsync(struct sh_mobile_lcdc_chan *ch)
++static int sh_mobile_lcdc_wait_for_vsync(struct sh_mobile_lcdc_chan *ch)
+ {
+ unsigned long ldintr;
+ int ret;
+@@ -686,7 +686,7 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
+ }
+
+ /*
+- * __sh_mobile_lcdc_start - Configure and tart the LCDC
++ * __sh_mobile_lcdc_start - Configure and start the LCDC
+ * @priv: LCDC device
+ *
+ * Configure all enabled channels and start the LCDC device. All external
+@@ -1035,8 +1035,8 @@ static void sh_mobile_lcdc_imageblit(struct fb_info *info,
+ sh_mobile_lcdc_deferred_io_touch(info);
+ }
+
+-static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
+- struct fb_info *info)
++static int sh_mobile_lcdc_pan(struct fb_var_screeninfo *var,
++ struct fb_info *info)
+ {
+ struct sh_mobile_lcdc_chan *ch = info->par;
+ struct sh_mobile_lcdc_priv *priv = ch->lcdc;
+@@ -1099,14 +1099,15 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
+ return 0;
+ }
+
+-static int sh_mobile_ioctl(struct fb_info *info, unsigned int cmd,
+- unsigned long arg)
++static int sh_mobile_lcdc_ioctl(struct fb_info *info, unsigned int cmd,
++ unsigned long arg)
+ {
++ struct sh_mobile_lcdc_chan *ch = info->par;
+ int retval;
+
+ switch (cmd) {
+ case FBIO_WAITFORVSYNC:
+- retval = sh_mobile_wait_for_vsync(info->par);
++ retval = sh_mobile_lcdc_wait_for_vsync(ch);
+ break;
+
+ default:
+@@ -1158,7 +1159,7 @@ static void sh_mobile_fb_reconfig(struct fb_info *info)
+ * Locking: both .fb_release() and .fb_open() are called with info->lock held if
+ * user == 1, or with console sem held, if user == 0.
+ */
+-static int sh_mobile_release(struct fb_info *info, int user)
++static int sh_mobile_lcdc_release(struct fb_info *info, int user)
+ {
+ struct sh_mobile_lcdc_chan *ch = info->par;
+
+@@ -1179,7 +1180,7 @@ static int sh_mobile_release(struct fb_info *info, int user)
+ return 0;
+ }
+
+-static int sh_mobile_open(struct fb_info *info, int user)
++static int sh_mobile_lcdc_open(struct fb_info *info, int user)
+ {
+ struct sh_mobile_lcdc_chan *ch = info->par;
+
+@@ -1192,7 +1193,8 @@ static int sh_mobile_open(struct fb_info *info, int user)
+ return 0;
+ }
+
+-static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
++static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var,
++ struct fb_info *info)
+ {
+ struct sh_mobile_lcdc_chan *ch = info->par;
+ struct sh_mobile_lcdc_priv *p = ch->lcdc;
+@@ -1313,7 +1315,7 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in
+ return 0;
+ }
+
+-static int sh_mobile_set_par(struct fb_info *info)
++static int sh_mobile_lcdc_set_par(struct fb_info *info)
+ {
+ struct sh_mobile_lcdc_chan *ch = info->par;
+ int ret;
+@@ -1383,8 +1385,8 @@ static int sh_mobile_lcdc_blank(int blank, struct fb_info *info)
+ * mode will reenable the clocks and update the screen in time,
+ * so it does not need this. */
+ if (!info->fbdefio) {
+- sh_mobile_wait_for_vsync(ch);
+- sh_mobile_wait_for_vsync(ch);
++ sh_mobile_lcdc_wait_for_vsync(ch);
++ sh_mobile_lcdc_wait_for_vsync(ch);
+ }
+ sh_mobile_lcdc_clk_off(p);
+ }
+@@ -1402,12 +1404,12 @@ static struct fb_ops sh_mobile_lcdc_ops = {
+ .fb_copyarea = sh_mobile_lcdc_copyarea,
+ .fb_imageblit = sh_mobile_lcdc_imageblit,
+ .fb_blank = sh_mobile_lcdc_blank,
+- .fb_pan_display = sh_mobile_fb_pan_display,
+- .fb_ioctl = sh_mobile_ioctl,
+- .fb_open = sh_mobile_open,
+- .fb_release = sh_mobile_release,
+- .fb_check_var = sh_mobile_check_var,
+- .fb_set_par = sh_mobile_set_par,
++ .fb_pan_display = sh_mobile_lcdc_pan,
++ .fb_ioctl = sh_mobile_lcdc_ioctl,
++ .fb_open = sh_mobile_lcdc_open,
++ .fb_release = sh_mobile_lcdc_release,
++ .fb_check_var = sh_mobile_lcdc_check_var,
++ .fb_set_par = sh_mobile_lcdc_set_par,
+ };
+
+ static void
+@@ -1537,7 +1539,7 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch,
+ else
+ var->grayscale = ch->format->fourcc;
+
+- ret = sh_mobile_check_var(var, info);
++ ret = sh_mobile_lcdc_check_var(var, info);
+ if (ret)
+ return ret;
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0041-fbdev-sh_mobile_lcdc-Implement-overlays-support.patch b/patches.armadillo800/0041-fbdev-sh_mobile_lcdc-Implement-overlays-support.patch
new file mode 100644
index 0000000000000..85bd66b55ddff
--- /dev/null
+++ b/patches.armadillo800/0041-fbdev-sh_mobile_lcdc-Implement-overlays-support.patch
@@ -0,0 +1,1137 @@
+From ae0b639299213d1d1361aa368c57ee8a3d94214b Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Mon, 12 Dec 2011 18:43:16 +0100
+Subject: fbdev: sh_mobile_lcdc: Implement overlays support
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+(cherry picked from commit c5deac3c9b2284a64326e8799dfe7416bc619c02)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ .../sysfs-devices-platform-sh_mobile_lcdc_fb | 44 +
+ drivers/video/sh_mobile_lcdcfb.c | 932 +++++++++++++++++++--
+ include/video/sh_mobile_lcdc.h | 7 +
+ 3 files changed, 911 insertions(+), 72 deletions(-)
+ create mode 100644 Documentation/ABI/testing/sysfs-devices-platform-sh_mobile_lcdc_fb
+
+diff --git a/Documentation/ABI/testing/sysfs-devices-platform-sh_mobile_lcdc_fb b/Documentation/ABI/testing/sysfs-devices-platform-sh_mobile_lcdc_fb
+new file mode 100644
+index 0000000..2107082
+--- /dev/null
++++ b/Documentation/ABI/testing/sysfs-devices-platform-sh_mobile_lcdc_fb
+@@ -0,0 +1,44 @@
++What: /sys/devices/platform/sh_mobile_lcdc_fb.[0-3]/graphics/fb[0-9]/ovl_alpha
++Date: May 2012
++Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
++Description:
++ This file is only available on fb[0-9] devices corresponding
++ to overlay planes.
++
++ Stores the alpha blending value for the overlay. Values range
++ from 0 (transparent) to 255 (opaque). The value is ignored if
++ the mode is not set to Alpha Blending.
++
++What: /sys/devices/platform/sh_mobile_lcdc_fb.[0-3]/graphics/fb[0-9]/ovl_mode
++Date: May 2012
++Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
++Description:
++ This file is only available on fb[0-9] devices corresponding
++ to overlay planes.
++
++ Selects the composition mode for the overlay. Possible values
++ are
++
++ 0 - Alpha Blending
++ 1 - ROP3
++
++What: /sys/devices/platform/sh_mobile_lcdc_fb.[0-3]/graphics/fb[0-9]/ovl_position
++Date: May 2012
++Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
++Description:
++ This file is only available on fb[0-9] devices corresponding
++ to overlay planes.
++
++ Stores the x,y overlay position on the display in pixels. The
++ position format is `[0-9]+,[0-9]+'.
++
++What: /sys/devices/platform/sh_mobile_lcdc_fb.[0-3]/graphics/fb[0-9]/ovl_rop3
++Date: May 2012
++Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
++Description:
++ This file is only available on fb[0-9] devices corresponding
++ to overlay planes.
++
++ Stores the raster operation (ROP3) for the overlay. Values
++ range from 0 to 255. The value is ignored if the mode is not
++ set to ROP3.
+diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
+index 799f871..98e81b3 100644
+--- a/drivers/video/sh_mobile_lcdcfb.c
++++ b/drivers/video/sh_mobile_lcdcfb.c
+@@ -12,6 +12,7 @@
+ #include <linux/backlight.h>
+ #include <linux/clk.h>
+ #include <linux/console.h>
++#include <linux/ctype.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/delay.h>
+ #include <linux/gpio.h>
+@@ -32,12 +33,176 @@
+
+ #include "sh_mobile_lcdcfb.h"
+
++/* ----------------------------------------------------------------------------
++ * Overlay register definitions
++ */
++
++#define LDBCR 0xb00
++#define LDBCR_UPC(n) (1 << ((n) + 16))
++#define LDBCR_UPF(n) (1 << ((n) + 8))
++#define LDBCR_UPD(n) (1 << ((n) + 0))
++#define LDBnBSIFR(n) (0xb20 + (n) * 0x20 + 0x00)
++#define LDBBSIFR_EN (1 << 31)
++#define LDBBSIFR_VS (1 << 29)
++#define LDBBSIFR_BRSEL (1 << 28)
++#define LDBBSIFR_MX (1 << 27)
++#define LDBBSIFR_MY (1 << 26)
++#define LDBBSIFR_CV3 (3 << 24)
++#define LDBBSIFR_CV2 (2 << 24)
++#define LDBBSIFR_CV1 (1 << 24)
++#define LDBBSIFR_CV0 (0 << 24)
++#define LDBBSIFR_CV_MASK (3 << 24)
++#define LDBBSIFR_LAY_MASK (0xff << 16)
++#define LDBBSIFR_LAY_SHIFT 16
++#define LDBBSIFR_ROP3_MASK (0xff << 16)
++#define LDBBSIFR_ROP3_SHIFT 16
++#define LDBBSIFR_AL_PL8 (3 << 14)
++#define LDBBSIFR_AL_PL1 (2 << 14)
++#define LDBBSIFR_AL_PK (1 << 14)
++#define LDBBSIFR_AL_1 (0 << 14)
++#define LDBBSIFR_AL_MASK (3 << 14)
++#define LDBBSIFR_SWPL (1 << 10)
++#define LDBBSIFR_SWPW (1 << 9)
++#define LDBBSIFR_SWPB (1 << 8)
++#define LDBBSIFR_RY (1 << 7)
++#define LDBBSIFR_CHRR_420 (2 << 0)
++#define LDBBSIFR_CHRR_422 (1 << 0)
++#define LDBBSIFR_CHRR_444 (0 << 0)
++#define LDBBSIFR_RPKF_ARGB32 (0x00 << 0)
++#define LDBBSIFR_RPKF_RGB16 (0x03 << 0)
++#define LDBBSIFR_RPKF_RGB24 (0x0b << 0)
++#define LDBBSIFR_RPKF_MASK (0x1f << 0)
++#define LDBnBSSZR(n) (0xb20 + (n) * 0x20 + 0x04)
++#define LDBBSSZR_BVSS_MASK (0xfff << 16)
++#define LDBBSSZR_BVSS_SHIFT 16
++#define LDBBSSZR_BHSS_MASK (0xfff << 0)
++#define LDBBSSZR_BHSS_SHIFT 0
++#define LDBnBLOCR(n) (0xb20 + (n) * 0x20 + 0x08)
++#define LDBBLOCR_CVLC_MASK (0xfff << 16)
++#define LDBBLOCR_CVLC_SHIFT 16
++#define LDBBLOCR_CHLC_MASK (0xfff << 0)
++#define LDBBLOCR_CHLC_SHIFT 0
++#define LDBnBSMWR(n) (0xb20 + (n) * 0x20 + 0x0c)
++#define LDBBSMWR_BSMWA_MASK (0xffff << 16)
++#define LDBBSMWR_BSMWA_SHIFT 16
++#define LDBBSMWR_BSMW_MASK (0xffff << 0)
++#define LDBBSMWR_BSMW_SHIFT 0
++#define LDBnBSAYR(n) (0xb20 + (n) * 0x20 + 0x10)
++#define LDBBSAYR_FG1A_MASK (0xff << 24)
++#define LDBBSAYR_FG1A_SHIFT 24
++#define LDBBSAYR_FG1R_MASK (0xff << 16)
++#define LDBBSAYR_FG1R_SHIFT 16
++#define LDBBSAYR_FG1G_MASK (0xff << 8)
++#define LDBBSAYR_FG1G_SHIFT 8
++#define LDBBSAYR_FG1B_MASK (0xff << 0)
++#define LDBBSAYR_FG1B_SHIFT 0
++#define LDBnBSACR(n) (0xb20 + (n) * 0x20 + 0x14)
++#define LDBBSACR_FG2A_MASK (0xff << 24)
++#define LDBBSACR_FG2A_SHIFT 24
++#define LDBBSACR_FG2R_MASK (0xff << 16)
++#define LDBBSACR_FG2R_SHIFT 16
++#define LDBBSACR_FG2G_MASK (0xff << 8)
++#define LDBBSACR_FG2G_SHIFT 8
++#define LDBBSACR_FG2B_MASK (0xff << 0)
++#define LDBBSACR_FG2B_SHIFT 0
++#define LDBnBSAAR(n) (0xb20 + (n) * 0x20 + 0x18)
++#define LDBBSAAR_AP_MASK (0xff << 24)
++#define LDBBSAAR_AP_SHIFT 24
++#define LDBBSAAR_R_MASK (0xff << 16)
++#define LDBBSAAR_R_SHIFT 16
++#define LDBBSAAR_GY_MASK (0xff << 8)
++#define LDBBSAAR_GY_SHIFT 8
++#define LDBBSAAR_B_MASK (0xff << 0)
++#define LDBBSAAR_B_SHIFT 0
++#define LDBnBPPCR(n) (0xb20 + (n) * 0x20 + 0x1c)
++#define LDBBPPCR_AP_MASK (0xff << 24)
++#define LDBBPPCR_AP_SHIFT 24
++#define LDBBPPCR_R_MASK (0xff << 16)
++#define LDBBPPCR_R_SHIFT 16
++#define LDBBPPCR_GY_MASK (0xff << 8)
++#define LDBBPPCR_GY_SHIFT 8
++#define LDBBPPCR_B_MASK (0xff << 0)
++#define LDBBPPCR_B_SHIFT 0
++#define LDBnBBGCL(n) (0xb10 + (n) * 0x04)
++#define LDBBBGCL_BGA_MASK (0xff << 24)
++#define LDBBBGCL_BGA_SHIFT 24
++#define LDBBBGCL_BGR_MASK (0xff << 16)
++#define LDBBBGCL_BGR_SHIFT 16
++#define LDBBBGCL_BGG_MASK (0xff << 8)
++#define LDBBBGCL_BGG_SHIFT 8
++#define LDBBBGCL_BGB_MASK (0xff << 0)
++#define LDBBBGCL_BGB_SHIFT 0
++
+ #define SIDE_B_OFFSET 0x1000
+ #define MIRROR_OFFSET 0x2000
+
+ #define MAX_XRES 1920
+ #define MAX_YRES 1080
+
++enum sh_mobile_lcdc_overlay_mode {
++ LCDC_OVERLAY_BLEND,
++ LCDC_OVERLAY_ROP3,
++};
++
++/*
++ * struct sh_mobile_lcdc_overlay - LCDC display overlay
++ *
++ * @channel: LCDC channel this overlay belongs to
++ * @cfg: Overlay configuration
++ * @info: Frame buffer device
++ * @index: Overlay index (0-3)
++ * @base: Overlay registers base address
++ * @enabled: True if the overlay is enabled
++ * @mode: Overlay blending mode (alpha blend or ROP3)
++ * @alpha: Global alpha blending value (0-255, for alpha blending mode)
++ * @rop3: Raster operation (for ROP3 mode)
++ * @fb_mem: Frame buffer virtual memory address
++ * @fb_size: Frame buffer size in bytes
++ * @dma_handle: Frame buffer DMA address
++ * @base_addr_y: Overlay base address (RGB or luma component)
++ * @base_addr_c: Overlay base address (chroma component)
++ * @pan_offset: Current pan offset in bytes
++ * @format: Current pixelf format
++ * @xres: Horizontal visible resolution
++ * @xres_virtual: Horizontal total resolution
++ * @yres: Vertical visible resolution
++ * @yres_virtual: Vertical total resolution
++ * @pitch: Overlay line pitch
++ * @pos_x: Horizontal overlay position
++ * @pos_y: Vertical overlay position
++ */
++struct sh_mobile_lcdc_overlay {
++ struct sh_mobile_lcdc_chan *channel;
++
++ const struct sh_mobile_lcdc_overlay_cfg *cfg;
++ struct fb_info *info;
++
++ unsigned int index;
++ unsigned long base;
++
++ bool enabled;
++ enum sh_mobile_lcdc_overlay_mode mode;
++ unsigned int alpha;
++ unsigned int rop3;
++
++ void *fb_mem;
++ unsigned long fb_size;
++
++ dma_addr_t dma_handle;
++ unsigned long base_addr_y;
++ unsigned long base_addr_c;
++ unsigned long pan_offset;
++
++ const struct sh_mobile_lcdc_format_info *format;
++ unsigned int xres;
++ unsigned int xres_virtual;
++ unsigned int yres;
++ unsigned int yres_virtual;
++ unsigned int pitch;
++ int pos_x;
++ int pos_y;
++};
++
+ struct sh_mobile_lcdc_priv {
+ void __iomem *base;
+ int irq;
+@@ -45,7 +210,10 @@ struct sh_mobile_lcdc_priv {
+ struct device *dev;
+ struct clk *dot_clk;
+ unsigned long lddckr;
++
+ struct sh_mobile_lcdc_chan ch[2];
++ struct sh_mobile_lcdc_overlay overlays[4];
++
+ struct notifier_block notifier;
+ int started;
+ int forced_fourcc; /* 2 channel LCDC must share fourcc setting */
+@@ -141,6 +309,13 @@ static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan,
+ return ioread32(chan->lcdc->base + chan->reg_offs[reg_nr]);
+ }
+
++static void lcdc_write_overlay(struct sh_mobile_lcdc_overlay *ovl,
++ int reg, unsigned long data)
++{
++ iowrite32(data, ovl->channel->lcdc->base + reg);
++ iowrite32(data, ovl->channel->lcdc->base + reg + SIDE_B_OFFSET);
++}
++
+ static void lcdc_write(struct sh_mobile_lcdc_priv *priv,
+ unsigned long reg_offs, unsigned long data)
+ {
+@@ -685,6 +860,96 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
+ lcdc_write_chan(ch, LDHAJR, tmp);
+ }
+
++static void sh_mobile_lcdc_overlay_setup(struct sh_mobile_lcdc_overlay *ovl)
++{
++ u32 format = 0;
++
++ if (!ovl->enabled) {
++ lcdc_write(ovl->channel->lcdc, LDBCR, LDBCR_UPC(ovl->index));
++ lcdc_write_overlay(ovl, LDBnBSIFR(ovl->index), 0);
++ lcdc_write(ovl->channel->lcdc, LDBCR,
++ LDBCR_UPF(ovl->index) | LDBCR_UPD(ovl->index));
++ return;
++ }
++
++ ovl->base_addr_y = ovl->dma_handle;
++ ovl->base_addr_c = ovl->base_addr_y + ovl->xres
++ * ovl->yres_virtual;
++
++ switch (ovl->mode) {
++ case LCDC_OVERLAY_BLEND:
++ format = LDBBSIFR_EN | (ovl->alpha << LDBBSIFR_LAY_SHIFT);
++ break;
++
++ case LCDC_OVERLAY_ROP3:
++ format = LDBBSIFR_EN | LDBBSIFR_BRSEL
++ | (ovl->rop3 << LDBBSIFR_ROP3_SHIFT);
++ break;
++ }
++
++ switch (ovl->format->fourcc) {
++ case V4L2_PIX_FMT_RGB565:
++ case V4L2_PIX_FMT_NV21:
++ case V4L2_PIX_FMT_NV61:
++ case V4L2_PIX_FMT_NV42:
++ format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW;
++ break;
++ case V4L2_PIX_FMT_BGR24:
++ case V4L2_PIX_FMT_NV12:
++ case V4L2_PIX_FMT_NV16:
++ case V4L2_PIX_FMT_NV24:
++ format |= LDBBSIFR_SWPL | LDBBSIFR_SWPW | LDBBSIFR_SWPB;
++ break;
++ case V4L2_PIX_FMT_BGR32:
++ default:
++ format |= LDBBSIFR_SWPL;
++ break;
++ }
++
++ switch (ovl->format->fourcc) {
++ case V4L2_PIX_FMT_RGB565:
++ format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB16;
++ break;
++ case V4L2_PIX_FMT_BGR24:
++ format |= LDBBSIFR_AL_1 | LDBBSIFR_RY | LDBBSIFR_RPKF_RGB24;
++ break;
++ case V4L2_PIX_FMT_BGR32:
++ format |= LDBBSIFR_AL_PK | LDBBSIFR_RY | LDDFR_PKF_ARGB32;
++ break;
++ case V4L2_PIX_FMT_NV12:
++ case V4L2_PIX_FMT_NV21:
++ format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_420;
++ break;
++ case V4L2_PIX_FMT_NV16:
++ case V4L2_PIX_FMT_NV61:
++ format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_422;
++ break;
++ case V4L2_PIX_FMT_NV24:
++ case V4L2_PIX_FMT_NV42:
++ format |= LDBBSIFR_AL_1 | LDBBSIFR_CHRR_444;
++ break;
++ }
++
++ lcdc_write(ovl->channel->lcdc, LDBCR, LDBCR_UPC(ovl->index));
++
++ lcdc_write_overlay(ovl, LDBnBSIFR(ovl->index), format);
++
++ lcdc_write_overlay(ovl, LDBnBSSZR(ovl->index),
++ (ovl->yres << LDBBSSZR_BVSS_SHIFT) |
++ (ovl->xres << LDBBSSZR_BHSS_SHIFT));
++ lcdc_write_overlay(ovl, LDBnBLOCR(ovl->index),
++ (ovl->pos_y << LDBBLOCR_CVLC_SHIFT) |
++ (ovl->pos_x << LDBBLOCR_CHLC_SHIFT));
++ lcdc_write_overlay(ovl, LDBnBSMWR(ovl->index),
++ ovl->pitch << LDBBSMWR_BSMW_SHIFT);
++
++ lcdc_write_overlay(ovl, LDBnBSAYR(ovl->index), ovl->base_addr_y);
++ lcdc_write_overlay(ovl, LDBnBSACR(ovl->index), ovl->base_addr_c);
++
++ lcdc_write(ovl->channel->lcdc, LDBCR,
++ LDBCR_UPF(ovl->index) | LDBCR_UPD(ovl->index));
++}
++
+ /*
+ * __sh_mobile_lcdc_start - Configure and start the LCDC
+ * @priv: LCDC device
+@@ -892,6 +1157,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
+ }
+ }
+
++ for (k = 0; k < ARRAY_SIZE(priv->overlays); ++k) {
++ struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[k];
++ sh_mobile_lcdc_overlay_setup(ovl);
++ }
++
+ /* Start the LCDC. */
+ __sh_mobile_lcdc_start(priv);
+
+@@ -975,8 +1245,506 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
+ sh_mobile_lcdc_clk_off(priv);
+ }
+
++static int __sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var,
++ struct fb_info *info)
++{
++ if (var->xres > MAX_XRES || var->yres > MAX_YRES)
++ return -EINVAL;
++
++ /* Make sure the virtual resolution is at least as big as the visible
++ * resolution.
++ */
++ if (var->xres_virtual < var->xres)
++ var->xres_virtual = var->xres;
++ if (var->yres_virtual < var->yres)
++ var->yres_virtual = var->yres;
++
++ if (sh_mobile_format_is_fourcc(var)) {
++ const struct sh_mobile_lcdc_format_info *format;
++
++ format = sh_mobile_format_info(var->grayscale);
++ if (format == NULL)
++ return -EINVAL;
++ var->bits_per_pixel = format->bpp;
++
++ /* Default to RGB and JPEG color-spaces for RGB and YUV formats
++ * respectively.
++ */
++ if (!format->yuv)
++ var->colorspace = V4L2_COLORSPACE_SRGB;
++ else if (var->colorspace != V4L2_COLORSPACE_REC709)
++ var->colorspace = V4L2_COLORSPACE_JPEG;
++ } else {
++ if (var->bits_per_pixel <= 16) { /* RGB 565 */
++ var->bits_per_pixel = 16;
++ var->red.offset = 11;
++ var->red.length = 5;
++ var->green.offset = 5;
++ var->green.length = 6;
++ var->blue.offset = 0;
++ var->blue.length = 5;
++ var->transp.offset = 0;
++ var->transp.length = 0;
++ } else if (var->bits_per_pixel <= 24) { /* RGB 888 */
++ var->bits_per_pixel = 24;
++ var->red.offset = 16;
++ var->red.length = 8;
++ var->green.offset = 8;
++ var->green.length = 8;
++ var->blue.offset = 0;
++ var->blue.length = 8;
++ var->transp.offset = 0;
++ var->transp.length = 0;
++ } else if (var->bits_per_pixel <= 32) { /* RGBA 888 */
++ var->bits_per_pixel = 32;
++ var->red.offset = 16;
++ var->red.length = 8;
++ var->green.offset = 8;
++ var->green.length = 8;
++ var->blue.offset = 0;
++ var->blue.length = 8;
++ var->transp.offset = 24;
++ var->transp.length = 8;
++ } else
++ return -EINVAL;
++
++ var->red.msb_right = 0;
++ var->green.msb_right = 0;
++ var->blue.msb_right = 0;
++ var->transp.msb_right = 0;
++ }
++
++ /* Make sure we don't exceed our allocated memory. */
++ if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 >
++ info->fix.smem_len)
++ return -EINVAL;
++
++ return 0;
++}
++
++/* -----------------------------------------------------------------------------
++ * Frame buffer operations - Overlays
++ */
++
++static ssize_t
++overlay_alpha_show(struct device *dev, struct device_attribute *attr, char *buf)
++{
++ struct fb_info *info = dev_get_drvdata(dev);
++ struct sh_mobile_lcdc_overlay *ovl = info->par;
++
++ return scnprintf(buf, PAGE_SIZE, "%u\n", ovl->alpha);
++}
++
++static ssize_t
++overlay_alpha_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct fb_info *info = dev_get_drvdata(dev);
++ struct sh_mobile_lcdc_overlay *ovl = info->par;
++ unsigned int alpha;
++ char *endp;
++
++ alpha = simple_strtoul(buf, &endp, 10);
++ if (isspace(*endp))
++ endp++;
++
++ if (endp - buf != count)
++ return -EINVAL;
++
++ if (alpha > 255)
++ return -EINVAL;
++
++ if (ovl->alpha != alpha) {
++ ovl->alpha = alpha;
++
++ if (ovl->mode == LCDC_OVERLAY_BLEND && ovl->enabled)
++ sh_mobile_lcdc_overlay_setup(ovl);
++ }
++
++ return count;
++}
++
++static ssize_t
++overlay_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
++{
++ struct fb_info *info = dev_get_drvdata(dev);
++ struct sh_mobile_lcdc_overlay *ovl = info->par;
++
++ return scnprintf(buf, PAGE_SIZE, "%u\n", ovl->mode);
++}
++
++static ssize_t
++overlay_mode_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct fb_info *info = dev_get_drvdata(dev);
++ struct sh_mobile_lcdc_overlay *ovl = info->par;
++ unsigned int mode;
++ char *endp;
++
++ mode = simple_strtoul(buf, &endp, 10);
++ if (isspace(*endp))
++ endp++;
++
++ if (endp - buf != count)
++ return -EINVAL;
++
++ if (mode != LCDC_OVERLAY_BLEND && mode != LCDC_OVERLAY_ROP3)
++ return -EINVAL;
++
++ if (ovl->mode != mode) {
++ ovl->mode = mode;
++
++ if (ovl->enabled)
++ sh_mobile_lcdc_overlay_setup(ovl);
++ }
++
++ return count;
++}
++
++static ssize_t
++overlay_position_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct fb_info *info = dev_get_drvdata(dev);
++ struct sh_mobile_lcdc_overlay *ovl = info->par;
++
++ return scnprintf(buf, PAGE_SIZE, "%d,%d\n", ovl->pos_x, ovl->pos_y);
++}
++
++static ssize_t
++overlay_position_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct fb_info *info = dev_get_drvdata(dev);
++ struct sh_mobile_lcdc_overlay *ovl = info->par;
++ char *endp;
++ int pos_x;
++ int pos_y;
++
++ pos_x = simple_strtol(buf, &endp, 10);
++ if (*endp != ',')
++ return -EINVAL;
++
++ pos_y = simple_strtol(endp + 1, &endp, 10);
++ if (isspace(*endp))
++ endp++;
++
++ if (endp - buf != count)
++ return -EINVAL;
++
++ if (ovl->pos_x != pos_x || ovl->pos_y != pos_y) {
++ ovl->pos_x = pos_x;
++ ovl->pos_y = pos_y;
++
++ if (ovl->enabled)
++ sh_mobile_lcdc_overlay_setup(ovl);
++ }
++
++ return count;
++}
++
++static ssize_t
++overlay_rop3_show(struct device *dev, struct device_attribute *attr, char *buf)
++{
++ struct fb_info *info = dev_get_drvdata(dev);
++ struct sh_mobile_lcdc_overlay *ovl = info->par;
++
++ return scnprintf(buf, PAGE_SIZE, "%u\n", ovl->rop3);
++}
++
++static ssize_t
++overlay_rop3_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct fb_info *info = dev_get_drvdata(dev);
++ struct sh_mobile_lcdc_overlay *ovl = info->par;
++ unsigned int rop3;
++ char *endp;
++
++ rop3 = !!simple_strtoul(buf, &endp, 10);
++ if (isspace(*endp))
++ endp++;
++
++ if (endp - buf != count)
++ return -EINVAL;
++
++ if (rop3 > 255)
++ return -EINVAL;
++
++ if (ovl->rop3 != rop3) {
++ ovl->rop3 = rop3;
++
++ if (ovl->mode == LCDC_OVERLAY_ROP3 && ovl->enabled)
++ sh_mobile_lcdc_overlay_setup(ovl);
++ }
++
++ return count;
++}
++
++static const struct device_attribute overlay_sysfs_attrs[] = {
++ __ATTR(ovl_alpha, S_IRUGO|S_IWUSR,
++ overlay_alpha_show, overlay_alpha_store),
++ __ATTR(ovl_mode, S_IRUGO|S_IWUSR,
++ overlay_mode_show, overlay_mode_store),
++ __ATTR(ovl_position, S_IRUGO|S_IWUSR,
++ overlay_position_show, overlay_position_store),
++ __ATTR(ovl_rop3, S_IRUGO|S_IWUSR,
++ overlay_rop3_show, overlay_rop3_store),
++};
++
++static const struct fb_fix_screeninfo sh_mobile_lcdc_overlay_fix = {
++ .id = "SH Mobile LCDC",
++ .type = FB_TYPE_PACKED_PIXELS,
++ .visual = FB_VISUAL_TRUECOLOR,
++ .accel = FB_ACCEL_NONE,
++ .xpanstep = 0,
++ .ypanstep = 1,
++ .ywrapstep = 0,
++ .capabilities = FB_CAP_FOURCC,
++};
++
++static int sh_mobile_lcdc_overlay_pan(struct fb_var_screeninfo *var,
++ struct fb_info *info)
++{
++ struct sh_mobile_lcdc_overlay *ovl = info->par;
++ unsigned long base_addr_y;
++ unsigned long base_addr_c;
++ unsigned long pan_offset;
++ unsigned long c_offset;
++
++ if (!ovl->format->yuv)
++ pan_offset = var->yoffset * ovl->pitch
++ + var->xoffset * (ovl->format->bpp / 8);
++ else
++ pan_offset = var->yoffset * ovl->pitch + var->xoffset;
++
++ if (pan_offset == ovl->pan_offset)
++ return 0; /* No change, do nothing */
++
++ /* Set the source address for the next refresh */
++ base_addr_y = ovl->dma_handle + pan_offset;
++
++ ovl->base_addr_y = base_addr_y;
++ ovl->base_addr_c = base_addr_y;
++
++ if (ovl->format->yuv) {
++ /* Set Y offset */
++ c_offset = var->yoffset * ovl->pitch
++ * (ovl->format->bpp - 8) / 8;
++ base_addr_c = ovl->dma_handle
++ + ovl->xres * ovl->yres_virtual
++ + c_offset;
++ /* Set X offset */
++ if (ovl->format->fourcc == V4L2_PIX_FMT_NV24)
++ base_addr_c += 2 * var->xoffset;
++ else
++ base_addr_c += var->xoffset;
++
++ ovl->base_addr_c = base_addr_c;
++ }
++
++ lcdc_write_overlay(ovl, LDBnBSAYR(ovl->index), ovl->base_addr_y);
++ lcdc_write_overlay(ovl, LDBnBSACR(ovl->index), ovl->base_addr_c);
++
++ ovl->pan_offset = pan_offset;
++
++ return 0;
++}
++
++static int sh_mobile_lcdc_overlay_ioctl(struct fb_info *info, unsigned int cmd,
++ unsigned long arg)
++{
++ struct sh_mobile_lcdc_overlay *ovl = info->par;
++
++ switch (cmd) {
++ case FBIO_WAITFORVSYNC:
++ return sh_mobile_lcdc_wait_for_vsync(ovl->channel);
++
++ default:
++ return -ENOIOCTLCMD;
++ }
++}
++
++static int sh_mobile_lcdc_overlay_check_var(struct fb_var_screeninfo *var,
++ struct fb_info *info)
++{
++ return __sh_mobile_lcdc_check_var(var, info);
++}
++
++static int sh_mobile_lcdc_overlay_set_par(struct fb_info *info)
++{
++ struct sh_mobile_lcdc_overlay *ovl = info->par;
++
++ ovl->format =
++ sh_mobile_format_info(sh_mobile_format_fourcc(&info->var));
++
++ ovl->xres = info->var.xres;
++ ovl->xres_virtual = info->var.xres_virtual;
++ ovl->yres = info->var.yres;
++ ovl->yres_virtual = info->var.yres_virtual;
++
++ if (ovl->format->yuv)
++ ovl->pitch = info->var.xres;
++ else
++ ovl->pitch = info->var.xres * ovl->format->bpp / 8;
++
++ sh_mobile_lcdc_overlay_setup(ovl);
++
++ info->fix.line_length = ovl->pitch;
++
++ if (sh_mobile_format_is_fourcc(&info->var)) {
++ info->fix.type = FB_TYPE_FOURCC;
++ info->fix.visual = FB_VISUAL_FOURCC;
++ } else {
++ info->fix.type = FB_TYPE_PACKED_PIXELS;
++ info->fix.visual = FB_VISUAL_TRUECOLOR;
++ }
++
++ return 0;
++}
++
++/* Overlay blanking. Disable the overlay when blanked. */
++static int sh_mobile_lcdc_overlay_blank(int blank, struct fb_info *info)
++{
++ struct sh_mobile_lcdc_overlay *ovl = info->par;
++
++ ovl->enabled = !blank;
++ sh_mobile_lcdc_overlay_setup(ovl);
++
++ /* Prevent the backlight from receiving a blanking event by returning
++ * a non-zero value.
++ */
++ return 1;
++}
++
++static struct fb_ops sh_mobile_lcdc_overlay_ops = {
++ .owner = THIS_MODULE,
++ .fb_read = fb_sys_read,
++ .fb_write = fb_sys_write,
++ .fb_fillrect = sys_fillrect,
++ .fb_copyarea = sys_copyarea,
++ .fb_imageblit = sys_imageblit,
++ .fb_blank = sh_mobile_lcdc_overlay_blank,
++ .fb_pan_display = sh_mobile_lcdc_overlay_pan,
++ .fb_ioctl = sh_mobile_lcdc_overlay_ioctl,
++ .fb_check_var = sh_mobile_lcdc_overlay_check_var,
++ .fb_set_par = sh_mobile_lcdc_overlay_set_par,
++};
++
++static void
++sh_mobile_lcdc_overlay_fb_unregister(struct sh_mobile_lcdc_overlay *ovl)
++{
++ struct fb_info *info = ovl->info;
++
++ if (info == NULL || info->dev == NULL)
++ return;
++
++ unregister_framebuffer(ovl->info);
++}
++
++static int __devinit
++sh_mobile_lcdc_overlay_fb_register(struct sh_mobile_lcdc_overlay *ovl)
++{
++ struct sh_mobile_lcdc_priv *lcdc = ovl->channel->lcdc;
++ struct fb_info *info = ovl->info;
++ unsigned int i;
++ int ret;
++
++ if (info == NULL)
++ return 0;
++
++ ret = register_framebuffer(info);
++ if (ret < 0)
++ return ret;
++
++ dev_info(lcdc->dev, "registered %s/overlay %u as %dx%d %dbpp.\n",
++ dev_name(lcdc->dev), ovl->index, info->var.xres,
++ info->var.yres, info->var.bits_per_pixel);
++
++ for (i = 0; i < ARRAY_SIZE(overlay_sysfs_attrs); ++i) {
++ ret = device_create_file(info->dev, &overlay_sysfs_attrs[i]);
++ if (ret < 0)
++ return ret;
++ }
++
++ return 0;
++}
++
++static void
++sh_mobile_lcdc_overlay_fb_cleanup(struct sh_mobile_lcdc_overlay *ovl)
++{
++ struct fb_info *info = ovl->info;
++
++ if (info == NULL || info->device == NULL)
++ return;
++
++ framebuffer_release(info);
++}
++
++static int __devinit
++sh_mobile_lcdc_overlay_fb_init(struct sh_mobile_lcdc_overlay *ovl)
++{
++ struct sh_mobile_lcdc_priv *priv = ovl->channel->lcdc;
++ struct fb_var_screeninfo *var;
++ struct fb_info *info;
++
++ /* Allocate and initialize the frame buffer device. */
++ info = framebuffer_alloc(0, priv->dev);
++ if (info == NULL) {
++ dev_err(priv->dev, "unable to allocate fb_info\n");
++ return -ENOMEM;
++ }
++
++ ovl->info = info;
++
++ info->flags = FBINFO_FLAG_DEFAULT;
++ info->fbops = &sh_mobile_lcdc_overlay_ops;
++ info->device = priv->dev;
++ info->screen_base = ovl->fb_mem;
++ info->par = ovl;
++
++ /* Initialize fixed screen information. Restrict pan to 2 lines steps
++ * for NV12 and NV21.
++ */
++ info->fix = sh_mobile_lcdc_overlay_fix;
++ snprintf(info->fix.id, sizeof(info->fix.id),
++ "SH Mobile LCDC Overlay %u", ovl->index);
++ info->fix.smem_start = ovl->dma_handle;
++ info->fix.smem_len = ovl->fb_size;
++ info->fix.line_length = ovl->pitch;
++
++ if (ovl->format->yuv)
++ info->fix.visual = FB_VISUAL_FOURCC;
++ else
++ info->fix.visual = FB_VISUAL_TRUECOLOR;
++
++ if (ovl->format->fourcc == V4L2_PIX_FMT_NV12 ||
++ ovl->format->fourcc == V4L2_PIX_FMT_NV21)
++ info->fix.ypanstep = 2;
++
++ /* Initialize variable screen information. */
++ var = &info->var;
++ memset(var, 0, sizeof(*var));
++ var->xres = ovl->xres;
++ var->yres = ovl->yres;
++ var->xres_virtual = ovl->xres_virtual;
++ var->yres_virtual = ovl->yres_virtual;
++ var->activate = FB_ACTIVATE_NOW;
++
++ /* Use the legacy API by default for RGB formats, and the FOURCC API
++ * for YUV formats.
++ */
++ if (!ovl->format->yuv)
++ var->bits_per_pixel = ovl->format->bpp;
++ else
++ var->grayscale = ovl->format->fourcc;
++
++ return sh_mobile_lcdc_overlay_check_var(var, info);
++}
++
+ /* -----------------------------------------------------------------------------
+- * Frame buffer operations
++ * Frame buffer operations - main frame buffer
+ */
+
+ static int sh_mobile_lcdc_setcolreg(u_int regno,
+@@ -1202,9 +1970,7 @@ static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var,
+ unsigned int best_xres = 0;
+ unsigned int best_yres = 0;
+ unsigned int i;
+-
+- if (var->xres > MAX_XRES || var->yres > MAX_YRES)
+- return -EINVAL;
++ int ret;
+
+ /* If board code provides us with a list of available modes, make sure
+ * we use one of them. Find the mode closest to the requested one. The
+@@ -1239,73 +2005,9 @@ static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var,
+ var->yres = best_yres;
+ }
+
+- /* Make sure the virtual resolution is at least as big as the visible
+- * resolution.
+- */
+- if (var->xres_virtual < var->xres)
+- var->xres_virtual = var->xres;
+- if (var->yres_virtual < var->yres)
+- var->yres_virtual = var->yres;
+-
+- if (sh_mobile_format_is_fourcc(var)) {
+- const struct sh_mobile_lcdc_format_info *format;
+-
+- format = sh_mobile_format_info(var->grayscale);
+- if (format == NULL)
+- return -EINVAL;
+- var->bits_per_pixel = format->bpp;
+-
+- /* Default to RGB and JPEG color-spaces for RGB and YUV formats
+- * respectively.
+- */
+- if (!format->yuv)
+- var->colorspace = V4L2_COLORSPACE_SRGB;
+- else if (var->colorspace != V4L2_COLORSPACE_REC709)
+- var->colorspace = V4L2_COLORSPACE_JPEG;
+- } else {
+- if (var->bits_per_pixel <= 16) { /* RGB 565 */
+- var->bits_per_pixel = 16;
+- var->red.offset = 11;
+- var->red.length = 5;
+- var->green.offset = 5;
+- var->green.length = 6;
+- var->blue.offset = 0;
+- var->blue.length = 5;
+- var->transp.offset = 0;
+- var->transp.length = 0;
+- } else if (var->bits_per_pixel <= 24) { /* RGB 888 */
+- var->bits_per_pixel = 24;
+- var->red.offset = 16;
+- var->red.length = 8;
+- var->green.offset = 8;
+- var->green.length = 8;
+- var->blue.offset = 0;
+- var->blue.length = 8;
+- var->transp.offset = 0;
+- var->transp.length = 0;
+- } else if (var->bits_per_pixel <= 32) { /* RGBA 888 */
+- var->bits_per_pixel = 32;
+- var->red.offset = 16;
+- var->red.length = 8;
+- var->green.offset = 8;
+- var->green.length = 8;
+- var->blue.offset = 0;
+- var->blue.length = 8;
+- var->transp.offset = 24;
+- var->transp.length = 8;
+- } else
+- return -EINVAL;
+-
+- var->red.msb_right = 0;
+- var->green.msb_right = 0;
+- var->blue.msb_right = 0;
+- var->transp.msb_right = 0;
+- }
+-
+- /* Make sure we don't exceed our allocated memory. */
+- if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 >
+- info->fix.smem_len)
+- return -EINVAL;
++ ret = __sh_mobile_lcdc_check_var(var, info);
++ if (ret < 0)
++ return ret;
+
+ /* only accept the forced_fourcc for dual channel configurations */
+ if (p->forced_fourcc &&
+@@ -1714,15 +2416,27 @@ static const struct fb_videomode default_720p __devinitconst = {
+ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
+ {
+ struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev);
+- int i;
++ unsigned int i;
+
+ fb_unregister_client(&priv->notifier);
+
++ for (i = 0; i < ARRAY_SIZE(priv->overlays); i++)
++ sh_mobile_lcdc_overlay_fb_unregister(&priv->overlays[i]);
+ for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
+ sh_mobile_lcdc_channel_fb_unregister(&priv->ch[i]);
+
+ sh_mobile_lcdc_stop(priv);
+
++ for (i = 0; i < ARRAY_SIZE(priv->overlays); i++) {
++ struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[i];
++
++ sh_mobile_lcdc_overlay_fb_cleanup(ovl);
++
++ if (ovl->fb_mem)
++ dma_free_coherent(&pdev->dev, ovl->fb_size,
++ ovl->fb_mem, ovl->dma_handle);
++ }
++
+ for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
+ struct sh_mobile_lcdc_chan *ch = &priv->ch[i];
+
+@@ -1798,6 +2512,61 @@ static int __devinit sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *
+ }
+
+ static int __devinit
++sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_priv *priv,
++ struct sh_mobile_lcdc_overlay *ovl)
++{
++ const struct sh_mobile_lcdc_format_info *format;
++ int ret;
++
++ if (ovl->cfg->fourcc == 0)
++ return 0;
++
++ /* Validate the format. */
++ format = sh_mobile_format_info(ovl->cfg->fourcc);
++ if (format == NULL) {
++ dev_err(priv->dev, "Invalid FOURCC %08x\n", ovl->cfg->fourcc);
++ return -EINVAL;
++ }
++
++ ovl->enabled = false;
++ ovl->mode = LCDC_OVERLAY_BLEND;
++ ovl->alpha = 255;
++ ovl->rop3 = 0;
++ ovl->pos_x = 0;
++ ovl->pos_y = 0;
++
++ /* The default Y virtual resolution is twice the panel size to allow for
++ * double-buffering.
++ */
++ ovl->format = format;
++ ovl->xres = ovl->cfg->max_xres;
++ ovl->xres_virtual = ovl->xres;
++ ovl->yres = ovl->cfg->max_yres;
++ ovl->yres_virtual = ovl->yres * 2;
++
++ if (!format->yuv)
++ ovl->pitch = ovl->xres * format->bpp / 8;
++ else
++ ovl->pitch = ovl->xres;
++
++ /* Allocate frame buffer memory. */
++ ovl->fb_size = ovl->cfg->max_xres * ovl->cfg->max_yres
++ * format->bpp / 8 * 2;
++ ovl->fb_mem = dma_alloc_coherent(priv->dev, ovl->fb_size,
++ &ovl->dma_handle, GFP_KERNEL);
++ if (!ovl->fb_mem) {
++ dev_err(priv->dev, "unable to allocate buffer\n");
++ return -ENOMEM;
++ }
++
++ ret = sh_mobile_lcdc_overlay_fb_init(ovl);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++static int __devinit
+ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
+ struct sh_mobile_lcdc_chan *ch)
+ {
+@@ -2005,6 +2774,17 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
+ goto err1;
+ }
+
++ for (i = 0; i < ARRAY_SIZE(pdata->overlays); i++) {
++ struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[i];
++
++ ovl->cfg = &pdata->overlays[i];
++ ovl->channel = &priv->ch[0];
++
++ error = sh_mobile_lcdc_overlay_init(priv, ovl);
++ if (error)
++ goto err1;
++ }
++
+ error = sh_mobile_lcdc_start(priv);
+ if (error) {
+ dev_err(&pdev->dev, "unable to start hardware\n");
+@@ -2019,6 +2799,14 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
+ goto err1;
+ }
+
++ for (i = 0; i < ARRAY_SIZE(pdata->overlays); i++) {
++ struct sh_mobile_lcdc_overlay *ovl = &priv->overlays[i];
++
++ error = sh_mobile_lcdc_overlay_fb_register(ovl);
++ if (error)
++ goto err1;
++ }
++
+ /* Failure ignored */
+ priv->notifier.notifier_call = sh_mobile_lcdc_notify;
+ fb_register_client(&priv->notifier);
+diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
+index 7571b27..ff43ffc 100644
+--- a/include/video/sh_mobile_lcdc.h
++++ b/include/video/sh_mobile_lcdc.h
+@@ -166,6 +166,12 @@ struct sh_mobile_lcdc_bl_info {
+ int (*get_brightness)(void);
+ };
+
++struct sh_mobile_lcdc_overlay_cfg {
++ int fourcc;
++ unsigned int max_xres;
++ unsigned int max_yres;
++};
++
+ struct sh_mobile_lcdc_chan_cfg {
+ int chan;
+ int fourcc;
+@@ -186,6 +192,7 @@ struct sh_mobile_lcdc_chan_cfg {
+ struct sh_mobile_lcdc_info {
+ int clock_source;
+ struct sh_mobile_lcdc_chan_cfg ch[2];
++ struct sh_mobile_lcdc_overlay_cfg overlays[4];
+ struct sh_mobile_meram_info *meram_dev;
+ };
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0042-sh_mobile_meram-Rename-operations-to-cache_-alloc-fr.patch b/patches.armadillo800/0042-sh_mobile_meram-Rename-operations-to-cache_-alloc-fr.patch
new file mode 100644
index 0000000000000..84b5cc703c4c6
--- /dev/null
+++ b/patches.armadillo800/0042-sh_mobile_meram-Rename-operations-to-cache_-alloc-fr.patch
@@ -0,0 +1,425 @@
+From 5175271a2ba2d97d73adadcaca3ba6b6616b6f23 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Thu, 15 Mar 2012 12:40:47 +0100
+Subject: sh_mobile_meram: Rename operations to cache_[alloc|free|update]
+
+The MERAM operations meram_register, meram_unregister and meram_update
+handle LCDC cache. In preparation for "raw" MERAM allocation, rename
+them to more appropriate names.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+(cherry picked from commit 4a2371772146b30113c9c837eb32b64f18376c0d)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_lcdcfb.c | 32 ++++---
+ drivers/video/sh_mobile_lcdcfb.h | 2 +-
+ drivers/video/sh_mobile_meram.c | 176 +++++++++++++++++++--------------------
+ include/video/sh_mobile_meram.h | 21 ++---
+ 4 files changed, 110 insertions(+), 121 deletions(-)
+
+diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
+index 98e81b3..e593e81 100644
+--- a/drivers/video/sh_mobile_lcdcfb.c
++++ b/drivers/video/sh_mobile_lcdcfb.c
+@@ -1104,7 +1104,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
+ /* Compute frame buffer base address and pitch for each channel. */
+ for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
+ int pixelformat;
+- void *meram;
++ void *cache;
+
+ ch = &priv->ch[k];
+ if (!ch->enabled)
+@@ -1119,12 +1119,10 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
+ ch->cfg->meram_cfg == NULL)
+ continue;
+
+- /* we need to de-init configured ICBs before we can
+- * re-initialize them.
+- */
+- if (ch->meram) {
+- mdev->ops->meram_unregister(mdev, ch->meram);
+- ch->meram = NULL;
++ /* Free the allocated MERAM cache. */
++ if (ch->cache) {
++ mdev->ops->cache_free(mdev, ch->cache);
++ ch->cache = NULL;
+ }
+
+ switch (ch->format->fourcc) {
+@@ -1146,14 +1144,14 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
+ break;
+ }
+
+- meram = mdev->ops->meram_register(mdev, ch->cfg->meram_cfg,
++ cache = mdev->ops->cache_alloc(mdev, ch->cfg->meram_cfg,
+ ch->pitch, ch->yres, pixelformat,
+ &ch->line_size);
+- if (!IS_ERR(meram)) {
+- mdev->ops->meram_update(mdev, meram,
++ if (!IS_ERR(cache)) {
++ mdev->ops->cache_update(mdev, cache,
+ ch->base_addr_y, ch->base_addr_c,
+ &ch->base_addr_y, &ch->base_addr_c);
+- ch->meram = meram;
++ ch->cache = cache;
+ }
+ }
+
+@@ -1223,12 +1221,12 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
+
+ sh_mobile_lcdc_display_off(ch);
+
+- /* disable the meram */
+- if (ch->meram) {
++ /* Free the MERAM cache. */
++ if (ch->cache) {
+ struct sh_mobile_meram_info *mdev;
+ mdev = priv->meram_dev;
+- mdev->ops->meram_unregister(mdev, ch->meram);
+- ch->meram = 0;
++ mdev->ops->cache_free(mdev, ch->cache);
++ ch->cache = 0;
+ }
+
+ }
+@@ -1839,11 +1837,11 @@ static int sh_mobile_lcdc_pan(struct fb_var_screeninfo *var,
+ base_addr_c += var->xoffset;
+ }
+
+- if (ch->meram) {
++ if (ch->cache) {
+ struct sh_mobile_meram_info *mdev;
+
+ mdev = priv->meram_dev;
+- mdev->ops->meram_update(mdev, ch->meram,
++ mdev->ops->cache_update(mdev, ch->cache,
+ base_addr_y, base_addr_c,
+ &base_addr_y, &base_addr_c);
+ }
+diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
+index 5c3bddd..e53cd11 100644
+--- a/drivers/video/sh_mobile_lcdcfb.h
++++ b/drivers/video/sh_mobile_lcdcfb.h
+@@ -59,7 +59,7 @@ struct sh_mobile_lcdc_chan {
+ unsigned long *reg_offs;
+ unsigned long ldmt1r_value;
+ unsigned long enabled; /* ME and SE in LDCNT2R */
+- void *meram;
++ void *cache;
+
+ struct mutex open_lock; /* protects the use counter */
+ int use_count;
+diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
+index 82ba830..4aa3fcb 100644
+--- a/drivers/video/sh_mobile_meram.c
++++ b/drivers/video/sh_mobile_meram.c
+@@ -194,13 +194,13 @@ static inline unsigned long meram_read_reg(void __iomem *base, unsigned int off)
+ }
+
+ /* -----------------------------------------------------------------------------
+- * Allocation
++ * LCDC cache planes allocation, init, cleanup and free
+ */
+
+ /* Allocate ICBs and MERAM for a plane. */
+-static int __meram_alloc(struct sh_mobile_meram_priv *priv,
+- struct sh_mobile_meram_fb_plane *plane,
+- size_t size)
++static int meram_plane_alloc(struct sh_mobile_meram_priv *priv,
++ struct sh_mobile_meram_fb_plane *plane,
++ size_t size)
+ {
+ unsigned long mem;
+ unsigned long idx;
+@@ -229,8 +229,8 @@ static int __meram_alloc(struct sh_mobile_meram_priv *priv,
+ }
+
+ /* Free ICBs and MERAM for a plane. */
+-static void __meram_free(struct sh_mobile_meram_priv *priv,
+- struct sh_mobile_meram_fb_plane *plane)
++static void meram_plane_free(struct sh_mobile_meram_priv *priv,
++ struct sh_mobile_meram_fb_plane *plane)
+ {
+ gen_pool_free(priv->pool, priv->meram + plane->marker->offset,
+ plane->marker->size * 1024);
+@@ -248,62 +248,6 @@ static int is_nvcolor(int cspace)
+ return 0;
+ }
+
+-/* Allocate memory for the ICBs and mark them as used. */
+-static struct sh_mobile_meram_fb_cache *
+-meram_alloc(struct sh_mobile_meram_priv *priv,
+- const struct sh_mobile_meram_cfg *cfg,
+- int pixelformat)
+-{
+- struct sh_mobile_meram_fb_cache *cache;
+- unsigned int nplanes = is_nvcolor(pixelformat) ? 2 : 1;
+- int ret;
+-
+- if (cfg->icb[0].meram_size == 0)
+- return ERR_PTR(-EINVAL);
+-
+- if (nplanes == 2 && cfg->icb[1].meram_size == 0)
+- return ERR_PTR(-EINVAL);
+-
+- cache = kzalloc(sizeof(*cache), GFP_KERNEL);
+- if (cache == NULL)
+- return ERR_PTR(-ENOMEM);
+-
+- cache->nplanes = nplanes;
+-
+- ret = __meram_alloc(priv, &cache->planes[0], cfg->icb[0].meram_size);
+- if (ret < 0)
+- goto error;
+-
+- cache->planes[0].marker->current_reg = 1;
+- cache->planes[0].marker->pixelformat = pixelformat;
+-
+- if (cache->nplanes == 1)
+- return cache;
+-
+- ret = __meram_alloc(priv, &cache->planes[1], cfg->icb[1].meram_size);
+- if (ret < 0) {
+- __meram_free(priv, &cache->planes[0]);
+- goto error;
+- }
+-
+- return cache;
+-
+-error:
+- kfree(cache);
+- return ERR_PTR(-ENOMEM);
+-}
+-
+-/* Unmark the specified ICB as used. */
+-static void meram_free(struct sh_mobile_meram_priv *priv,
+- struct sh_mobile_meram_fb_cache *cache)
+-{
+- __meram_free(priv, &cache->planes[0]);
+- if (cache->nplanes == 2)
+- __meram_free(priv, &cache->planes[1]);
+-
+- kfree(cache);
+-}
+-
+ /* Set the next address to fetch. */
+ static void meram_set_next_addr(struct sh_mobile_meram_priv *priv,
+ struct sh_mobile_meram_fb_cache *cache,
+@@ -355,10 +299,10 @@ meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata,
+ (((x) * (y) + (MERAM_LINE_WIDTH - 1)) & ~(MERAM_LINE_WIDTH - 1))
+
+ /* Initialize MERAM. */
+-static int meram_init(struct sh_mobile_meram_priv *priv,
+- struct sh_mobile_meram_fb_plane *plane,
+- unsigned int xres, unsigned int yres,
+- unsigned int *out_pitch)
++static int meram_plane_init(struct sh_mobile_meram_priv *priv,
++ struct sh_mobile_meram_fb_plane *plane,
++ unsigned int xres, unsigned int yres,
++ unsigned int *out_pitch)
+ {
+ struct sh_mobile_meram_icb *marker = plane->marker;
+ unsigned long total_byte_count = MERAM_CALC_BYTECOUNT(xres, yres);
+@@ -427,8 +371,8 @@ static int meram_init(struct sh_mobile_meram_priv *priv,
+ return 0;
+ }
+
+-static void meram_deinit(struct sh_mobile_meram_priv *priv,
+- struct sh_mobile_meram_fb_plane *plane)
++static void meram_plane_cleanup(struct sh_mobile_meram_priv *priv,
++ struct sh_mobile_meram_fb_plane *plane)
+ {
+ /* disable ICB */
+ meram_write_icb(priv->base, plane->cache->index, MExxCTL,
+@@ -441,18 +385,60 @@ static void meram_deinit(struct sh_mobile_meram_priv *priv,
+ }
+
+ /* -----------------------------------------------------------------------------
+- * Registration/unregistration
++ * LCDC cache operations
+ */
+
+-static void *sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
+- const struct sh_mobile_meram_cfg *cfg,
+- unsigned int xres, unsigned int yres,
+- unsigned int pixelformat,
+- unsigned int *pitch)
++/* Allocate memory for the ICBs and mark them as used. */
++static struct sh_mobile_meram_fb_cache *
++meram_cache_alloc(struct sh_mobile_meram_priv *priv,
++ const struct sh_mobile_meram_cfg *cfg,
++ int pixelformat)
++{
++ unsigned int nplanes = is_nvcolor(pixelformat) ? 2 : 1;
++ struct sh_mobile_meram_fb_cache *cache;
++ int ret;
++
++ cache = kzalloc(sizeof(*cache), GFP_KERNEL);
++ if (cache == NULL)
++ return ERR_PTR(-ENOMEM);
++
++ cache->nplanes = nplanes;
++
++ ret = meram_plane_alloc(priv, &cache->planes[0],
++ cfg->icb[0].meram_size);
++ if (ret < 0)
++ goto error;
++
++ cache->planes[0].marker->current_reg = 1;
++ cache->planes[0].marker->pixelformat = pixelformat;
++
++ if (cache->nplanes == 1)
++ return cache;
++
++ ret = meram_plane_alloc(priv, &cache->planes[1],
++ cfg->icb[1].meram_size);
++ if (ret < 0) {
++ meram_plane_free(priv, &cache->planes[0]);
++ goto error;
++ }
++
++ return cache;
++
++error:
++ kfree(cache);
++ return ERR_PTR(-ENOMEM);
++}
++
++static void *sh_mobile_cache_alloc(struct sh_mobile_meram_info *pdata,
++ const struct sh_mobile_meram_cfg *cfg,
++ unsigned int xres, unsigned int yres,
++ unsigned int pixelformat,
++ unsigned int *pitch)
+ {
+ struct sh_mobile_meram_fb_cache *cache;
+ struct sh_mobile_meram_priv *priv = pdata->priv;
+ struct platform_device *pdev = pdata->pdev;
++ unsigned int nplanes = is_nvcolor(pixelformat) ? 2 : 1;
+ unsigned int out_pitch;
+
+ if (pixelformat != SH_MOBILE_MERAM_PF_NV &&
+@@ -469,10 +455,16 @@ static void *sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
+ return ERR_PTR(-EINVAL);
+ }
+
++ if (cfg->icb[0].meram_size == 0)
++ return ERR_PTR(-EINVAL);
++
++ if (nplanes == 2 && cfg->icb[1].meram_size == 0)
++ return ERR_PTR(-EINVAL);
++
+ mutex_lock(&priv->lock);
+
+ /* We now register the ICBs and allocate the MERAM regions. */
+- cache = meram_alloc(priv, cfg, pixelformat);
++ cache = meram_cache_alloc(priv, cfg, pixelformat);
+ if (IS_ERR(cache)) {
+ dev_err(&pdev->dev, "MERAM allocation failed (%ld).",
+ PTR_ERR(cache));
+@@ -480,14 +472,14 @@ static void *sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
+ }
+
+ /* initialize MERAM */
+- meram_init(priv, &cache->planes[0], xres, yres, &out_pitch);
++ meram_plane_init(priv, &cache->planes[0], xres, yres, &out_pitch);
+ *pitch = out_pitch;
+ if (pixelformat == SH_MOBILE_MERAM_PF_NV)
+- meram_init(priv, &cache->planes[1], xres, (yres + 1) / 2,
+- &out_pitch);
++ meram_plane_init(priv, &cache->planes[1],
++ xres, (yres + 1) / 2, &out_pitch);
+ else if (pixelformat == SH_MOBILE_MERAM_PF_NV24)
+- meram_init(priv, &cache->planes[1], 2 * xres, (yres + 1) / 2,
+- &out_pitch);
++ meram_plane_init(priv, &cache->planes[1],
++ 2 * xres, (yres + 1) / 2, &out_pitch);
+
+ err:
+ mutex_unlock(&priv->lock);
+@@ -495,25 +487,29 @@ err:
+ }
+
+ static void
+-sh_mobile_meram_unregister(struct sh_mobile_meram_info *pdata, void *data)
++sh_mobile_cache_free(struct sh_mobile_meram_info *pdata, void *data)
+ {
+ struct sh_mobile_meram_fb_cache *cache = data;
+ struct sh_mobile_meram_priv *priv = pdata->priv;
+
+ mutex_lock(&priv->lock);
+
+- /* deinit & free */
+- meram_deinit(priv, &cache->planes[0]);
+- if (cache->nplanes == 2)
+- meram_deinit(priv, &cache->planes[1]);
++ /* Cleanup and free. */
++ meram_plane_cleanup(priv, &cache->planes[0]);
++ meram_plane_free(priv, &cache->planes[0]);
+
+- meram_free(priv, cache);
++ if (cache->nplanes == 2) {
++ meram_plane_cleanup(priv, &cache->planes[1]);
++ meram_plane_free(priv, &cache->planes[1]);
++ }
++
++ kfree(cache);
+
+ mutex_unlock(&priv->lock);
+ }
+
+ static void
+-sh_mobile_meram_update(struct sh_mobile_meram_info *pdata, void *data,
++sh_mobile_cache_update(struct sh_mobile_meram_info *pdata, void *data,
+ unsigned long base_addr_y, unsigned long base_addr_c,
+ unsigned long *icb_addr_y, unsigned long *icb_addr_c)
+ {
+@@ -530,9 +526,9 @@ sh_mobile_meram_update(struct sh_mobile_meram_info *pdata, void *data,
+
+ static struct sh_mobile_meram_ops sh_mobile_meram_ops = {
+ .module = THIS_MODULE,
+- .meram_register = sh_mobile_meram_register,
+- .meram_unregister = sh_mobile_meram_unregister,
+- .meram_update = sh_mobile_meram_update,
++ .cache_alloc = sh_mobile_cache_alloc,
++ .cache_free = sh_mobile_cache_free,
++ .cache_update = sh_mobile_cache_update,
+ };
+
+ /* -----------------------------------------------------------------------------
+diff --git a/include/video/sh_mobile_meram.h b/include/video/sh_mobile_meram.h
+index 29b2fd3..8a5afaf 100644
+--- a/include/video/sh_mobile_meram.h
++++ b/include/video/sh_mobile_meram.h
+@@ -41,19 +41,14 @@ struct sh_mobile_meram_cfg {
+ struct module;
+ struct sh_mobile_meram_ops {
+ struct module *module;
+- /* register usage of meram */
+- void *(*meram_register)(struct sh_mobile_meram_info *meram_dev,
+- const struct sh_mobile_meram_cfg *cfg,
+- unsigned int xres, unsigned int yres,
+- unsigned int pixelformat,
+- unsigned int *pitch);
+-
+- /* unregister usage of meram */
+- void (*meram_unregister)(struct sh_mobile_meram_info *meram_dev,
+- void *data);
+-
+- /* update meram settings */
+- void (*meram_update)(struct sh_mobile_meram_info *meram_dev, void *data,
++
++ /* LCDC cache management */
++ void *(*cache_alloc)(struct sh_mobile_meram_info *meram_dev,
++ const struct sh_mobile_meram_cfg *cfg,
++ unsigned int xres, unsigned int yres,
++ unsigned int pixelformat, unsigned int *pitch);
++ void (*cache_free)(struct sh_mobile_meram_info *meram_dev, void *data);
++ void (*cache_update)(struct sh_mobile_meram_info *meram_dev, void *data,
+ unsigned long base_addr_y,
+ unsigned long base_addr_c,
+ unsigned long *icb_addr_y,
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0043-sh_mobile_meram-Use-direct-function-calls-for-the-pu.patch b/patches.armadillo800/0043-sh_mobile_meram-Use-direct-function-calls-for-the-pu.patch
new file mode 100644
index 0000000000000..64653c1fbaa3a
--- /dev/null
+++ b/patches.armadillo800/0043-sh_mobile_meram-Use-direct-function-calls-for-the-pu.patch
@@ -0,0 +1,265 @@
+From b8fe39bce6f2c38cfa04299077173aff50600687 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Thu, 15 Mar 2012 12:40:47 +0100
+Subject: sh_mobile_meram: Use direct function calls for the public API
+
+There's no reason to use abstract operation pointers to implement the
+MERAM API. Replace them by direct function calls.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+(cherry picked from commit 6e729b416b44296f5ed503b40ac58c2bffb43caf)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_lcdcfb.c | 27 ++++++++--------------
+ drivers/video/sh_mobile_meram.c | 40 ++++++++++++++++----------------
+ include/video/sh_mobile_meram.h | 50 ++++++++++++++++++++++++++++------------
+ 3 files changed, 65 insertions(+), 52 deletions(-)
+
+diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
+index e593e81..9da4b1b6 100644
+--- a/drivers/video/sh_mobile_lcdcfb.c
++++ b/drivers/video/sh_mobile_lcdcfb.c
+@@ -1115,13 +1115,12 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
+ ch->line_size = ch->pitch;
+
+ /* Enable MERAM if possible. */
+- if (mdev == NULL || mdev->ops == NULL ||
+- ch->cfg->meram_cfg == NULL)
++ if (mdev == NULL || ch->cfg->meram_cfg == NULL)
+ continue;
+
+ /* Free the allocated MERAM cache. */
+ if (ch->cache) {
+- mdev->ops->cache_free(mdev, ch->cache);
++ sh_mobile_meram_cache_free(mdev, ch->cache);
+ ch->cache = NULL;
+ }
+
+@@ -1144,11 +1143,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
+ break;
+ }
+
+- cache = mdev->ops->cache_alloc(mdev, ch->cfg->meram_cfg,
++ cache = sh_mobile_meram_cache_alloc(mdev, ch->cfg->meram_cfg,
+ ch->pitch, ch->yres, pixelformat,
+ &ch->line_size);
+ if (!IS_ERR(cache)) {
+- mdev->ops->cache_update(mdev, cache,
++ sh_mobile_meram_cache_update(mdev, cache,
+ ch->base_addr_y, ch->base_addr_c,
+ &ch->base_addr_y, &ch->base_addr_c);
+ ch->cache = cache;
+@@ -1223,9 +1222,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
+
+ /* Free the MERAM cache. */
+ if (ch->cache) {
+- struct sh_mobile_meram_info *mdev;
+- mdev = priv->meram_dev;
+- mdev->ops->cache_free(mdev, ch->cache);
++ sh_mobile_meram_cache_free(priv->meram_dev, ch->cache);
+ ch->cache = 0;
+ }
+
+@@ -1808,7 +1805,7 @@ static int sh_mobile_lcdc_pan(struct fb_var_screeninfo *var,
+ struct sh_mobile_lcdc_priv *priv = ch->lcdc;
+ unsigned long ldrcntr;
+ unsigned long new_pan_offset;
+- unsigned long base_addr_y, base_addr_c;
++ unsigned long base_addr_y, base_addr_c = 0;
+ unsigned long c_offset;
+
+ if (!ch->format->yuv)
+@@ -1837,14 +1834,10 @@ static int sh_mobile_lcdc_pan(struct fb_var_screeninfo *var,
+ base_addr_c += var->xoffset;
+ }
+
+- if (ch->cache) {
+- struct sh_mobile_meram_info *mdev;
+-
+- mdev = priv->meram_dev;
+- mdev->ops->cache_update(mdev, ch->cache,
+- base_addr_y, base_addr_c,
+- &base_addr_y, &base_addr_c);
+- }
++ if (ch->cache)
++ sh_mobile_meram_cache_update(priv->meram_dev, ch->cache,
++ base_addr_y, base_addr_c,
++ &base_addr_y, &base_addr_c);
+
+ ch->base_addr_y = base_addr_y;
+ ch->base_addr_c = base_addr_c;
+diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
+index 4aa3fcb..fdb6fc1 100644
+--- a/drivers/video/sh_mobile_meram.c
++++ b/drivers/video/sh_mobile_meram.c
+@@ -11,6 +11,7 @@
+
+ #include <linux/device.h>
+ #include <linux/err.h>
++#include <linux/export.h>
+ #include <linux/genalloc.h>
+ #include <linux/io.h>
+ #include <linux/kernel.h>
+@@ -429,11 +430,10 @@ error:
+ return ERR_PTR(-ENOMEM);
+ }
+
+-static void *sh_mobile_cache_alloc(struct sh_mobile_meram_info *pdata,
+- const struct sh_mobile_meram_cfg *cfg,
+- unsigned int xres, unsigned int yres,
+- unsigned int pixelformat,
+- unsigned int *pitch)
++void *sh_mobile_meram_cache_alloc(struct sh_mobile_meram_info *pdata,
++ const struct sh_mobile_meram_cfg *cfg,
++ unsigned int xres, unsigned int yres,
++ unsigned int pixelformat, unsigned int *pitch)
+ {
+ struct sh_mobile_meram_fb_cache *cache;
+ struct sh_mobile_meram_priv *priv = pdata->priv;
+@@ -441,6 +441,9 @@ static void *sh_mobile_cache_alloc(struct sh_mobile_meram_info *pdata,
+ unsigned int nplanes = is_nvcolor(pixelformat) ? 2 : 1;
+ unsigned int out_pitch;
+
++ if (priv == NULL)
++ return ERR_PTR(-ENODEV);
++
+ if (pixelformat != SH_MOBILE_MERAM_PF_NV &&
+ pixelformat != SH_MOBILE_MERAM_PF_NV24 &&
+ pixelformat != SH_MOBILE_MERAM_PF_RGB)
+@@ -485,9 +488,10 @@ err:
+ mutex_unlock(&priv->lock);
+ return cache;
+ }
++EXPORT_SYMBOL_GPL(sh_mobile_meram_cache_alloc);
+
+-static void
+-sh_mobile_cache_free(struct sh_mobile_meram_info *pdata, void *data)
++void
++sh_mobile_meram_cache_free(struct sh_mobile_meram_info *pdata, void *data)
+ {
+ struct sh_mobile_meram_fb_cache *cache = data;
+ struct sh_mobile_meram_priv *priv = pdata->priv;
+@@ -507,11 +511,14 @@ sh_mobile_cache_free(struct sh_mobile_meram_info *pdata, void *data)
+
+ mutex_unlock(&priv->lock);
+ }
+-
+-static void
+-sh_mobile_cache_update(struct sh_mobile_meram_info *pdata, void *data,
+- unsigned long base_addr_y, unsigned long base_addr_c,
+- unsigned long *icb_addr_y, unsigned long *icb_addr_c)
++EXPORT_SYMBOL_GPL(sh_mobile_meram_cache_free);
++
++void
++sh_mobile_meram_cache_update(struct sh_mobile_meram_info *pdata, void *data,
++ unsigned long base_addr_y,
++ unsigned long base_addr_c,
++ unsigned long *icb_addr_y,
++ unsigned long *icb_addr_c)
+ {
+ struct sh_mobile_meram_fb_cache *cache = data;
+ struct sh_mobile_meram_priv *priv = pdata->priv;
+@@ -523,13 +530,7 @@ sh_mobile_cache_update(struct sh_mobile_meram_info *pdata, void *data,
+
+ mutex_unlock(&priv->lock);
+ }
+-
+-static struct sh_mobile_meram_ops sh_mobile_meram_ops = {
+- .module = THIS_MODULE,
+- .cache_alloc = sh_mobile_cache_alloc,
+- .cache_free = sh_mobile_cache_free,
+- .cache_update = sh_mobile_cache_update,
+-};
++EXPORT_SYMBOL_GPL(sh_mobile_meram_cache_update);
+
+ /* -----------------------------------------------------------------------------
+ * Power management
+@@ -620,7 +621,6 @@ static int __devinit sh_mobile_meram_probe(struct platform_device *pdev)
+ for (i = 0; i < MERAM_ICB_NUM; ++i)
+ priv->icbs[i].index = i;
+
+- pdata->ops = &sh_mobile_meram_ops;
+ pdata->priv = priv;
+ pdata->pdev = pdev;
+
+diff --git a/include/video/sh_mobile_meram.h b/include/video/sh_mobile_meram.h
+index 8a5afaf..1134837 100644
+--- a/include/video/sh_mobile_meram.h
++++ b/include/video/sh_mobile_meram.h
+@@ -15,7 +15,6 @@ enum {
+
+
+ struct sh_mobile_meram_priv;
+-struct sh_mobile_meram_ops;
+
+ /*
+ * struct sh_mobile_meram_info - MERAM platform data
+@@ -24,7 +23,6 @@ struct sh_mobile_meram_ops;
+ struct sh_mobile_meram_info {
+ int addr_mode;
+ u32 reserved_icbs;
+- struct sh_mobile_meram_ops *ops;
+ struct sh_mobile_meram_priv *priv;
+ struct platform_device *pdev;
+ };
+@@ -38,21 +36,43 @@ struct sh_mobile_meram_cfg {
+ struct sh_mobile_meram_icb_cfg icb[2];
+ };
+
+-struct module;
+-struct sh_mobile_meram_ops {
+- struct module *module;
+-
+- /* LCDC cache management */
+- void *(*cache_alloc)(struct sh_mobile_meram_info *meram_dev,
+- const struct sh_mobile_meram_cfg *cfg,
+- unsigned int xres, unsigned int yres,
+- unsigned int pixelformat, unsigned int *pitch);
+- void (*cache_free)(struct sh_mobile_meram_info *meram_dev, void *data);
+- void (*cache_update)(struct sh_mobile_meram_info *meram_dev, void *data,
++#if defined(CONFIG_FB_SH_MOBILE_MERAM) || \
++ defined(CONFIG_FB_SH_MOBILE_MERAM_MODULE)
++void *sh_mobile_meram_cache_alloc(struct sh_mobile_meram_info *dev,
++ const struct sh_mobile_meram_cfg *cfg,
++ unsigned int xres, unsigned int yres,
++ unsigned int pixelformat,
++ unsigned int *pitch);
++void sh_mobile_meram_cache_free(struct sh_mobile_meram_info *dev, void *data);
++void sh_mobile_meram_cache_update(struct sh_mobile_meram_info *dev, void *data,
++ unsigned long base_addr_y,
++ unsigned long base_addr_c,
++ unsigned long *icb_addr_y,
++ unsigned long *icb_addr_c);
++#else
++static inline void *
++sh_mobile_meram_cache_alloc(struct sh_mobile_meram_info *dev,
++ const struct sh_mobile_meram_cfg *cfg,
++ unsigned int xres, unsigned int yres,
++ unsigned int pixelformat,
++ unsigned int *pitch)
++{
++ return ERR_PTR(-ENODEV);
++}
++
++static inline void
++sh_mobile_meram_cache_free(struct sh_mobile_meram_info *dev, void *data)
++{
++}
++
++static inline void
++sh_mobile_meram_cache_update(struct sh_mobile_meram_info *dev, void *data,
+ unsigned long base_addr_y,
+ unsigned long base_addr_c,
+ unsigned long *icb_addr_y,
+- unsigned long *icb_addr_c);
+-};
++ unsigned long *icb_addr_c)
++{
++}
++#endif
+
+ #endif /* __VIDEO_SH_MOBILE_MERAM_H__ */
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0044-sh_mobile_meram-Add-direct-MERAM-allocation-API.patch b/patches.armadillo800/0044-sh_mobile_meram-Add-direct-MERAM-allocation-API.patch
new file mode 100644
index 0000000000000..0602f7715b36c
--- /dev/null
+++ b/patches.armadillo800/0044-sh_mobile_meram-Add-direct-MERAM-allocation-API.patch
@@ -0,0 +1,129 @@
+From 81c446ad9189a068ef555c436c96d651dc86c4da Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Thu, 15 Mar 2012 13:18:17 +0100
+Subject: sh_mobile_meram: Add direct MERAM allocation API
+
+The API can be used to allocate and free MERAM blocks directly, without
+going through ICBs.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+(cherry picked from commit 239921ec1d969e904676f444a92e6d68a928d98c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_meram.c | 41 +++++++++++++++++++++++++++++++++++++----
+ include/video/sh_mobile_meram.h | 16 ++++++++++++++++
+ 2 files changed, 53 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
+index fdb6fc1..7a0ba8b 100644
+--- a/drivers/video/sh_mobile_meram.c
++++ b/drivers/video/sh_mobile_meram.c
+@@ -195,6 +195,21 @@ static inline unsigned long meram_read_reg(void __iomem *base, unsigned int off)
+ }
+
+ /* -----------------------------------------------------------------------------
++ * MERAM allocation and free
++ */
++
++static unsigned long meram_alloc(struct sh_mobile_meram_priv *priv, size_t size)
++{
++ return gen_pool_alloc(priv->pool, size);
++}
++
++static void meram_free(struct sh_mobile_meram_priv *priv, unsigned long mem,
++ size_t size)
++{
++ gen_pool_free(priv->pool, mem, size);
++}
++
++/* -----------------------------------------------------------------------------
+ * LCDC cache planes allocation, init, cleanup and free
+ */
+
+@@ -216,7 +231,7 @@ static int meram_plane_alloc(struct sh_mobile_meram_priv *priv,
+ return -ENOMEM;
+ plane->marker = &priv->icbs[idx];
+
+- mem = gen_pool_alloc(priv->pool, size * 1024);
++ mem = meram_alloc(priv, size * 1024);
+ if (mem == 0)
+ return -ENOMEM;
+
+@@ -233,8 +248,8 @@ static int meram_plane_alloc(struct sh_mobile_meram_priv *priv,
+ static void meram_plane_free(struct sh_mobile_meram_priv *priv,
+ struct sh_mobile_meram_fb_plane *plane)
+ {
+- gen_pool_free(priv->pool, priv->meram + plane->marker->offset,
+- plane->marker->size * 1024);
++ meram_free(priv, priv->meram + plane->marker->offset,
++ plane->marker->size * 1024);
+
+ __clear_bit(plane->marker->index, &priv->used_icb);
+ __clear_bit(plane->cache->index, &priv->used_icb);
+@@ -386,9 +401,27 @@ static void meram_plane_cleanup(struct sh_mobile_meram_priv *priv,
+ }
+
+ /* -----------------------------------------------------------------------------
+- * LCDC cache operations
++ * MERAM operations
+ */
+
++unsigned long sh_mobile_meram_alloc(struct sh_mobile_meram_info *pdata,
++ size_t size)
++{
++ struct sh_mobile_meram_priv *priv = pdata->priv;
++
++ return meram_alloc(priv, size);
++}
++EXPORT_SYMBOL_GPL(sh_mobile_meram_alloc);
++
++void sh_mobile_meram_free(struct sh_mobile_meram_info *pdata, unsigned long mem,
++ size_t size)
++{
++ struct sh_mobile_meram_priv *priv = pdata->priv;
++
++ meram_free(priv, mem, size);
++}
++EXPORT_SYMBOL_GPL(sh_mobile_meram_free);
++
+ /* Allocate memory for the ICBs and mark them as used. */
+ static struct sh_mobile_meram_fb_cache *
+ meram_cache_alloc(struct sh_mobile_meram_priv *priv,
+diff --git a/include/video/sh_mobile_meram.h b/include/video/sh_mobile_meram.h
+index 1134837..062e6e7 100644
+--- a/include/video/sh_mobile_meram.h
++++ b/include/video/sh_mobile_meram.h
+@@ -38,6 +38,10 @@ struct sh_mobile_meram_cfg {
+
+ #if defined(CONFIG_FB_SH_MOBILE_MERAM) || \
+ defined(CONFIG_FB_SH_MOBILE_MERAM_MODULE)
++unsigned long sh_mobile_meram_alloc(struct sh_mobile_meram_info *meram_dev,
++ size_t size);
++void sh_mobile_meram_free(struct sh_mobile_meram_info *meram_dev,
++ unsigned long mem, size_t size);
+ void *sh_mobile_meram_cache_alloc(struct sh_mobile_meram_info *dev,
+ const struct sh_mobile_meram_cfg *cfg,
+ unsigned int xres, unsigned int yres,
+@@ -50,6 +54,18 @@ void sh_mobile_meram_cache_update(struct sh_mobile_meram_info *dev, void *data,
+ unsigned long *icb_addr_y,
+ unsigned long *icb_addr_c);
+ #else
++static inline unsigned long
++sh_mobile_meram_alloc(struct sh_mobile_meram_info *meram_dev, size_t size)
++{
++ return 0;
++}
++
++static inline void
++sh_mobile_meram_free(struct sh_mobile_meram_info *meram_dev,
++ unsigned long mem, size_t size)
++{
++}
++
+ static inline void *
+ sh_mobile_meram_cache_alloc(struct sh_mobile_meram_info *dev,
+ const struct sh_mobile_meram_cfg *cfg,
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0045-fbdev-sh_mobile_lcdc-Destroy-mutex-at-remove-time.patch b/patches.armadillo800/0045-fbdev-sh_mobile_lcdc-Destroy-mutex-at-remove-time.patch
new file mode 100644
index 0000000000000..3df2f9ab9ecef
--- /dev/null
+++ b/patches.armadillo800/0045-fbdev-sh_mobile_lcdc-Destroy-mutex-at-remove-time.patch
@@ -0,0 +1,37 @@
+From fbcfe8a409c3a0177d599e2b6a73a70fd4dffc8a Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Thu, 15 Mar 2012 18:34:05 +0100
+Subject: fbdev: sh_mobile_lcdc: Destroy mutex at remove time
+
+Add a missing mutex_destroy() call when the driver is unbound from the
+device.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+(cherry picked from commit 0c75c4e073a8ec35bfd6c8adcceb2b896f2063e2)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_lcdcfb.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
+index 9da4b1b6..644c230 100644
+--- a/drivers/video/sh_mobile_lcdcfb.c
++++ b/drivers/video/sh_mobile_lcdcfb.c
+@@ -2444,8 +2444,11 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
+ }
+
+ for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
+- if (priv->ch[i].bl)
+- sh_mobile_lcdc_bl_remove(priv->ch[i].bl);
++ struct sh_mobile_lcdc_chan *ch = &priv->ch[i];
++
++ if (ch->bl)
++ sh_mobile_lcdc_bl_remove(ch->bl);
++ mutex_destroy(&ch->open_lock);
+ }
+
+ if (priv->dot_clk) {
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0046-fbdev-sh_mobile_lcdc-Fix-line-pitch-computation.patch b/patches.armadillo800/0046-fbdev-sh_mobile_lcdc-Fix-line-pitch-computation.patch
new file mode 100644
index 0000000000000..378217b52603d
--- /dev/null
+++ b/patches.armadillo800/0046-fbdev-sh_mobile_lcdc-Fix-line-pitch-computation.patch
@@ -0,0 +1,72 @@
+From 8a18c739cb6639c5b8e43cc19929f98c532afae7 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Wed, 18 Jul 2012 16:29:20 +0200
+Subject: fbdev: sh_mobile_lcdc: Fix line pitch computation
+
+Line pitch depends on the virtual horizontal resolution, compute it
+accordingly.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+(cherry picked from commit 16ca21c9a9f64577221c47d8d2f00d13b880aefa)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_lcdcfb.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
+index 644c230..67877cc 100644
+--- a/drivers/video/sh_mobile_lcdcfb.c
++++ b/drivers/video/sh_mobile_lcdcfb.c
+@@ -1580,9 +1580,9 @@ static int sh_mobile_lcdc_overlay_set_par(struct fb_info *info)
+ ovl->yres_virtual = info->var.yres_virtual;
+
+ if (ovl->format->yuv)
+- ovl->pitch = info->var.xres;
++ ovl->pitch = info->var.xres_virtual;
+ else
+- ovl->pitch = info->var.xres * ovl->format->bpp / 8;
++ ovl->pitch = info->var.xres_virtual * ovl->format->bpp / 8;
+
+ sh_mobile_lcdc_overlay_setup(ovl);
+
+@@ -2024,9 +2024,9 @@ static int sh_mobile_lcdc_set_par(struct fb_info *info)
+ ch->yres_virtual = info->var.yres_virtual;
+
+ if (ch->format->yuv)
+- ch->pitch = info->var.xres;
++ ch->pitch = info->var.xres_virtual;
+ else
+- ch->pitch = info->var.xres * ch->format->bpp / 8;
++ ch->pitch = info->var.xres_virtual * ch->format->bpp / 8;
+
+ ret = sh_mobile_lcdc_start(ch->lcdc);
+ if (ret < 0)
+@@ -2539,9 +2539,9 @@ sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_priv *priv,
+ ovl->yres_virtual = ovl->yres * 2;
+
+ if (!format->yuv)
+- ovl->pitch = ovl->xres * format->bpp / 8;
++ ovl->pitch = ovl->xres_virtual * format->bpp / 8;
+ else
+- ovl->pitch = ovl->xres;
++ ovl->pitch = ovl->xres_virtual;
+
+ /* Allocate frame buffer memory. */
+ ovl->fb_size = ovl->cfg->max_xres * ovl->cfg->max_yres
+@@ -2628,10 +2628,10 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
+
+ if (!format->yuv) {
+ ch->colorspace = V4L2_COLORSPACE_SRGB;
+- ch->pitch = ch->xres * format->bpp / 8;
++ ch->pitch = ch->xres_virtual * format->bpp / 8;
+ } else {
+ ch->colorspace = V4L2_COLORSPACE_REC709;
+- ch->pitch = ch->xres;
++ ch->pitch = ch->xres_virtual;
+ }
+
+ ch->display.width = cfg->panel_cfg.width;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0047-fbdev-sh_mobile_lcdc-Use-channel-configuration-to-in.patch b/patches.armadillo800/0047-fbdev-sh_mobile_lcdc-Use-channel-configuration-to-in.patch
new file mode 100644
index 0000000000000..b14dd22a45d7c
--- /dev/null
+++ b/patches.armadillo800/0047-fbdev-sh_mobile_lcdc-Use-channel-configuration-to-in.patch
@@ -0,0 +1,53 @@
+From 1cd17c833c8811e06b3dddbe9a9c71e6735a58f9 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Wed, 18 Jul 2012 16:59:16 +0200
+Subject: fbdev: sh_mobile_lcdc: Use channel configuration to initialize fb
+ device
+
+Copy the x and y virtual resolutions from the channel information
+instead of recomputing them.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+(cherry picked from commit bd5f2c6911c210af52fa4dc4cf504043ff8a4971)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_lcdcfb.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
+index 67877cc..68011b5 100644
+--- a/drivers/video/sh_mobile_lcdcfb.c
++++ b/drivers/video/sh_mobile_lcdcfb.c
+@@ -2214,14 +2214,14 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch,
+ info->fix.ypanstep = 2;
+
+ /* Initialize variable screen information using the first mode as
+- * default. The default Y virtual resolution is twice the panel size to
+- * allow for double-buffering.
++ * default.
+ */
+ var = &info->var;
+ fb_videomode_to_var(var, mode);
+ var->width = ch->cfg->panel_cfg.width;
+ var->height = ch->cfg->panel_cfg.height;
+- var->yres_virtual = var->yres * 2;
++ var->xres_virtual = ch->xres_virtual;
++ var->yres_virtual = ch->yres_virtual;
+ var->activate = FB_ACTIVATE_NOW;
+
+ /* Use the legacy API by default for RGB formats, and the FOURCC API
+@@ -2619,7 +2619,9 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
+ num_modes = cfg->num_modes;
+ }
+
+- /* Use the first mode as default. */
++ /* Use the first mode as default. The default Y virtual resolution is
++ * twice the panel size to allow for double-buffering.
++ */
+ ch->format = format;
+ ch->xres = mode->xres;
+ ch->xres_virtual = mode->xres;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0048-fbdev-sh_mobile_lcdc-Support-horizontal-panning.patch b/patches.armadillo800/0048-fbdev-sh_mobile_lcdc-Support-horizontal-panning.patch
new file mode 100644
index 0000000000000..80ab27b4bd142
--- /dev/null
+++ b/patches.armadillo800/0048-fbdev-sh_mobile_lcdc-Support-horizontal-panning.patch
@@ -0,0 +1,72 @@
+From 194360fff0a2a4255630477db84bf7af704109ca Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Wed, 18 Jul 2012 17:09:04 +0200
+Subject: fbdev: sh_mobile_lcdc: Support horizontal panning
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+(cherry picked from commit 15dede882e564601947f2ce4b647742c0351be6d)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_lcdcfb.c | 22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
+index 68011b5..d82c1de 100644
+--- a/drivers/video/sh_mobile_lcdcfb.c
++++ b/drivers/video/sh_mobile_lcdcfb.c
+@@ -1493,7 +1493,7 @@ static const struct fb_fix_screeninfo sh_mobile_lcdc_overlay_fix = {
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_TRUECOLOR,
+ .accel = FB_ACCEL_NONE,
+- .xpanstep = 0,
++ .xpanstep = 1,
+ .ypanstep = 1,
+ .ywrapstep = 0,
+ .capabilities = FB_CAP_FOURCC,
+@@ -1714,9 +1714,14 @@ sh_mobile_lcdc_overlay_fb_init(struct sh_mobile_lcdc_overlay *ovl)
+ else
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+- if (ovl->format->fourcc == V4L2_PIX_FMT_NV12 ||
+- ovl->format->fourcc == V4L2_PIX_FMT_NV21)
++ switch (ovl->format->fourcc) {
++ case V4L2_PIX_FMT_NV16:
++ case V4L2_PIX_FMT_NV61:
+ info->fix.ypanstep = 2;
++ case V4L2_PIX_FMT_NV12:
++ case V4L2_PIX_FMT_NV21:
++ info->fix.xpanstep = 2;
++ }
+
+ /* Initialize variable screen information. */
+ var = &info->var;
+@@ -1771,7 +1776,7 @@ static const struct fb_fix_screeninfo sh_mobile_lcdc_fix = {
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_TRUECOLOR,
+ .accel = FB_ACCEL_NONE,
+- .xpanstep = 0,
++ .xpanstep = 1,
+ .ypanstep = 1,
+ .ywrapstep = 0,
+ .capabilities = FB_CAP_FOURCC,
+@@ -2209,9 +2214,14 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch,
+ else
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+- if (ch->format->fourcc == V4L2_PIX_FMT_NV12 ||
+- ch->format->fourcc == V4L2_PIX_FMT_NV21)
++ switch (ch->format->fourcc) {
++ case V4L2_PIX_FMT_NV16:
++ case V4L2_PIX_FMT_NV61:
+ info->fix.ypanstep = 2;
++ case V4L2_PIX_FMT_NV12:
++ case V4L2_PIX_FMT_NV21:
++ info->fix.xpanstep = 2;
++ }
+
+ /* Initialize variable screen information using the first mode as
+ * default.
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0049-fbdev-sh_mobile_lcdc-Fix-overlay-registers-update-du.patch b/patches.armadillo800/0049-fbdev-sh_mobile_lcdc-Fix-overlay-registers-update-du.patch
new file mode 100644
index 0000000000000..ee64fdba9c7f0
--- /dev/null
+++ b/patches.armadillo800/0049-fbdev-sh_mobile_lcdc-Fix-overlay-registers-update-du.patch
@@ -0,0 +1,41 @@
+From 07f80feb4f79273ade0b493d4f173d4721709d74 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Thu, 19 Jul 2012 02:29:52 +0200
+Subject: fbdev: sh_mobile_lcdc: Fix overlay registers update during pan
+ operation
+
+Updating overlay registers require switching to overlay update mode.
+This was correctly done when configuring the overlay format and size,
+but not when updating the base address registers during pan operation.
+Fix it.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+(cherry picked from commit 8be7c66995bf06769dc4c5f7a62f3cd62a627e7e)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_lcdcfb.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
+index d82c1de..a502709 100644
+--- a/drivers/video/sh_mobile_lcdcfb.c
++++ b/drivers/video/sh_mobile_lcdcfb.c
+@@ -1539,9 +1539,14 @@ static int sh_mobile_lcdc_overlay_pan(struct fb_var_screeninfo *var,
+ ovl->base_addr_c = base_addr_c;
+ }
+
++ lcdc_write(ovl->channel->lcdc, LDBCR, LDBCR_UPC(ovl->index));
++
+ lcdc_write_overlay(ovl, LDBnBSAYR(ovl->index), ovl->base_addr_y);
+ lcdc_write_overlay(ovl, LDBnBSACR(ovl->index), ovl->base_addr_c);
+
++ lcdc_write(ovl->channel->lcdc, LDBCR,
++ LDBCR_UPF(ovl->index) | LDBCR_UPD(ovl->index));
++
+ ovl->pan_offset = pan_offset;
+
+ return 0;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0050-fbdev-sh_mobile_lcdc-Fix-pan-offset-computation-in-Y.patch b/patches.armadillo800/0050-fbdev-sh_mobile_lcdc-Fix-pan-offset-computation-in-Y.patch
new file mode 100644
index 0000000000000..d72596f9b1593
--- /dev/null
+++ b/patches.armadillo800/0050-fbdev-sh_mobile_lcdc-Fix-pan-offset-computation-in-Y.patch
@@ -0,0 +1,241 @@
+From 896e926e26d250d1b5397c5a39d12fb25c6928b5 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Thu, 15 Mar 2012 18:15:37 +0100
+Subject: fbdev: sh_mobile_lcdc: Fix pan offset computation in YUV mode
+
+The chroma plane offset in memory is equal to the luma plane maximum
+size. Fix offset computations.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+(cherry picked from commit a4aa25f6e7885a42c90fe5f0a965403df6cbc943)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_lcdcfb.c | 110 ++++++++++++++++++---------------------
+ drivers/video/sh_mobile_lcdcfb.h | 3 +-
+ 2 files changed, 54 insertions(+), 59 deletions(-)
+
+diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
+index a502709..8cb653b 100644
+--- a/drivers/video/sh_mobile_lcdcfb.c
++++ b/drivers/video/sh_mobile_lcdcfb.c
+@@ -161,7 +161,7 @@ enum sh_mobile_lcdc_overlay_mode {
+ * @dma_handle: Frame buffer DMA address
+ * @base_addr_y: Overlay base address (RGB or luma component)
+ * @base_addr_c: Overlay base address (chroma component)
+- * @pan_offset: Current pan offset in bytes
++ * @pan_y_offset: Panning linear offset in bytes (luma component)
+ * @format: Current pixelf format
+ * @xres: Horizontal visible resolution
+ * @xres_virtual: Horizontal total resolution
+@@ -191,7 +191,7 @@ struct sh_mobile_lcdc_overlay {
+ dma_addr_t dma_handle;
+ unsigned long base_addr_y;
+ unsigned long base_addr_c;
+- unsigned long pan_offset;
++ unsigned long pan_y_offset;
+
+ const struct sh_mobile_lcdc_format_info *format;
+ unsigned int xres;
+@@ -873,8 +873,8 @@ static void sh_mobile_lcdc_overlay_setup(struct sh_mobile_lcdc_overlay *ovl)
+ }
+
+ ovl->base_addr_y = ovl->dma_handle;
+- ovl->base_addr_c = ovl->base_addr_y + ovl->xres
+- * ovl->yres_virtual;
++ ovl->base_addr_c = ovl->dma_handle
++ + ovl->xres_virtual * ovl->yres_virtual;
+
+ switch (ovl->mode) {
+ case LCDC_OVERLAY_BLEND:
+@@ -1111,7 +1111,8 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
+ continue;
+
+ ch->base_addr_y = ch->dma_handle;
+- ch->base_addr_c = ch->base_addr_y + ch->xres * ch->yres_virtual;
++ ch->base_addr_c = ch->dma_handle
++ + ch->xres_virtual * ch->yres_virtual;
+ ch->line_size = ch->pitch;
+
+ /* Enable MERAM if possible. */
+@@ -1505,39 +1506,36 @@ static int sh_mobile_lcdc_overlay_pan(struct fb_var_screeninfo *var,
+ struct sh_mobile_lcdc_overlay *ovl = info->par;
+ unsigned long base_addr_y;
+ unsigned long base_addr_c;
+- unsigned long pan_offset;
++ unsigned long y_offset;
+ unsigned long c_offset;
+
+- if (!ovl->format->yuv)
+- pan_offset = var->yoffset * ovl->pitch
+- + var->xoffset * (ovl->format->bpp / 8);
+- else
+- pan_offset = var->yoffset * ovl->pitch + var->xoffset;
++ if (!ovl->format->yuv) {
++ y_offset = (var->yoffset * ovl->xres_virtual + var->xoffset)
++ * ovl->format->bpp / 8;
++ c_offset = 0;
++ } else {
++ unsigned int xsub = ovl->format->bpp < 24 ? 2 : 1;
++ unsigned int ysub = ovl->format->bpp < 16 ? 2 : 1;
++
++ y_offset = var->yoffset * ovl->xres_virtual + var->xoffset;
++ c_offset = var->yoffset / ysub * ovl->xres_virtual * 2 / xsub
++ + var->xoffset * 2 / xsub;
++ }
+
+- if (pan_offset == ovl->pan_offset)
+- return 0; /* No change, do nothing */
++ /* If the Y offset hasn't changed, the C offset hasn't either. There's
++ * nothing to do in that case.
++ */
++ if (y_offset == ovl->pan_y_offset)
++ return 0;
+
+ /* Set the source address for the next refresh */
+- base_addr_y = ovl->dma_handle + pan_offset;
++ base_addr_y = ovl->dma_handle + y_offset;
++ base_addr_c = ovl->dma_handle + ovl->xres_virtual * ovl->yres_virtual
++ + c_offset;
+
+ ovl->base_addr_y = base_addr_y;
+- ovl->base_addr_c = base_addr_y;
+-
+- if (ovl->format->yuv) {
+- /* Set Y offset */
+- c_offset = var->yoffset * ovl->pitch
+- * (ovl->format->bpp - 8) / 8;
+- base_addr_c = ovl->dma_handle
+- + ovl->xres * ovl->yres_virtual
+- + c_offset;
+- /* Set X offset */
+- if (ovl->format->fourcc == V4L2_PIX_FMT_NV24)
+- base_addr_c += 2 * var->xoffset;
+- else
+- base_addr_c += var->xoffset;
+-
+- ovl->base_addr_c = base_addr_c;
+- }
++ ovl->base_addr_c = base_addr_c;
++ ovl->pan_y_offset = y_offset;
+
+ lcdc_write(ovl->channel->lcdc, LDBCR, LDBCR_UPC(ovl->index));
+
+@@ -1547,8 +1545,6 @@ static int sh_mobile_lcdc_overlay_pan(struct fb_var_screeninfo *var,
+ lcdc_write(ovl->channel->lcdc, LDBCR,
+ LDBCR_UPF(ovl->index) | LDBCR_UPD(ovl->index));
+
+- ovl->pan_offset = pan_offset;
+-
+ return 0;
+ }
+
+@@ -1814,35 +1810,33 @@ static int sh_mobile_lcdc_pan(struct fb_var_screeninfo *var,
+ struct sh_mobile_lcdc_chan *ch = info->par;
+ struct sh_mobile_lcdc_priv *priv = ch->lcdc;
+ unsigned long ldrcntr;
+- unsigned long new_pan_offset;
+- unsigned long base_addr_y, base_addr_c = 0;
++ unsigned long base_addr_y, base_addr_c;
++ unsigned long y_offset;
+ unsigned long c_offset;
+
+- if (!ch->format->yuv)
+- new_pan_offset = var->yoffset * ch->pitch
+- + var->xoffset * (ch->format->bpp / 8);
+- else
+- new_pan_offset = var->yoffset * ch->pitch + var->xoffset;
++ if (!ch->format->yuv) {
++ y_offset = (var->yoffset * ch->xres_virtual + var->xoffset)
++ * ch->format->bpp / 8;
++ c_offset = 0;
++ } else {
++ unsigned int xsub = ch->format->bpp < 24 ? 2 : 1;
++ unsigned int ysub = ch->format->bpp < 16 ? 2 : 1;
+
+- if (new_pan_offset == ch->pan_offset)
+- return 0; /* No change, do nothing */
++ y_offset = var->yoffset * ch->xres_virtual + var->xoffset;
++ c_offset = var->yoffset / ysub * ch->xres_virtual * 2 / xsub
++ + var->xoffset * 2 / xsub;
++ }
+
+- ldrcntr = lcdc_read(priv, _LDRCNTR);
++ /* If the Y offset hasn't changed, the C offset hasn't either. There's
++ * nothing to do in that case.
++ */
++ if (y_offset == ch->pan_y_offset)
++ return 0;
+
+ /* Set the source address for the next refresh */
+- base_addr_y = ch->dma_handle + new_pan_offset;
+- if (ch->format->yuv) {
+- /* Set y offset */
+- c_offset = var->yoffset * ch->pitch
+- * (ch->format->bpp - 8) / 8;
+- base_addr_c = ch->dma_handle + ch->xres * ch->yres_virtual
+- + c_offset;
+- /* Set x offset */
+- if (ch->format->fourcc == V4L2_PIX_FMT_NV24)
+- base_addr_c += 2 * var->xoffset;
+- else
+- base_addr_c += var->xoffset;
+- }
++ base_addr_y = ch->dma_handle + y_offset;
++ base_addr_c = ch->dma_handle + ch->xres_virtual * ch->yres_virtual
++ + c_offset;
+
+ if (ch->cache)
+ sh_mobile_meram_cache_update(priv->meram_dev, ch->cache,
+@@ -1851,17 +1845,18 @@ static int sh_mobile_lcdc_pan(struct fb_var_screeninfo *var,
+
+ ch->base_addr_y = base_addr_y;
+ ch->base_addr_c = base_addr_c;
++ ch->pan_y_offset = y_offset;
+
+ lcdc_write_chan_mirror(ch, LDSA1R, base_addr_y);
+ if (ch->format->yuv)
+ lcdc_write_chan_mirror(ch, LDSA2R, base_addr_c);
+
++ ldrcntr = lcdc_read(priv, _LDRCNTR);
+ if (lcdc_chan_is_sublcd(ch))
+ lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_SRS);
+ else
+ lcdc_write(ch->lcdc, _LDRCNTR, ldrcntr ^ LDRCNTR_MRS);
+
+- ch->pan_offset = new_pan_offset;
+
+ sh_mobile_lcdc_deferred_io_touch(info);
+
+@@ -2734,7 +2729,6 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
+ }
+ init_waitqueue_head(&ch->frame_end_wait);
+ init_completion(&ch->vsync_completion);
+- ch->pan_offset = 0;
+
+ /* probe the backlight is there is one defined */
+ if (ch->cfg->bl_info.max_brightness)
+diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
+index e53cd11..0f92f65 100644
+--- a/drivers/video/sh_mobile_lcdcfb.h
++++ b/drivers/video/sh_mobile_lcdcfb.h
+@@ -47,6 +47,7 @@ struct sh_mobile_lcdc_entity {
+ /*
+ * struct sh_mobile_lcdc_chan - LCDC display channel
+ *
++ * @pan_y_offset: Panning linear offset in bytes (luma component)
+ * @base_addr_y: Frame buffer viewport base address (luma component)
+ * @base_addr_c: Frame buffer viewport base address (chroma component)
+ * @pitch: Frame buffer line pitch
+@@ -68,7 +69,7 @@ struct sh_mobile_lcdc_chan {
+ unsigned long fb_size;
+
+ dma_addr_t dma_handle;
+- unsigned long pan_offset;
++ unsigned long pan_y_offset;
+
+ unsigned long frame_end;
+ wait_queue_head_t frame_end_wait;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0051-fbdev-sh_mobile_lcdc-Fix-vertical-panning-step.patch b/patches.armadillo800/0051-fbdev-sh_mobile_lcdc-Fix-vertical-panning-step.patch
new file mode 100644
index 0000000000000..2662cba50a404
--- /dev/null
+++ b/patches.armadillo800/0051-fbdev-sh_mobile_lcdc-Fix-vertical-panning-step.patch
@@ -0,0 +1,55 @@
+From 633f3cd2b85466e5744a86cbe888d78f30302083 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Thu, 26 Jul 2012 14:36:55 +0200
+Subject: fbdev: sh_mobile_lcdc: Fix vertical panning step
+
+Commit 15dede882e564601947f2ce4b647742c0351be6d added support for
+horizontal panning but accidentally computes the Y pan step value
+incorrectly for NV12/21 and NV16/61 formats. Fix this.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
+(cherry picked from commit ac33a207b13a70bbca6e58094e28bd92b9fc1ff3)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/video/sh_mobile_lcdcfb.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
+index 8cb653b..699487c 100644
+--- a/drivers/video/sh_mobile_lcdcfb.c
++++ b/drivers/video/sh_mobile_lcdcfb.c
+@@ -1716,11 +1716,11 @@ sh_mobile_lcdc_overlay_fb_init(struct sh_mobile_lcdc_overlay *ovl)
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+ switch (ovl->format->fourcc) {
+- case V4L2_PIX_FMT_NV16:
+- case V4L2_PIX_FMT_NV61:
+- info->fix.ypanstep = 2;
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
++ info->fix.ypanstep = 2;
++ case V4L2_PIX_FMT_NV16:
++ case V4L2_PIX_FMT_NV61:
+ info->fix.xpanstep = 2;
+ }
+
+@@ -2215,11 +2215,11 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch,
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+ switch (ch->format->fourcc) {
+- case V4L2_PIX_FMT_NV16:
+- case V4L2_PIX_FMT_NV61:
+- info->fix.ypanstep = 2;
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
++ info->fix.ypanstep = 2;
++ case V4L2_PIX_FMT_NV16:
++ case V4L2_PIX_FMT_NV61:
+ info->fix.xpanstep = 2;
+ }
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0052-ARM-mach-shmobile-r8a7740-add-gpio_irq-support.patch b/patches.armadillo800/0052-ARM-mach-shmobile-r8a7740-add-gpio_irq-support.patch
new file mode 100644
index 0000000000000..e33085a762801
--- /dev/null
+++ b/patches.armadillo800/0052-ARM-mach-shmobile-r8a7740-add-gpio_irq-support.patch
@@ -0,0 +1,83 @@
+From 18ed06783eaf892967a3260bd9056a4aba81bfa0 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 6 Apr 2012 01:28:14 -0700
+Subject: ARM: mach-shmobile: r8a7740: add gpio_irq support
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 9f6b78223b7b49bc06d2e84b15d48f02206ec3c3)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/pfc-r8a7740.c | 39 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/pfc-r8a7740.c b/arch/arm/mach-shmobile/pfc-r8a7740.c
+index a4fff69..670fe18 100644
+--- a/arch/arm/mach-shmobile/pfc-r8a7740.c
++++ b/arch/arm/mach-shmobile/pfc-r8a7740.c
+@@ -22,6 +22,7 @@
+ #include <linux/kernel.h>
+ #include <linux/gpio.h>
+ #include <mach/r8a7740.h>
++#include <mach/irqs.h>
+
+ #define CPU_ALL_PORT(fn, pfx, sfx) \
+ PORT_10(fn, pfx, sfx), PORT_90(fn, pfx, sfx), \
+@@ -2527,6 +2528,41 @@ static struct pinmux_data_reg pinmux_data_regs[] = {
+ { },
+ };
+
++static struct pinmux_irq pinmux_irqs[] = {
++ PINMUX_IRQ(evt2irq(0x0200), PORT2_FN0, PORT13_FN0), /* IRQ0A */
++ PINMUX_IRQ(evt2irq(0x0220), PORT20_FN0), /* IRQ1A */
++ PINMUX_IRQ(evt2irq(0x0240), PORT11_FN0, PORT12_FN0), /* IRQ2A */
++ PINMUX_IRQ(evt2irq(0x0260), PORT10_FN0, PORT14_FN0), /* IRQ3A */
++ PINMUX_IRQ(evt2irq(0x0280), PORT15_FN0, PORT172_FN0), /* IRQ4A */
++ PINMUX_IRQ(evt2irq(0x02A0), PORT0_FN0, PORT1_FN0), /* IRQ5A */
++ PINMUX_IRQ(evt2irq(0x02C0), PORT121_FN0, PORT173_FN0), /* IRQ6A */
++ PINMUX_IRQ(evt2irq(0x02E0), PORT120_FN0, PORT209_FN0), /* IRQ7A */
++ PINMUX_IRQ(evt2irq(0x0300), PORT119_FN0), /* IRQ8A */
++ PINMUX_IRQ(evt2irq(0x0320), PORT118_FN0, PORT210_FN0), /* IRQ9A */
++ PINMUX_IRQ(evt2irq(0x0340), PORT19_FN0), /* IRQ10A */
++ PINMUX_IRQ(evt2irq(0x0360), PORT104_FN0), /* IRQ11A */
++ PINMUX_IRQ(evt2irq(0x0380), PORT42_FN0, PORT97_FN0), /* IRQ12A */
++ PINMUX_IRQ(evt2irq(0x03A0), PORT64_FN0, PORT98_FN0), /* IRQ13A */
++ PINMUX_IRQ(evt2irq(0x03C0), PORT63_FN0, PORT99_FN0), /* IRQ14A */
++ PINMUX_IRQ(evt2irq(0x03E0), PORT62_FN0, PORT100_FN0), /* IRQ15A */
++ PINMUX_IRQ(evt2irq(0x3200), PORT68_FN0, PORT211_FN0), /* IRQ16A */
++ PINMUX_IRQ(evt2irq(0x3220), PORT69_FN0), /* IRQ17A */
++ PINMUX_IRQ(evt2irq(0x3240), PORT70_FN0), /* IRQ18A */
++ PINMUX_IRQ(evt2irq(0x3260), PORT71_FN0), /* IRQ19A */
++ PINMUX_IRQ(evt2irq(0x3280), PORT67_FN0), /* IRQ20A */
++ PINMUX_IRQ(evt2irq(0x32A0), PORT202_FN0), /* IRQ21A */
++ PINMUX_IRQ(evt2irq(0x32C0), PORT95_FN0), /* IRQ22A */
++ PINMUX_IRQ(evt2irq(0x32E0), PORT96_FN0), /* IRQ23A */
++ PINMUX_IRQ(evt2irq(0x3300), PORT180_FN0), /* IRQ24A */
++ PINMUX_IRQ(evt2irq(0x3320), PORT38_FN0), /* IRQ25A */
++ PINMUX_IRQ(evt2irq(0x3340), PORT58_FN0, PORT81_FN0), /* IRQ26A */
++ PINMUX_IRQ(evt2irq(0x3360), PORT57_FN0, PORT168_FN0), /* IRQ27A */
++ PINMUX_IRQ(evt2irq(0x3380), PORT56_FN0, PORT169_FN0), /* IRQ28A */
++ PINMUX_IRQ(evt2irq(0x33A0), PORT50_FN0, PORT170_FN0), /* IRQ29A */
++ PINMUX_IRQ(evt2irq(0x33C0), PORT49_FN0, PORT171_FN0), /* IRQ30A */
++ PINMUX_IRQ(evt2irq(0x33E0), PORT41_FN0, PORT167_FN0), /* IRQ31A */
++};
++
+ static struct pinmux_info r8a7740_pinmux_info = {
+ .name = "r8a7740_pfc",
+ .reserved_id = PINMUX_RESERVED,
+@@ -2554,6 +2590,9 @@ static struct pinmux_info r8a7740_pinmux_info = {
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
++
++ .gpio_irq = pinmux_irqs,
++ .gpio_irq_size = ARRAY_SIZE(pinmux_irqs),
+ };
+
+ void r8a7740_pinmux_init(void)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0053-ARM-mach-shmobile-r8a7740-cleanup-I2C-workaround-met.patch b/patches.armadillo800/0053-ARM-mach-shmobile-r8a7740-cleanup-I2C-workaround-met.patch
new file mode 100644
index 0000000000000..b750ea78f1a8e
--- /dev/null
+++ b/patches.armadillo800/0053-ARM-mach-shmobile-r8a7740-cleanup-I2C-workaround-met.patch
@@ -0,0 +1,48 @@
+From 46dccabaa06e08bb7b9b2ac4b46f784b8afba7f0 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 13 Apr 2012 02:41:06 -0700
+Subject: ARM: mach-shmobile: r8a7740: cleanup I2C workaround method
+
+Current workaround of I2C on r8a7740 used mdelay(),
+but it was an overkill.
+This patch cleans up the workaround delay.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 4228716c87f7915410721952bad3e568fb5f2431)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/setup-r8a7740.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/arch/arm/mach-shmobile/setup-r8a7740.c
++++ b/arch/arm/mach-shmobile/setup-r8a7740.c
+@@ -368,19 +368,19 @@ static void r8a7740_i2c_workaround(struc
+ i2c_write(reg, ICSTART, i2c_read(reg, ICSTART) | 0x10);
+ i2c_read(reg, ICSTART); /* dummy read */
+
+- mdelay(100);
++ udelay(10);
+
+ i2c_write(reg, ICCR, 0x01);
+- i2c_read(reg, ICCR);
+ i2c_write(reg, ICSTART, 0x00);
+- i2c_read(reg, ICSTART);
++
++ udelay(10);
+
+ i2c_write(reg, ICCR, 0x10);
+- mdelay(100);
++ udelay(10);
+ i2c_write(reg, ICCR, 0x00);
+- mdelay(100);
++ udelay(10);
+ i2c_write(reg, ICCR, 0x10);
+- mdelay(100);
++ udelay(10);
+
+ iounmap(reg);
+ }
diff --git a/patches.armadillo800/0054-ARM-mach-shmobile-clock-r8a7740-add-FSI-clock.patch b/patches.armadillo800/0054-ARM-mach-shmobile-clock-r8a7740-add-FSI-clock.patch
new file mode 100644
index 0000000000000..474b8fcdbc926
--- /dev/null
+++ b/patches.armadillo800/0054-ARM-mach-shmobile-clock-r8a7740-add-FSI-clock.patch
@@ -0,0 +1,47 @@
+From 9b696a8092bedbd771c4b8e6a8c12edbd6881444 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 1 Apr 2012 18:46:09 -0700
+Subject: ARM: mach-shmobile: clock-r8a7740: add FSI clock
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 7ee8948d158946e52ea21562f2ceef268439f36e)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-r8a7740.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
+index 99c4d74..b6fa1b7 100644
+--- a/arch/arm/mach-shmobile/clock-r8a7740.c
++++ b/arch/arm/mach-shmobile/clock-r8a7740.c
+@@ -257,7 +257,7 @@ enum {
+ MSTP222,
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+
+- MSTP329, MSTP323,
++ MSTP329, MSTP328, MSTP323,
+
+ MSTP_NR
+ };
+@@ -280,6 +280,7 @@ static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP200] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
+
+ [MSTP329] = SH_CLK_MSTP32(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
++ [MSTP328] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /* FSI */
+ [MSTP323] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
+ };
+
+@@ -334,6 +335,7 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]),
+
+ CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
++ CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]),
+ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]),
+ };
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0055-ARM-mach-shmobile-clock-r8a7740-add-USB-clock.patch b/patches.armadillo800/0055-ARM-mach-shmobile-clock-r8a7740-add-USB-clock.patch
new file mode 100644
index 0000000000000..3e72e0bca4d55
--- /dev/null
+++ b/patches.armadillo800/0055-ARM-mach-shmobile-clock-r8a7740-add-USB-clock.patch
@@ -0,0 +1,208 @@
+From a747b7aa896100a6b9dd0dc0828c27ef344f381c Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 24 Apr 2012 02:07:47 -0700
+Subject: ARM: mach-shmobile: clock-r8a7740: add USB clock
+
+R8A7740 USB needs many clocks for workaround,
+and it has confusing name "usb24s" and "usb24".
+This "usb24s" will be used by other clocks.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit fcca3f0f007d97f095a3ebe8f209021b517309d2)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-r8a7740.c | 118 ++++++++++++++++++++++++++++++++-
+ 1 file changed, 116 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
+index b6fa1b7..b9b1d73 100644
+--- a/arch/arm/mach-shmobile/clock-r8a7740.c
++++ b/arch/arm/mach-shmobile/clock-r8a7740.c
+@@ -47,6 +47,7 @@
+ #define PLLC01CR 0xe6150028
+
+ #define SUBCKCR 0xe6150080
++#define USBCKCR 0xe615008c
+
+ #define MSTPSR0 0xe6150030
+ #define MSTPSR1 0xe6150038
+@@ -181,6 +182,100 @@ static struct clk pllc1_div2_clk = {
+ .parent = &pllc1_clk,
+ };
+
++/* USB clock */
++static struct clk *usb24s_parents[] = {
++ [0] = &system_clk,
++ [1] = &extal2_clk
++};
++
++static unsigned long usb24s_recalc(struct clk *clk)
++{
++ return clk->parent->rate;
++};
++
++static int usb24s_enable(struct clk *clk)
++{
++ __raw_writel(__raw_readl(USBCKCR) & ~(1 << 8), USBCKCR);
++
++ return 0;
++}
++
++static void usb24s_disable(struct clk *clk)
++{
++ __raw_writel(__raw_readl(USBCKCR) | (1 << 8), USBCKCR);
++}
++
++static int usb24s_set_parent(struct clk *clk, struct clk *parent)
++{
++ int i, ret;
++ u32 val;
++
++ if (!clk->parent_table || !clk->parent_num)
++ return -EINVAL;
++
++ /* Search the parent */
++ for (i = 0; i < clk->parent_num; i++)
++ if (clk->parent_table[i] == parent)
++ break;
++
++ if (i == clk->parent_num)
++ return -ENODEV;
++
++ ret = clk_reparent(clk, parent);
++ if (ret < 0)
++ return ret;
++
++ val = __raw_readl(USBCKCR);
++ val &= ~(1 << 7);
++ val |= i << 7;
++ __raw_writel(val, USBCKCR);
++
++ return 0;
++}
++
++static struct sh_clk_ops usb24s_clk_ops = {
++ .recalc = usb24s_recalc,
++ .enable = usb24s_enable,
++ .disable = usb24s_disable,
++ .set_parent = usb24s_set_parent,
++};
++
++static struct clk usb24s_clk = {
++ .ops = &usb24s_clk_ops,
++ .parent_table = usb24s_parents,
++ .parent_num = ARRAY_SIZE(usb24s_parents),
++ .parent = &system_clk,
++};
++
++static unsigned long usb24_recalc(struct clk *clk)
++{
++ return clk->parent->rate /
++ ((__raw_readl(USBCKCR) & (1 << 6)) ? 1 : 2);
++};
++
++static int usb24_set_rate(struct clk *clk, unsigned long rate)
++{
++ u32 val;
++
++ /* closer to which ? parent->rate or parent->rate/2 */
++ val = __raw_readl(USBCKCR);
++ val &= ~(1 << 6);
++ val |= (rate > (clk->parent->rate / 4) * 3) << 6;
++ __raw_writel(val, USBCKCR);
++
++ return 0;
++}
++
++static struct sh_clk_ops usb24_clk_ops = {
++ .recalc = usb24_recalc,
++ .set_rate = usb24_set_rate,
++};
++
++static struct clk usb24_clk = {
++ .ops = &usb24_clk_ops,
++ .parent = &usb24s_clk,
++};
++
+ struct clk *main_clks[] = {
+ &extalr_clk,
+ &extal1_clk,
+@@ -196,6 +291,8 @@ struct clk *main_clks[] = {
+ &pllc0_clk,
+ &pllc1_clk,
+ &pllc1_div2_clk,
++ &usb24s_clk,
++ &usb24_clk,
+ };
+
+ static void div4_kick(struct clk *clk)
+@@ -223,7 +320,7 @@ static struct clk_div4_table div4_table = {
+
+ enum {
+ DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP,
+- DIV4_HPP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP,
++ DIV4_HPP, DIV4_USBP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP,
+ DIV4_NR
+ };
+
+@@ -234,6 +331,7 @@ struct clk div4_clks[DIV4_NR] = {
+ [DIV4_M1] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_HP] = SH_CLK_DIV4(&pllc1_clk, FRQCRB, 4, 0x6fff, 0),
+ [DIV4_HPP] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 20, 0x6fff, 0),
++ [DIV4_USBP] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 16, 0x6fff, 0),
+ [DIV4_S] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 12, 0x6fff, 0),
+ [DIV4_ZB] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 8, 0x6fff, 0),
+ [DIV4_M3] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 4, 0x6fff, 0),
+@@ -257,7 +355,9 @@ enum {
+ MSTP222,
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+
+- MSTP329, MSTP328, MSTP323,
++ MSTP329, MSTP328, MSTP323, MSTP320,
++
++ MSTP416, MSTP407, MSTP406,
+
+ MSTP_NR
+ };
+@@ -282,6 +382,11 @@ static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP329] = SH_CLK_MSTP32(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
+ [MSTP328] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /* FSI */
+ [MSTP323] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
++ [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 20, 0), /* USBF */
++
++ [MSTP416] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 16, 0), /* USBHOST */
++ [MSTP407] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 7, 0), /* USB-Func */
++ [MSTP406] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 6, 0), /* USB Phy */
+ };
+
+ static struct clk_lookup lookups[] = {
+@@ -300,6 +405,7 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
+ CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
+ CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
++ CLKDEV_CON_ID("usb24s", &usb24s_clk),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
+@@ -337,6 +443,14 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
+ CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]),
+ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]),
++ CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP320]),
++
++ /* ICK */
++ CLKDEV_ICK_ID("host", "renesas_usbhs", &mstp_clks[MSTP416]),
++ CLKDEV_ICK_ID("func", "renesas_usbhs", &mstp_clks[MSTP407]),
++ CLKDEV_ICK_ID("phy", "renesas_usbhs", &mstp_clks[MSTP406]),
++ CLKDEV_ICK_ID("pci", "renesas_usbhs", &div4_clks[DIV4_USBP]),
++ CLKDEV_ICK_ID("usb24", "renesas_usbhs", &usb24_clk),
+ };
+
+ void __init r8a7740_clock_init(u8 md_ck)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0056-ARM-mach-shmobile-clock-r8a7740-add-SDHI-clock.patch b/patches.armadillo800/0056-ARM-mach-shmobile-clock-r8a7740-add-SDHI-clock.patch
new file mode 100644
index 0000000000000..86c437981cf93
--- /dev/null
+++ b/patches.armadillo800/0056-ARM-mach-shmobile-clock-r8a7740-add-SDHI-clock.patch
@@ -0,0 +1,57 @@
+From df046bb39c81fb474109a85f21b35345df0b9441 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 24 Apr 2012 02:08:11 -0700
+Subject: ARM: mach-shmobile: clock-r8a7740: add SDHI clock
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 19ad322de262c810463aeb8769c66474d8b68210)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-r8a7740.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
+index b9b1d73..86f7147 100644
+--- a/arch/arm/mach-shmobile/clock-r8a7740.c
++++ b/arch/arm/mach-shmobile/clock-r8a7740.c
+@@ -356,8 +356,9 @@ enum {
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+
+ MSTP329, MSTP328, MSTP323, MSTP320,
++ MSTP314, MSTP313,
+
+- MSTP416, MSTP407, MSTP406,
++ MSTP416, MSTP415, MSTP407, MSTP406,
+
+ MSTP_NR
+ };
+@@ -383,8 +384,11 @@ static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP328] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /* FSI */
+ [MSTP323] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
+ [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 20, 0), /* USBF */
++ [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
++ [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
+
+ [MSTP416] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 16, 0), /* USBHOST */
++ [MSTP415] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
+ [MSTP407] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 7, 0), /* USB-Func */
+ [MSTP406] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 6, 0), /* USB Phy */
+ };
+@@ -444,6 +448,10 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]),
+ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]),
+ CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP320]),
++ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
++ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
++
++ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]),
+
+ /* ICK */
+ CLKDEV_ICK_ID("host", "renesas_usbhs", &mstp_clks[MSTP416]),
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0057-ARM-mach-shmobile-clock-r8a7740-add-MMCIF-clock.patch b/patches.armadillo800/0057-ARM-mach-shmobile-clock-r8a7740-add-MMCIF-clock.patch
new file mode 100644
index 0000000000000..e0c1a387c076b
--- /dev/null
+++ b/patches.armadillo800/0057-ARM-mach-shmobile-clock-r8a7740-add-MMCIF-clock.patch
@@ -0,0 +1,48 @@
+From 3b4d84a8de5adaa8ec1b4db8b3409fc75340bd7f Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 24 Apr 2012 02:08:29 -0700
+Subject: ARM: mach-shmobile: clock-r8a7740: add MMCIF clock
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit f2c2d7e9210c4a82336b208adc88630cd0e77f57)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-r8a7740.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
+index 86f7147..89a2f9d 100644
+--- a/arch/arm/mach-shmobile/clock-r8a7740.c
++++ b/arch/arm/mach-shmobile/clock-r8a7740.c
+@@ -356,7 +356,7 @@ enum {
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+
+ MSTP329, MSTP328, MSTP323, MSTP320,
+- MSTP314, MSTP313,
++ MSTP314, MSTP313, MSTP312,
+
+ MSTP416, MSTP415, MSTP407, MSTP406,
+
+@@ -386,6 +386,7 @@ static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 20, 0), /* USBF */
+ [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
+ [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
++ [MSTP312] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
+
+ [MSTP416] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 16, 0), /* USBHOST */
+ [MSTP415] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
+@@ -450,6 +451,7 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP320]),
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
++ CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP312]),
+
+ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]),
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0058-ARM-mach-shmobile-clock-r8a7740-use-followparent_rec.patch b/patches.armadillo800/0058-ARM-mach-shmobile-clock-r8a7740-use-followparent_rec.patch
new file mode 100644
index 0000000000000..db699188a7dde
--- /dev/null
+++ b/patches.armadillo800/0058-ARM-mach-shmobile-clock-r8a7740-use-followparent_rec.patch
@@ -0,0 +1,48 @@
+From 02b6fac5cb1a97bb8851976abdd8a229a852907f Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 6 May 2012 18:12:41 -0700
+Subject: ARM: mach-shmobile: clock-r8a7740: use followparent_recalc on usb24s
+
+If the clocks is always same value as the parent clock,
+we can use followparent_recalc() for .recalc
+
+Reported-by: Paul Mundt <lethal@linux-sh.org>
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Reviewed-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit c8241085e8606a14ef48e6d99556133c48aaddaf)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-r8a7740.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
+index 89a2f9d..81b54a6 100644
+--- a/arch/arm/mach-shmobile/clock-r8a7740.c
++++ b/arch/arm/mach-shmobile/clock-r8a7740.c
+@@ -188,11 +188,6 @@ static struct clk *usb24s_parents[] = {
+ [1] = &extal2_clk
+ };
+
+-static unsigned long usb24s_recalc(struct clk *clk)
+-{
+- return clk->parent->rate;
+-};
+-
+ static int usb24s_enable(struct clk *clk)
+ {
+ __raw_writel(__raw_readl(USBCKCR) & ~(1 << 8), USBCKCR);
+@@ -234,7 +229,7 @@ static int usb24s_set_parent(struct clk *clk, struct clk *parent)
+ }
+
+ static struct sh_clk_ops usb24s_clk_ops = {
+- .recalc = usb24s_recalc,
++ .recalc = followparent_recalc,
+ .enable = usb24s_enable,
+ .disable = usb24s_disable,
+ .set_parent = usb24s_set_parent,
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0059-ARM-mach-shmobile-add-armadillo800eva-board-support.patch b/patches.armadillo800/0059-ARM-mach-shmobile-add-armadillo800eva-board-support.patch
new file mode 100644
index 0000000000000..f40a99937f618
--- /dev/null
+++ b/patches.armadillo800/0059-ARM-mach-shmobile-add-armadillo800eva-board-support.patch
@@ -0,0 +1,232 @@
+From 6dbc9d7efd3ddd2dbc0a1b95b3a237173df5e1d8 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 6 Apr 2012 01:28:59 -0700
+Subject: ARM: mach-shmobile: add armadillo800eva board support.
+
+This adds very basic armadillo800eva board (R-Mobile A1) support
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 4d22e564ca7bb5c7340c782aedd93bed99f3fb41)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/Kconfig | 11 +-
+ arch/arm/mach-shmobile/Makefile | 1 +
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 154 +++++++++++++++++++++++++
+ 3 files changed, 164 insertions(+), 2 deletions(-)
+ create mode 100644 arch/arm/mach-shmobile/board-armadillo800eva.c
+
+diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
+index 2cda0c2..799e996 100644
+--- a/arch/arm/mach-shmobile/Kconfig
++++ b/arch/arm/mach-shmobile/Kconfig
+@@ -95,6 +95,11 @@ config MACH_BONITO
+ select ARCH_REQUIRE_GPIOLIB
+ depends on ARCH_R8A7740
+
++config MACH_ARMADILLO800EVA
++ bool "Armadillo-800 EVA board"
++ depends on ARCH_R8A7740
++ select ARCH_REQUIRE_GPIOLIB
++
+ config MACH_MARZEN
+ bool "MARZEN board"
+ depends on ARCH_R8A7779
+@@ -112,7 +117,8 @@ config MEMORY_START
+ hex "Physical memory start address"
+ default "0x50000000" if MACH_G3EVM
+ default "0x40000000" if MACH_G4EVM || MACH_AP4EVB || MACH_AG5EVM || \
+- MACH_MACKEREL || MACH_BONITO
++ MACH_MACKEREL || MACH_BONITO || \
++ MACH_ARMADILLO800EVA
+ default "0x41000000" if MACH_KOTA2
+ default "0x00000000"
+ ---help---
+@@ -124,7 +130,8 @@ config MEMORY_SIZE
+ hex "Physical memory size"
+ default "0x08000000" if MACH_G3EVM
+ default "0x08000000" if MACH_G4EVM
+- default "0x20000000" if MACH_AG5EVM || MACH_BONITO
++ default "0x20000000" if MACH_AG5EVM || MACH_BONITO || \
++ MACH_ARMADILLO800EVA
+ default "0x1e000000" if MACH_KOTA2
+ default "0x10000000" if MACH_AP4EVB || MACH_MACKEREL
+ default "0x04000000"
+diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
+index 53846a1e..b39033b 100644
+--- a/arch/arm/mach-shmobile/Makefile
++++ b/arch/arm/mach-shmobile/Makefile
+@@ -50,6 +50,7 @@ obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o
+ obj-$(CONFIG_MACH_KOTA2) += board-kota2.o
+ obj-$(CONFIG_MACH_BONITO) += board-bonito.o
+ obj-$(CONFIG_MACH_MARZEN) += board-marzen.o
++obj-$(CONFIG_MACH_ARMADILLO800EVA) += board-armadillo800eva.o
+
+ # Framework support
+ obj-$(CONFIG_SMP) += $(smp-y)
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+new file mode 100644
+index 0000000..28bc259
+--- /dev/null
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -0,0 +1,154 @@
++/*
++ * armadillo 800 eva board support
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.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; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/err.h>
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++#include <linux/gpio.h>
++#include <mach/common.h>
++#include <mach/irqs.h>
++#include <asm/page.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/map.h>
++#include <asm/mach/time.h>
++#include <asm/hardware/cache-l2x0.h>
++#include <mach/r8a7740.h>
++
++/*
++ * CON1 Camera Module
++ * CON2 Extension Bus
++ * CON3 HDMI Output
++ * CON4 Composite Video Output
++ * CON5 H-UDI JTAG
++ * CON6 ARM JTAG
++ * CON7 SD1
++ * CON8 SD2
++ * CON9 RTC BackUp
++ * CON10 Monaural Mic Input
++ * CON11 Stereo Headphone Output
++ * CON12 Audio Line Output(L)
++ * CON13 Audio Line Output(R)
++ * CON14 AWL13 Module
++ * CON15 Extension
++ * CON16 LCD1
++ * CON17 LCD2
++ * CON19 Power Input
++ * CON20 USB1
++ * CON21 USB2
++ * CON22 Serial
++ * CON23 LAN
++ * CON24 USB3
++ * LED1 Camera LED(Yellow)
++ * LED2 Power LED (Green)
++ * ED3-LED6 User LED(Yellow)
++ * LED7 LAN link LED(Green)
++ * LED8 LAN activity LED(Yellow)
++ */
++
++/*
++ * DipSwitch
++ *
++ * SW1
++ *
++ * -12345678-+---------------+----------------------------
++ * 1 | boot | hermit
++ * 0 | boot | OS auto boot
++ * -12345678-+---------------+----------------------------
++ * 00 | boot device | eMMC
++ * 10 | boot device | SDHI0 (CON7)
++ * 01 | boot device | -
++ * 11 | boot device | Extension Buss (CS0)
++ * -12345678-+---------------+----------------------------
++ * 0 | Extension Bus | D8-D15 disable, eMMC enable
++ * 1 | Extension Bus | D8-D15 enable, eMMC disable
++ * -12345678-+---------------+----------------------------
++ * 0 | SDHI1 | COM8 enable, COM14 disable
++ * 1 | SDHI1 | COM8 enable, COM14 disable
++ * -12345678-+---------------+----------------------------
++ * 00 | JTAG | SH-X2
++ * 10 | JTAG | ARM
++ * 01 | JTAG | -
++ * 11 | JTAG | Boundary Scan
++ *-----------+---------------+----------------------------
++ */
++
++/*
++ * board devices
++ */
++static struct platform_device *eva_devices[] __initdata = {
++};
++
++/*
++ * board init
++ */
++static void __init eva_init(void)
++{
++ r8a7740_pinmux_init();
++
++ /* SCIFA1 */
++ gpio_request(GPIO_FN_SCIFA1_RXD, NULL);
++ gpio_request(GPIO_FN_SCIFA1_TXD, NULL);
++
++#ifdef CONFIG_CACHE_L2X0
++ /* Early BRESP enable, Shared attribute override enable, 32K*8way */
++ l2x0_init(__io(0xf0002000), 0x40440000, 0x82000fff);
++#endif
++
++ r8a7740_add_standard_devices();
++
++ platform_add_devices(eva_devices,
++ ARRAY_SIZE(eva_devices));
++}
++
++static void __init eva_earlytimer_init(void)
++{
++ struct clk *xtal1;
++
++ r8a7740_clock_init(MD_CK0 | MD_CK2);
++
++ xtal1 = clk_get(NULL, "extal1");
++ if (!IS_ERR(xtal1)) {
++ /* armadillo 800 eva extal1 is 24MHz */
++ clk_set_rate(xtal1, 24000000);
++ clk_put(xtal1);
++ }
++
++ shmobile_earlytimer_init();
++}
++
++static void __init eva_add_early_devices(void)
++{
++ r8a7740_add_early_devices();
++
++ /* override timer setup with board-specific code */
++ shmobile_timer.init = eva_earlytimer_init;
++}
++
++MACHINE_START(ARMADILLO800EVA, "armadillo800eva")
++ .map_io = r8a7740_map_io,
++ .init_early = eva_add_early_devices,
++ .init_irq = r8a7740_init_irq,
++ .handle_irq = shmobile_handle_irq_intc,
++ .init_machine = eva_init,
++ .timer = &shmobile_timer,
++MACHINE_END
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0060-ARM-mach-shmobile-armadillo800eva-add-defconfig.patch b/patches.armadillo800/0060-ARM-mach-shmobile-armadillo800eva-add-defconfig.patch
new file mode 100644
index 0000000000000..2ee612615feab
--- /dev/null
+++ b/patches.armadillo800/0060-ARM-mach-shmobile-armadillo800eva-add-defconfig.patch
@@ -0,0 +1,169 @@
+From 90660861a7540365f6c7c4412f30a74e4a7d9dd3 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 6 Apr 2012 01:29:36 -0700
+Subject: ARM: mach-shmobile: armadillo800eva: add defconfig
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit edc4910171f332466fa8f164de3d2395d80163db)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/configs/armadillo800eva_defconfig | 143 +++++++++++++++++++++++++++++
+ 1 file changed, 143 insertions(+)
+ create mode 100644 arch/arm/configs/armadillo800eva_defconfig
+
+diff --git a/arch/arm/configs/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig
+new file mode 100644
+index 0000000..0d20749
+--- /dev/null
++++ b/arch/arm/configs/armadillo800eva_defconfig
+@@ -0,0 +1,143 @@
++CONFIG_EXPERIMENTAL=y
++CONFIG_SYSVIPC=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_KALLSYMS_ALL=y
++CONFIG_SLAB=y
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++CONFIG_MODULE_FORCE_UNLOAD=y
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_IOSCHED_DEADLINE is not set
++# CONFIG_IOSCHED_CFQ is not set
++CONFIG_ARCH_SHMOBILE=y
++CONFIG_ARCH_R8A7740=y
++CONFIG_MACH_ARMADILLO800EVA=y
++# CONFIG_SH_TIMER_TMU is not set
++# CONFIG_ARM_THUMB is not set
++CONFIG_CPU_BPREDICT_DISABLE=y
++# CONFIG_CACHE_L2X0 is not set
++CONFIG_ARM_ERRATA_430973=y
++CONFIG_ARM_ERRATA_458693=y
++CONFIG_ARM_ERRATA_460075=y
++CONFIG_ARM_ERRATA_720789=y
++CONFIG_ARM_ERRATA_743622=y
++CONFIG_ARM_ERRATA_751472=y
++CONFIG_ARM_ERRATA_754322=y
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++CONFIG_FORCE_MAX_ZONEORDER=13
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096"
++CONFIG_CMDLINE_FORCE=y
++CONFIG_KEXEC=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++# CONFIG_SUSPEND is not set
++CONFIG_NET=y
++CONFIG_PACKET=y
++CONFIG_UNIX=y
++CONFIG_INET=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_BEET is not set
++# CONFIG_INET_LRO is not set
++# CONFIG_INET_DIAG is not set
++# CONFIG_IPV6 is not set
++# CONFIG_WIRELESS is not set
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_SCSI=y
++CONFIG_BLK_DEV_SD=y
++CONFIG_MD=y
++CONFIG_BLK_DEV_DM=y
++CONFIG_NETDEVICES=y
++# CONFIG_NET_VENDOR_BROADCOM is not set
++# CONFIG_NET_VENDOR_CHELSIO 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_NATSEMI is not set
++CONFIG_SH_ETH=y
++# CONFIG_NET_VENDOR_SEEQ is not set
++# CONFIG_NET_VENDOR_STMICRO is not set
++# CONFIG_WLAN is not set
++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_KEYBOARD_ATKBD is not set
++CONFIG_KEYBOARD_GPIO=y
++# CONFIG_INPUT_MOUSE is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++CONFIG_TOUCHSCREEN_ST1232=y
++# CONFIG_SERIO is not set
++# CONFIG_LEGACY_PTYS is not set
++CONFIG_SERIAL_SH_SCI=y
++CONFIG_SERIAL_SH_SCI_NR_UARTS=8
++CONFIG_SERIAL_SH_SCI_CONSOLE=y
++# CONFIG_HW_RANDOM is not set
++CONFIG_I2C=y
++CONFIG_I2C_SH_MOBILE=y
++# CONFIG_HWMON is not set
++CONFIG_FB=y
++CONFIG_FB_MODE_HELPERS=y
++CONFIG_FB_SH_MOBILE_LCDC=y
++CONFIG_LCD_CLASS_DEVICE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
++CONFIG_LOGO=y
++# CONFIG_LOGO_LINUX_MONO is not set
++# CONFIG_LOGO_LINUX_VGA16 is not set
++CONFIG_SOUND=y
++CONFIG_SND=y
++# CONFIG_SND_SUPPORT_OLD_API is not set
++# CONFIG_SND_VERBOSE_PROCFS is not set
++# CONFIG_SND_DRIVERS is not set
++# CONFIG_SND_ARM is not set
++CONFIG_SND_SOC=y
++CONFIG_SND_SOC_SH4_FSI=y
++# CONFIG_HID_SUPPORT is not set
++# CONFIG_USB_SUPPORT is not set
++CONFIG_UIO=y
++CONFIG_UIO_PDRV_GENIRQ=y
++# CONFIG_DNOTIFY is not set
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_TMPFS=y
++# CONFIG_MISC_FILESYSTEMS is not set
++CONFIG_NFS_FS=y
++CONFIG_NFS_V3=y
++CONFIG_NFS_V3_ACL=y
++CONFIG_NFS_V4=y
++CONFIG_NFS_V4_1=y
++CONFIG_ROOT_NFS=y
++CONFIG_NLS_CODEPAGE_437=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++# CONFIG_ENABLE_MUST_CHECK is not set
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_DEBUG_SECTION_MISMATCH=y
++CONFIG_DEBUG_KERNEL=y
++CONFIG_LOCKUP_DETECTOR=y
++CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
++# CONFIG_DETECT_HUNG_TASK is not set
++# CONFIG_SCHED_DEBUG is not set
++CONFIG_DEBUG_KMEMLEAK=y
++CONFIG_DEBUG_SPINLOCK=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_FTRACE is not set
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_CBC=y
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_DES=y
++CONFIG_CRYPTO_ANSI_CPRNG=y
++CONFIG_XZ_DEC=y
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0061-ARM-mach-shmobile-armadillo800eva-add-support-LCDC0.patch b/patches.armadillo800/0061-ARM-mach-shmobile-armadillo800eva-add-support-LCDC0.patch
new file mode 100644
index 0000000000000..7aab5bd8bc305
--- /dev/null
+++ b/patches.armadillo800/0061-ARM-mach-shmobile-armadillo800eva-add-support-LCDC0.patch
@@ -0,0 +1,160 @@
+From 4dac8081711cdd9f55ee3191344bff84f7b573ff Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 6 Apr 2012 01:30:09 -0700
+Subject: ARM: mach-shmobile: armadillo800eva: add support LCDC0
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit dad29d1c29b7a8699403e45822065d979309f756)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 105 +++++++++++++++++++++++++
+ 1 file changed, 105 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 28bc259..5cc17a8 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -24,6 +24,7 @@
+ #include <linux/kernel.h>
+ #include <linux/platform_device.h>
+ #include <linux/gpio.h>
++#include <linux/videodev2.h>
+ #include <mach/common.h>
+ #include <mach/irqs.h>
+ #include <asm/page.h>
+@@ -33,6 +34,7 @@
+ #include <asm/mach/time.h>
+ #include <asm/hardware/cache-l2x0.h>
+ #include <mach/r8a7740.h>
++#include <video/sh_mobile_lcdc.h>
+
+ /*
+ * CON1 Camera Module
+@@ -92,10 +94,66 @@
+ *-----------+---------------+----------------------------
+ */
+
++/* LCDC */
++static struct fb_videomode lcdc0_mode = {
++ .name = "AMPIER/AM-800480",
++ .xres = 800,
++ .yres = 480,
++ .left_margin = 88,
++ .right_margin = 40,
++ .hsync_len = 128,
++ .upper_margin = 20,
++ .lower_margin = 5,
++ .vsync_len = 5,
++ .sync = 0,
++};
++
++static struct sh_mobile_lcdc_info lcdc0_info = {
++ .clock_source = LCDC_CLK_BUS,
++ .ch[0] = {
++ .chan = LCDC_CHAN_MAINLCD,
++ .fourcc = V4L2_PIX_FMT_RGB565,
++ .interface_type = RGB24,
++ .clock_divider = 5,
++ .flags = 0,
++ .lcd_modes = &lcdc0_mode,
++ .num_modes = 1,
++ .panel_cfg = {
++ .width = 111,
++ .height = 68,
++ },
++ },
++};
++
++static struct resource lcdc0_resources[] = {
++ [0] = {
++ .name = "LCD0",
++ .start = 0xfe940000,
++ .end = 0xfe943fff,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = intcs_evt2irq(0x580),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device lcdc0_device = {
++ .name = "sh_mobile_lcdc_fb",
++ .num_resources = ARRAY_SIZE(lcdc0_resources),
++ .resource = lcdc0_resources,
++ .id = 0,
++ .dev = {
++ .platform_data = &lcdc0_info,
++ .coherent_dma_mask = ~0,
++ },
++};
++
+ /*
+ * board devices
+ */
+ static struct platform_device *eva_devices[] __initdata = {
++ &lcdc0_device,
+ };
+
+ /*
+@@ -109,6 +167,53 @@ static void __init eva_init(void)
+ gpio_request(GPIO_FN_SCIFA1_RXD, NULL);
+ gpio_request(GPIO_FN_SCIFA1_TXD, NULL);
+
++ /* LCDC0 */
++ gpio_request(GPIO_FN_LCDC0_SELECT, NULL);
++ gpio_request(GPIO_FN_LCD0_D0, NULL);
++ gpio_request(GPIO_FN_LCD0_D1, NULL);
++ gpio_request(GPIO_FN_LCD0_D2, NULL);
++ gpio_request(GPIO_FN_LCD0_D3, NULL);
++ gpio_request(GPIO_FN_LCD0_D4, NULL);
++ gpio_request(GPIO_FN_LCD0_D5, NULL);
++ gpio_request(GPIO_FN_LCD0_D6, NULL);
++ gpio_request(GPIO_FN_LCD0_D7, NULL);
++ gpio_request(GPIO_FN_LCD0_D8, NULL);
++ gpio_request(GPIO_FN_LCD0_D9, NULL);
++ gpio_request(GPIO_FN_LCD0_D10, NULL);
++ gpio_request(GPIO_FN_LCD0_D11, NULL);
++ gpio_request(GPIO_FN_LCD0_D12, NULL);
++ gpio_request(GPIO_FN_LCD0_D13, NULL);
++ gpio_request(GPIO_FN_LCD0_D14, NULL);
++ gpio_request(GPIO_FN_LCD0_D15, NULL);
++ gpio_request(GPIO_FN_LCD0_D16, NULL);
++ gpio_request(GPIO_FN_LCD0_D17, NULL);
++ gpio_request(GPIO_FN_LCD0_D18_PORT40, NULL);
++ gpio_request(GPIO_FN_LCD0_D19_PORT4, NULL);
++ gpio_request(GPIO_FN_LCD0_D20_PORT3, NULL);
++ gpio_request(GPIO_FN_LCD0_D21_PORT2, NULL);
++ gpio_request(GPIO_FN_LCD0_D22_PORT0, NULL);
++ gpio_request(GPIO_FN_LCD0_D23_PORT1, NULL);
++ gpio_request(GPIO_FN_LCD0_DCK, NULL);
++ gpio_request(GPIO_FN_LCD0_VSYN, NULL);
++ gpio_request(GPIO_FN_LCD0_HSYN, NULL);
++ gpio_request(GPIO_FN_LCD0_DISP, NULL);
++ gpio_request(GPIO_FN_LCD0_LCLK_PORT165, NULL);
++
++ gpio_request(GPIO_PORT61, NULL); /* LCDDON */
++ gpio_direction_output(GPIO_PORT61, 1);
++
++ gpio_request(GPIO_PORT202, NULL); /* LCD0_LED_CONT */
++ gpio_direction_output(GPIO_PORT202, 0);
++
++ /*
++ * CAUTION
++ *
++ * DBGMD/LCDC0/FSIA MUX
++ * DBGMD_SELECT_B should be set after setting PFC Function.
++ */
++ gpio_request(GPIO_PORT176, NULL);
++ gpio_direction_output(GPIO_PORT176, 1);
++
+ #ifdef CONFIG_CACHE_L2X0
+ /* Early BRESP enable, Shared attribute override enable, 32K*8way */
+ l2x0_init(__io(0xf0002000), 0x40440000, 0x82000fff);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0062-ARM-mach-shmobile-armadillo800eva-add-support-gpio_k.patch b/patches.armadillo800/0062-ARM-mach-shmobile-armadillo800eva-add-support-gpio_k.patch
new file mode 100644
index 0000000000000..813c5ef4c4829
--- /dev/null
+++ b/patches.armadillo800/0062-ARM-mach-shmobile-armadillo800eva-add-support-gpio_k.patch
@@ -0,0 +1,70 @@
+From 683089b4115c60b9b9f35ec3f5d91122a8a416e1 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 6 Apr 2012 01:31:33 -0700
+Subject: ARM: mach-shmobile: armadillo800eva: add support gpio_key
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit f7e7d31a1299e11be780f8e2d235570792849e31)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 5cc17a8..0bce9b8 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -22,8 +22,10 @@
+ #include <linux/clk.h>
+ #include <linux/err.h>
+ #include <linux/kernel.h>
++#include <linux/input.h>
+ #include <linux/platform_device.h>
+ #include <linux/gpio.h>
++#include <linux/gpio_keys.h>
+ #include <linux/videodev2.h>
+ #include <mach/common.h>
+ #include <mach/irqs.h>
+@@ -149,11 +151,35 @@ static struct platform_device lcdc0_device = {
+ },
+ };
+
++/* GPIO KEY */
++#define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 }
++
++static struct gpio_keys_button gpio_buttons[] = {
++ GPIO_KEY(KEY_POWER, GPIO_PORT99, "SW1"),
++ GPIO_KEY(KEY_BACK, GPIO_PORT100, "SW2"),
++ GPIO_KEY(KEY_MENU, GPIO_PORT97, "SW3"),
++ GPIO_KEY(KEY_HOME, GPIO_PORT98, "SW4"),
++};
++
++static struct gpio_keys_platform_data gpio_key_info = {
++ .buttons = gpio_buttons,
++ .nbuttons = ARRAY_SIZE(gpio_buttons),
++};
++
++static struct platform_device gpio_keys_device = {
++ .name = "gpio-keys",
++ .id = -1,
++ .dev = {
++ .platform_data = &gpio_key_info,
++ },
++};
++
+ /*
+ * board devices
+ */
+ static struct platform_device *eva_devices[] __initdata = {
+ &lcdc0_device,
++ &gpio_keys_device,
+ };
+
+ /*
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0063-ARM-mach-shmobile-armadillo800eva-add-support-sh_eth.patch b/patches.armadillo800/0063-ARM-mach-shmobile-armadillo800eva-add-support-sh_eth.patch
new file mode 100644
index 0000000000000..a66c2450f1462
--- /dev/null
+++ b/patches.armadillo800/0063-ARM-mach-shmobile-armadillo800eva-add-support-sh_eth.patch
@@ -0,0 +1,109 @@
+From ab1150c0be9d95c57f6f03a56917c77b2af01bce Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 6 Apr 2012 01:32:02 -0700
+Subject: ARM: mach-shmobile: armadillo800eva: add support sh_eth
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit d8fed1e254ba1ed38fd2977fdac4c2e35ed5dbc1)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 58 ++++++++++++++++++++++++++
+ 1 file changed, 58 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 0bce9b8..d439e7f 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -26,6 +26,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/gpio.h>
+ #include <linux/gpio_keys.h>
++#include <linux/sh_eth.h>
+ #include <linux/videodev2.h>
+ #include <mach/common.h>
+ #include <mach/irqs.h>
+@@ -96,6 +97,38 @@
+ *-----------+---------------+----------------------------
+ */
+
++/* Ether */
++static struct sh_eth_plat_data sh_eth_platdata = {
++ .phy = 0x00, /* LAN8710A */
++ .edmac_endian = EDMAC_LITTLE_ENDIAN,
++ .register_type = SH_ETH_REG_GIGABIT,
++ .phy_interface = PHY_INTERFACE_MODE_MII,
++};
++
++static struct resource sh_eth_resources[] = {
++ {
++ .start = 0xe9a00000,
++ .end = 0xe9a00800 - 1,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = 0xe9a01800,
++ .end = 0xe9a02000 - 1,
++ .flags = IORESOURCE_MEM,
++ }, {
++ .start = evt2irq(0x0500),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device sh_eth_device = {
++ .name = "sh-eth",
++ .dev = {
++ .platform_data = &sh_eth_platdata,
++ },
++ .resource = sh_eth_resources,
++ .num_resources = ARRAY_SIZE(sh_eth_resources),
++};
++
+ /* LCDC */
+ static struct fb_videomode lcdc0_mode = {
+ .name = "AMPIER/AM-800480",
+@@ -180,6 +213,7 @@ static struct platform_device gpio_keys_device = {
+ static struct platform_device *eva_devices[] __initdata = {
+ &lcdc0_device,
+ &gpio_keys_device,
++ &sh_eth_device,
+ };
+
+ /*
+@@ -231,6 +265,30 @@ static void __init eva_init(void)
+ gpio_request(GPIO_PORT202, NULL); /* LCD0_LED_CONT */
+ gpio_direction_output(GPIO_PORT202, 0);
+
++ /* GETHER */
++ gpio_request(GPIO_FN_ET_CRS, NULL);
++ gpio_request(GPIO_FN_ET_MDC, NULL);
++ gpio_request(GPIO_FN_ET_MDIO, NULL);
++ gpio_request(GPIO_FN_ET_TX_ER, NULL);
++ gpio_request(GPIO_FN_ET_RX_ER, NULL);
++ gpio_request(GPIO_FN_ET_ERXD0, NULL);
++ gpio_request(GPIO_FN_ET_ERXD1, NULL);
++ gpio_request(GPIO_FN_ET_ERXD2, NULL);
++ gpio_request(GPIO_FN_ET_ERXD3, NULL);
++ gpio_request(GPIO_FN_ET_TX_CLK, NULL);
++ gpio_request(GPIO_FN_ET_TX_EN, NULL);
++ gpio_request(GPIO_FN_ET_ETXD0, NULL);
++ gpio_request(GPIO_FN_ET_ETXD1, NULL);
++ gpio_request(GPIO_FN_ET_ETXD2, NULL);
++ gpio_request(GPIO_FN_ET_ETXD3, NULL);
++ gpio_request(GPIO_FN_ET_PHY_INT, NULL);
++ gpio_request(GPIO_FN_ET_COL, NULL);
++ gpio_request(GPIO_FN_ET_RX_DV, NULL);
++ gpio_request(GPIO_FN_ET_RX_CLK, NULL);
++
++ gpio_request(GPIO_PORT18, NULL); /* PHY_RST */
++ gpio_direction_output(GPIO_PORT18, 1);
++
+ /*
+ * CAUTION
+ *
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0064-ARM-mach-shmobile-armadillo800eva-add-support-ST1232.patch b/patches.armadillo800/0064-ARM-mach-shmobile-armadillo800eva-add-support-ST1232.patch
new file mode 100644
index 0000000000000..3dc4e30a947a7
--- /dev/null
+++ b/patches.armadillo800/0064-ARM-mach-shmobile-armadillo800eva-add-support-ST1232.patch
@@ -0,0 +1,59 @@
+From 6c075ffc555411ed9a75c338058837c617323f16 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 6 Apr 2012 01:30:42 -0700
+Subject: ARM: mach-shmobile: armadillo800eva: add support ST1232
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Reviewed-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 46cf668748070e54879d528fa58107abc835dff3)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index d439e7f..4d066f9 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -207,6 +207,14 @@ static struct platform_device gpio_keys_device = {
+ },
+ };
+
++/* I2C */
++static struct i2c_board_info i2c0_devices[] = {
++ {
++ I2C_BOARD_INFO("st1232-ts", 0x55),
++ .irq = evt2irq(0x0340),
++ },
++};
++
+ /*
+ * board devices
+ */
+@@ -265,6 +273,11 @@ static void __init eva_init(void)
+ gpio_request(GPIO_PORT202, NULL); /* LCD0_LED_CONT */
+ gpio_direction_output(GPIO_PORT202, 0);
+
++ /* Touchscreen */
++ gpio_request(GPIO_FN_IRQ10, NULL); /* TP_INT */
++ gpio_request(GPIO_PORT166, NULL); /* TP_RST_B */
++ gpio_direction_output(GPIO_PORT166, 1);
++
+ /* GETHER */
+ gpio_request(GPIO_FN_ET_CRS, NULL);
+ gpio_request(GPIO_FN_ET_MDC, NULL);
+@@ -303,6 +316,8 @@ static void __init eva_init(void)
+ l2x0_init(__io(0xf0002000), 0x40440000, 0x82000fff);
+ #endif
+
++ i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
++
+ r8a7740_add_standard_devices();
+
+ platform_add_devices(eva_devices,
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0065-ARM-mach-shmobile-armadillo800eva-add-USB-function-s.patch b/patches.armadillo800/0065-ARM-mach-shmobile-armadillo800eva-add-USB-function-s.patch
new file mode 100644
index 0000000000000..f153b6ecad422
--- /dev/null
+++ b/patches.armadillo800/0065-ARM-mach-shmobile-armadillo800eva-add-USB-function-s.patch
@@ -0,0 +1,326 @@
+From 1dae1324b5c1a1b5c27de07729b9b52a61037b3e Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 24 Apr 2012 02:09:08 -0700
+Subject: ARM: mach-shmobile: armadillo800eva: add USB function support
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 1c96293e9f8b8ec9620201bcf7f776f0e0f89edb)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 247 ++++++++++++++++++++++++-
+ 1 file changed, 237 insertions(+), 10 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 4d066f9..1d25d5f 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -20,14 +20,17 @@
+ */
+
+ #include <linux/clk.h>
++#include <linux/delay.h>
+ #include <linux/err.h>
+ #include <linux/kernel.h>
+ #include <linux/input.h>
++#include <linux/irq.h>
+ #include <linux/platform_device.h>
+ #include <linux/gpio.h>
+ #include <linux/gpio_keys.h>
+ #include <linux/sh_eth.h>
+ #include <linux/videodev2.h>
++#include <linux/usb/renesas_usbhs.h>
+ #include <mach/common.h>
+ #include <mach/irqs.h>
+ #include <asm/page.h>
+@@ -90,6 +93,9 @@
+ * 0 | SDHI1 | COM8 enable, COM14 disable
+ * 1 | SDHI1 | COM8 enable, COM14 disable
+ * -12345678-+---------------+----------------------------
++ * 0 | USB0 | COM20 enable, COM24 disable
++ * 1 | USB0 | COM20 disable, COM24 enable
++ * -12345678-+---------------+----------------------------
+ * 00 | JTAG | SH-X2
+ * 10 | JTAG | ARM
+ * 01 | JTAG | -
+@@ -97,6 +103,195 @@
+ *-----------+---------------+----------------------------
+ */
+
++/*
++ * USB function
++ *
++ * When you use USB Function,
++ * set SW1.6 ON, and connect cable to CN24.
++ *
++ * USBF needs workaround on R8A7740 chip.
++ * These are a little bit complex.
++ * see
++ * usbhsf_power_ctrl()
++ *
++ * CAUTION
++ *
++ * It uses autonomy mode for USB hotplug at this point
++ * (= usbhs_private.platform_callback.get_vbus is NULL),
++ * since we don't know what's happen on PM control
++ * on this workaround.
++ */
++#define USBCR1 0xe605810a
++#define USBH 0xC6700000
++#define USBH_USBCTR 0x10834
++
++struct usbhsf_private {
++ struct clk *phy;
++ struct clk *usb24;
++ struct clk *pci;
++ struct clk *func;
++ struct clk *host;
++ void __iomem *usbh_base;
++ struct renesas_usbhs_platform_info info;
++};
++
++#define usbhsf_get_priv(pdev) \
++ container_of(renesas_usbhs_get_info(pdev), \
++ struct usbhsf_private, info)
++
++static int usbhsf_get_id(struct platform_device *pdev)
++{
++ return USBHS_GADGET;
++}
++
++static void usbhsf_power_ctrl(struct platform_device *pdev,
++ void __iomem *base, int enable)
++{
++ struct usbhsf_private *priv = usbhsf_get_priv(pdev);
++
++ /*
++ * Work around for USB Function.
++ * It needs USB host clock, and settings
++ */
++ if (enable) {
++ /*
++ * enable all the related usb clocks
++ * for usb workaround
++ */
++ clk_enable(priv->usb24);
++ clk_enable(priv->pci);
++ clk_enable(priv->host);
++ clk_enable(priv->func);
++ clk_enable(priv->phy);
++
++ /*
++ * set USBCR1
++ *
++ * Port1 is driven by USB function,
++ * Port2 is driven by USB HOST
++ * One HOST (Port1 or Port2 is HOST)
++ * USB PLL input clock = 24MHz
++ */
++ __raw_writew(0xd750, USBCR1);
++ mdelay(1);
++
++ /*
++ * start USB Host
++ */
++ __raw_writel(0x0000000c, priv->usbh_base + USBH_USBCTR);
++ __raw_writel(0x00000008, priv->usbh_base + USBH_USBCTR);
++ mdelay(10);
++
++ /*
++ * USB PHY Power ON
++ */
++ __raw_writew(0xd770, USBCR1);
++ __raw_writew(0x4000, base + 0x102); /* USBF :: SUSPMODE */
++
++ } else {
++ __raw_writel(0x0000010f, priv->usbh_base + USBH_USBCTR);
++ __raw_writew(0xd7c0, USBCR1); /* GPIO */
++
++ clk_disable(priv->phy);
++ clk_disable(priv->func); /* usb work around */
++ clk_disable(priv->host); /* usb work around */
++ clk_disable(priv->pci); /* usb work around */
++ clk_disable(priv->usb24); /* usb work around */
++ }
++}
++
++static void usbhsf_hardware_exit(struct platform_device *pdev)
++{
++ struct usbhsf_private *priv = usbhsf_get_priv(pdev);
++
++ if (!IS_ERR(priv->phy))
++ clk_put(priv->phy);
++ if (!IS_ERR(priv->usb24))
++ clk_put(priv->usb24);
++ if (!IS_ERR(priv->pci))
++ clk_put(priv->pci);
++ if (!IS_ERR(priv->host))
++ clk_put(priv->host);
++ if (!IS_ERR(priv->func))
++ clk_put(priv->func);
++ if (priv->usbh_base)
++ iounmap(priv->usbh_base);
++
++ priv->phy = NULL;
++ priv->usb24 = NULL;
++ priv->pci = NULL;
++ priv->host = NULL;
++ priv->func = NULL;
++ priv->usbh_base = NULL;
++}
++
++static int usbhsf_hardware_init(struct platform_device *pdev)
++{
++ struct usbhsf_private *priv = usbhsf_get_priv(pdev);
++
++ priv->phy = clk_get(&pdev->dev, "phy");
++ priv->usb24 = clk_get(&pdev->dev, "usb24");
++ priv->pci = clk_get(&pdev->dev, "pci");
++ priv->func = clk_get(&pdev->dev, "func");
++ priv->host = clk_get(&pdev->dev, "host");
++ priv->usbh_base = ioremap_nocache(USBH, 0x20000);
++
++ if (IS_ERR(priv->phy) ||
++ IS_ERR(priv->usb24) ||
++ IS_ERR(priv->pci) ||
++ IS_ERR(priv->host) ||
++ IS_ERR(priv->func) ||
++ !priv->usbh_base) {
++ dev_err(&pdev->dev, "USB clock setting failed\n");
++ usbhsf_hardware_exit(pdev);
++ return -EIO;
++ }
++
++ /* usb24 use 1/1 of parent clock (= usb24s = 24MHz) */
++ clk_set_rate(priv->usb24,
++ clk_get_rate(clk_get_parent(priv->usb24)));
++
++ return 0;
++}
++
++static struct usbhsf_private usbhsf_private = {
++ .info = {
++ .platform_callback = {
++ .get_id = usbhsf_get_id,
++ .hardware_init = usbhsf_hardware_init,
++ .hardware_exit = usbhsf_hardware_exit,
++ .power_ctrl = usbhsf_power_ctrl,
++ },
++ .driver_param = {
++ .buswait_bwait = 5,
++ .detection_delay = 5,
++ },
++ }
++};
++
++static struct resource usbhsf_resources[] = {
++ {
++ .name = "USBHS",
++ .start = 0xe6890000,
++ .end = 0xe6890104 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .start = evt2irq(0x0A20),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device usbhsf_device = {
++ .name = "renesas_usbhs",
++ .dev = {
++ .platform_data = &usbhsf_private.info,
++ },
++ .id = -1,
++ .num_resources = ARRAY_SIZE(usbhsf_resources),
++ .resource = usbhsf_resources,
++};
++
+ /* Ether */
+ static struct sh_eth_plat_data sh_eth_platdata = {
+ .phy = 0x00, /* LAN8710A */
+@@ -224,11 +419,41 @@ static struct platform_device *eva_devices[] __initdata = {
+ &sh_eth_device,
+ };
+
++static void __init eva_clock_init(void)
++{
++ struct clk *system = clk_get(NULL, "system_clk");
++ struct clk *xtal1 = clk_get(NULL, "extal1");
++ struct clk *usb24s = clk_get(NULL, "usb24s");
++
++ if (IS_ERR(system) ||
++ IS_ERR(xtal1) ||
++ IS_ERR(usb24s)) {
++ pr_err("armadillo800eva board clock init failed\n");
++ goto clock_error;
++ }
++
++ /* armadillo 800 eva extal1 is 24MHz */
++ clk_set_rate(xtal1, 24000000);
++
++ /* usb24s use extal1 (= system) clock (= 24MHz) */
++ clk_set_parent(usb24s, system);
++
++clock_error:
++ if (!IS_ERR(system))
++ clk_put(system);
++ if (!IS_ERR(xtal1))
++ clk_put(xtal1);
++ if (!IS_ERR(usb24s))
++ clk_put(usb24s);
++}
++
+ /*
+ * board init
+ */
+ static void __init eva_init(void)
+ {
++ eva_clock_init();
++
+ r8a7740_pinmux_init();
+
+ /* SCIFA1 */
+@@ -302,6 +527,18 @@ static void __init eva_init(void)
+ gpio_request(GPIO_PORT18, NULL); /* PHY_RST */
+ gpio_direction_output(GPIO_PORT18, 1);
+
++ /* USB */
++ gpio_request(GPIO_PORT159, NULL); /* USB_DEVICE_MODE */
++ gpio_direction_input(GPIO_PORT159);
++
++ if (gpio_get_value(GPIO_PORT159)) {
++ /* USB Host */
++ } else {
++ /* USB Func */
++ gpio_request(GPIO_FN_VBUS, NULL);
++ platform_device_register(&usbhsf_device);
++ }
++
+ /*
+ * CAUTION
+ *
+@@ -326,17 +563,7 @@ static void __init eva_init(void)
+
+ static void __init eva_earlytimer_init(void)
+ {
+- struct clk *xtal1;
+-
+ r8a7740_clock_init(MD_CK0 | MD_CK2);
+-
+- xtal1 = clk_get(NULL, "extal1");
+- if (!IS_ERR(xtal1)) {
+- /* armadillo 800 eva extal1 is 24MHz */
+- clk_set_rate(xtal1, 24000000);
+- clk_put(xtal1);
+- }
+-
+ shmobile_earlytimer_init();
+ }
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0066-ARM-mach-shmobile-armadillo800eva-add-SDHI0-support.patch b/patches.armadillo800/0066-ARM-mach-shmobile-armadillo800eva-add-SDHI0-support.patch
new file mode 100644
index 0000000000000..d98a57088be6c
--- /dev/null
+++ b/patches.armadillo800/0066-ARM-mach-shmobile-armadillo800eva-add-SDHI0-support.patch
@@ -0,0 +1,129 @@
+From 4cc08f83ce664539a9c3dab8a1b486002346ee83 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 24 Apr 2012 02:09:19 -0700
+Subject: ARM: mach-shmobile: armadillo800eva: add SDHI0 support
+
+On armadillo800eva board,
+CD (= Card Detect) pin is not connected to SDHI0_CD.
+Then, we can use IRQ31 as card detect irq,
+but it needs chattering removal operation.
+We should use IRQ card detect in the future,
+but this patch use polling mode at this point.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 49c01112d6afdb679276c172ffcd4f1205c1ff97)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 71 ++++++++++++++++++++++++++
+ 1 file changed, 71 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 1d25d5f..ed85686 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -31,6 +31,9 @@
+ #include <linux/sh_eth.h>
+ #include <linux/videodev2.h>
+ #include <linux/usb/renesas_usbhs.h>
++#include <linux/mfd/tmio.h>
++#include <linux/mmc/host.h>
++#include <linux/mmc/sh_mobile_sdhi.h>
+ #include <mach/common.h>
+ #include <mach/irqs.h>
+ #include <asm/page.h>
+@@ -402,6 +405,55 @@ static struct platform_device gpio_keys_device = {
+ },
+ };
+
++/* SDHI0 */
++/*
++ * FIXME
++ *
++ * It use polling mode here, since
++ * CD (= Card Detect) pin is not connected to SDHI0_CD.
++ * We can use IRQ31 as card detect irq,
++ * but it needs chattering removal operation
++ */
++#define IRQ31 evt2irq(0x33E0)
++static struct sh_mobile_sdhi_info sdhi0_info = {
++ .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |\
++ MMC_CAP_NEEDS_POLL,
++ .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
++ .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT,
++};
++
++static struct resource sdhi0_resources[] = {
++ {
++ .name = "SDHI0",
++ .start = 0xe6850000,
++ .end = 0xe6850100 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ /*
++ * no SH_MOBILE_SDHI_IRQ_CARD_DETECT here
++ */
++ {
++ .name = SH_MOBILE_SDHI_IRQ_SDCARD,
++ .start = evt2irq(0x0E20),
++ .flags = IORESOURCE_IRQ,
++ },
++ {
++ .name = SH_MOBILE_SDHI_IRQ_SDIO,
++ .start = evt2irq(0x0E40),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device sdhi0_device = {
++ .name = "sh_mobile_sdhi",
++ .id = 0,
++ .dev = {
++ .platform_data = &sdhi0_info,
++ },
++ .num_resources = ARRAY_SIZE(sdhi0_resources),
++ .resource = sdhi0_resources,
++};
++
+ /* I2C */
+ static struct i2c_board_info i2c0_devices[] = {
+ {
+@@ -417,6 +469,7 @@ static struct platform_device *eva_devices[] __initdata = {
+ &lcdc0_device,
+ &gpio_keys_device,
+ &sh_eth_device,
++ &sdhi0_device,
+ };
+
+ static void __init eva_clock_init(void)
+@@ -539,6 +592,24 @@ static void __init eva_init(void)
+ platform_device_register(&usbhsf_device);
+ }
+
++ /* SDHI0 */
++ gpio_request(GPIO_FN_SDHI0_CMD, NULL);
++ gpio_request(GPIO_FN_SDHI0_CLK, NULL);
++ gpio_request(GPIO_FN_SDHI0_D0, NULL);
++ gpio_request(GPIO_FN_SDHI0_D1, NULL);
++ gpio_request(GPIO_FN_SDHI0_D2, NULL);
++ gpio_request(GPIO_FN_SDHI0_D3, NULL);
++ gpio_request(GPIO_FN_SDHI0_WP, NULL);
++
++ gpio_request(GPIO_PORT17, NULL); /* SDHI0_18/33_B */
++ gpio_request(GPIO_PORT74, NULL); /* SDHI0_PON */
++ gpio_request(GPIO_PORT75, NULL); /* SDSLOT1_PON */
++ gpio_direction_output(GPIO_PORT17, 0);
++ gpio_direction_output(GPIO_PORT74, 1);
++ gpio_direction_output(GPIO_PORT75, 1);
++
++ /* we can use GPIO_FN_IRQ31_PORT167 here for SDHI0 CD irq */
++
+ /*
+ * CAUTION
+ *
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0067-ARM-mach-shmobile-armadillo800eva-add-SDHI1-support.patch b/patches.armadillo800/0067-ARM-mach-shmobile-armadillo800eva-add-SDHI1-support.patch
new file mode 100644
index 0000000000000..ff2fe866e3f91
--- /dev/null
+++ b/patches.armadillo800/0067-ARM-mach-shmobile-armadillo800eva-add-SDHI1-support.patch
@@ -0,0 +1,113 @@
+From 78c21b71d7b4c9b2a5b2a785aca79aee0b9ffba2 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 24 Apr 2012 02:09:31 -0700
+Subject: ARM: mach-shmobile: armadillo800eva: add SDHI1 support
+
+We can switch CON8/CON14 by SW1.5
+SDHI1 is CON8 (SW1.5 = ON)
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 2e3a5ef28f8182c439a5a276ff4c0883c02787f4)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 66 +++++++++++++++++++++++++-
+ 1 file changed, 65 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index ed85686..5f62428 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -93,7 +93,7 @@
+ * 0 | Extension Bus | D8-D15 disable, eMMC enable
+ * 1 | Extension Bus | D8-D15 enable, eMMC disable
+ * -12345678-+---------------+----------------------------
+- * 0 | SDHI1 | COM8 enable, COM14 disable
++ * 0 | SDHI1 | COM8 disable, COM14 enable
+ * 1 | SDHI1 | COM8 enable, COM14 disable
+ * -12345678-+---------------+----------------------------
+ * 0 | USB0 | COM20 enable, COM24 disable
+@@ -454,6 +454,44 @@ static struct platform_device sdhi0_device = {
+ .resource = sdhi0_resources,
+ };
+
++/* SDHI1 */
++static struct sh_mobile_sdhi_info sdhi1_info = {
++ .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ,
++ .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
++ .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT,
++};
++
++static struct resource sdhi1_resources[] = {
++ [0] = {
++ .name = "SDHI1",
++ .start = 0xe6860000,
++ .end = 0xe6860100 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = evt2irq(0x0E80),
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ .start = evt2irq(0x0EA0),
++ .flags = IORESOURCE_IRQ,
++ },
++ [3] = {
++ .start = evt2irq(0x0EC0),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device sdhi1_device = {
++ .name = "sh_mobile_sdhi",
++ .id = 1,
++ .dev = {
++ .platform_data = &sdhi1_info,
++ },
++ .num_resources = ARRAY_SIZE(sdhi1_resources),
++ .resource = sdhi1_resources,
++};
++
+ /* I2C */
+ static struct i2c_board_info i2c0_devices[] = {
+ {
+@@ -619,6 +657,32 @@ static void __init eva_init(void)
+ gpio_request(GPIO_PORT176, NULL);
+ gpio_direction_output(GPIO_PORT176, 1);
+
++ /*
++ * We can switch CON8/CON14 by SW1.5,
++ * but it needs after DBGMD_SELECT_B
++ */
++ gpio_request(GPIO_PORT6, NULL);
++ gpio_direction_input(GPIO_PORT6);
++ if (gpio_get_value(GPIO_PORT6)) {
++ /* CON14 enable */
++ } else {
++ /* CON8 (SDHI1) enable */
++ gpio_request(GPIO_FN_SDHI1_CLK, NULL);
++ gpio_request(GPIO_FN_SDHI1_CMD, NULL);
++ gpio_request(GPIO_FN_SDHI1_D0, NULL);
++ gpio_request(GPIO_FN_SDHI1_D1, NULL);
++ gpio_request(GPIO_FN_SDHI1_D2, NULL);
++ gpio_request(GPIO_FN_SDHI1_D3, NULL);
++ gpio_request(GPIO_FN_SDHI1_CD, NULL);
++ gpio_request(GPIO_FN_SDHI1_WP, NULL);
++
++ gpio_request(GPIO_PORT16, NULL); /* SDSLOT2_PON */
++ gpio_direction_output(GPIO_PORT16, 1);
++
++ platform_device_register(&sdhi1_device);
++ }
++
++
+ #ifdef CONFIG_CACHE_L2X0
+ /* Early BRESP enable, Shared attribute override enable, 32K*8way */
+ l2x0_init(__io(0xf0002000), 0x40440000, 0x82000fff);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0068-ARM-mach-shmobile-armadillo800eva-add-MMCIF-support.patch b/patches.armadillo800/0068-ARM-mach-shmobile-armadillo800eva-add-MMCIF-support.patch
new file mode 100644
index 0000000000000..fe15b6ab9e5f1
--- /dev/null
+++ b/patches.armadillo800/0068-ARM-mach-shmobile-armadillo800eva-add-MMCIF-support.patch
@@ -0,0 +1,108 @@
+From 0d4e5e39563404cb97b24a37388535b6c54ac90d Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 24 Apr 2012 02:09:42 -0700
+Subject: ARM: mach-shmobile: armadillo800eva: add MMCIF support
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 0a4266bb22774bb0b6390d2633a151d996a14e77)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 57 ++++++++++++++++++++++++++
+ 1 file changed, 57 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 5f62428..0cfaec5 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -33,6 +33,7 @@
+ #include <linux/usb/renesas_usbhs.h>
+ #include <linux/mfd/tmio.h>
+ #include <linux/mmc/host.h>
++#include <linux/mmc/sh_mmcif.h>
+ #include <linux/mmc/sh_mobile_sdhi.h>
+ #include <mach/common.h>
+ #include <mach/irqs.h>
+@@ -492,6 +493,44 @@ static struct platform_device sdhi1_device = {
+ .resource = sdhi1_resources,
+ };
+
++/* MMCIF */
++static struct sh_mmcif_plat_data sh_mmcif_plat = {
++ .sup_pclk = 0,
++ .ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
++ .caps = MMC_CAP_4_BIT_DATA |
++ MMC_CAP_8_BIT_DATA |
++ MMC_CAP_NONREMOVABLE,
++};
++
++static struct resource sh_mmcif_resources[] = {
++ [0] = {
++ .name = "MMCIF",
++ .start = 0xe6bd0000,
++ .end = 0xe6bd0100 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ /* MMC ERR */
++ .start = evt2irq(0x1AC0),
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ /* MMC NOR */
++ .start = evt2irq(0x1AE0),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device sh_mmcif_device = {
++ .name = "sh_mmcif",
++ .id = -1,
++ .dev = {
++ .platform_data = &sh_mmcif_plat,
++ },
++ .num_resources = ARRAY_SIZE(sh_mmcif_resources),
++ .resource = sh_mmcif_resources,
++};
++
+ /* I2C */
+ static struct i2c_board_info i2c0_devices[] = {
+ {
+@@ -508,6 +547,7 @@ static struct platform_device *eva_devices[] __initdata = {
+ &gpio_keys_device,
+ &sh_eth_device,
+ &sdhi0_device,
++ &sh_mmcif_device,
+ };
+
+ static void __init eva_clock_init(void)
+@@ -649,6 +689,23 @@ static void __init eva_init(void)
+ /* we can use GPIO_FN_IRQ31_PORT167 here for SDHI0 CD irq */
+
+ /*
++ * MMCIF
++ *
++ * Here doesn't care SW1.4 status,
++ * since CON2 is not mounted.
++ */
++ gpio_request(GPIO_FN_MMC1_CLK_PORT103, NULL);
++ gpio_request(GPIO_FN_MMC1_CMD_PORT104, NULL);
++ gpio_request(GPIO_FN_MMC1_D0_PORT149, NULL);
++ gpio_request(GPIO_FN_MMC1_D1_PORT148, NULL);
++ gpio_request(GPIO_FN_MMC1_D2_PORT147, NULL);
++ gpio_request(GPIO_FN_MMC1_D3_PORT146, NULL);
++ gpio_request(GPIO_FN_MMC1_D4_PORT145, NULL);
++ gpio_request(GPIO_FN_MMC1_D5_PORT144, NULL);
++ gpio_request(GPIO_FN_MMC1_D6_PORT143, NULL);
++ gpio_request(GPIO_FN_MMC1_D7_PORT142, NULL);
++
++ /*
+ * CAUTION
+ *
+ * DBGMD/LCDC0/FSIA MUX
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0069-ARM-mach-shmobile-r8a7740-reserve-DMA-memory-for-the.patch b/patches.armadillo800/0069-ARM-mach-shmobile-r8a7740-reserve-DMA-memory-for-the.patch
new file mode 100644
index 0000000000000..90555bdbcc333
--- /dev/null
+++ b/patches.armadillo800/0069-ARM-mach-shmobile-r8a7740-reserve-DMA-memory-for-the.patch
@@ -0,0 +1,47 @@
+From 3d1f581e9dbb224b5f0543883cc3e86876c8e5fe Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 24 Apr 2012 02:10:05 -0700
+Subject: ARM: mach-shmobile: r8a7740: reserve DMA memory for the frame buffer
+
+The default 2MB size of DMA coherent memory isn't enough for allocate
+frame buffer memory.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 3841e6f561af717478b253ce1dcba7bff9e9f890)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/setup-r8a7740.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
+index 34a1548..ec4eb49 100644
+--- a/arch/arm/mach-shmobile/setup-r8a7740.c
++++ b/arch/arm/mach-shmobile/setup-r8a7740.c
+@@ -18,6 +18,7 @@
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+ #include <linux/delay.h>
++#include <linux/dma-mapping.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/io.h>
+@@ -60,6 +61,12 @@ static struct map_desc r8a7740_io_desc[] __initdata = {
+ void __init r8a7740_map_io(void)
+ {
+ iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc));
++
++ /*
++ * DMA memory at 0xff200000 - 0xffdfffff. The default 2MB size isn't
++ * enough to allocate the frame buffer memory.
++ */
++ init_consistent_dma_size(12 << 20);
+ }
+
+ /* SCIFA0 */
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0070-ARM-mach-shmobile-clock-r8a7740-add-sh-eth-clock.patch b/patches.armadillo800/0070-ARM-mach-shmobile-clock-r8a7740-add-sh-eth-clock.patch
new file mode 100644
index 0000000000000..1205439ce95a5
--- /dev/null
+++ b/patches.armadillo800/0070-ARM-mach-shmobile-clock-r8a7740-add-sh-eth-clock.patch
@@ -0,0 +1,64 @@
+From c1d7a1d9c12959dea7cc4f0552e6b7985afeb186 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 6 May 2012 22:58:41 -0700
+Subject: ARM: mach-shmobile: clock-r8a7740: add sh-eth clock
+
+armadillo800eva board is using sh-eth, but clock-r8a7740 didn't care it.
+This clock was enabled by boot-loader.
+This patch fix it up.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Reviewed-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 9c18f238c1ec36b9912b5b36ae24e0c221179044)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 1 +
+ arch/arm/mach-shmobile/clock-r8a7740.c | 3 +++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 0cfaec5..e750ea6 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -321,6 +321,7 @@ static struct resource sh_eth_resources[] = {
+
+ static struct platform_device sh_eth_device = {
+ .name = "sh-eth",
++ .id = -1,
+ .dev = {
+ .platform_data = &sh_eth_platdata,
+ },
+diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
+index 81b54a6..26eea5f 100644
+--- a/arch/arm/mach-shmobile/clock-r8a7740.c
++++ b/arch/arm/mach-shmobile/clock-r8a7740.c
+@@ -352,6 +352,7 @@ enum {
+
+ MSTP329, MSTP328, MSTP323, MSTP320,
+ MSTP314, MSTP313, MSTP312,
++ MSTP309,
+
+ MSTP416, MSTP415, MSTP407, MSTP406,
+
+@@ -382,6 +383,7 @@ static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
+ [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
+ [MSTP312] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
++ [MSTP309] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 9, 0), /* GEther */
+
+ [MSTP416] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 16, 0), /* USBHOST */
+ [MSTP415] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
+@@ -447,6 +449,7 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
+ CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP312]),
++ CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP309]),
+
+ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]),
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0071-ARM-mach-shmobile-armadillo800eva-defconfig-update.patch b/patches.armadillo800/0071-ARM-mach-shmobile-armadillo800eva-defconfig-update.patch
new file mode 100644
index 0000000000000..0fdb8e8588a0c
--- /dev/null
+++ b/patches.armadillo800/0071-ARM-mach-shmobile-armadillo800eva-defconfig-update.patch
@@ -0,0 +1,87 @@
+From b578e0342552c51f1d81de4d730bf5325f52b48a Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Wed, 25 Apr 2012 20:57:13 -0700
+Subject: ARM: mach-shmobile: armadillo800eva: defconfig update
+
+This patch enable USBFunc/SHDI/MMCIF,
+remove debug settings,
+and cleanuped by c2330e286f68f1c408b4aa6515ba49d57f05beae script
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 9183857d503f915ee05abb6e03cea7253dcbace6)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/configs/armadillo800eva_defconfig | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/arch/arm/configs/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig
+index 0d20749..ddc9fe6 100644
+--- a/arch/arm/configs/armadillo800eva_defconfig
++++ b/arch/arm/configs/armadillo800eva_defconfig
+@@ -10,7 +10,6 @@ CONFIG_LOG_BUF_SHIFT=16
+ CONFIG_SYSFS_DEPRECATED=y
+ CONFIG_SYSFS_DEPRECATED_V2=y
+ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+-CONFIG_KALLSYMS_ALL=y
+ CONFIG_SLAB=y
+ CONFIG_MODULES=y
+ CONFIG_MODULE_UNLOAD=y
+@@ -63,6 +62,7 @@ CONFIG_BLK_DEV_DM=y
+ CONFIG_NETDEVICES=y
+ # CONFIG_NET_VENDOR_BROADCOM is not set
+ # CONFIG_NET_VENDOR_CHELSIO is not set
++# CONFIG_NET_VENDOR_CIRRUS is not set
+ # CONFIG_NET_VENDOR_FARADAY is not set
+ # CONFIG_NET_VENDOR_INTEL is not set
+ # CONFIG_NET_VENDOR_MARVELL is not set
+@@ -70,6 +70,7 @@ CONFIG_NETDEVICES=y
+ # CONFIG_NET_VENDOR_NATSEMI is not set
+ CONFIG_SH_ETH=y
+ # CONFIG_NET_VENDOR_SEEQ is not set
++# CONFIG_NET_VENDOR_SMSC is not set
+ # CONFIG_NET_VENDOR_STMICRO is not set
+ # CONFIG_WLAN is not set
+ # CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+@@ -106,7 +107,15 @@ CONFIG_SND=y
+ CONFIG_SND_SOC=y
+ CONFIG_SND_SOC_SH4_FSI=y
+ # CONFIG_HID_SUPPORT is not set
+-# CONFIG_USB_SUPPORT is not set
++CONFIG_USB=y
++# CONFIG_USB_DEVICE_CLASS is not set
++CONFIG_USB_RENESAS_USBHS=y
++CONFIG_USB_GADGET=y
++CONFIG_USB_RENESAS_USBHS_UDC=y
++CONFIG_USB_ETH=m
++CONFIG_MMC=y
++CONFIG_MMC_SDHI=y
++CONFIG_MMC_SH_MMCIF=y
+ CONFIG_UIO=y
+ CONFIG_UIO_PDRV_GENIRQ=y
+ # CONFIG_DNOTIFY is not set
+@@ -124,17 +133,7 @@ CONFIG_NLS_CODEPAGE_437=y
+ CONFIG_NLS_ISO8859_1=y
+ # CONFIG_ENABLE_WARN_DEPRECATED is not set
+ # CONFIG_ENABLE_MUST_CHECK is not set
+-CONFIG_MAGIC_SYSRQ=y
+-CONFIG_DEBUG_SECTION_MISMATCH=y
+-CONFIG_DEBUG_KERNEL=y
+-CONFIG_LOCKUP_DETECTOR=y
+-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+-# CONFIG_DETECT_HUNG_TASK is not set
+-# CONFIG_SCHED_DEBUG is not set
+-CONFIG_DEBUG_KMEMLEAK=y
+-CONFIG_DEBUG_SPINLOCK=y
+-CONFIG_DEBUG_INFO=y
+-# CONFIG_FTRACE is not set
++# CONFIG_ARM_UNWIND is not set
+ CONFIG_CRYPTO=y
+ CONFIG_CRYPTO_CBC=y
+ CONFIG_CRYPTO_MD5=y
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0072-ARM-mach-shmobile-Use-DT_MACHINE-for-armadillo-800-e.patch b/patches.armadillo800/0072-ARM-mach-shmobile-Use-DT_MACHINE-for-armadillo-800-e.patch
new file mode 100644
index 0000000000000..6050a9081e557
--- /dev/null
+++ b/patches.armadillo800/0072-ARM-mach-shmobile-Use-DT_MACHINE-for-armadillo-800-e.patch
@@ -0,0 +1,88 @@
+From e8f0e8b7d350aad665d17ffe656edaa2c2dda533 Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Mon, 14 May 2012 19:54:41 +0900
+Subject: ARM: mach-shmobile: Use DT_MACHINE for armadillo 800 eva
+
+Use DT_MACHINE_START() on the r8a7740 based armadillo 800 eva board.
+
+Also include a tiny DTS file to describe the board and update the
+Kconfig dependencies to select CONFIG_USE_OF.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit e6bf705911a0b64c589b6c408a316e7d465acbbd)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/boot/dts/r8a7740-armadillo800eva.dts | 22 ++++++++++++++++++++++
+ arch/arm/mach-shmobile/Kconfig | 1 +
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 8 +++++++-
+ 3 files changed, 30 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm/boot/dts/r8a7740-armadillo800eva.dts
+
+diff --git a/arch/arm/boot/dts/r8a7740-armadillo800eva.dts b/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
+new file mode 100644
+index 0000000..a7505a9
+--- /dev/null
++++ b/arch/arm/boot/dts/r8a7740-armadillo800eva.dts
+@@ -0,0 +1,22 @@
++/*
++ * Device Tree Source for the armadillo 800 eva board
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ *
++ * 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.
++ */
++
++/dts-v1/;
++/include/ "skeleton.dtsi"
++
++/ {
++ model = "armadillo 800 eva";
++ compatible = "renesas,armadillo800eva";
++
++ memory {
++ device_type = "memory";
++ reg = <0x40000000 0x20000000>;
++ };
++};
+diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
+index 799e996..da57dde 100644
+--- a/arch/arm/mach-shmobile/Kconfig
++++ b/arch/arm/mach-shmobile/Kconfig
+@@ -99,6 +99,7 @@ config MACH_ARMADILLO800EVA
+ bool "Armadillo-800 EVA board"
+ depends on ARCH_R8A7740
+ select ARCH_REQUIRE_GPIOLIB
++ select USE_OF
+
+ config MACH_MARZEN
+ bool "MARZEN board"
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index e750ea6..9e37026 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -768,11 +768,17 @@ static void __init eva_add_early_devices(void)
+ shmobile_timer.init = eva_earlytimer_init;
+ }
+
+-MACHINE_START(ARMADILLO800EVA, "armadillo800eva")
++static const char *eva_boards_compat_dt[] __initdata = {
++ "renesas,armadillo800eva",
++ NULL,
++};
++
++DT_MACHINE_START(ARMADILLO800EVA_DT, "armadillo800eva")
+ .map_io = r8a7740_map_io,
+ .init_early = eva_add_early_devices,
+ .init_irq = r8a7740_init_irq,
+ .handle_irq = shmobile_handle_irq_intc,
+ .init_machine = eva_init,
+ .timer = &shmobile_timer,
++ .dt_compat = eva_boards_compat_dt,
+ MACHINE_END
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0073-ARM-shmobile-r8a7740-add-HDMI-interrupt-support.patch b/patches.armadillo800/0073-ARM-shmobile-r8a7740-add-HDMI-interrupt-support.patch
new file mode 100644
index 0000000000000..d84ba6b9a4af1
--- /dev/null
+++ b/patches.armadillo800/0073-ARM-shmobile-r8a7740-add-HDMI-interrupt-support.patch
@@ -0,0 +1,82 @@
+From 86c25d5111c1edb9ca3cc28eaa0abd387250959a Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 12 Jun 2012 02:35:15 -0700
+Subject: ARM: shmobile: r8a7740: add HDMI interrupt support
+
+It is required from sh_mobile_hdmi driver.
+This patch is based on v1.0 manual
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 7d7136cabcad632a81cd568a9c1135db276fe0f2)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/intc-r8a7740.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/intc-r8a7740.c b/arch/arm/mach-shmobile/intc-r8a7740.c
+index 09c42af..9a69a31 100644
+--- a/arch/arm/mach-shmobile/intc-r8a7740.c
++++ b/arch/arm/mach-shmobile/intc-r8a7740.c
+@@ -71,10 +71,12 @@ enum {
+ DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3,
+ DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR,
+ SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM,
++ HDMI,
+ USBH_INT, USBH_OHCI, USBH_EHCI, USBH_PME, USBH_BIND,
+ RSPI_OVRF, RSPI_SPTEF, RSPI_SPRF,
+ SPU2_0, SPU2_1,
+ FSI, FMSI,
++ HDMI_SSS, HDMI_KEY,
+ IPMMU,
+ AP_ARM_CTIIRQ, AP_ARM_PMURQ,
+ MFIS2,
+@@ -182,6 +184,7 @@ static struct intc_vect intca_vectors[] __initdata = {
+ INTC_VECT(USBH_EHCI, 0x1580),
+ INTC_VECT(USBH_PME, 0x15A0),
+ INTC_VECT(USBH_BIND, 0x15C0),
++ INTC_VECT(HDMI, 0x1700),
+ INTC_VECT(RSPI_OVRF, 0x1780),
+ INTC_VECT(RSPI_SPTEF, 0x17A0),
+ INTC_VECT(RSPI_SPRF, 0x17C0),
+@@ -189,6 +192,8 @@ static struct intc_vect intca_vectors[] __initdata = {
+ INTC_VECT(SPU2_1, 0x1820),
+ INTC_VECT(FSI, 0x1840),
+ INTC_VECT(FMSI, 0x1860),
++ INTC_VECT(HDMI_SSS, 0x18A0),
++ INTC_VECT(HDMI_KEY, 0x18C0),
+ INTC_VECT(IPMMU, 0x1920),
+ INTC_VECT(AP_ARM_CTIIRQ, 0x1980),
+ INTC_VECT(AP_ARM_PMURQ, 0x19A0),
+@@ -304,11 +309,11 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = {
+ USBH_EHCI, USBH_PME, USBH_BIND, 0 } },
+ /* IMR3A3 / IMCR3A3 */
+ { /* IMR4A3 / IMCR4A3 */ 0xe6950090, 0xe69500d0, 8,
+- { 0, 0, 0, 0,
++ { HDMI, 0, 0, 0,
+ RSPI_OVRF, RSPI_SPTEF, RSPI_SPRF, 0 } },
+ { /* IMR5A3 / IMCR5A3 */ 0xe6950094, 0xe69500d4, 8,
+ { SPU2_0, SPU2_1, FSI, FMSI,
+- 0, 0, 0, 0 } },
++ 0, HDMI_SSS, HDMI_KEY, 0 } },
+ { /* IMR6A3 / IMCR6A3 */ 0xe6950098, 0xe69500d8, 8,
+ { 0, IPMMU, 0, 0,
+ AP_ARM_CTIIRQ, AP_ARM_PMURQ, 0, 0 } },
+@@ -353,10 +358,10 @@ static struct intc_prio_reg intca_prio_registers[] __initdata = {
+ { 0xe6950014, 0, 16, 4, /* IPRFA3 */ { USBH2, 0, 0, 0 } },
+ /* IPRGA3 */
+ /* IPRHA3 */
+- /* IPRIA3 */
++ { 0xe6950020, 0, 16, 4, /* IPRIA3 */ { HDMI, 0, 0, 0 } },
+ { 0xe6950024, 0, 16, 4, /* IPRJA3 */ { RSPI, 0, 0, 0 } },
+ { 0xe6950028, 0, 16, 4, /* IPRKA3 */ { SPU2, 0, FSI, FMSI } },
+- /* IPRLA3 */
++ { 0xe695002c, 0, 16, 4, /* IPRLA3 */ { 0, HDMI_SSS, HDMI_KEY, 0 } },
+ { 0xe6950030, 0, 16, 4, /* IPRMA3 */ { IPMMU, 0, 0, 0 } },
+ { 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } },
+ { 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S,
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0074-ARM-shmobile-r8a7740-add-HDMI-clock-support.patch b/patches.armadillo800/0074-ARM-shmobile-r8a7740-add-HDMI-clock-support.patch
new file mode 100644
index 0000000000000..707d43aec5dee
--- /dev/null
+++ b/patches.armadillo800/0074-ARM-shmobile-r8a7740-add-HDMI-clock-support.patch
@@ -0,0 +1,146 @@
+From 86a946d62d5993f9f8bff6db6445a0a12893665d Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 12 Jun 2012 02:35:36 -0700
+Subject: ARM: shmobile: r8a7740: add HDMI clock support
+
+It is required from sh_mobile_hdmi driver.
+This patch is based on v1.0 manual
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit c6750acb3b54c77c011045467770d5143be749ee)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-r8a7740.c | 84 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 84 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
+index 26eea5f..b095343 100644
+--- a/arch/arm/mach-shmobile/clock-r8a7740.c
++++ b/arch/arm/mach-shmobile/clock-r8a7740.c
+@@ -54,6 +54,7 @@
+ #define MSTPSR2 0xe6150040
+ #define MSTPSR3 0xe6150048
+ #define MSTPSR4 0xe615004c
++#define HDMICKCR 0xe6150094
+ #define SMSTPCR0 0xe6150130
+ #define SMSTPCR1 0xe6150134
+ #define SMSTPCR2 0xe6150138
+@@ -313,6 +314,79 @@ static struct clk_div4_table div4_table = {
+ .kick = div4_kick,
+ };
+
++/* DIV6 reparent */
++enum {
++ DIV6_HDMI,
++ DIV6_REPARENT_NR,
++};
++
++static struct clk *hdmi_parent[] = {
++ [0] = &pllc1_div2_clk,
++ [1] = &system_clk,
++ [2] = &dv_clk
++};
++
++static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
++ [DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
++ hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
++};
++
++/* HDMI1/2 clock */
++static unsigned long hdmi12_recalc(struct clk *clk)
++{
++ u32 val = __raw_readl(HDMICKCR);
++ int shift = (int)clk->priv;
++
++ val >>= shift;
++ val &= 0x3;
++
++ return clk->parent->rate / (1 << val);
++};
++
++static int hdmi12_set_rate(struct clk *clk, unsigned long rate)
++{
++ u32 val, mask;
++ int i, shift;
++
++ for (i = 0; i < 3; i++)
++ if (rate == clk->parent->rate / (1 << i))
++ goto find;
++ return -ENODEV;
++
++find:
++ shift = (int)clk->priv;
++
++ val = __raw_readl(HDMICKCR);
++ mask = ~(0x3 << shift);
++ val = (val & mask) | i << shift;
++ __raw_writel(val, HDMICKCR);
++
++ return 0;
++};
++
++static struct sh_clk_ops hdmi12_clk_ops = {
++ .recalc = hdmi12_recalc,
++ .set_rate = hdmi12_set_rate,
++};
++
++static struct clk hdmi1_clk = {
++ .ops = &hdmi12_clk_ops,
++ .priv = (void *)9,
++ .parent = &div6_reparent_clks[DIV6_HDMI], /* late install */
++};
++
++static struct clk hdmi2_clk = {
++ .ops = &hdmi12_clk_ops,
++ .priv = (void *)11,
++ .parent = &div6_reparent_clks[DIV6_HDMI], /* late install */
++};
++
++static struct clk *late_main_clks[] = {
++ &hdmi1_clk,
++ &hdmi2_clk,
++};
++
++/* MSTP */
+ enum {
+ DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP,
+ DIV4_HPP, DIV4_USBP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP,
+@@ -408,6 +482,8 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
+ CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
+ CLKDEV_CON_ID("usb24s", &usb24s_clk),
++ CLKDEV_CON_ID("hdmi1", &hdmi1_clk),
++ CLKDEV_CON_ID("hdmi2", &hdmi2_clk),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
+@@ -459,6 +535,7 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_ICK_ID("phy", "renesas_usbhs", &mstp_clks[MSTP406]),
+ CLKDEV_ICK_ID("pci", "renesas_usbhs", &div4_clks[DIV4_USBP]),
+ CLKDEV_ICK_ID("usb24", "renesas_usbhs", &usb24_clk),
++ CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
+ };
+
+ void __init r8a7740_clock_init(u8 md_ck)
+@@ -495,8 +572,15 @@ void __init r8a7740_clock_init(u8 md_ck)
+ ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+
+ if (!ret)
++ ret = sh_clk_div6_reparent_register(div6_reparent_clks,
++ DIV6_REPARENT_NR);
++
++ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+
++ for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
++ ret = clk_register(late_main_clks[k]);
++
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ if (!ret)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0075-ARM-shmobile-r8a7740-add-HDMI-GPIO-support.patch b/patches.armadillo800/0075-ARM-shmobile-r8a7740-add-HDMI-GPIO-support.patch
new file mode 100644
index 0000000000000..8619f0d0d14f3
--- /dev/null
+++ b/patches.armadillo800/0075-ARM-shmobile-r8a7740-add-HDMI-GPIO-support.patch
@@ -0,0 +1,76 @@
+From 77cd6be2b59e2839e6c2b8cab77a480e092aedec Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 12 Jun 2012 02:35:58 -0700
+Subject: ARM: shmobile: r8a7740: add HDMI GPIO support
+
+In order to enable HDMI GPIO selection from platform board,
+this patch adds its interface to GPIO framework.
+
+This patch is based on v1.0 manual
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit e2dcd461a7ba0c3deb44336136ea784c8b972292)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/include/mach/r8a7740.h | 4 ++++
+ arch/arm/mach-shmobile/pfc-r8a7740.c | 9 +++++++++
+ 2 files changed, 13 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+index 9d447ab..2764846 100644
+--- a/arch/arm/mach-shmobile/include/mach/r8a7740.h
++++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+@@ -565,6 +565,10 @@ enum {
+ GPIO_FN_RESETP_PULLUP,
+ GPIO_FN_RESETP_PLAIN,
+
++ /* HDMI */
++ GPIO_FN_HDMI_HPD,
++ GPIO_FN_HDMI_CEC,
++
+ /* SDENC */
+ GPIO_FN_SDENC_CPG,
+ GPIO_FN_SDENC_DV_CLKI,
+diff --git a/arch/arm/mach-shmobile/pfc-r8a7740.c b/arch/arm/mach-shmobile/pfc-r8a7740.c
+index 670fe18..0dda816 100644
+--- a/arch/arm/mach-shmobile/pfc-r8a7740.c
++++ b/arch/arm/mach-shmobile/pfc-r8a7740.c
+@@ -560,6 +560,9 @@ enum {
+ /* SDENC */
+ SDENC_CPG_MARK, SDENC_DV_CLKI_MARK,
+
++ /* HDMI */
++ HDMI_HPD_MARK, HDMI_CEC_MARK,
++
+ /* DEBUG */
+ EDEBGREQ_PULLUP_MARK, /* for JTAG */
+ EDEBGREQ_PULLDOWN_MARK,
+@@ -1620,9 +1623,11 @@ static pinmux_enum_t pinmux_data[] = {
+
+ /* Port210 */
+ PINMUX_DATA(IRQ9_PORT210_MARK, PORT210_FN0, MSEL1CR_9_1),
++ PINMUX_DATA(HDMI_HPD_MARK, PORT210_FN1),
+
+ /* Port211 */
+ PINMUX_DATA(IRQ16_PORT211_MARK, PORT211_FN0, MSEL1CR_16_1),
++ PINMUX_DATA(HDMI_CEC_MARK, PORT211_FN1),
+
+ /* LCDC select */
+ PINMUX_DATA(LCDC0_SELECT_MARK, MSEL3CR_6_0),
+@@ -2097,6 +2102,10 @@ static struct pinmux_gpio pinmux_gpios[] = {
+ GPIO_FN(SDENC_CPG),
+ GPIO_FN(SDENC_DV_CLKI),
+
++ /* HDMI */
++ GPIO_FN(HDMI_HPD),
++ GPIO_FN(HDMI_CEC),
++
+ /* SYSC */
+ GPIO_FN(RESETP_PULLUP),
+ GPIO_FN(RESETP_PLAIN),
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0076-ARM-shmobile-r8a7740-add-MERAM-work-around.patch b/patches.armadillo800/0076-ARM-shmobile-r8a7740-add-MERAM-work-around.patch
new file mode 100644
index 0000000000000..ac9838b85cc66
--- /dev/null
+++ b/patches.armadillo800/0076-ARM-shmobile-r8a7740-add-MERAM-work-around.patch
@@ -0,0 +1,34 @@
+From acd1ae033a03a0c6356e68d9d17427afb0f53eb0 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 12 Jun 2012 02:36:21 -0700
+Subject: ARM: shmobile: r8a7740: add MERAM work-around
+
+r8a7740 chip has lasting errata on MERAM buffer, and this patch adds
+its work-around on setup-r8a7740.c
+It solved CEU/VIO6C/2D-DMAC/VCP1/VPU5F/JPU/DISP memroy access error.
+
+But MERAM driver can't control this issue,
+since this work-around requires access to non-MERAM register address.
+So, This it will be called as board specific code at this point.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit d49679e5928709bce8937dce396458b139c4b34d)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -587,6 +587,7 @@ static void __init eva_init(void)
+ eva_clock_init();
+
+ r8a7740_pinmux_init();
++ r8a7740_meram_workaround();
+
+ /* SCIFA1 */
+ gpio_request(GPIO_FN_SCIFA1_RXD, NULL);
diff --git a/patches.armadillo800/0077-ARM-shmobile-r8a7740-add-CEU-clock-support.patch b/patches.armadillo800/0077-ARM-shmobile-r8a7740-add-CEU-clock-support.patch
new file mode 100644
index 0000000000000..8c3989bc6c5e5
--- /dev/null
+++ b/patches.armadillo800/0077-ARM-shmobile-r8a7740-add-CEU-clock-support.patch
@@ -0,0 +1,101 @@
+From 5484e5aba2cd92f69af04090ab0f4e018175df69 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 12 Jun 2012 02:36:39 -0700
+Subject: ARM: shmobile: r8a7740: add CEU clock support
+
+It is required from sh_mobile_ceu_camera driver.
+This patch is based on v1.0 manual
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit ad9f1721c15b84f1a2e45a8a03f1ff7c86c2829b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-r8a7740.c | 23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
+index b095343..ce0930a 100644
+--- a/arch/arm/mach-shmobile/clock-r8a7740.c
++++ b/arch/arm/mach-shmobile/clock-r8a7740.c
+@@ -43,6 +43,8 @@
+ /* CPG registers */
+ #define FRQCRA 0xe6150000
+ #define FRQCRB 0xe6150004
++#define VCLKCR1 0xE6150008
++#define VCLKCR2 0xE615000c
+ #define FRQCRC 0xe61500e0
+ #define PLLC01CR 0xe6150028
+
+@@ -317,6 +319,7 @@ static struct clk_div4_table div4_table = {
+ /* DIV6 reparent */
+ enum {
+ DIV6_HDMI,
++ DIV6_VCLK1, DIV6_VCLK2,
+ DIV6_REPARENT_NR,
+ };
+
+@@ -326,9 +329,21 @@ static struct clk *hdmi_parent[] = {
+ [2] = &dv_clk
+ };
+
++static struct clk *vclk_parents[8] = {
++ [0] = &pllc1_div2_clk,
++ [2] = &dv_clk,
++ [3] = &usb24s_clk,
++ [4] = &extal1_div2_clk,
++ [5] = &extalr_clk,
++};
++
+ static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
+ [DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
+ hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
++ [DIV6_VCLK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
++ vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3),
++ [DIV6_VCLK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
++ vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3),
+ };
+
+ /* HDMI1/2 clock */
+@@ -417,7 +432,7 @@ static struct clk div6_clks[DIV6_NR] = {
+ };
+
+ enum {
+- MSTP125,
++ MSTP128, MSTP127, MSTP125,
+ MSTP116, MSTP111, MSTP100, MSTP117,
+
+ MSTP230,
+@@ -434,6 +449,8 @@ enum {
+ };
+
+ static struct clk mstp_clks[MSTP_NR] = {
++ [MSTP128] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR1, 28, 0), /* CEU21 */
++ [MSTP127] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR1, 27, 0), /* CEU20 */
+ [MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
+ [MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
+ [MSTP116] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
+@@ -484,6 +501,8 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_CON_ID("usb24s", &usb24s_clk),
+ CLKDEV_CON_ID("hdmi1", &hdmi1_clk),
+ CLKDEV_CON_ID("hdmi2", &hdmi2_clk),
++ CLKDEV_CON_ID("video1", &div6_reparent_clks[DIV6_VCLK1]),
++ CLKDEV_CON_ID("video2", &div6_reparent_clks[DIV6_VCLK2]),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
+@@ -506,6 +525,8 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]),
+ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]),
+ CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]),
++ CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]),
++ CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP128]),
+
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]),
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]),
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0078-ARM-shmobile-r8a7740-add-FSI-parent-clock-support.patch b/patches.armadillo800/0078-ARM-shmobile-r8a7740-add-FSI-parent-clock-support.patch
new file mode 100644
index 0000000000000..f4e614367c9e7
--- /dev/null
+++ b/patches.armadillo800/0078-ARM-shmobile-r8a7740-add-FSI-parent-clock-support.patch
@@ -0,0 +1,125 @@
+From 3380d7910c8f2625a74337bd1a3f1d81bc146c73 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 12 Jun 2012 02:36:58 -0700
+Subject: ARM: shmobile: r8a7740: add FSI parent clock support
+
+r8a7740 FSI can select its parent clock,
+and its selection is dependent on platform board.
+
+In order to enable FSI parent selection from platform board,
+this patch adds its interface to clock framework.
+
+This patch is based on v1.0 manual
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 69efac9a8bc6d479bc4c339ae4ac4d353460def6)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-r8a7740.c | 31 +++++++++++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
+index ce0930a..7b9e4ab 100644
+--- a/arch/arm/mach-shmobile/clock-r8a7740.c
++++ b/arch/arm/mach-shmobile/clock-r8a7740.c
+@@ -46,6 +46,7 @@
+ #define VCLKCR1 0xE6150008
+ #define VCLKCR2 0xE615000c
+ #define FRQCRC 0xe61500e0
++#define FSIACKCR 0xe6150018
+ #define PLLC01CR 0xe6150028
+
+ #define SUBCKCR 0xe6150080
+@@ -56,6 +57,7 @@
+ #define MSTPSR2 0xe6150040
+ #define MSTPSR3 0xe6150048
+ #define MSTPSR4 0xe615004c
++#define FSIBCKCR 0xe6150090
+ #define HDMICKCR 0xe6150094
+ #define SMSTPCR0 0xe6150130
+ #define SMSTPCR1 0xe6150134
+@@ -274,6 +276,13 @@ static struct clk usb24_clk = {
+ .parent = &usb24s_clk,
+ };
+
++/* External FSIACK/FSIBCK clock */
++static struct clk fsiack_clk = {
++};
++
++static struct clk fsibck_clk = {
++};
++
+ struct clk *main_clks[] = {
+ &extalr_clk,
+ &extal1_clk,
+@@ -291,6 +300,8 @@ struct clk *main_clks[] = {
+ &pllc1_div2_clk,
+ &usb24s_clk,
+ &usb24_clk,
++ &fsiack_clk,
++ &fsibck_clk,
+ };
+
+ static void div4_kick(struct clk *clk)
+@@ -320,6 +331,7 @@ static struct clk_div4_table div4_table = {
+ enum {
+ DIV6_HDMI,
+ DIV6_VCLK1, DIV6_VCLK2,
++ DIV6_FSIA, DIV6_FSIB,
+ DIV6_REPARENT_NR,
+ };
+
+@@ -337,6 +349,16 @@ static struct clk *vclk_parents[8] = {
+ [5] = &extalr_clk,
+ };
+
++static struct clk *fsia_parents[] = {
++ [0] = &pllc1_div2_clk,
++ [1] = &fsiack_clk, /* external clock */
++};
++
++static struct clk *fsib_parents[] = {
++ [0] = &pllc1_div2_clk,
++ [1] = &fsibck_clk, /* external clock */
++};
++
+ static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
+ [DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
+ hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
+@@ -344,6 +366,10 @@ static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
+ vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3),
+ [DIV6_VCLK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
+ vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3),
++ [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
++ fsia_parents, ARRAY_SIZE(fsia_parents), 6, 2),
++ [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
++ fsib_parents, ARRAY_SIZE(fsib_parents), 6, 2),
+ };
+
+ /* HDMI1/2 clock */
+@@ -503,6 +529,8 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_CON_ID("hdmi2", &hdmi2_clk),
+ CLKDEV_CON_ID("video1", &div6_reparent_clks[DIV6_VCLK1]),
+ CLKDEV_CON_ID("video2", &div6_reparent_clks[DIV6_VCLK2]),
++ CLKDEV_CON_ID("fsiack", &fsiack_clk),
++ CLKDEV_CON_ID("fsibck", &fsibck_clk),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
+@@ -557,6 +585,9 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_ICK_ID("pci", "renesas_usbhs", &div4_clks[DIV4_USBP]),
+ CLKDEV_ICK_ID("usb24", "renesas_usbhs", &usb24_clk),
+ CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
++
++ CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
++ CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
+ };
+
+ void __init r8a7740_clock_init(u8 md_ck)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0079-ARM-shmobile-r8a7740-add-FSI-B-for-HDMI-GPIO-support.patch b/patches.armadillo800/0079-ARM-shmobile-r8a7740-add-FSI-B-for-HDMI-GPIO-support.patch
new file mode 100644
index 0000000000000..ddaab4fa15797
--- /dev/null
+++ b/patches.armadillo800/0079-ARM-shmobile-r8a7740-add-FSI-B-for-HDMI-GPIO-support.patch
@@ -0,0 +1,97 @@
+From ead2de820556aa2682e1505f691a5207365d4e69 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 12 Jun 2012 02:37:16 -0700
+Subject: ARM: shmobile: r8a7740: add FSI-B (for HDMI) GPIO support
+
+In order to enable FSI-B selection from platform board,
+this patch adds its interface to GPIO framework.
+
+This patch is based on v1.0 manual
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 147d1ffdc21d067f0084f0911dbf1eee57e3d76b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/include/mach/r8a7740.h | 5 ++++-
+ arch/arm/mach-shmobile/pfc-r8a7740.c | 11 +++++++++--
+ 2 files changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+index 2764846..6468fcc 100644
+--- a/arch/arm/mach-shmobile/include/mach/r8a7740.h
++++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+@@ -139,7 +139,7 @@ enum {
+ GPIO_FN_DBGMD10, GPIO_FN_DBGMD11, GPIO_FN_DBGMD20,
+ GPIO_FN_DBGMD21,
+
+- /* FSI */
++ /* FSI-A */
+ GPIO_FN_FSIAISLD_PORT0, /* FSIAISLD Port 0/5 */
+ GPIO_FN_FSIAISLD_PORT5,
+ GPIO_FN_FSIASPDIF_PORT9, /* FSIASPDIF Port 9/18 */
+@@ -150,6 +150,9 @@ enum {
+ GPIO_FN_FSIACK, GPIO_FN_FSIAILR,
+ GPIO_FN_FSIAIBT,
+
++ /* FSI-B */
++ GPIO_FN_FSIBCK,
++
+ /* FMSI */
+ GPIO_FN_FMSISLD_PORT1, /* FMSISLD Port 1/6 */
+ GPIO_FN_FMSISLD_PORT6,
+diff --git a/arch/arm/mach-shmobile/pfc-r8a7740.c b/arch/arm/mach-shmobile/pfc-r8a7740.c
+index 0dda816..03def0f 100644
+--- a/arch/arm/mach-shmobile/pfc-r8a7740.c
++++ b/arch/arm/mach-shmobile/pfc-r8a7740.c
+@@ -169,7 +169,7 @@ enum {
+ DBGMD10_MARK, DBGMD11_MARK, DBGMD20_MARK,
+ DBGMD21_MARK,
+
+- /* FSI */
++ /* FSI-A */
+ FSIAISLD_PORT0_MARK, /* FSIAISLD Port 0/5 */
+ FSIAISLD_PORT5_MARK,
+ FSIASPDIF_PORT9_MARK, /* FSIASPDIF Port 9/18 */
+@@ -178,6 +178,9 @@ enum {
+ FSIAOBT_MARK, FSIAOSLD_MARK, FSIAOMC_MARK,
+ FSIACK_MARK, FSIAILR_MARK, FSIAIBT_MARK,
+
++ /* FSI-B */
++ FSIBCK_MARK,
++
+ /* FMSI */
+ FMSISLD_PORT1_MARK, /* FMSISLD Port 1/6 */
+ FMSISLD_PORT6_MARK,
+@@ -774,6 +777,7 @@ static pinmux_enum_t pinmux_data[] = {
+
+ /* Port11 */
+ PINMUX_DATA(FSIACK_MARK, PORT11_FN1),
++ PINMUX_DATA(FSIBCK_MARK, PORT11_FN2),
+ PINMUX_DATA(IRQ2_PORT11_MARK, PORT11_FN0, MSEL1CR_2_0),
+
+ /* Port12 */
+@@ -1696,7 +1700,7 @@ static struct pinmux_gpio pinmux_gpios[] = {
+ GPIO_FN(DBGMD10), GPIO_FN(DBGMD11), GPIO_FN(DBGMD20),
+ GPIO_FN(DBGMD21),
+
+- /* FSI */
++ /* FSI-A */
+ GPIO_FN(FSIAISLD_PORT0), /* FSIAISLD Port 0/5 */
+ GPIO_FN(FSIAISLD_PORT5),
+ GPIO_FN(FSIASPDIF_PORT9), /* FSIASPDIF Port 9/18 */
+@@ -1705,6 +1709,9 @@ static struct pinmux_gpio pinmux_gpios[] = {
+ GPIO_FN(FSIAOBT), GPIO_FN(FSIAOSLD), GPIO_FN(FSIAOMC),
+ GPIO_FN(FSIACK), GPIO_FN(FSIAILR), GPIO_FN(FSIAIBT),
+
++ /* FSI-B */
++ GPIO_FN(FSIBCK),
++
+ /* FMSI */
+ GPIO_FN(FMSISLD_PORT1), /* FMSISLD Port 1/6 */
+ GPIO_FN(FMSISLD_PORT6),
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0080-ARM-shmobile-armadillo800eva-enable-HDMI.patch b/patches.armadillo800/0080-ARM-shmobile-armadillo800eva-enable-HDMI.patch
new file mode 100644
index 0000000000000..731d6c1e8e3ed
--- /dev/null
+++ b/patches.armadillo800/0080-ARM-shmobile-armadillo800eva-enable-HDMI.patch
@@ -0,0 +1,197 @@
+From e92cdf42dfe94be35bc251b5eaa9a0db2c8679e9 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 12 Jun 2012 02:39:11 -0700
+Subject: ARM: shmobile: armadillo800eva: enable HDMI
+
+This patch enable HDMI support on CON3.
+And removed unnecessary CONFIG_SYSFS_DEPRECATED_xxx config.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 910c14d0b8f121df420a878cbd973ffa7d549393)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/configs/armadillo800eva_defconfig | 10 +--
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 100 +++++++++++++++++++++++++
+ 2 files changed, 101 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm/configs/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig
+index ddc9fe6..f6ebdde 100644
+--- a/arch/arm/configs/armadillo800eva_defconfig
++++ b/arch/arm/configs/armadillo800eva_defconfig
+@@ -5,10 +5,7 @@ CONFIG_IKCONFIG_PROC=y
+ CONFIG_LOG_BUF_SHIFT=16
+ # CONFIG_UTS_NS is not set
+ # CONFIG_IPC_NS is not set
+-# CONFIG_USER_NS is not set
+ # CONFIG_PID_NS is not set
+-CONFIG_SYSFS_DEPRECATED=y
+-CONFIG_SYSFS_DEPRECATED_V2=y
+ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+ CONFIG_SLAB=y
+ CONFIG_MODULES=y
+@@ -90,25 +87,21 @@ CONFIG_I2C=y
+ CONFIG_I2C_SH_MOBILE=y
+ # CONFIG_HWMON is not set
+ CONFIG_FB=y
+-CONFIG_FB_MODE_HELPERS=y
+ CONFIG_FB_SH_MOBILE_LCDC=y
++CONFIG_FB_SH_MOBILE_HDMI=y
+ CONFIG_LCD_CLASS_DEVICE=y
+ CONFIG_FRAMEBUFFER_CONSOLE=y
+ CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+ CONFIG_LOGO=y
+ # CONFIG_LOGO_LINUX_MONO is not set
+ # CONFIG_LOGO_LINUX_VGA16 is not set
+-CONFIG_SOUND=y
+-CONFIG_SND=y
+ # CONFIG_SND_SUPPORT_OLD_API is not set
+ # CONFIG_SND_VERBOSE_PROCFS is not set
+ # CONFIG_SND_DRIVERS is not set
+ # CONFIG_SND_ARM is not set
+-CONFIG_SND_SOC=y
+ CONFIG_SND_SOC_SH4_FSI=y
+ # CONFIG_HID_SUPPORT is not set
+ CONFIG_USB=y
+-# CONFIG_USB_DEVICE_CLASS is not set
+ CONFIG_USB_RENESAS_USBHS=y
+ CONFIG_USB_GADGET=y
+ CONFIG_USB_RENESAS_USBHS_UDC=y
+@@ -124,7 +117,6 @@ CONFIG_VFAT_FS=y
+ CONFIG_TMPFS=y
+ # CONFIG_MISC_FILESYSTEMS is not set
+ CONFIG_NFS_FS=y
+-CONFIG_NFS_V3=y
+ CONFIG_NFS_V3_ACL=y
+ CONFIG_NFS_V4=y
+ CONFIG_NFS_V4_1=y
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 6e6839d..4e6893f 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -45,6 +45,7 @@
+ #include <asm/hardware/cache-l2x0.h>
+ #include <mach/r8a7740.h>
+ #include <video/sh_mobile_lcdc.h>
++#include <video/sh_mobile_hdmi.h>
+
+ /*
+ * CON1 Camera Module
+@@ -384,6 +385,103 @@ static struct platform_device lcdc0_device = {
+ },
+ };
+
++/*
++ * LCDC1/HDMI
++ */
++static struct sh_mobile_hdmi_info hdmi_info = {
++ .flags = HDMI_OUTPUT_PUSH_PULL |
++ HDMI_OUTPUT_POLARITY_HI |
++ HDMI_32BIT_REG |
++ HDMI_HAS_HTOP1 |
++ HDMI_SND_SRC_SPDIF,
++};
++
++static struct resource hdmi_resources[] = {
++ [0] = {
++ .name = "HDMI",
++ .start = 0xe6be0000,
++ .end = 0xe6be03ff,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = evt2irq(0x1700),
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ .name = "HDMI emma3pf",
++ .start = 0xe6be4000,
++ .end = 0xe6be43ff,
++ .flags = IORESOURCE_MEM,
++ },
++};
++
++static struct platform_device hdmi_device = {
++ .name = "sh-mobile-hdmi",
++ .num_resources = ARRAY_SIZE(hdmi_resources),
++ .resource = hdmi_resources,
++ .id = -1,
++ .dev = {
++ .platform_data = &hdmi_info,
++ },
++};
++
++static const struct fb_videomode lcdc1_mode = {
++ .name = "HDMI 720p",
++ .xres = 1280,
++ .yres = 720,
++ .pixclock = 13468,
++ .left_margin = 220,
++ .right_margin = 110,
++ .hsync_len = 40,
++ .upper_margin = 20,
++ .lower_margin = 5,
++ .vsync_len = 5,
++ .refresh = 60,
++ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
++};
++
++static struct sh_mobile_lcdc_info hdmi_lcdc_info = {
++ .clock_source = LCDC_CLK_PERIPHERAL, /* HDMI clock */
++ .ch[0] = {
++ .chan = LCDC_CHAN_MAINLCD,
++ .fourcc = V4L2_PIX_FMT_RGB565,
++ .interface_type = RGB24,
++ .clock_divider = 1,
++ .flags = LCDC_FLAGS_DWPOL,
++ .lcd_modes = &lcdc1_mode,
++ .num_modes = 1,
++ .tx_dev = &hdmi_device,
++ .panel_cfg = {
++ .width = 1280,
++ .height = 720,
++ },
++ },
++};
++
++static struct resource hdmi_lcdc_resources[] = {
++ [0] = {
++ .name = "LCDC1",
++ .start = 0xfe944000,
++ .end = 0xfe948000 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = intcs_evt2irq(0x1780),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device hdmi_lcdc_device = {
++ .name = "sh_mobile_lcdc_fb",
++ .num_resources = ARRAY_SIZE(hdmi_lcdc_resources),
++ .resource = hdmi_lcdc_resources,
++ .id = 1,
++ .dev = {
++ .platform_data = &hdmi_lcdc_info,
++ .coherent_dma_mask = ~0,
++ },
++};
++
+ /* GPIO KEY */
+ #define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 }
+
+@@ -549,6 +647,8 @@ static struct platform_device *eva_devices[] __initdata = {
+ &sh_eth_device,
+ &sdhi0_device,
+ &sh_mmcif_device,
++ &hdmi_device,
++ &hdmi_lcdc_device,
+ };
+
+ static void __init eva_clock_init(void)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0081-ARM-mach-shmobile-armadillo800eva-Use-late-init-mach.patch b/patches.armadillo800/0081-ARM-mach-shmobile-armadillo800eva-Use-late-init-mach.patch
new file mode 100644
index 0000000000000..5854c1f663670
--- /dev/null
+++ b/patches.armadillo800/0081-ARM-mach-shmobile-armadillo800eva-Use-late-init-mach.patch
@@ -0,0 +1,35 @@
+From e942f8cdf5f982742f6bc8cb49fd546bb828ffce Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Wed, 20 Jun 2012 12:53:25 +0200
+Subject: ARM: mach-shmobile: armadillo800eva: Use late init machine hook
+
+Since commit 21cc1b7ede3cf456cf1d51f8a906093261f7c111 ("ARM: shmobile:
+use machine specific hook for late init") suspend and CPU idle are not
+initialized automatically anymore. Set shmobile_init_late() as the
+machine late init hook to initialize them.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 37f971b68009b8fadd322130787d693137302925)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 4e6893f..bbf5ccff 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -880,6 +880,7 @@ DT_MACHINE_START(ARMADILLO800EVA_DT, "armadillo800eva")
+ .init_irq = r8a7740_init_irq,
+ .handle_irq = shmobile_handle_irq_intc,
+ .init_machine = eva_init,
++ .init_late = shmobile_init_late,
+ .timer = &shmobile_timer,
+ .dt_compat = eva_boards_compat_dt,
+ MACHINE_END
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0082-ARM-shmobile-armadillo800eva-enable-camera.patch b/patches.armadillo800/0082-ARM-shmobile-armadillo800eva-enable-camera.patch
new file mode 100644
index 0000000000000..28a60b6f93b19
--- /dev/null
+++ b/patches.armadillo800/0082-ARM-shmobile-armadillo800eva-enable-camera.patch
@@ -0,0 +1,192 @@
+From c7934751659fc8d58c97d51edc6fdb5af8307330 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 12 Jun 2012 02:40:07 -0700
+Subject: ARM: shmobile: armadillo800eva: enable camera
+
+This patch enable camera support on CON1
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 3760e79450f48e31fde2b2dd49c5ab6a685c3ea8)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/configs/armadillo800eva_defconfig | 10 +++
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 111 ++++++++++++++++++++++++-
+ 2 files changed, 120 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/configs/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig
+index f6ebdde..df1ce54 100644
+--- a/arch/arm/configs/armadillo800eva_defconfig
++++ b/arch/arm/configs/armadillo800eva_defconfig
+@@ -86,6 +86,16 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
+ CONFIG_I2C=y
+ CONFIG_I2C_SH_MOBILE=y
+ # CONFIG_HWMON is not set
++CONFIG_MEDIA_SUPPORT=y
++CONFIG_VIDEO_DEV=y
++# CONFIG_RC_CORE is not set
++# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
++# CONFIG_V4L_USB_DRIVERS is not set
++CONFIG_V4L_PLATFORM_DRIVERS=y
++CONFIG_SOC_CAMERA=y
++CONFIG_SOC_CAMERA_MT9T112=y
++CONFIG_VIDEO_SH_MOBILE_CEU=y
++# CONFIG_RADIO_ADAPTERS is not set
+ CONFIG_FB=y
+ CONFIG_FB_SH_MOBILE_LCDC=y
+ CONFIG_FB_SH_MOBILE_HDMI=y
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index bbf5ccff..a513ebe 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -37,13 +37,16 @@
+ #include <linux/mmc/sh_mobile_sdhi.h>
+ #include <mach/common.h>
+ #include <mach/irqs.h>
++#include <mach/r8a7740.h>
++#include <media/mt9t112.h>
++#include <media/sh_mobile_ceu.h>
++#include <media/soc_camera.h>
+ #include <asm/page.h>
+ #include <asm/mach-types.h>
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+ #include <asm/mach/time.h>
+ #include <asm/hardware/cache-l2x0.h>
+-#include <mach/r8a7740.h>
+ #include <video/sh_mobile_lcdc.h>
+ #include <video/sh_mobile_hdmi.h>
+
+@@ -630,6 +633,87 @@ static struct platform_device sh_mmcif_device = {
+ .resource = sh_mmcif_resources,
+ };
+
++/* Camera */
++static int mt9t111_power(struct device *dev, int mode)
++{
++ struct clk *mclk = clk_get(NULL, "video1");
++
++ if (IS_ERR(mclk)) {
++ dev_err(dev, "can't get video1 clock\n");
++ return -EINVAL;
++ }
++
++ if (mode) {
++ /* video1 (= CON1 camera) expect 24MHz */
++ clk_set_rate(mclk, clk_round_rate(mclk, 24000000));
++ clk_enable(mclk);
++ gpio_direction_output(GPIO_PORT158, 1);
++ } else {
++ gpio_direction_output(GPIO_PORT158, 0);
++ clk_disable(mclk);
++ }
++
++ clk_put(mclk);
++
++ return 0;
++}
++
++static struct i2c_board_info i2c_camera_mt9t111 = {
++ I2C_BOARD_INFO("mt9t112", 0x3d),
++};
++
++static struct mt9t112_camera_info mt9t111_info = {
++ .divider = { 16, 0, 0, 7, 0, 10, 14, 7, 7 },
++};
++
++static struct soc_camera_link mt9t111_link = {
++ .i2c_adapter_id = 0,
++ .bus_id = 0,
++ .board_info = &i2c_camera_mt9t111,
++ .power = mt9t111_power,
++ .priv = &mt9t111_info,
++};
++
++static struct platform_device camera_device = {
++ .name = "soc-camera-pdrv",
++ .id = 0,
++ .dev = {
++ .platform_data = &mt9t111_link,
++ },
++};
++
++/* CEU0 */
++static struct sh_mobile_ceu_info sh_mobile_ceu0_info = {
++ .flags = SH_CEU_FLAG_LOWER_8BIT,
++};
++
++static struct resource ceu0_resources[] = {
++ [0] = {
++ .name = "CEU",
++ .start = 0xfe910000,
++ .end = 0xfe91009f,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = intcs_evt2irq(0x0500),
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ /* place holder for contiguous memory */
++ },
++};
++
++static struct platform_device ceu0_device = {
++ .name = "sh_mobile_ceu",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(ceu0_resources),
++ .resource = ceu0_resources,
++ .dev = {
++ .platform_data = &sh_mobile_ceu0_info,
++ .coherent_dma_mask = 0xffffffff,
++ },
++};
++
+ /* I2C */
+ static struct i2c_board_info i2c0_devices[] = {
+ {
+@@ -649,6 +733,8 @@ static struct platform_device *eva_devices[] __initdata = {
+ &sh_mmcif_device,
+ &hdmi_device,
+ &hdmi_lcdc_device,
++ &camera_device,
++ &ceu0_device,
+ };
+
+ static void __init eva_clock_init(void)
+@@ -807,6 +893,29 @@ static void __init eva_init(void)
+ gpio_request(GPIO_FN_MMC1_D6_PORT143, NULL);
+ gpio_request(GPIO_FN_MMC1_D7_PORT142, NULL);
+
++ /* CEU0 */
++ gpio_request(GPIO_FN_VIO0_D7, NULL);
++ gpio_request(GPIO_FN_VIO0_D6, NULL);
++ gpio_request(GPIO_FN_VIO0_D5, NULL);
++ gpio_request(GPIO_FN_VIO0_D4, NULL);
++ gpio_request(GPIO_FN_VIO0_D3, NULL);
++ gpio_request(GPIO_FN_VIO0_D2, NULL);
++ gpio_request(GPIO_FN_VIO0_D1, NULL);
++ gpio_request(GPIO_FN_VIO0_D0, NULL);
++ gpio_request(GPIO_FN_VIO0_CLK, NULL);
++ gpio_request(GPIO_FN_VIO0_HD, NULL);
++ gpio_request(GPIO_FN_VIO0_VD, NULL);
++ gpio_request(GPIO_FN_VIO0_FIELD, NULL);
++ gpio_request(GPIO_FN_VIO_CKO, NULL);
++
++ /* CON1/CON15 Camera */
++ gpio_request(GPIO_PORT173, NULL); /* STANDBY */
++ gpio_request(GPIO_PORT172, NULL); /* RST */
++ gpio_request(GPIO_PORT158, NULL); /* CAM_PON */
++ gpio_direction_output(GPIO_PORT173, 0);
++ gpio_direction_output(GPIO_PORT172, 1);
++ gpio_direction_output(GPIO_PORT158, 0); /* see mt9t111_power() */
++
+ /*
+ * CAUTION
+ *
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0083-ARM-shmobile-r8a7740-add-DMAEngine-support-for-FSI.patch b/patches.armadillo800/0083-ARM-shmobile-r8a7740-add-DMAEngine-support-for-FSI.patch
new file mode 100644
index 0000000000000..5f28f1e2dfaef
--- /dev/null
+++ b/patches.armadillo800/0083-ARM-shmobile-r8a7740-add-DMAEngine-support-for-FSI.patch
@@ -0,0 +1,299 @@
+From 0e0018e5c4b1d2d6c6fe9d67a8c5916752884589 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 25 Jun 2012 03:36:49 -0700
+Subject: ARM: shmobile: r8a7740: add DMAEngine support for FSI
+
+Current shdmac can support FSI DMAC on r8a7740.
+This support reduce CPU duty when sound was playback.
+
+This patch is based on v1.0 manual
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 643c3307bbbe7e80c6693376137971fbdcbe1c82)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-r8a7740.c | 8 +-
+ arch/arm/mach-shmobile/include/mach/r8a7740.h | 8 ++
+ arch/arm/mach-shmobile/setup-r8a7740.c | 198 ++++++++++++++++++++++++++
+ 3 files changed, 213 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
+index 7b9e4ab..39b1311 100644
+--- a/arch/arm/mach-shmobile/clock-r8a7740.c
++++ b/arch/arm/mach-shmobile/clock-r8a7740.c
+@@ -463,6 +463,7 @@ enum {
+
+ MSTP230,
+ MSTP222,
++ MSTP218, MSTP217, MSTP216,
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+
+ MSTP329, MSTP328, MSTP323, MSTP320,
+@@ -485,6 +486,9 @@ static struct clk mstp_clks[MSTP_NR] = {
+
+ [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */
+ [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */
++ [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */
++ [MSTP217] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */
++ [MSTP216] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */
+ [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
+ [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
+ [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
+@@ -563,7 +567,9 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
+ CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]),
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]),
+-
++ CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]),
++ CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]),
++ CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]),
+ CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]),
+ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]),
+
+diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+index 6468fcc..f71507b 100644
+--- a/arch/arm/mach-shmobile/include/mach/r8a7740.h
++++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+@@ -588,4 +588,12 @@ enum {
+ GPIO_FN_TRACEAUD_FROM_MEMC,
+ };
+
++/* DMA slave IDs */
++enum {
++ SHDMA_SLAVE_INVALID,
++ SHDMA_SLAVE_FSIA_RX,
++ SHDMA_SLAVE_FSIA_TX,
++ SHDMA_SLAVE_FSIB_TX,
++};
++
+ #endif /* __ASM_R8A7740_H__ */
+diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
+index 366311b..516a7ec 100644
+--- a/arch/arm/mach-shmobile/setup-r8a7740.c
++++ b/arch/arm/mach-shmobile/setup-r8a7740.c
+@@ -24,7 +24,9 @@
+ #include <linux/io.h>
+ #include <linux/platform_device.h>
+ #include <linux/serial_sci.h>
++#include <linux/sh_dma.h>
+ #include <linux/sh_timer.h>
++#include <linux/dma-mapping.h>
+ #include <mach/r8a7740.h>
+ #include <mach/common.h>
+ #include <mach/irqs.h>
+@@ -276,6 +278,199 @@ static struct platform_device *r8a7740_early_devices[] __initdata = {
+ &cmt10_device,
+ };
+
++/* DMA */
++enum {
++ XMIT_SZ_8BIT = 0,
++ XMIT_SZ_16BIT = 1,
++ XMIT_SZ_32BIT = 2,
++ XMIT_SZ_64BIT = 7,
++ XMIT_SZ_128BIT = 3,
++ XMIT_SZ_256BIT = 4,
++ XMIT_SZ_512BIT = 5,
++};
++
++/* log2(size / 8) - used to calculate number of transfers */
++#define TS_SHIFT { \
++ [XMIT_SZ_8BIT] = 0, \
++ [XMIT_SZ_16BIT] = 1, \
++ [XMIT_SZ_32BIT] = 2, \
++ [XMIT_SZ_64BIT] = 3, \
++ [XMIT_SZ_128BIT] = 4, \
++ [XMIT_SZ_256BIT] = 5, \
++ [XMIT_SZ_512BIT] = 6, \
++}
++
++#define TS_INDEX2VAL(i) ((((i) & 0x3) << 3) | (((i) & 0xc) << (20 - 2)))
++#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz)))
++#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz)))
++
++static const struct sh_dmae_slave_config r8a7740_dmae_slaves[] = {
++ {
++ .slave_id = SHDMA_SLAVE_FSIA_TX,
++ .addr = 0xfe1f0024,
++ .chcr = CHCR_TX(XMIT_SZ_32BIT),
++ .mid_rid = 0xb1,
++ }, {
++ .slave_id = SHDMA_SLAVE_FSIA_RX,
++ .addr = 0xfe1f0020,
++ .chcr = CHCR_RX(XMIT_SZ_32BIT),
++ .mid_rid = 0xb2,
++ }, {
++ .slave_id = SHDMA_SLAVE_FSIB_TX,
++ .addr = 0xfe1f0064,
++ .chcr = CHCR_TX(XMIT_SZ_32BIT),
++ .mid_rid = 0xb5,
++ },
++};
++
++#define DMA_CHANNEL(a, b, c) \
++{ \
++ .offset = a, \
++ .dmars = b, \
++ .dmars_bit = c, \
++ .chclr_offset = (0x220 - 0x20) + a \
++}
++
++static const struct sh_dmae_channel r8a7740_dmae_channels[] = {
++ DMA_CHANNEL(0x00, 0, 0),
++ DMA_CHANNEL(0x10, 0, 8),
++ DMA_CHANNEL(0x20, 4, 0),
++ DMA_CHANNEL(0x30, 4, 8),
++ DMA_CHANNEL(0x50, 8, 0),
++ DMA_CHANNEL(0x60, 8, 8),
++};
++
++static const unsigned int ts_shift[] = TS_SHIFT;
++
++static struct sh_dmae_pdata dma_platform_data = {
++ .slave = r8a7740_dmae_slaves,
++ .slave_num = ARRAY_SIZE(r8a7740_dmae_slaves),
++ .channel = r8a7740_dmae_channels,
++ .channel_num = ARRAY_SIZE(r8a7740_dmae_channels),
++ .ts_low_shift = 3,
++ .ts_low_mask = 0x18,
++ .ts_high_shift = (20 - 2),
++ .ts_high_mask = 0x00300000,
++ .ts_shift = ts_shift,
++ .ts_shift_num = ARRAY_SIZE(ts_shift),
++ .dmaor_init = DMAOR_DME,
++ .chclr_present = 1,
++};
++
++/* Resource order important! */
++static struct resource r8a7740_dmae0_resources[] = {
++ {
++ /* Channel registers and DMAOR */
++ .start = 0xfe008020,
++ .end = 0xfe00828f,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ /* DMARSx */
++ .start = 0xfe009000,
++ .end = 0xfe00900b,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "error_irq",
++ .start = evt2irq(0x20c0),
++ .end = evt2irq(0x20c0),
++ .flags = IORESOURCE_IRQ,
++ },
++ {
++ /* IRQ for channels 0-5 */
++ .start = evt2irq(0x2000),
++ .end = evt2irq(0x20a0),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++/* Resource order important! */
++static struct resource r8a7740_dmae1_resources[] = {
++ {
++ /* Channel registers and DMAOR */
++ .start = 0xfe018020,
++ .end = 0xfe01828f,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ /* DMARSx */
++ .start = 0xfe019000,
++ .end = 0xfe01900b,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "error_irq",
++ .start = evt2irq(0x21c0),
++ .end = evt2irq(0x21c0),
++ .flags = IORESOURCE_IRQ,
++ },
++ {
++ /* IRQ for channels 0-5 */
++ .start = evt2irq(0x2100),
++ .end = evt2irq(0x21a0),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++/* Resource order important! */
++static struct resource r8a7740_dmae2_resources[] = {
++ {
++ /* Channel registers and DMAOR */
++ .start = 0xfe028020,
++ .end = 0xfe02828f,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ /* DMARSx */
++ .start = 0xfe029000,
++ .end = 0xfe02900b,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = "error_irq",
++ .start = evt2irq(0x22c0),
++ .end = evt2irq(0x22c0),
++ .flags = IORESOURCE_IRQ,
++ },
++ {
++ /* IRQ for channels 0-5 */
++ .start = evt2irq(0x2200),
++ .end = evt2irq(0x22a0),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device dma0_device = {
++ .name = "sh-dma-engine",
++ .id = 0,
++ .resource = r8a7740_dmae0_resources,
++ .num_resources = ARRAY_SIZE(r8a7740_dmae0_resources),
++ .dev = {
++ .platform_data = &dma_platform_data,
++ },
++};
++
++static struct platform_device dma1_device = {
++ .name = "sh-dma-engine",
++ .id = 1,
++ .resource = r8a7740_dmae1_resources,
++ .num_resources = ARRAY_SIZE(r8a7740_dmae1_resources),
++ .dev = {
++ .platform_data = &dma_platform_data,
++ },
++};
++
++static struct platform_device dma2_device = {
++ .name = "sh-dma-engine",
++ .id = 2,
++ .resource = r8a7740_dmae2_resources,
++ .num_resources = ARRAY_SIZE(r8a7740_dmae2_resources),
++ .dev = {
++ .platform_data = &dma_platform_data,
++ },
++};
++
+ /* I2C */
+ static struct resource i2c0_resources[] = {
+ [0] = {
+@@ -322,6 +517,9 @@ static struct platform_device i2c1_device = {
+ static struct platform_device *r8a7740_late_devices[] __initdata = {
+ &i2c0_device,
+ &i2c1_device,
++ &dma0_device,
++ &dma1_device,
++ &dma2_device,
+ };
+
+ /*
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0084-ARM-shmobile-r8a7740-add-DMAEngine-support-for-SDHI.patch b/patches.armadillo800/0084-ARM-shmobile-r8a7740-add-DMAEngine-support-for-SDHI.patch
new file mode 100644
index 0000000000000..c76b22f9c08ec
--- /dev/null
+++ b/patches.armadillo800/0084-ARM-shmobile-r8a7740-add-DMAEngine-support-for-SDHI.patch
@@ -0,0 +1,80 @@
+From b96167a50df2468ba7f7eb96fab0bec5e0ee7106 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 25 Jun 2012 03:37:00 -0700
+Subject: ARM: shmobile: r8a7740: add DMAEngine support for SDHI
+
+Current shdmac can support SDHI DMAC on r8a7740.
+This support reduce CPU duty when SDHI access.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit cb76eb812ee03187da3b46e190895b55019d2133)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/include/mach/r8a7740.h | 6 ++++++
+ arch/arm/mach-shmobile/setup-r8a7740.c | 30 +++++++++++++++++++++++++++
+ 2 files changed, 36 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+index f71507b..0f14ce8 100644
+--- a/arch/arm/mach-shmobile/include/mach/r8a7740.h
++++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+@@ -591,6 +591,12 @@ enum {
+ /* DMA slave IDs */
+ enum {
+ SHDMA_SLAVE_INVALID,
++ SHDMA_SLAVE_SDHI0_RX,
++ SHDMA_SLAVE_SDHI0_TX,
++ SHDMA_SLAVE_SDHI1_RX,
++ SHDMA_SLAVE_SDHI1_TX,
++ SHDMA_SLAVE_SDHI2_RX,
++ SHDMA_SLAVE_SDHI2_TX,
+ SHDMA_SLAVE_FSIA_RX,
+ SHDMA_SLAVE_FSIA_TX,
+ SHDMA_SLAVE_FSIB_TX,
+diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
+index 516a7ec..320c43a 100644
+--- a/arch/arm/mach-shmobile/setup-r8a7740.c
++++ b/arch/arm/mach-shmobile/setup-r8a7740.c
+@@ -306,6 +306,36 @@ enum {
+
+ static const struct sh_dmae_slave_config r8a7740_dmae_slaves[] = {
+ {
++ .slave_id = SHDMA_SLAVE_SDHI0_TX,
++ .addr = 0xe6850030,
++ .chcr = CHCR_TX(XMIT_SZ_16BIT),
++ .mid_rid = 0xc1,
++ }, {
++ .slave_id = SHDMA_SLAVE_SDHI0_RX,
++ .addr = 0xe6850030,
++ .chcr = CHCR_RX(XMIT_SZ_16BIT),
++ .mid_rid = 0xc2,
++ }, {
++ .slave_id = SHDMA_SLAVE_SDHI1_TX,
++ .addr = 0xe6860030,
++ .chcr = CHCR_TX(XMIT_SZ_16BIT),
++ .mid_rid = 0xc9,
++ }, {
++ .slave_id = SHDMA_SLAVE_SDHI1_RX,
++ .addr = 0xe6860030,
++ .chcr = CHCR_RX(XMIT_SZ_16BIT),
++ .mid_rid = 0xca,
++ }, {
++ .slave_id = SHDMA_SLAVE_SDHI2_TX,
++ .addr = 0xe6870030,
++ .chcr = CHCR_TX(XMIT_SZ_16BIT),
++ .mid_rid = 0xcd,
++ }, {
++ .slave_id = SHDMA_SLAVE_SDHI2_RX,
++ .addr = 0xe6870030,
++ .chcr = CHCR_RX(XMIT_SZ_16BIT),
++ .mid_rid = 0xce,
++ }, {
+ .slave_id = SHDMA_SLAVE_FSIA_TX,
+ .addr = 0xfe1f0024,
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0085-ARM-shmobile-r8a7740-add-DMAEngine-support-for-USB.patch b/patches.armadillo800/0085-ARM-shmobile-r8a7740-add-DMAEngine-support-for-USB.patch
new file mode 100644
index 0000000000000..4384aca2946ff
--- /dev/null
+++ b/patches.armadillo800/0085-ARM-shmobile-r8a7740-add-DMAEngine-support-for-USB.patch
@@ -0,0 +1,170 @@
+From 59ea669a42f7a0fa16df6d769a6843d3060b64f2 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 25 Jun 2012 03:37:10 -0700
+Subject: ARM: shmobile: r8a7740: add DMAEngine support for USB
+
+Current shdmac can support USB DMAC on r8a7740.
+This support reduce CPU duty when USB access.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit dbf382e556931aa75b2d7970d64661544d6c327c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-r8a7740.c | 4 +-
+ arch/arm/mach-shmobile/include/mach/r8a7740.h | 2 +
+ arch/arm/mach-shmobile/setup-r8a7740.c | 87 +++++++++++++++++++++++++++
+ 3 files changed, 92 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
+index 39b1311..daf3eac 100644
+--- a/arch/arm/mach-shmobile/clock-r8a7740.c
++++ b/arch/arm/mach-shmobile/clock-r8a7740.c
+@@ -463,7 +463,7 @@ enum {
+
+ MSTP230,
+ MSTP222,
+- MSTP218, MSTP217, MSTP216,
++ MSTP218, MSTP217, MSTP216, MSTP214,
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+
+ MSTP329, MSTP328, MSTP323, MSTP320,
+@@ -489,6 +489,7 @@ static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */
+ [MSTP217] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */
+ [MSTP216] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */
++ [MSTP214] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 14, 0), /* USBDMAC */
+ [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
+ [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
+ [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
+@@ -567,6 +568,7 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
+ CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]),
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]),
++ CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]),
+ CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]),
+ CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]),
+ CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]),
+diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+index 0f14ce8..8bd7b9c 100644
+--- a/arch/arm/mach-shmobile/include/mach/r8a7740.h
++++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+@@ -600,6 +600,8 @@ enum {
+ SHDMA_SLAVE_FSIA_RX,
+ SHDMA_SLAVE_FSIA_TX,
+ SHDMA_SLAVE_FSIB_TX,
++ SHDMA_SLAVE_USBHS_TX,
++ SHDMA_SLAVE_USBHS_RX,
+ };
+
+ #endif /* __ASM_R8A7740_H__ */
+diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
+index 320c43a..5e84609 100644
+--- a/arch/arm/mach-shmobile/setup-r8a7740.c
++++ b/arch/arm/mach-shmobile/setup-r8a7740.c
+@@ -501,6 +501,92 @@ static struct platform_device dma2_device = {
+ },
+ };
+
++/* USB-DMAC */
++/* Transmit sizes and respective CHCR register values */
++enum {
++ USBTS_XMIT_SZ_8BYTE = 0,
++ USBTS_XMIT_SZ_16BYTE = 1,
++ USBTS_XMIT_SZ_32BYTE = 2,
++};
++
++/* log2(size / 8) - used to calculate number of transfers */
++static const unsigned int dma_usbts_shift[] = {
++ [USBTS_XMIT_SZ_8BYTE] = 3,
++ [USBTS_XMIT_SZ_16BYTE] = 4,
++ [USBTS_XMIT_SZ_32BYTE] = 5,
++};
++
++static const struct sh_dmae_channel r8a7740_usb_dma_channels[] = {
++ {
++ .offset = 0,
++ }, {
++ .offset = 0x20,
++ },
++};
++
++#define USBTS_INDEX2VAL(i) (((i) & 3) << 6)
++
++static const struct sh_dmae_slave_config r8a7740_usb_dma_slaves[] = {
++ {
++ .slave_id = SHDMA_SLAVE_USBHS_TX,
++ .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE),
++ }, {
++ .slave_id = SHDMA_SLAVE_USBHS_RX,
++ .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE),
++ },
++};
++
++static struct sh_dmae_pdata usb_dma_platform_data = {
++ .slave = r8a7740_usb_dma_slaves,
++ .slave_num = ARRAY_SIZE(r8a7740_usb_dma_slaves),
++ .channel = r8a7740_usb_dma_channels,
++ .channel_num = ARRAY_SIZE(r8a7740_usb_dma_channels),
++ .ts_low_shift = 6,
++ .ts_low_mask = 0xc0,
++ .ts_high_shift = 0,
++ .ts_high_mask = 0,
++ .ts_shift = dma_usbts_shift,
++ .ts_shift_num = ARRAY_SIZE(dma_usbts_shift),
++ .dmaor_init = DMAOR_DME,
++ .chcr_offset = 0x14,
++ .chcr_ie_bit = 1 << 5,
++ .dmaor_is_32bit = 1,
++ .needs_tend_set = 1,
++ .no_dmars = 1,
++ .slave_only = 1,
++};
++
++static struct resource r8a7740_usb_dma_resources[] = {
++ {
++ /* Channel registers and DMAOR */
++ .start = 0xe68a0020,
++ .end = 0xe68a0064 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ /* VCR/SWR/DMICR */
++ .start = 0xe68a0000,
++ .end = 0xe68a0014 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ /* IRQ for channels */
++ .start = evt2irq(0x0a00),
++ .end = evt2irq(0x0a00),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device usb_dma_device = {
++ .name = "sh-dma-engine",
++ .id = 3,
++ .resource = r8a7740_usb_dma_resources,
++ .num_resources = ARRAY_SIZE(r8a7740_usb_dma_resources),
++ .dev = {
++ .platform_data = &usb_dma_platform_data,
++ },
++};
++
+ /* I2C */
+ static struct resource i2c0_resources[] = {
+ [0] = {
+@@ -550,6 +636,7 @@ static struct platform_device *r8a7740_late_devices[] __initdata = {
+ &dma0_device,
+ &dma1_device,
+ &dma2_device,
++ &usb_dma_device,
+ };
+
+ /*
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0086-ARM-shmobile-use-common-DMAEngine-definitions-on-r8a.patch b/patches.armadillo800/0086-ARM-shmobile-use-common-DMAEngine-definitions-on-r8a.patch
new file mode 100644
index 0000000000000..8233c22cb7f12
--- /dev/null
+++ b/patches.armadillo800/0086-ARM-shmobile-use-common-DMAEngine-definitions-on-r8a.patch
@@ -0,0 +1,139 @@
+From 5fa62ea250079de3ea68853067d0935524c3e766 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 25 Jun 2012 03:43:10 -0700
+Subject: ARM: shmobile: use common DMAEngine definitions on r8a7740
+
+This patch switch over to use common DMAEngine definitions,
+and reduced a waste of code.
+
+It is easy to understand if sh_dmae_pdata / sh_dmae_slave_config
+settings are used defined value instead of direct value.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit d7de938f3da618b1592427f625e150c0a68b9ecb)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/setup-r8a7740.c | 64 ++++++----------------------------
+ 1 file changed, 11 insertions(+), 53 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
+index 5e84609..48d7bbf 100644
+--- a/arch/arm/mach-shmobile/setup-r8a7740.c
++++ b/arch/arm/mach-shmobile/setup-r8a7740.c
+@@ -27,6 +27,7 @@
+ #include <linux/sh_dma.h>
+ #include <linux/sh_timer.h>
+ #include <linux/dma-mapping.h>
++#include <mach/dma-register.h>
+ #include <mach/r8a7740.h>
+ #include <mach/common.h>
+ #include <mach/irqs.h>
+@@ -279,31 +280,6 @@ static struct platform_device *r8a7740_early_devices[] __initdata = {
+ };
+
+ /* DMA */
+-enum {
+- XMIT_SZ_8BIT = 0,
+- XMIT_SZ_16BIT = 1,
+- XMIT_SZ_32BIT = 2,
+- XMIT_SZ_64BIT = 7,
+- XMIT_SZ_128BIT = 3,
+- XMIT_SZ_256BIT = 4,
+- XMIT_SZ_512BIT = 5,
+-};
+-
+-/* log2(size / 8) - used to calculate number of transfers */
+-#define TS_SHIFT { \
+- [XMIT_SZ_8BIT] = 0, \
+- [XMIT_SZ_16BIT] = 1, \
+- [XMIT_SZ_32BIT] = 2, \
+- [XMIT_SZ_64BIT] = 3, \
+- [XMIT_SZ_128BIT] = 4, \
+- [XMIT_SZ_256BIT] = 5, \
+- [XMIT_SZ_512BIT] = 6, \
+-}
+-
+-#define TS_INDEX2VAL(i) ((((i) & 0x3) << 3) | (((i) & 0xc) << (20 - 2)))
+-#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz)))
+-#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz)))
+-
+ static const struct sh_dmae_slave_config r8a7740_dmae_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_SDHI0_TX,
+@@ -370,19 +346,17 @@ static const struct sh_dmae_channel r8a7740_dmae_channels[] = {
+ DMA_CHANNEL(0x60, 8, 8),
+ };
+
+-static const unsigned int ts_shift[] = TS_SHIFT;
+-
+ static struct sh_dmae_pdata dma_platform_data = {
+ .slave = r8a7740_dmae_slaves,
+ .slave_num = ARRAY_SIZE(r8a7740_dmae_slaves),
+ .channel = r8a7740_dmae_channels,
+ .channel_num = ARRAY_SIZE(r8a7740_dmae_channels),
+- .ts_low_shift = 3,
+- .ts_low_mask = 0x18,
+- .ts_high_shift = (20 - 2),
+- .ts_high_mask = 0x00300000,
+- .ts_shift = ts_shift,
+- .ts_shift_num = ARRAY_SIZE(ts_shift),
++ .ts_low_shift = TS_LOW_SHIFT,
++ .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
++ .ts_high_shift = TS_HI_SHIFT,
++ .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
++ .ts_shift = dma_ts_shift,
++ .ts_shift_num = ARRAY_SIZE(dma_ts_shift),
+ .dmaor_init = DMAOR_DME,
+ .chclr_present = 1,
+ };
+@@ -502,20 +476,6 @@ static struct platform_device dma2_device = {
+ };
+
+ /* USB-DMAC */
+-/* Transmit sizes and respective CHCR register values */
+-enum {
+- USBTS_XMIT_SZ_8BYTE = 0,
+- USBTS_XMIT_SZ_16BYTE = 1,
+- USBTS_XMIT_SZ_32BYTE = 2,
+-};
+-
+-/* log2(size / 8) - used to calculate number of transfers */
+-static const unsigned int dma_usbts_shift[] = {
+- [USBTS_XMIT_SZ_8BYTE] = 3,
+- [USBTS_XMIT_SZ_16BYTE] = 4,
+- [USBTS_XMIT_SZ_32BYTE] = 5,
+-};
+-
+ static const struct sh_dmae_channel r8a7740_usb_dma_channels[] = {
+ {
+ .offset = 0,
+@@ -524,8 +484,6 @@ static const struct sh_dmae_channel r8a7740_usb_dma_channels[] = {
+ },
+ };
+
+-#define USBTS_INDEX2VAL(i) (((i) & 3) << 6)
+-
+ static const struct sh_dmae_slave_config r8a7740_usb_dma_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_USBHS_TX,
+@@ -541,10 +499,10 @@ static struct sh_dmae_pdata usb_dma_platform_data = {
+ .slave_num = ARRAY_SIZE(r8a7740_usb_dma_slaves),
+ .channel = r8a7740_usb_dma_channels,
+ .channel_num = ARRAY_SIZE(r8a7740_usb_dma_channels),
+- .ts_low_shift = 6,
+- .ts_low_mask = 0xc0,
+- .ts_high_shift = 0,
+- .ts_high_mask = 0,
++ .ts_low_shift = USBTS_LOW_SHIFT,
++ .ts_low_mask = USBTS_LOW_BIT << USBTS_LOW_SHIFT,
++ .ts_high_shift = USBTS_HI_SHIFT,
++ .ts_high_mask = USBTS_HI_BIT << USBTS_HI_SHIFT,
+ .ts_shift = dma_usbts_shift,
+ .ts_shift_num = ARRAY_SIZE(dma_usbts_shift),
+ .dmaor_init = DMAOR_DME,
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0087-ARM-shmobile-armadillo800eva-enable-FSI-WM8978-sound.patch b/patches.armadillo800/0087-ARM-shmobile-armadillo800eva-enable-FSI-WM8978-sound.patch
new file mode 100644
index 0000000000000..b62ac1815ed1f
--- /dev/null
+++ b/patches.armadillo800/0087-ARM-shmobile-armadillo800eva-enable-FSI-WM8978-sound.patch
@@ -0,0 +1,184 @@
+From 2b0c07b75a3b421285bae10961bf20e0011839b6 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 25 Jun 2012 03:32:50 -0700
+Subject: ARM: shmobile: armadillo800eva: enable FSI-WM8978 sound
+
+This patch enable sound support on CON11
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 5389bf719f87101339f292256392bff5ae926917)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/Kconfig | 1 +
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 99 ++++++++++++++++++++++++++
+ 2 files changed, 100 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
+index da57dde..c74b74a 100644
+--- a/arch/arm/mach-shmobile/Kconfig
++++ b/arch/arm/mach-shmobile/Kconfig
+@@ -100,6 +100,7 @@ config MACH_ARMADILLO800EVA
+ depends on ARCH_R8A7740
+ select ARCH_REQUIRE_GPIOLIB
+ select USE_OF
++ select SND_SOC_WM8978 if SND_SIMPLE_CARD
+
+ config MACH_MARZEN
+ bool "MARZEN board"
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index a513ebe..afe7860 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -49,6 +49,8 @@
+ #include <asm/hardware/cache-l2x0.h>
+ #include <video/sh_mobile_lcdc.h>
+ #include <video/sh_mobile_hdmi.h>
++#include <sound/sh_fsi.h>
++#include <sound/simple_card.h>
+
+ /*
+ * CON1 Camera Module
+@@ -112,6 +114,28 @@
+ */
+
+ /*
++ * FSI-WM8978
++ *
++ * this command is required when playback.
++ *
++ * # amixer set "Headphone" 50
++ */
++
++/*
++ * FIXME !!
++ *
++ * gpio_no_direction
++ *
++ * current gpio frame work doesn't have
++ * the method to control only pull up/down/free.
++ * this function should be replaced by correct gpio function
++ */
++static void __init gpio_no_direction(u32 addr)
++{
++ __raw_writeb(0x00, addr);
++}
++
++/*
+ * USB function
+ *
+ * When you use USB Function,
+@@ -714,12 +738,71 @@ static struct platform_device ceu0_device = {
+ },
+ };
+
++/* FSI */
++static struct sh_fsi_platform_info fsi_info = {
++ /* FSI-WM8978 */
++ .port_a = {
++ },
++};
++
++static struct resource fsi_resources[] = {
++ [0] = {
++ .name = "FSI",
++ .start = 0xfe1f0000,
++ .end = 0xfe1f8400 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = evt2irq(0x1840),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device fsi_device = {
++ .name = "sh_fsi2",
++ .id = -1,
++ .num_resources = ARRAY_SIZE(fsi_resources),
++ .resource = fsi_resources,
++ .dev = {
++ .platform_data = &fsi_info,
++ },
++};
++
++/* FSI-WM8978 */
++static struct asoc_simple_dai_init_info fsi_wm8978_init_info = {
++ .fmt = SND_SOC_DAIFMT_I2S,
++ .codec_daifmt = SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_NB_NF,
++ .cpu_daifmt = SND_SOC_DAIFMT_CBS_CFS,
++ .sysclk = 12288000,
++};
++
++static struct asoc_simple_card_info fsi_wm8978_info = {
++ .name = "wm8978",
++ .card = "FSI2A-WM8978",
++ .cpu_dai = "fsia-dai",
++ .codec = "wm8978.0-001a",
++ .platform = "sh_fsi2",
++ .codec_dai = "wm8978-hifi",
++ .init = &fsi_wm8978_init_info,
++};
++
++static struct platform_device fsi_wm8978_device = {
++ .name = "asoc-simple-card",
++ .id = 0,
++ .dev = {
++ .platform_data = &fsi_wm8978_info,
++ },
++};
++
+ /* I2C */
+ static struct i2c_board_info i2c0_devices[] = {
+ {
+ I2C_BOARD_INFO("st1232-ts", 0x55),
+ .irq = evt2irq(0x0340),
+ },
++ {
++ I2C_BOARD_INFO("wm8978", 0x1a),
++ },
+ };
+
+ /*
+@@ -735,6 +818,8 @@ static struct platform_device *eva_devices[] __initdata = {
+ &hdmi_lcdc_device,
+ &camera_device,
+ &ceu0_device,
++ &fsi_device,
++ &fsi_wm8978_device,
+ };
+
+ static void __init eva_clock_init(void)
+@@ -768,6 +853,8 @@ clock_error:
+ /*
+ * board init
+ */
++#define GPIO_PORT7CR 0xe6050007
++#define GPIO_PORT8CR 0xe6050008
+ static void __init eva_init(void)
+ {
+ eva_clock_init();
+@@ -916,6 +1003,18 @@ static void __init eva_init(void)
+ gpio_direction_output(GPIO_PORT172, 1);
+ gpio_direction_output(GPIO_PORT158, 0); /* see mt9t111_power() */
+
++ /* FSI-WM8978 */
++ gpio_request(GPIO_FN_FSIAIBT, NULL);
++ gpio_request(GPIO_FN_FSIAILR, NULL);
++ gpio_request(GPIO_FN_FSIAOMC, NULL);
++ gpio_request(GPIO_FN_FSIAOSLD, NULL);
++ gpio_request(GPIO_FN_FSIAISLD_PORT5, NULL);
++
++ gpio_request(GPIO_PORT7, NULL);
++ gpio_request(GPIO_PORT8, NULL);
++ gpio_no_direction(GPIO_PORT7CR); /* FSIAOBT needs no direction */
++ gpio_no_direction(GPIO_PORT8CR); /* FSIAOLR needs no direction */
++
+ /*
+ * CAUTION
+ *
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0088-ARM-shmobile-armadillo800eva-enable-FSI-HDMI-sound.patch b/patches.armadillo800/0088-ARM-shmobile-armadillo800eva-enable-FSI-HDMI-sound.patch
new file mode 100644
index 0000000000000..120c3153d5cdf
--- /dev/null
+++ b/patches.armadillo800/0088-ARM-shmobile-armadillo800eva-enable-FSI-HDMI-sound.patch
@@ -0,0 +1,176 @@
+From 850c6f996ee51eddf540325ec5c892073dbc2567 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 25 Jun 2012 03:33:04 -0700
+Subject: ARM: shmobile: armadillo800eva: enable FSI-HDMI sound
+
+This patch enable HDMI sound support on CON3
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 0676c05e57c6e37fc9f985a8f6ea2883e5b2cbda)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 82 +++++++++++++++++++++++++-
+ 1 file changed, 79 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index afe7860..df5fd2c 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -739,10 +739,42 @@ static struct platform_device ceu0_device = {
+ };
+
+ /* FSI */
++static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
++{
++ struct clk *fsib;
++ int ret;
++
++ /* it support 48KHz only */
++ if (48000 != rate)
++ return -EINVAL;
++
++ fsib = clk_get(dev, "ickb");
++ if (IS_ERR(fsib))
++ return -EINVAL;
++
++ if (enable) {
++ ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
++ clk_enable(fsib);
++ } else {
++ ret = 0;
++ clk_disable(fsib);
++ }
++
++ clk_put(fsib);
++
++ return ret;
++}
++
+ static struct sh_fsi_platform_info fsi_info = {
+ /* FSI-WM8978 */
+ .port_a = {
+ },
++ /* FSI-HDMI */
++ .port_b = {
++ .flags = SH_FSI_FMT_SPDIF |
++ SH_FSI_ENABLE_STREAM_MODE,
++ .set_rate = fsi_hdmi_set_rate,
++ }
+ };
+
+ static struct resource fsi_resources[] = {
+@@ -794,6 +826,29 @@ static struct platform_device fsi_wm8978_device = {
+ },
+ };
+
++/* FSI-HDMI */
++static struct asoc_simple_dai_init_info fsi2_hdmi_init_info = {
++ .cpu_daifmt = SND_SOC_DAIFMT_CBM_CFM,
++};
++
++static struct asoc_simple_card_info fsi2_hdmi_info = {
++ .name = "HDMI",
++ .card = "FSI2B-HDMI",
++ .cpu_dai = "fsib-dai",
++ .codec = "sh-mobile-hdmi",
++ .platform = "sh_fsi2",
++ .codec_dai = "sh_mobile_hdmi-hifi",
++ .init = &fsi2_hdmi_init_info,
++};
++
++static struct platform_device fsi_hdmi_device = {
++ .name = "asoc-simple-card",
++ .id = 1,
++ .dev = {
++ .platform_data = &fsi2_hdmi_info,
++ },
++};
++
+ /* I2C */
+ static struct i2c_board_info i2c0_devices[] = {
+ {
+@@ -819,6 +874,7 @@ static struct platform_device *eva_devices[] __initdata = {
+ &camera_device,
+ &ceu0_device,
+ &fsi_device,
++ &fsi_hdmi_device,
+ &fsi_wm8978_device,
+ };
+
+@@ -827,10 +883,14 @@ static void __init eva_clock_init(void)
+ struct clk *system = clk_get(NULL, "system_clk");
+ struct clk *xtal1 = clk_get(NULL, "extal1");
+ struct clk *usb24s = clk_get(NULL, "usb24s");
++ struct clk *fsibck = clk_get(NULL, "fsibck");
++ struct clk *fsib = clk_get(&fsi_device.dev, "ickb");
+
+ if (IS_ERR(system) ||
+ IS_ERR(xtal1) ||
+- IS_ERR(usb24s)) {
++ IS_ERR(usb24s) ||
++ IS_ERR(fsibck) ||
++ IS_ERR(fsib)) {
+ pr_err("armadillo800eva board clock init failed\n");
+ goto clock_error;
+ }
+@@ -841,6 +901,11 @@ static void __init eva_clock_init(void)
+ /* usb24s use extal1 (= system) clock (= 24MHz) */
+ clk_set_parent(usb24s, system);
+
++ /* FSIBCK is 12.288MHz, and it is parent of FSI-B */
++ clk_set_parent(fsib, fsibck);
++ clk_set_rate(fsibck, 12288000);
++ clk_set_rate(fsib, 12288000);
++
+ clock_error:
+ if (!IS_ERR(system))
+ clk_put(system);
+@@ -848,6 +913,10 @@ clock_error:
+ clk_put(xtal1);
+ if (!IS_ERR(usb24s))
+ clk_put(usb24s);
++ if (!IS_ERR(fsibck))
++ clk_put(fsibck);
++ if (!IS_ERR(fsib))
++ clk_put(fsib);
+ }
+
+ /*
+@@ -857,8 +926,6 @@ clock_error:
+ #define GPIO_PORT8CR 0xe6050008
+ static void __init eva_init(void)
+ {
+- eva_clock_init();
+-
+ r8a7740_pinmux_init();
+ r8a7740_meram_workaround();
+
+@@ -1015,6 +1082,13 @@ static void __init eva_init(void)
+ gpio_no_direction(GPIO_PORT7CR); /* FSIAOBT needs no direction */
+ gpio_no_direction(GPIO_PORT8CR); /* FSIAOLR needs no direction */
+
++ /* FSI-HDMI */
++ gpio_request(GPIO_FN_FSIBCK, NULL);
++
++ /* HDMI */
++ gpio_request(GPIO_FN_HDMI_HPD, NULL);
++ gpio_request(GPIO_FN_HDMI_CEC, NULL);
++
+ /*
+ * CAUTION
+ *
+@@ -1061,6 +1135,8 @@ static void __init eva_init(void)
+
+ platform_add_devices(eva_devices,
+ ARRAY_SIZE(eva_devices));
++
++ eva_clock_init();
+ }
+
+ static void __init eva_earlytimer_init(void)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0089-ARM-shmobile-armadillo800eva-enable-DMAEngine-on-FSI.patch b/patches.armadillo800/0089-ARM-shmobile-armadillo800eva-enable-DMAEngine-on-FSI.patch
new file mode 100644
index 0000000000000..e2c925f1c6a57
--- /dev/null
+++ b/patches.armadillo800/0089-ARM-shmobile-armadillo800eva-enable-DMAEngine-on-FSI.patch
@@ -0,0 +1,54 @@
+From 95f8bc86715253ac6371cf581049a13a0a1d94eb Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 25 Jun 2012 03:37:20 -0700
+Subject: ARM: shmobile: armadillo800eva: enable DMAEngine on FSI
+
+It is possible to reduce CPU load if FSI playback used DMAEngine.
+This patch enabled it.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit dc7dd5841f714c3bc3f358cb126ba4432947e854)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/configs/armadillo800eva_defconfig | 2 ++
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/arch/arm/configs/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig
+index df1ce54..16bbb3f 100644
+--- a/arch/arm/configs/armadillo800eva_defconfig
++++ b/arch/arm/configs/armadillo800eva_defconfig
+@@ -119,6 +119,8 @@ CONFIG_USB_ETH=m
+ CONFIG_MMC=y
+ CONFIG_MMC_SDHI=y
+ CONFIG_MMC_SH_MMCIF=y
++CONFIG_DMADEVICES=y
++CONFIG_SH_DMAE=y
+ CONFIG_UIO=y
+ CONFIG_UIO_PDRV_GENIRQ=y
+ # CONFIG_DNOTIFY is not set
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index df5fd2c..032e04d 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -768,12 +768,14 @@ static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
+ static struct sh_fsi_platform_info fsi_info = {
+ /* FSI-WM8978 */
+ .port_a = {
++ .tx_id = SHDMA_SLAVE_FSIA_TX,
+ },
+ /* FSI-HDMI */
+ .port_b = {
+ .flags = SH_FSI_FMT_SPDIF |
+ SH_FSI_ENABLE_STREAM_MODE,
+ .set_rate = fsi_hdmi_set_rate,
++ .tx_id = SHDMA_SLAVE_FSIB_TX,
+ }
+ };
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0090-ARM-shmobile-armadillo800eva-enable-DMAEngine-on-SDH.patch b/patches.armadillo800/0090-ARM-shmobile-armadillo800eva-enable-DMAEngine-on-SDH.patch
new file mode 100644
index 0000000000000..7b80c65db76bf
--- /dev/null
+++ b/patches.armadillo800/0090-ARM-shmobile-armadillo800eva-enable-DMAEngine-on-SDH.patch
@@ -0,0 +1,43 @@
+From 67c3e7eb10a9da8600072c0b2292287dafe97219 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 25 Jun 2012 03:37:38 -0700
+Subject: ARM: shmobile: armadillo800eva: enable DMAEngine on SDHI
+
+It is possible to reduce CPU load if SDHI used DMAEngine.
+This patch enabled it.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 95798e350dde44920a021a7e7e720a3be15e8220)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 032e04d..54bf618 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -543,6 +543,8 @@ static struct platform_device gpio_keys_device = {
+ */
+ #define IRQ31 evt2irq(0x33E0)
+ static struct sh_mobile_sdhi_info sdhi0_info = {
++ .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
++ .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX,
+ .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |\
+ MMC_CAP_NEEDS_POLL,
+ .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
+@@ -583,6 +585,8 @@ static struct platform_device sdhi0_device = {
+
+ /* SDHI1 */
+ static struct sh_mobile_sdhi_info sdhi1_info = {
++ .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX,
++ .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX,
+ .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ,
+ .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
+ .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT,
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0091-ARM-shmobile-armadillo800eva-enable-DMAEngine-on-USB.patch b/patches.armadillo800/0091-ARM-shmobile-armadillo800eva-enable-DMAEngine-on-USB.patch
new file mode 100644
index 0000000000000..27ccbe4039b8a
--- /dev/null
+++ b/patches.armadillo800/0091-ARM-shmobile-armadillo800eva-enable-DMAEngine-on-USB.patch
@@ -0,0 +1,34 @@
+From ad78daa637449523d9cdfd7b28f5ea0150ac349a Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 25 Jun 2012 03:37:47 -0700
+Subject: ARM: shmobile: armadillo800eva: enable DMAEngine on USB
+
+It is possible to reduce CPU load if USB used DMAEngine.
+This patch enabled it.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit f7e566fa26b7d34514d5ba7b8b4464934be8ff2c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 54bf618..539f1cf 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -297,6 +297,8 @@ static struct usbhsf_private usbhsf_private = {
+ .driver_param = {
+ .buswait_bwait = 5,
+ .detection_delay = 5,
++ .d0_rx_id = SHDMA_SLAVE_USBHS_RX,
++ .d1_tx_id = SHDMA_SLAVE_USBHS_TX,
+ },
+ }
+ };
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0092-ARM-shmobile-use-common-extra-gpio-functions-on-arma.patch b/patches.armadillo800/0092-ARM-shmobile-use-common-extra-gpio-functions-on-arma.patch
new file mode 100644
index 0000000000000..897c4321f1f99
--- /dev/null
+++ b/patches.armadillo800/0092-ARM-shmobile-use-common-extra-gpio-functions-on-arma.patch
@@ -0,0 +1,60 @@
+From 2d6b318376b8c20432ed164d31b047a74c6d5215 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 25 Jun 2012 03:41:45 -0700
+Subject: ARM: shmobile: use common extra gpio functions on armadillo800eva
+
+This patch switch over to use common extra gpio method,
+and reduced a waste of code on SH-ARM.
+
+But these functions should be replaced by correct
+gpio function in the future.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit a01366b4b5cc669633d1cf6ee327c85a5406ef5f)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 18 ++----------------
+ 1 file changed, 2 insertions(+), 16 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 539f1cf..a4fd71a 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -122,20 +122,6 @@
+ */
+
+ /*
+- * FIXME !!
+- *
+- * gpio_no_direction
+- *
+- * current gpio frame work doesn't have
+- * the method to control only pull up/down/free.
+- * this function should be replaced by correct gpio function
+- */
+-static void __init gpio_no_direction(u32 addr)
+-{
+- __raw_writeb(0x00, addr);
+-}
+-
+-/*
+ * USB function
+ *
+ * When you use USB Function,
+@@ -1087,8 +1073,8 @@ static void __init eva_init(void)
+
+ gpio_request(GPIO_PORT7, NULL);
+ gpio_request(GPIO_PORT8, NULL);
+- gpio_no_direction(GPIO_PORT7CR); /* FSIAOBT needs no direction */
+- gpio_no_direction(GPIO_PORT8CR); /* FSIAOLR needs no direction */
++ gpio_direction_none(GPIO_PORT7CR); /* FSIAOBT needs no direction */
++ gpio_direction_none(GPIO_PORT8CR); /* FSIAOLR needs no direction */
+
+ /* FSI-HDMI */
+ gpio_request(GPIO_FN_FSIBCK, NULL);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0093-ARM-mach-shmobile-add-fixed-voltage-regulators-to-ar.patch b/patches.armadillo800/0093-ARM-mach-shmobile-add-fixed-voltage-regulators-to-ar.patch
new file mode 100644
index 0000000000000..2024d81a86244
--- /dev/null
+++ b/patches.armadillo800/0093-ARM-mach-shmobile-add-fixed-voltage-regulators-to-ar.patch
@@ -0,0 +1,61 @@
+From 6a9259faadbdfcb18a8f2ee78d414ae7194a2b10 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Fri, 29 Jun 2012 08:33:11 +0200
+Subject: ARM: mach-shmobile: add fixed voltage regulators to armadillo800eva
+
+On armadillo800eva provide a 3.3V supply for its SD/MMC-card interfaces.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit f65ad7e36cbae24f05ea2314ad63e9dd23294c60)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index a4fd71a..7c77f07 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -28,6 +28,8 @@
+ #include <linux/platform_device.h>
+ #include <linux/gpio.h>
+ #include <linux/gpio_keys.h>
++#include <linux/regulator/fixed.h>
++#include <linux/regulator/machine.h>
+ #include <linux/sh_eth.h>
+ #include <linux/videodev2.h>
+ #include <linux/usb/renesas_usbhs.h>
+@@ -520,6 +522,17 @@ static struct platform_device gpio_keys_device = {
+ },
+ };
+
++/* Fixed 3.3V regulator to be used by SDHI0, SDHI1, MMCIF */
++static struct regulator_consumer_supply fixed3v3_power_consumers[] =
++{
++ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
++ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
++ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
++ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
++ REGULATOR_SUPPLY("vmmc", "sh_mmcif"),
++ REGULATOR_SUPPLY("vqmmc", "sh_mmcif"),
++};
++
+ /* SDHI0 */
+ /*
+ * FIXME
+@@ -920,6 +933,9 @@ clock_error:
+ #define GPIO_PORT8CR 0xe6050008
+ static void __init eva_init(void)
+ {
++ regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
++ ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
++
+ r8a7740_pinmux_init();
+ r8a7740_meram_workaround();
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0094-ARM-mach-shmobile-Convert-sh_clk_mstp32_register-to-.patch b/patches.armadillo800/0094-ARM-mach-shmobile-Convert-sh_clk_mstp32_register-to-.patch
new file mode 100644
index 0000000000000..0b7bb32b076a7
--- /dev/null
+++ b/patches.armadillo800/0094-ARM-mach-shmobile-Convert-sh_clk_mstp32_register-to-.patch
@@ -0,0 +1,107 @@
+From 34b7faf5447e1eefc86e43779a132ad8e8cf5c32 Mon Sep 17 00:00:00 2001
+From: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+Date: Wed, 27 Jun 2012 09:59:00 +0900
+Subject: ARM: mach-shmobile: Convert sh_clk_mstp32_register to
+ sh_clk_mstp_register
+
+sh_clk_mstp32_register is deprecated. This convert to sh_clk_mstp_register.
+
+Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 64e9de2f854fb5d08d255b24568c60b090f2603a)
+
+Conflicts:
+ arch/arm/mach-shmobile/clock-r8a7740.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-r8a7740.c | 2 +-
+ arch/arm/mach-shmobile/clock-r8a7779.c | 2 +-
+ arch/arm/mach-shmobile/clock-sh7367.c | 2 +-
+ arch/arm/mach-shmobile/clock-sh7372.c | 2 +-
+ arch/arm/mach-shmobile/clock-sh7377.c | 2 +-
+ arch/arm/mach-shmobile/clock-sh73a0.c | 2 +-
+ 6 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
+index daf3eac..ad5fccc 100644
+--- a/arch/arm/mach-shmobile/clock-r8a7740.c
++++ b/arch/arm/mach-shmobile/clock-r8a7740.c
+@@ -636,7 +636,7 @@ void __init r8a7740_clock_init(u8 md_ck)
+ DIV6_REPARENT_NR);
+
+ if (!ret)
+- ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
++ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
+ ret = clk_register(late_main_clks[k]);
+diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c
+index 7d6e9fe..339c62c 100644
+--- a/arch/arm/mach-shmobile/clock-r8a7779.c
++++ b/arch/arm/mach-shmobile/clock-r8a7779.c
+@@ -162,7 +162,7 @@ void __init r8a7779_clock_init(void)
+ ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+ if (!ret)
+- ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
++ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
+ ret = clk_register(late_main_clks[k]);
+diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c
+index 006e7b5..162b791 100644
+--- a/arch/arm/mach-shmobile/clock-sh7367.c
++++ b/arch/arm/mach-shmobile/clock-sh7367.c
+@@ -344,7 +344,7 @@ void __init sh7367_clock_init(void)
+ ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+
+ if (!ret)
+- ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
++ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
+index 94d1f88..5a2894b 100644
+--- a/arch/arm/mach-shmobile/clock-sh7372.c
++++ b/arch/arm/mach-shmobile/clock-sh7372.c
+@@ -704,7 +704,7 @@ void __init sh7372_clock_init(void)
+ ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
+
+ if (!ret)
+- ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
++ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
+ ret = clk_register(late_main_clks[k]);
+diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c
+index 0798a15..85f2a3e 100644
+--- a/arch/arm/mach-shmobile/clock-sh7377.c
++++ b/arch/arm/mach-shmobile/clock-sh7377.c
+@@ -355,7 +355,7 @@ void __init sh7377_clock_init(void)
+ ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+
+ if (!ret)
+- ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
++ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
+index 472d1f5..f6788be 100644
+--- a/arch/arm/mach-shmobile/clock-sh73a0.c
++++ b/arch/arm/mach-shmobile/clock-sh73a0.c
+@@ -612,7 +612,7 @@ void __init sh73a0_clock_init(void)
+ ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
+
+ if (!ret)
+- ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
++ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
+ ret = clk_register(late_main_clks[k]);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0095-ARM-shmobile-r8a7740-fixup-MSEL1CR-7bit-control.patch b/patches.armadillo800/0095-ARM-shmobile-r8a7740-fixup-MSEL1CR-7bit-control.patch
new file mode 100644
index 0000000000000..f609f35d3a170
--- /dev/null
+++ b/patches.armadillo800/0095-ARM-shmobile-r8a7740-fixup-MSEL1CR-7bit-control.patch
@@ -0,0 +1,45 @@
+From e52c21c95e6ce158bd78d4b0d3b55fb4350beb4a Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 5 Jul 2012 01:25:24 -0700
+Subject: ARM: shmobile: r8a7740: fixup: MSEL1CR 7bit control
+
+MSEL1CR 7bit selects IRQ7 source pin which was
+VBUS pin or A21/MSIOF0_RSYNC/MSIOF1_TSYNC pin.
+But current pfc-r8a7740 MSEL1CR 7bit setting was wrong.
+This patch fix it up
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 444c5ed8d746140cd8f5591f708e5f1f84a9876e)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/pfc-r8a7740.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/pfc-r8a7740.c b/arch/arm/mach-shmobile/pfc-r8a7740.c
+index 03def0f..ce9e7fa 100644
+--- a/arch/arm/mach-shmobile/pfc-r8a7740.c
++++ b/arch/arm/mach-shmobile/pfc-r8a7740.c
+@@ -1261,7 +1261,7 @@ static pinmux_enum_t pinmux_data[] = {
+ PINMUX_DATA(A21_MARK, PORT120_FN1),
+ PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT120_FN2),
+ PINMUX_DATA(MSIOF1_TSYNC_PORT120_MARK, PORT120_FN3, MSEL4CR_10_0),
+- PINMUX_DATA(IRQ7_PORT120_MARK, PORT120_FN0, MSEL1CR_7_0),
++ PINMUX_DATA(IRQ7_PORT120_MARK, PORT120_FN0, MSEL1CR_7_1),
+
+ /* Port121 */
+ PINMUX_DATA(A20_MARK, PORT121_FN1),
+@@ -1623,7 +1623,7 @@ static pinmux_enum_t pinmux_data[] = {
+
+ /* Port209 */
+ PINMUX_DATA(VBUS_MARK, PORT209_FN1),
+- PINMUX_DATA(IRQ7_PORT209_MARK, PORT209_FN0, MSEL1CR_7_1),
++ PINMUX_DATA(IRQ7_PORT209_MARK, PORT209_FN0, MSEL1CR_7_0),
+
+ /* Port210 */
+ PINMUX_DATA(IRQ9_PORT210_MARK, PORT210_FN0, MSEL1CR_9_1),
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0096-ARM-shmobile-r8a7740-add-A4S-pm-domain-support.patch b/patches.armadillo800/0096-ARM-shmobile-r8a7740-add-A4S-pm-domain-support.patch
new file mode 100644
index 0000000000000..be5eee6388c00
--- /dev/null
+++ b/patches.armadillo800/0096-ARM-shmobile-r8a7740-add-A4S-pm-domain-support.patch
@@ -0,0 +1,122 @@
+From cfbc3351777b8b9160e410b3f1dfdb2558214b1a Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 5 Jul 2012 01:25:58 -0700
+Subject: ARM: shmobile: r8a7740: add A4S pm domain support
+
+This patch adds basic A4S pm domain support.
+Now, below devices can be controled by PM
+
+Common-SHwy, Common-HPB, BSC, MFI, MMFROM, HS-SHwy,
+SYS-HPB, INTCA, DBSC, DDRPHY (Logic),
+ATAPI, GbEther, AXI-bus
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 8459293c27bcd13aabacb7ee8097f6818f2ceedb)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/Makefile | 1 +
+ arch/arm/mach-shmobile/include/mach/r8a7740.h | 6 ++++++
+ arch/arm/mach-shmobile/pm-r8a7740.c | 30 +++++++++++++++++++++++++++
+ arch/arm/mach-shmobile/setup-r8a7740.c | 5 +++++
+ 4 files changed, 42 insertions(+)
+ create mode 100644 arch/arm/mach-shmobile/pm-r8a7740.c
+
+diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
+index b39033b..7804bd1 100644
+--- a/arch/arm/mach-shmobile/Makefile
++++ b/arch/arm/mach-shmobile/Makefile
+@@ -39,6 +39,7 @@ obj-$(CONFIG_SUSPEND) += suspend.o
+ obj-$(CONFIG_CPU_IDLE) += cpuidle.o
+ obj-$(CONFIG_ARCH_SHMOBILE) += pm-rmobile.o
+ obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o
++obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o
+ obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o
+
+ # Board objects
+diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+index 8bd7b9c..e8c87e9 100644
+--- a/arch/arm/mach-shmobile/include/mach/r8a7740.h
++++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+@@ -19,6 +19,8 @@
+ #ifndef __ASM_R8A7740_H__
+ #define __ASM_R8A7740_H__
+
++#include <mach/pm-rmobile.h>
++
+ /*
+ * MD_CKx pin
+ */
+@@ -604,4 +606,8 @@ enum {
+ SHDMA_SLAVE_USBHS_RX,
+ };
+
++#ifdef CONFIG_PM
++extern struct rmobile_pm_domain r8a7740_pd_a4s;
++#endif /* CONFIG_PM */
++
+ #endif /* __ASM_R8A7740_H__ */
+diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c
+new file mode 100644
+index 0000000..d2fe815
+--- /dev/null
++++ b/arch/arm/mach-shmobile/pm-r8a7740.c
+@@ -0,0 +1,30 @@
++/*
++ * r8a7740 power management support
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License. See the file "COPYING" in the main directory of this archive
++ * for more details.
++ */
++#include <mach/pm-rmobile.h>
++
++#ifdef CONFIG_PM
++static int r8a7740_pd_a4s_suspend(void)
++{
++ /*
++ * The A4S domain contains the CPU core and therefore it should
++ * only be turned off if the CPU is in use.
++ */
++ return -EBUSY;
++}
++
++struct rmobile_pm_domain r8a7740_pd_a4s = {
++ .genpd.name = "A4S",
++ .bit_shift = 10,
++ .gov = &pm_domain_always_on_gov,
++ .no_debug = true,
++ .suspend = r8a7740_pd_a4s_suspend,
++};
++#endif /* CONFIG_PM */
+diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
+index 48d7bbf..c37ad75 100644
+--- a/arch/arm/mach-shmobile/setup-r8a7740.c
++++ b/arch/arm/mach-shmobile/setup-r8a7740.c
+@@ -29,6 +29,7 @@
+ #include <linux/dma-mapping.h>
+ #include <mach/dma-register.h>
+ #include <mach/r8a7740.h>
++#include <mach/pm-rmobile.h>
+ #include <mach/common.h>
+ #include <mach/irqs.h>
+ #include <asm/mach-types.h>
+@@ -671,6 +672,10 @@ void __init r8a7740_add_standard_devices(void)
+ r8a7740_i2c_workaround(&i2c0_device);
+ r8a7740_i2c_workaround(&i2c1_device);
+
++ /* PM domain */
++ rmobile_init_pm_domain(&r8a7740_pd_a4s);
++
++ /* add devices */
+ platform_add_devices(r8a7740_early_devices,
+ ARRAY_SIZE(r8a7740_early_devices));
+ platform_add_devices(r8a7740_late_devices,
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0097-ARM-shmobile-r8a7740-add-A3SP-pm-domain-support.patch b/patches.armadillo800/0097-ARM-shmobile-r8a7740-add-A3SP-pm-domain-support.patch
new file mode 100644
index 0000000000000..3a6b491842d2a
--- /dev/null
+++ b/patches.armadillo800/0097-ARM-shmobile-r8a7740-add-A3SP-pm-domain-support.patch
@@ -0,0 +1,107 @@
+From 12c6836de664df0456e3d827b605ef1bf4bb323a Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 5 Jul 2012 01:26:31 -0700
+Subject: ARM: shmobile: r8a7740: add A3SP pm domain support
+
+This patch adds basic A3SP pm domain support.
+Now, below devices can be controled by PM
+
+DMAC1/2/3, IPMMU, DDM, FLCTL, SYS-HPB, BBIF1, MSIOF1/2,
+SCIFA,SCIFB, IIC1, IrDA, USBH, USBDMAC, SDHI0/1/2, TPU,
+DREQPAK (Sys), MMCIF, RSPI, SIM, USBF
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 802a5639aa7041b27cb865d3be289cd8afe3387b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/include/mach/r8a7740.h | 1 +
+ arch/arm/mach-shmobile/pm-r8a7740.c | 19 +++++++++++++++++++
+ arch/arm/mach-shmobile/setup-r8a7740.c | 16 ++++++++++++++++
+ 3 files changed, 36 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+index e8c87e9..a5691cf 100644
+--- a/arch/arm/mach-shmobile/include/mach/r8a7740.h
++++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+@@ -608,6 +608,7 @@ enum {
+
+ #ifdef CONFIG_PM
+ extern struct rmobile_pm_domain r8a7740_pd_a4s;
++extern struct rmobile_pm_domain r8a7740_pd_a3sp;
+ #endif /* CONFIG_PM */
+
+ #endif /* __ASM_R8A7740_H__ */
+diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c
+index d2fe815..de7c621 100644
+--- a/arch/arm/mach-shmobile/pm-r8a7740.c
++++ b/arch/arm/mach-shmobile/pm-r8a7740.c
+@@ -8,6 +8,7 @@
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
++#include <linux/console.h>
+ #include <mach/pm-rmobile.h>
+
+ #ifdef CONFIG_PM
+@@ -27,4 +28,22 @@ struct rmobile_pm_domain r8a7740_pd_a4s = {
+ .no_debug = true,
+ .suspend = r8a7740_pd_a4s_suspend,
+ };
++
++static int r8a7740_pd_a3sp_suspend(void)
++{
++ /*
++ * Serial consoles make use of SCIF hardware located in A3SP,
++ * keep such power domain on if "no_console_suspend" is set.
++ */
++ return console_suspend_enabled ? 0 : -EBUSY;
++}
++
++struct rmobile_pm_domain r8a7740_pd_a3sp = {
++ .genpd.name = "A3SP",
++ .bit_shift = 11,
++ .gov = &pm_domain_always_on_gov,
++ .no_debug = true,
++ .suspend = r8a7740_pd_a3sp_suspend,
++};
++
+ #endif /* CONFIG_PM */
+diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
+index c37ad75..59c79412 100644
+--- a/arch/arm/mach-shmobile/setup-r8a7740.c
++++ b/arch/arm/mach-shmobile/setup-r8a7740.c
+@@ -674,12 +674,28 @@ void __init r8a7740_add_standard_devices(void)
+
+ /* PM domain */
+ rmobile_init_pm_domain(&r8a7740_pd_a4s);
++ rmobile_init_pm_domain(&r8a7740_pd_a3sp);
++
++ rmobile_pm_add_subdomain(&r8a7740_pd_a4s, &r8a7740_pd_a3sp);
+
+ /* add devices */
+ platform_add_devices(r8a7740_early_devices,
+ ARRAY_SIZE(r8a7740_early_devices));
+ platform_add_devices(r8a7740_late_devices,
+ ARRAY_SIZE(r8a7740_late_devices));
++
++ /* add devices to PM domain */
++
++ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif0_device);
++ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif1_device);
++ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif2_device);
++ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif3_device);
++ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif4_device);
++ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif5_device);
++ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif6_device);
++ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif7_device);
++ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scifb_device);
++ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &i2c1_device);
+ }
+
+ static void __init r8a7740_earlytimer_init(void)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0098-ARM-shmobile-r8a7740-add-A4LC-pm-domain-support.patch b/patches.armadillo800/0098-ARM-shmobile-r8a7740-add-A4LC-pm-domain-support.patch
new file mode 100644
index 0000000000000..b3b936d34863d
--- /dev/null
+++ b/patches.armadillo800/0098-ARM-shmobile-r8a7740-add-A4LC-pm-domain-support.patch
@@ -0,0 +1,63 @@
+From ffd8b73a5eead1c3d0361edd426cd5560a853b6c Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 5 Jul 2012 01:26:53 -0700
+Subject: ARM: shmobile: r8a7740: add A4LC pm domain support
+
+This patch adds basic A4LC pm domain support.
+Now, below devices can be controled by PM
+
+MERAM, LCDC, VOU, ICBS, SDENC-Link
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit a330ce3cdaba5202051edf8ae69482e15fdc9db5)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/include/mach/r8a7740.h | 1 +
+ arch/arm/mach-shmobile/pm-r8a7740.c | 5 +++++
+ arch/arm/mach-shmobile/setup-r8a7740.c | 1 +
+ 3 files changed, 7 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+index a5691cf..7143147 100644
+--- a/arch/arm/mach-shmobile/include/mach/r8a7740.h
++++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h
+@@ -609,6 +609,7 @@ enum {
+ #ifdef CONFIG_PM
+ extern struct rmobile_pm_domain r8a7740_pd_a4s;
+ extern struct rmobile_pm_domain r8a7740_pd_a3sp;
++extern struct rmobile_pm_domain r8a7740_pd_a4lc;
+ #endif /* CONFIG_PM */
+
+ #endif /* __ASM_R8A7740_H__ */
+diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c
+index de7c621..893504d 100644
+--- a/arch/arm/mach-shmobile/pm-r8a7740.c
++++ b/arch/arm/mach-shmobile/pm-r8a7740.c
+@@ -46,4 +46,9 @@ struct rmobile_pm_domain r8a7740_pd_a3sp = {
+ .suspend = r8a7740_pd_a3sp_suspend,
+ };
+
++struct rmobile_pm_domain r8a7740_pd_a4lc = {
++ .genpd.name = "A4LC",
++ .bit_shift = 1,
++};
++
+ #endif /* CONFIG_PM */
+diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
+index 59c79412..c006d8d 100644
+--- a/arch/arm/mach-shmobile/setup-r8a7740.c
++++ b/arch/arm/mach-shmobile/setup-r8a7740.c
+@@ -675,6 +675,7 @@ void __init r8a7740_add_standard_devices(void)
+ /* PM domain */
+ rmobile_init_pm_domain(&r8a7740_pd_a4s);
+ rmobile_init_pm_domain(&r8a7740_pd_a3sp);
++ rmobile_init_pm_domain(&r8a7740_pd_a4lc);
+
+ rmobile_pm_add_subdomain(&r8a7740_pd_a4s, &r8a7740_pd_a3sp);
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0099-ARM-shmobile-armadillo800eva-USB-Func-enables-extern.patch b/patches.armadillo800/0099-ARM-shmobile-armadillo800eva-USB-Func-enables-extern.patch
new file mode 100644
index 0000000000000..05a8453ce3075
--- /dev/null
+++ b/patches.armadillo800/0099-ARM-shmobile-armadillo800eva-USB-Func-enables-extern.patch
@@ -0,0 +1,130 @@
+From a15b184d2c262c2133a1573ae9516633fdaf6f60 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 5 Jul 2012 01:27:14 -0700
+Subject: ARM: shmobile: armadillo800eva: USB Func enables external IRQ mode
+
+We can control renesas_usbhs driver as 2 way which are
+autonomy mode and external IRQ trigger mode.
+
+Autonomy mode is very easy settings for platform,
+but it required USB power domain always ON,
+since its connection/disconnection IRQ come from it.
+
+If platform uses external IRQ trigger mode,
+USB power domain can be OFF, since its
+connection/disconnection IRQ come from external IRQ.
+
+This patch enable external IRQ mode.
+Now it is possible to add USB support on A4SP domain.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit d483b983a5efaa101714186a8485a5fd4de42fba)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 46 +++++++++++++++++++++-----
+ 1 file changed, 38 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 7c77f07..5002f64 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -133,14 +133,8 @@
+ * These are a little bit complex.
+ * see
+ * usbhsf_power_ctrl()
+- *
+- * CAUTION
+- *
+- * It uses autonomy mode for USB hotplug at this point
+- * (= usbhs_private.platform_callback.get_vbus is NULL),
+- * since we don't know what's happen on PM control
+- * on this workaround.
+ */
++#define IRQ7 evt2irq(0x02e0)
+ #define USBCR1 0xe605810a
+ #define USBH 0xC6700000
+ #define USBH_USBCTR 0x10834
+@@ -220,6 +214,20 @@ static void usbhsf_power_ctrl(struct platform_device *pdev,
+ }
+ }
+
++static int usbhsf_get_vbus(struct platform_device *pdev)
++{
++ return gpio_get_value(GPIO_PORT209);
++}
++
++static irqreturn_t usbhsf_interrupt(int irq, void *data)
++{
++ struct platform_device *pdev = data;
++
++ renesas_usbhs_call_notify_hotplug(pdev);
++
++ return IRQ_HANDLED;
++}
++
+ static void usbhsf_hardware_exit(struct platform_device *pdev)
+ {
+ struct usbhsf_private *priv = usbhsf_get_priv(pdev);
+@@ -243,11 +251,14 @@ static void usbhsf_hardware_exit(struct platform_device *pdev)
+ priv->host = NULL;
+ priv->func = NULL;
+ priv->usbh_base = NULL;
++
++ free_irq(IRQ7, pdev);
+ }
+
+ static int usbhsf_hardware_init(struct platform_device *pdev)
+ {
+ struct usbhsf_private *priv = usbhsf_get_priv(pdev);
++ int ret;
+
+ priv->phy = clk_get(&pdev->dev, "phy");
+ priv->usb24 = clk_get(&pdev->dev, "usb24");
+@@ -267,6 +278,14 @@ static int usbhsf_hardware_init(struct platform_device *pdev)
+ return -EIO;
+ }
+
++ ret = request_irq(IRQ7, usbhsf_interrupt, IRQF_TRIGGER_NONE,
++ dev_name(&pdev->dev), pdev);
++ if (ret) {
++ dev_err(&pdev->dev, "request_irq err\n");
++ return ret;
++ }
++ irq_set_irq_type(IRQ7, IRQ_TYPE_EDGE_BOTH);
++
+ /* usb24 use 1/1 of parent clock (= usb24s = 24MHz) */
+ clk_set_rate(priv->usb24,
+ clk_get_rate(clk_get_parent(priv->usb24)));
+@@ -278,6 +297,7 @@ static struct usbhsf_private usbhsf_private = {
+ .info = {
+ .platform_callback = {
+ .get_id = usbhsf_get_id,
++ .get_vbus = usbhsf_get_vbus,
+ .hardware_init = usbhsf_hardware_init,
+ .hardware_exit = usbhsf_hardware_exit,
+ .power_ctrl = usbhsf_power_ctrl,
+@@ -1018,7 +1038,17 @@ static void __init eva_init(void)
+ /* USB Host */
+ } else {
+ /* USB Func */
+- gpio_request(GPIO_FN_VBUS, NULL);
++ /*
++ * A1 chip has 2 IRQ7 pin and it was controled by MSEL register.
++ * OTOH, usbhs interrupt needs its value (HI/LOW) to decide
++ * USB connection/disconnection (usbhsf_get_vbus()).
++ * This means we needs to select GPIO_FN_IRQ7_PORT209 first,
++ * and select GPIO_PORT209 here
++ */
++ gpio_request(GPIO_FN_IRQ7_PORT209, NULL);
++ gpio_request(GPIO_PORT209, NULL);
++ gpio_direction_input(GPIO_PORT209);
++
+ platform_device_register(&usbhsf_device);
+ }
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0100-ARM-shmobile-armadillo800eva-A4LC-domain-includes-LC.patch b/patches.armadillo800/0100-ARM-shmobile-armadillo800eva-A4LC-domain-includes-LC.patch
new file mode 100644
index 0000000000000..77f0990b4887d
--- /dev/null
+++ b/patches.armadillo800/0100-ARM-shmobile-armadillo800eva-A4LC-domain-includes-LC.patch
@@ -0,0 +1,35 @@
+From ac8b41bd50ebd214726fffdac141ee4d37d3fb40 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 5 Jul 2012 01:27:37 -0700
+Subject: ARM: shmobile: armadillo800eva: A4LC domain includes LCDC
+
+It is possible to control LCDC under A4LC domain to reduce power.
+This patch enable it.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 1000076a88d58acf77d8fa8bf5d2567425b8ea1b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 5002f64..101242a 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -1177,6 +1177,9 @@ static void __init eva_init(void)
+ ARRAY_SIZE(eva_devices));
+
+ eva_clock_init();
++
++ rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &lcdc0_device);
++ rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &hdmi_lcdc_device);
+ }
+
+ static void __init eva_earlytimer_init(void)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0101-ARM-shmobile-armadillo800eva-A3SP-domain-includes-US.patch b/patches.armadillo800/0101-ARM-shmobile-armadillo800eva-A3SP-domain-includes-US.patch
new file mode 100644
index 0000000000000..03ae976fb3584
--- /dev/null
+++ b/patches.armadillo800/0101-ARM-shmobile-armadillo800eva-A3SP-domain-includes-US.patch
@@ -0,0 +1,55 @@
+From 481b82720f5d1da8062da229cecc6ccfd875fb68 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 5 Jul 2012 01:28:00 -0700
+Subject: ARM: shmobile: armadillo800eva: A3SP domain includes USB
+
+Because USB Func is controlled by external IRQ mode,
+it is possible to control USB under A3SP domain to reduce power.
+This patch enables it.
+
+Armadillo800eva board switchs USB Host/Func by SW1.6,
+So, the device to adds into domain is selected on this patch.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 0f54788d8b4f7aa8d74b0a5a0ad706bcc216b3c7)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 101242a..cf10f92 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -953,6 +953,8 @@ clock_error:
+ #define GPIO_PORT8CR 0xe6050008
+ static void __init eva_init(void)
+ {
++ struct platform_device *usb = NULL;
++
+ regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
+ ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
+
+@@ -1050,6 +1052,7 @@ static void __init eva_init(void)
+ gpio_direction_input(GPIO_PORT209);
+
+ platform_device_register(&usbhsf_device);
++ usb = &usbhsf_device;
+ }
+
+ /* SDHI0 */
+@@ -1180,6 +1183,8 @@ static void __init eva_init(void)
+
+ rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &lcdc0_device);
+ rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &hdmi_lcdc_device);
++ if (usb)
++ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, usb);
+ }
+
+ static void __init eva_earlytimer_init(void)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0102-ARM-mach-shmobile-r8a7740-generic-board-support-via-.patch b/patches.armadillo800/0102-ARM-mach-shmobile-r8a7740-generic-board-support-via-.patch
new file mode 100644
index 0000000000000..d3e0e1c9ba671
--- /dev/null
+++ b/patches.armadillo800/0102-ARM-mach-shmobile-r8a7740-generic-board-support-via-.patch
@@ -0,0 +1,118 @@
+From db4818fde4a8b81acde03834936d131a21c4ae4f Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Fri, 6 Jul 2012 17:08:07 +0900
+Subject: ARM: mach-shmobile: r8a7740 generic board support via DT
+
+Add generic DT board support for the r8a7740 SoC.
+
+SCIF serial ports and timers are kept as regular
+platform devices. Other on-chip and on-board devices
+should be configured via the device tree.
+
+At this point there is no interrupt controller support
+in place but such code will be added over time when
+proper IRQ domain support has been added to INTC.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 755d57b2229bd8cfa1d553c0b6878f2096f55ec3)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/boot/dts/r8a7740.dtsi | 21 +++++++++++++++
+ arch/arm/mach-shmobile/setup-r8a7740.c | 47 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 68 insertions(+)
+ create mode 100644 arch/arm/boot/dts/r8a7740.dtsi
+
+diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi
+new file mode 100644
+index 0000000..798fa35
+--- /dev/null
++++ b/arch/arm/boot/dts/r8a7740.dtsi
+@@ -0,0 +1,21 @@
++/*
++ * Device Tree Source for the r8a7740 SoC
++ *
++ * Copyright (C) 2012 Renesas Solutions Corp.
++ *
++ * 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/ "skeleton.dtsi"
++
++/ {
++ compatible = "renesas,r8a7740";
++
++ cpus {
++ cpu@0 {
++ compatible = "arm,cortex-a9";
++ };
++ };
++};
+diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
+index c006d8d..78948a9 100644
+--- a/arch/arm/mach-shmobile/setup-r8a7740.c
++++ b/arch/arm/mach-shmobile/setup-r8a7740.c
+@@ -23,6 +23,7 @@
+ #include <linux/init.h>
+ #include <linux/io.h>
+ #include <linux/platform_device.h>
++#include <linux/of_platform.h>
+ #include <linux/serial_sci.h>
+ #include <linux/sh_dma.h>
+ #include <linux/sh_timer.h>
+@@ -716,3 +717,49 @@ void __init r8a7740_add_early_devices(void)
+ /* override timer setup with soc-specific code */
+ shmobile_timer.init = r8a7740_earlytimer_init;
+ }
++
++#ifdef CONFIG_USE_OF
++
++void __init r8a7740_add_early_devices_dt(void)
++{
++ shmobile_setup_delay(800, 1, 3); /* Cortex-A9 @ 800MHz */
++
++ early_platform_add_devices(r8a7740_early_devices,
++ ARRAY_SIZE(r8a7740_early_devices));
++
++ /* setup early console here as well */
++ shmobile_setup_console();
++}
++
++static const struct of_dev_auxdata r8a7740_auxdata_lookup[] __initconst = {
++ { }
++};
++
++void __init r8a7740_add_standard_devices_dt(void)
++{
++ /* clocks are setup late during boot in the case of DT */
++ r8a7740_clock_init(0);
++
++ platform_add_devices(r8a7740_early_devices,
++ ARRAY_SIZE(r8a7740_early_devices));
++
++ of_platform_populate(NULL, of_default_bus_match_table,
++ r8a7740_auxdata_lookup, NULL);
++}
++
++static const char *r8a7740_boards_compat_dt[] __initdata = {
++ "renesas,r8a7740",
++ NULL,
++};
++
++DT_MACHINE_START(SH7372_DT, "Generic R8A7740 (Flattened Device Tree)")
++ .map_io = r8a7740_map_io,
++ .init_early = r8a7740_add_early_devices_dt,
++ .init_irq = r8a7740_init_irq,
++ .handle_irq = shmobile_handle_irq_intc,
++ .init_machine = r8a7740_add_standard_devices_dt,
++ .timer = &shmobile_timer,
++ .dt_compat = r8a7740_boards_compat_dt,
++MACHINE_END
++
++#endif /* CONFIG_USE_OF */
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0103-ARM-mach-shmobile-armadillo800eva-defconfig-Allow-us.patch b/patches.armadillo800/0103-ARM-mach-shmobile-armadillo800eva-defconfig-Allow-us.patch
new file mode 100644
index 0000000000000..3b6f0565cf068
--- /dev/null
+++ b/patches.armadillo800/0103-ARM-mach-shmobile-armadillo800eva-defconfig-Allow-us.patch
@@ -0,0 +1,43 @@
+From 8a8dced180f83f64ff5d6098281f27053df630ad Mon Sep 17 00:00:00 2001
+From: Simon Horman <horms@verge.net.au>
+Date: Fri, 6 Jul 2012 20:08:15 +0900
+Subject: ARM: mach-shmobile: armadillo800eva: defconfig Allow use of armhf
+ userspace
+
+This allows use a Debian armhf usespace
+as well as the existing ability to use a Debian armel userspace.
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 70523b4e57cb6eeb1da7c8ebf19df855221825ad)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/configs/armadillo800eva_defconfig | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/configs/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig
+index 16bbb3f..7d87184 100644
+--- a/arch/arm/configs/armadillo800eva_defconfig
++++ b/arch/arm/configs/armadillo800eva_defconfig
+@@ -18,7 +18,7 @@ CONFIG_ARCH_SHMOBILE=y
+ CONFIG_ARCH_R8A7740=y
+ CONFIG_MACH_ARMADILLO800EVA=y
+ # CONFIG_SH_TIMER_TMU is not set
+-# CONFIG_ARM_THUMB is not set
++CONFIG_ARM_THUMB=y
+ CONFIG_CPU_BPREDICT_DISABLE=y
+ # CONFIG_CACHE_L2X0 is not set
+ CONFIG_ARM_ERRATA_430973=y
+@@ -36,6 +36,7 @@ CONFIG_ZBOOT_ROM_BSS=0x0
+ CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096"
+ CONFIG_CMDLINE_FORCE=y
+ CONFIG_KEXEC=y
++CONFIG_VFP=y
+ # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+ # CONFIG_SUSPEND is not set
+ CONFIG_NET=y
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0104-ARM-mach-shmobile-armadillo800eva-Fix-GPIO-buttons-d.patch b/patches.armadillo800/0104-ARM-mach-shmobile-armadillo800eva-Fix-GPIO-buttons-d.patch
new file mode 100644
index 0000000000000..8184e72a98c73
--- /dev/null
+++ b/patches.armadillo800/0104-ARM-mach-shmobile-armadillo800eva-Fix-GPIO-buttons-d.patch
@@ -0,0 +1,40 @@
+From fdfc19ff5c71ac77f6cc8781402dd92452e4e053 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Tue, 24 Jul 2012 15:26:08 +0200
+Subject: ARM: mach-shmobile: armadillo800eva: Fix GPIO buttons descriptions
+
+The GPIO buttons are named SW3, SW4, SW5 and SW6 on the board
+silkscreen. Update the buttons descriptions accordingly.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+(cherry picked from commit 2d85b9494d10501f20ebf043f8d599e45736d78f)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index cf10f92..a002504 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -523,10 +523,10 @@ static struct platform_device hdmi_lcdc_device = {
+ #define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 }
+
+ static struct gpio_keys_button gpio_buttons[] = {
+- GPIO_KEY(KEY_POWER, GPIO_PORT99, "SW1"),
+- GPIO_KEY(KEY_BACK, GPIO_PORT100, "SW2"),
+- GPIO_KEY(KEY_MENU, GPIO_PORT97, "SW3"),
+- GPIO_KEY(KEY_HOME, GPIO_PORT98, "SW4"),
++ GPIO_KEY(KEY_POWER, GPIO_PORT99, "SW3"),
++ GPIO_KEY(KEY_BACK, GPIO_PORT100, "SW4"),
++ GPIO_KEY(KEY_MENU, GPIO_PORT97, "SW5"),
++ GPIO_KEY(KEY_HOME, GPIO_PORT98, "SW6"),
+ };
+
+ static struct gpio_keys_platform_data gpio_key_info = {
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0105-ARM-mach-shmobile-armadillo800eva-Enable-power-butto.patch b/patches.armadillo800/0105-ARM-mach-shmobile-armadillo800eva-Enable-power-butto.patch
new file mode 100644
index 0000000000000..3e9c99ce7b035
--- /dev/null
+++ b/patches.armadillo800/0105-ARM-mach-shmobile-armadillo800eva-Enable-power-butto.patch
@@ -0,0 +1,37 @@
+From 10ee1d677c8fa257269f2c5e062525035b866a61 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Tue, 24 Jul 2012 15:26:09 +0200
+Subject: ARM: mach-shmobile: armadillo800eva: Enable power button as wakeup
+ source
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+(cherry picked from commit 5c1d2d16772e2d7d4e2e8da99a92d6f50b9102f0)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index a002504..65cb793 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -520,10 +520,11 @@ static struct platform_device hdmi_lcdc_device = {
+ };
+
+ /* GPIO KEY */
+-#define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 }
++#define GPIO_KEY(c, g, d, ...) \
++ { .code = c, .gpio = g, .desc = d, .active_low = 1, __VA_ARGS__ }
+
+ static struct gpio_keys_button gpio_buttons[] = {
+- GPIO_KEY(KEY_POWER, GPIO_PORT99, "SW3"),
++ GPIO_KEY(KEY_POWER, GPIO_PORT99, "SW3", .wakeup = 1),
+ GPIO_KEY(KEY_BACK, GPIO_PORT100, "SW4"),
+ GPIO_KEY(KEY_MENU, GPIO_PORT97, "SW5"),
+ GPIO_KEY(KEY_HOME, GPIO_PORT98, "SW6"),
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0106-ARM-shmobile-armadillo800eva-fixup-sound-card-detect.patch b/patches.armadillo800/0106-ARM-shmobile-armadillo800eva-fixup-sound-card-detect.patch
new file mode 100644
index 0000000000000..58ffe1c24a30e
--- /dev/null
+++ b/patches.armadillo800/0106-ARM-shmobile-armadillo800eva-fixup-sound-card-detect.patch
@@ -0,0 +1,43 @@
+From 974462b8ff3fbb6468b94d52690a5707b2ccb955 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Wed, 8 Aug 2012 23:03:07 -0700
+Subject: ARM: shmobile: armadillo800eva: fixup: sound card detection order
+
+Since armadillo800eva has 2 sound cards,
+and had reversed deferred probe order issue,
+it was purposely registered in reverse order.
+
+But it was solved by
+1d29cfa57471a5e4b8a7c2a7433eeba170d3ad92
+(driver core: fixup reversed deferred probe order)
+
+armadillo800eva board is expecting that
+FSI-WM8978 is the 1st, and FSI-HDMI is the 2nd sound card.
+This patch fixes it up
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+(cherry picked from commit ee3c843d0fc21c68ced93b982b5731178a24df68)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index 65cb793..453a6e5 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -902,8 +902,8 @@ static struct platform_device *eva_devices[] __initdata = {
+ &camera_device,
+ &ceu0_device,
+ &fsi_device,
+- &fsi_hdmi_device,
+ &fsi_wm8978_device,
++ &fsi_hdmi_device,
+ };
+
+ static void __init eva_clock_init(void)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.armadillo800/0107-ARM-shmobile-armadillo800eva-enable-rw-rootfs-mount.patch b/patches.armadillo800/0107-ARM-shmobile-armadillo800eva-enable-rw-rootfs-mount.patch
new file mode 100644
index 0000000000000..b53acd69ee321
--- /dev/null
+++ b/patches.armadillo800/0107-ARM-shmobile-armadillo800eva-enable-rw-rootfs-mount.patch
@@ -0,0 +1,39 @@
+From 1b5f7629ee098b784f2b8e2ee49d03d90e01f811 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 2 Sep 2012 23:06:52 -0700
+Subject: ARM: shmobile: armadillo800eva: enable rw rootfs mount
+
+armadillo800eva default boot loader is "hermit",
+and it's tag->u.core.flags has flag when kernel boots.
+Because of this, ${LINUX}/arch/arm/kernel/setup.c :: parse_tag_core()
+didn't remove MS_RDONLY flag from root_mountflags.
+Thus, the rootfs is mounted as "readonly".
+This patch adds "rw" kernel parameter,
+and enable read/write mounts for rootfs
+
+Cc: Masahiro Nakai <nakai@atmark-techno.com>
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+(cherry picked from commit 28e515878f8896b33c325ff9767cb0237210fb4c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/configs/armadillo800eva_defconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/configs/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig
+index 7d87184..90610c7 100644
+--- a/arch/arm/configs/armadillo800eva_defconfig
++++ b/arch/arm/configs/armadillo800eva_defconfig
+@@ -33,7 +33,7 @@ CONFIG_AEABI=y
+ CONFIG_FORCE_MAX_ZONEORDER=13
+ CONFIG_ZBOOT_ROM_TEXT=0x0
+ CONFIG_ZBOOT_ROM_BSS=0x0
+-CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096"
++CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096 rw"
+ CONFIG_CMDLINE_FORCE=y
+ CONFIG_KEXEC=y
+ CONFIG_VFP=y
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0001-sh-clkfwk-Support-variable-size-accesses-for-MSTP-cl.patch b/patches.marzen/0001-sh-clkfwk-Support-variable-size-accesses-for-MSTP-cl.patch
new file mode 100644
index 0000000000000..f043fca8c27fa
--- /dev/null
+++ b/patches.marzen/0001-sh-clkfwk-Support-variable-size-accesses-for-MSTP-cl.patch
@@ -0,0 +1,154 @@
+From aa9210ec33e000900e3ad25d7b98c7897027b1f2 Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Wed, 11 Apr 2012 12:05:50 +0900
+Subject: sh: clkfwk: Support variable size accesses for MSTP clocks.
+
+The bulk of the MSTP users require 32-bit access, but this isn't the case
+for some of the SH-2A parts, so add in some basic infrastructure to let
+the CPU define its required access size in preparation.
+
+Requested-by: Phil Edworthy <phil.edworthy@renesas.com>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 4d6ddb08acc48368c5b7ac431f9d00db7227d2ed)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/sh/clk/cpg.c | 38 +++++++++++++++++++++++++++-----------
+ include/linux/sh_clk.h | 34 +++++++++++++++++++++++++++++++---
+ 2 files changed, 58 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
+index 91b6d52..6cbda48 100644
+--- a/drivers/sh/clk/cpg.c
++++ b/drivers/sh/clk/cpg.c
+@@ -2,6 +2,7 @@
+ * Helper routines for SuperH Clock Pulse Generator blocks (CPG).
+ *
+ * Copyright (C) 2010 Magnus Damm
++ * Copyright (C) 2010 - 2012 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+@@ -13,26 +14,41 @@
+ #include <linux/io.h>
+ #include <linux/sh_clk.h>
+
+-static int sh_clk_mstp32_enable(struct clk *clk)
++static int sh_clk_mstp_enable(struct clk *clk)
+ {
+- iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit),
+- clk->mapped_reg);
++ if (clk->flags & CLK_ENABLE_REG_8BIT)
++ iowrite8(ioread8(clk->mapped_reg) & ~(1 << clk->enable_bit),
++ clk->mapped_reg);
++ else if (clk->flags & CLK_ENABLE_REG_16BIT)
++ iowrite16(ioread16(clk->mapped_reg) & ~(1 << clk->enable_bit),
++ clk->mapped_reg);
++ else
++ iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit),
++ clk->mapped_reg);
++
+ return 0;
+ }
+
+-static void sh_clk_mstp32_disable(struct clk *clk)
++static void sh_clk_mstp_disable(struct clk *clk)
+ {
+- iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit),
+- clk->mapped_reg);
++ if (clk->flags & CLK_ENABLE_REG_8BIT)
++ iowrite8(ioread8(clk->mapped_reg) | (1 << clk->enable_bit),
++ clk->mapped_reg);
++ else if (clk->flags & CLK_ENABLE_REG_16BIT)
++ iowrite16(ioread16(clk->mapped_reg) | (1 << clk->enable_bit),
++ clk->mapped_reg);
++ else
++ iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit),
++ clk->mapped_reg);
+ }
+
+-static struct sh_clk_ops sh_clk_mstp32_clk_ops = {
+- .enable = sh_clk_mstp32_enable,
+- .disable = sh_clk_mstp32_disable,
++static struct sh_clk_ops sh_clk_mstp_clk_ops = {
++ .enable = sh_clk_mstp_enable,
++ .disable = sh_clk_mstp_disable,
+ .recalc = followparent_recalc,
+ };
+
+-int __init sh_clk_mstp32_register(struct clk *clks, int nr)
++int __init sh_clk_mstp_register(struct clk *clks, int nr)
+ {
+ struct clk *clkp;
+ int ret = 0;
+@@ -40,7 +56,7 @@ int __init sh_clk_mstp32_register(struct clk *clks, int nr)
+
+ for (k = 0; !ret && (k < nr); k++) {
+ clkp = clks + k;
+- clkp->ops = &sh_clk_mstp32_clk_ops;
++ clkp->ops = &sh_clk_mstp_clk_ops;
+ ret |= clk_register(clkp);
+ }
+
+diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h
+index 0a9d8f2..c513b73 100644
+--- a/include/linux/sh_clk.h
++++ b/include/linux/sh_clk.h
+@@ -59,7 +59,15 @@ struct clk {
+ unsigned int nr_freqs;
+ };
+
+-#define CLK_ENABLE_ON_INIT (1 << 0)
++#define CLK_ENABLE_ON_INIT BIT(0)
++
++#define CLK_ENABLE_REG_32BIT BIT(1) /* default access size */
++#define CLK_ENABLE_REG_16BIT BIT(2)
++#define CLK_ENABLE_REG_8BIT BIT(3)
++
++#define CLK_ENABLE_REG_MASK (CLK_ENABLE_REG_32BIT | \
++ CLK_ENABLE_REG_16BIT | \
++ CLK_ENABLE_REG_8BIT)
+
+ /* drivers/sh/clk.c */
+ unsigned long followparent_recalc(struct clk *);
+@@ -102,7 +110,7 @@ long clk_round_parent(struct clk *clk, unsigned long target,
+ unsigned long *best_freq, unsigned long *parent_freq,
+ unsigned int div_min, unsigned int div_max);
+
+-#define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags) \
++#define SH_CLK_MSTP(_parent, _enable_reg, _enable_bit, _flags) \
+ { \
+ .parent = _parent, \
+ .enable_reg = (void __iomem *)_enable_reg, \
+@@ -110,7 +118,27 @@ long clk_round_parent(struct clk *clk, unsigned long target,
+ .flags = _flags, \
+ }
+
+-int sh_clk_mstp32_register(struct clk *clks, int nr);
++#define SH_CLK_MSTP32(_p, _r, _b, _f) \
++ SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_32BIT)
++
++#define SH_CLK_MSTP16(_p, _r, _b, _f) \
++ SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_16BIT)
++
++#define SH_CLK_MSTP8(_p, _r, _b, _f) \
++ SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_8BIT)
++
++int sh_clk_mstp_register(struct clk *clks, int nr);
++
++/*
++ * MSTP registration never really cared about access size, despite the
++ * original enable/disable pairs assuming a 32-bit access. Clocks are
++ * responsible for defining their access sizes either directly or via the
++ * clock definition wrappers.
++ */
++static inline int __deprecated sh_clk_mstp32_register(struct clk *clks, int nr)
++{
++ return sh_clk_mstp_register(clks, nr);
++}
+
+ #define SH_CLK_DIV4(_parent, _reg, _shift, _div_bitmap, _flags) \
+ { \
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0002-sh-clkfwk-Support-variable-size-accesses-for-div4-di.patch b/patches.marzen/0002-sh-clkfwk-Support-variable-size-accesses-for-div4-di.patch
new file mode 100644
index 0000000000000..5d1fac6d005fe
--- /dev/null
+++ b/patches.marzen/0002-sh-clkfwk-Support-variable-size-accesses-for-div4-di.patch
@@ -0,0 +1,202 @@
+From 5a1639b2287a62e965e2355c68ef52da597b9a3c Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Thu, 12 Apr 2012 19:50:40 +0900
+Subject: sh: clkfwk: Support variable size accesses for div4/div6 clocks.
+
+This follows the MSTP clock change and implements variable access size
+support for the rest of the CPG clocks, too. Upcoming SH-2A support has
+need of this for 16-bit div4 clocks, while others will follow.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 104fa61a7dd83197160d5cafedc0e94ad9cd7fcc)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/sh/clk/cpg.c | 71 +++++++++++++++++++++++++++-------------------------
+ 1 file changed, 37 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
+index 6cbda48..f0d015d 100644
+--- a/drivers/sh/clk/cpg.c
++++ b/drivers/sh/clk/cpg.c
+@@ -14,32 +14,35 @@
+ #include <linux/io.h>
+ #include <linux/sh_clk.h>
+
+-static int sh_clk_mstp_enable(struct clk *clk)
++static unsigned int sh_clk_read(struct clk *clk)
+ {
+ if (clk->flags & CLK_ENABLE_REG_8BIT)
+- iowrite8(ioread8(clk->mapped_reg) & ~(1 << clk->enable_bit),
+- clk->mapped_reg);
++ return ioread8(clk->mapped_reg);
+ else if (clk->flags & CLK_ENABLE_REG_16BIT)
+- iowrite16(ioread16(clk->mapped_reg) & ~(1 << clk->enable_bit),
+- clk->mapped_reg);
+- else
+- iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit),
+- clk->mapped_reg);
++ return ioread16(clk->mapped_reg);
+
+- return 0;
++ return ioread32(clk->mapped_reg);
+ }
+
+-static void sh_clk_mstp_disable(struct clk *clk)
++static void sh_clk_write(int value, struct clk *clk)
+ {
+ if (clk->flags & CLK_ENABLE_REG_8BIT)
+- iowrite8(ioread8(clk->mapped_reg) | (1 << clk->enable_bit),
+- clk->mapped_reg);
++ iowrite8(value, clk->mapped_reg);
+ else if (clk->flags & CLK_ENABLE_REG_16BIT)
+- iowrite16(ioread16(clk->mapped_reg) | (1 << clk->enable_bit),
+- clk->mapped_reg);
++ iowrite16(value, clk->mapped_reg);
+ else
+- iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit),
+- clk->mapped_reg);
++ iowrite32(value, clk->mapped_reg);
++}
++
++static int sh_clk_mstp_enable(struct clk *clk)
++{
++ sh_clk_write(sh_clk_read(clk) & ~(1 << clk->enable_bit), clk);
++ return 0;
++}
++
++static void sh_clk_mstp_disable(struct clk *clk)
++{
++ sh_clk_write(sh_clk_read(clk) | (1 << clk->enable_bit), clk);
+ }
+
+ static struct sh_clk_ops sh_clk_mstp_clk_ops = {
+@@ -88,7 +91,7 @@ static unsigned long sh_clk_div6_recalc(struct clk *clk)
+ clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
+ table, NULL);
+
+- idx = ioread32(clk->mapped_reg) & 0x003f;
++ idx = sh_clk_read(clk) & 0x003f;
+
+ return clk->freq_table[idx].frequency;
+ }
+@@ -114,10 +117,10 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent)
+ if (ret < 0)
+ return ret;
+
+- value = ioread32(clk->mapped_reg) &
++ value = sh_clk_read(clk) &
+ ~(((1 << clk->src_width) - 1) << clk->src_shift);
+
+- iowrite32(value | (i << clk->src_shift), clk->mapped_reg);
++ sh_clk_write(value | (i << clk->src_shift), clk);
+
+ /* Rebuild the frequency table */
+ clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
+@@ -135,10 +138,10 @@ static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate)
+ if (idx < 0)
+ return idx;
+
+- value = ioread32(clk->mapped_reg);
++ value = sh_clk_read(clk);
+ value &= ~0x3f;
+ value |= idx;
+- iowrite32(value, clk->mapped_reg);
++ sh_clk_write(value, clk);
+ return 0;
+ }
+
+@@ -149,9 +152,9 @@ static int sh_clk_div6_enable(struct clk *clk)
+
+ ret = sh_clk_div6_set_rate(clk, clk->rate);
+ if (ret == 0) {
+- value = ioread32(clk->mapped_reg);
++ value = sh_clk_read(clk);
+ value &= ~0x100; /* clear stop bit to enable clock */
+- iowrite32(value, clk->mapped_reg);
++ sh_clk_write(value, clk);
+ }
+ return ret;
+ }
+@@ -160,10 +163,10 @@ static void sh_clk_div6_disable(struct clk *clk)
+ {
+ unsigned long value;
+
+- value = ioread32(clk->mapped_reg);
++ value = sh_clk_read(clk);
+ value |= 0x100; /* stop clock */
+ value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */
+- iowrite32(value, clk->mapped_reg);
++ sh_clk_write(value, clk);
+ }
+
+ static struct sh_clk_ops sh_clk_div6_clk_ops = {
+@@ -198,7 +201,7 @@ static int __init sh_clk_init_parent(struct clk *clk)
+ return -EINVAL;
+ }
+
+- val = (ioread32(clk->mapped_reg) >> clk->src_shift);
++ val = (sh_clk_read(clk) >> clk->src_shift);
+ val &= (1 << clk->src_width) - 1;
+
+ if (val >= clk->parent_num) {
+@@ -268,7 +271,7 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk)
+ clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
+ table, &clk->arch_flags);
+
+- idx = (ioread32(clk->mapped_reg) >> clk->enable_bit) & 0x000f;
++ idx = (sh_clk_read(clk) >> clk->enable_bit) & 0x000f;
+
+ return clk->freq_table[idx].frequency;
+ }
+@@ -286,15 +289,15 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
+ */
+
+ if (parent->flags & CLK_ENABLE_ON_INIT)
+- value = ioread32(clk->mapped_reg) & ~(1 << 7);
++ value = sh_clk_read(clk) & ~(1 << 7);
+ else
+- value = ioread32(clk->mapped_reg) | (1 << 7);
++ value = sh_clk_read(clk) | (1 << 7);
+
+ ret = clk_reparent(clk, parent);
+ if (ret < 0)
+ return ret;
+
+- iowrite32(value, clk->mapped_reg);
++ sh_clk_write(value, clk);
+
+ /* Rebiuld the frequency table */
+ clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
+@@ -311,10 +314,10 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
+ if (idx < 0)
+ return idx;
+
+- value = ioread32(clk->mapped_reg);
++ value = sh_clk_read(clk);
+ value &= ~(0xf << clk->enable_bit);
+ value |= (idx << clk->enable_bit);
+- iowrite32(value, clk->mapped_reg);
++ sh_clk_write(value, clk);
+
+ if (d4t->kick)
+ d4t->kick(clk);
+@@ -324,13 +327,13 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
+
+ static int sh_clk_div4_enable(struct clk *clk)
+ {
+- iowrite32(ioread32(clk->mapped_reg) & ~(1 << 8), clk->mapped_reg);
++ sh_clk_write(sh_clk_read(clk) & ~(1 << 8), clk);
+ return 0;
+ }
+
+ static void sh_clk_div4_disable(struct clk *clk)
+ {
+- iowrite32(ioread32(clk->mapped_reg) | (1 << 8), clk->mapped_reg);
++ sh_clk_write(sh_clk_read(clk) | (1 << 8), clk);
+ }
+
+ static struct sh_clk_ops sh_clk_div4_clk_ops = {
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0003-sh-clkfwk-Move-to-common-clk_div_table-accessors-for.patch b/patches.marzen/0003-sh-clkfwk-Move-to-common-clk_div_table-accessors-for.patch
new file mode 100644
index 0000000000000..c7a6b9b0b9344
--- /dev/null
+++ b/patches.marzen/0003-sh-clkfwk-Move-to-common-clk_div_table-accessors-for.patch
@@ -0,0 +1,169 @@
+From cd33eef0c195fa40494a8115aa1202bdaed860a0 Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Fri, 25 May 2012 14:59:26 +0900
+Subject: sh: clkfwk: Move to common clk_div_table accessors for div4/div6.
+
+This plugs in a generic clk_div_table, based on the div4 version. div6 is
+then adopted to use it for encapsulating its div table, which permits us
+to start div6/4 unification, as well as preparation for other div types.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit a60977a51333a8108f0574aa26094d66b7fedf34)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/sh/clk/cpg.c | 46 +++++++++++++++++++++++++++++++++++-----------
+ include/linux/sh_clk.h | 5 +++--
+ 2 files changed, 38 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
+index f0d015d..9dea329 100644
+--- a/drivers/sh/clk/cpg.c
++++ b/drivers/sh/clk/cpg.c
+@@ -71,6 +71,22 @@ static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate)
+ return clk_rate_table_round(clk, clk->freq_table, rate);
+ }
+
++/*
++ * Div/mult table lookup helpers
++ */
++static inline struct clk_div_table *clk_to_div_table(struct clk *clk)
++{
++ return clk->priv;
++}
++
++static inline struct clk_div_mult_table *clk_to_div_mult_table(struct clk *clk)
++{
++ return clk_to_div_table(clk)->div_mult_table;
++}
++
++/*
++ * div6 support
++ */
+ static int sh_clk_div6_divisors[64] = {
+ 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,
+@@ -78,14 +94,18 @@ static int sh_clk_div6_divisors[64] = {
+ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
+ };
+
+-static struct clk_div_mult_table sh_clk_div6_table = {
++static struct clk_div_mult_table div6_div_mult_table = {
+ .divisors = sh_clk_div6_divisors,
+ .nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors),
+ };
+
++static struct clk_div_table sh_clk_div6_table = {
++ .div_mult_table = &div6_div_mult_table,
++};
++
+ static unsigned long sh_clk_div6_recalc(struct clk *clk)
+ {
+- struct clk_div_mult_table *table = &sh_clk_div6_table;
++ struct clk_div_mult_table *table = clk_to_div_mult_table(clk);
+ unsigned int idx;
+
+ clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
+@@ -98,7 +118,7 @@ static unsigned long sh_clk_div6_recalc(struct clk *clk)
+
+ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent)
+ {
+- struct clk_div_mult_table *table = &sh_clk_div6_table;
++ struct clk_div_mult_table *table = clk_to_div_mult_table(clk);
+ u32 value;
+ int ret, i;
+
+@@ -223,7 +243,8 @@ static int __init sh_clk_div6_register_ops(struct clk *clks, int nr,
+ {
+ struct clk *clkp;
+ void *freq_table;
+- int nr_divs = sh_clk_div6_table.nr_divisors;
++ struct clk_div_table *table = &sh_clk_div6_table;
++ int nr_divs = table->div_mult_table->nr_divisors;
+ int freq_table_size = sizeof(struct cpufreq_frequency_table);
+ int ret = 0;
+ int k;
+@@ -239,6 +260,7 @@ static int __init sh_clk_div6_register_ops(struct clk *clks, int nr,
+ clkp = clks + k;
+
+ clkp->ops = ops;
++ clkp->priv = table;
+ clkp->freq_table = freq_table + (k * freq_table_size);
+ clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
+ ret = clk_register(clkp);
+@@ -262,10 +284,12 @@ int __init sh_clk_div6_reparent_register(struct clk *clks, int nr)
+ &sh_clk_div6_reparent_clk_ops);
+ }
+
++/*
++ * div4 support
++ */
+ static unsigned long sh_clk_div4_recalc(struct clk *clk)
+ {
+- struct clk_div4_table *d4t = clk->priv;
+- struct clk_div_mult_table *table = d4t->div_mult_table;
++ struct clk_div_mult_table *table = clk_to_div_mult_table(clk);
+ unsigned int idx;
+
+ clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
+@@ -278,8 +302,7 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk)
+
+ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
+ {
+- struct clk_div4_table *d4t = clk->priv;
+- struct clk_div_mult_table *table = d4t->div_mult_table;
++ struct clk_div_mult_table *table = clk_to_div_mult_table(clk);
+ u32 value;
+ int ret;
+
+@@ -308,7 +331,7 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
+
+ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
+ {
+- struct clk_div4_table *d4t = clk->priv;
++ struct clk_div_table *dt = clk_to_div_table(clk);
+ unsigned long value;
+ int idx = clk_rate_table_find(clk, clk->freq_table, rate);
+ if (idx < 0)
+@@ -319,8 +342,9 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
+ value |= (idx << clk->enable_bit);
+ sh_clk_write(value, clk);
+
+- if (d4t->kick)
+- d4t->kick(clk);
++ /* XXX: Should use a post-change notifier */
++ if (dt->kick)
++ dt->kick(clk);
+
+ return 0;
+ }
+diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h
+index c513b73..706b803 100644
+--- a/include/linux/sh_clk.h
++++ b/include/linux/sh_clk.h
+@@ -18,7 +18,6 @@ struct clk_mapping {
+ struct kref ref;
+ };
+
+-
+ struct sh_clk_ops {
+ #ifdef CONFIG_SH_CLK_CPG_LEGACY
+ void (*init)(struct clk *clk);
+@@ -149,11 +148,13 @@ static inline int __deprecated sh_clk_mstp32_register(struct clk *clks, int nr)
+ .flags = _flags, \
+ }
+
+-struct clk_div4_table {
++struct clk_div_table {
+ struct clk_div_mult_table *div_mult_table;
+ void (*kick)(struct clk *clk);
+ };
+
++#define clk_div4_table clk_div_table
++
+ int sh_clk_div4_register(struct clk *clks, int nr,
+ struct clk_div4_table *table);
+ int sh_clk_div4_enable_register(struct clk *clks, int nr,
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0004-sh-clkfwk-Introduce-a-div_mask-for-variable-div-type.patch b/patches.marzen/0004-sh-clkfwk-Introduce-a-div_mask-for-variable-div-type.patch
new file mode 100644
index 0000000000000..f8629fb9d0541
--- /dev/null
+++ b/patches.marzen/0004-sh-clkfwk-Introduce-a-div_mask-for-variable-div-type.patch
@@ -0,0 +1,117 @@
+From a0643bdb2770016b5930f9cbe5dee7a36e6951fc Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Fri, 25 May 2012 15:21:43 +0900
+Subject: sh: clkfwk: Introduce a div_mask for variable div types.
+
+This plugs in a div_mask for the clock and sets it up for the existing
+div6/4 cases. This will make it possible to support other div types, as
+well as share more div6/4 infrastructure.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 1111cc1e8080b5ff46f5b945acb2f99d6176b2d1)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/sh/clk/cpg.c | 10 +++++-----
+ include/linux/sh_clk.h | 8 ++++++++
+ 2 files changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
+index 9dea329..9386bd2 100644
+--- a/drivers/sh/clk/cpg.c
++++ b/drivers/sh/clk/cpg.c
+@@ -111,7 +111,7 @@ static unsigned long sh_clk_div6_recalc(struct clk *clk)
+ clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
+ table, NULL);
+
+- idx = sh_clk_read(clk) & 0x003f;
++ idx = sh_clk_read(clk) & clk->div_mask;
+
+ return clk->freq_table[idx].frequency;
+ }
+@@ -159,7 +159,7 @@ static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate)
+ return idx;
+
+ value = sh_clk_read(clk);
+- value &= ~0x3f;
++ value &= ~clk->div_mask;
+ value |= idx;
+ sh_clk_write(value, clk);
+ return 0;
+@@ -185,7 +185,7 @@ static void sh_clk_div6_disable(struct clk *clk)
+
+ value = sh_clk_read(clk);
+ value |= 0x100; /* stop clock */
+- value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */
++ value |= clk->div_mask; /* VDIV bits must be non-zero, overwrite divider */
+ sh_clk_write(value, clk);
+ }
+
+@@ -295,7 +295,7 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk)
+ clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
+ table, &clk->arch_flags);
+
+- idx = (sh_clk_read(clk) >> clk->enable_bit) & 0x000f;
++ idx = (sh_clk_read(clk) >> clk->enable_bit) & clk->div_mask;
+
+ return clk->freq_table[idx].frequency;
+ }
+@@ -338,7 +338,7 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
+ return idx;
+
+ value = sh_clk_read(clk);
+- value &= ~(0xf << clk->enable_bit);
++ value &= ~(clk->div_mask << clk->enable_bit);
+ value |= (idx << clk->enable_bit);
+ sh_clk_write(value, clk);
+
+diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h
+index 706b803..d540b81 100644
+--- a/include/linux/sh_clk.h
++++ b/include/linux/sh_clk.h
+@@ -30,6 +30,10 @@ struct sh_clk_ops {
+ long (*round_rate)(struct clk *clk, unsigned long rate);
+ };
+
++#define SH_CLK_DIV_MSK(div) ((1 << (div)) - 1)
++#define SH_CLK_DIV4_MSK SH_CLK_DIV_MSK(4)
++#define SH_CLK_DIV6_MSK SH_CLK_DIV_MSK(6)
++
+ struct clk {
+ struct list_head node;
+ struct clk *parent;
+@@ -51,6 +55,7 @@ struct clk {
+ unsigned int enable_bit;
+ void __iomem *mapped_reg;
+
++ unsigned int div_mask;
+ unsigned long arch_flags;
+ void *priv;
+ struct clk_mapping *mapping;
+@@ -145,6 +150,7 @@ static inline int __deprecated sh_clk_mstp32_register(struct clk *clks, int nr)
+ .enable_reg = (void __iomem *)_reg, \
+ .enable_bit = _shift, \
+ .arch_flags = _div_bitmap, \
++ .div_mask = SH_CLK_DIV4_MSK, \
+ .flags = _flags, \
+ }
+
+@@ -167,6 +173,7 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr,
+ { \
+ .enable_reg = (void __iomem *)_reg, \
+ .flags = _flags, \
++ .div_mask = SH_CLK_DIV6_MSK, \
+ .parent_table = _parents, \
+ .parent_num = _num_parents, \
+ .src_shift = _src_shift, \
+@@ -177,6 +184,7 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr,
+ { \
+ .parent = _parent, \
+ .enable_reg = (void __iomem *)_reg, \
++ .div_mask = SH_CLK_DIV6_MSK, \
+ .flags = _flags, \
+ }
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0005-sh-clkfwk-Use-shared-sh_clk_div_recalc.patch b/patches.marzen/0005-sh-clkfwk-Use-shared-sh_clk_div_recalc.patch
new file mode 100644
index 0000000000000..beb1b9ba8e5ca
--- /dev/null
+++ b/patches.marzen/0005-sh-clkfwk-Use-shared-sh_clk_div_recalc.patch
@@ -0,0 +1,167 @@
+From 4a3185214cc3715feff6d802b0df478e7e61901e Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Fri, 25 May 2012 15:26:01 +0900
+Subject: sh: clkfwk: Use shared sh_clk_div_recalc().
+
+This generalizes the div4 recalc routine for use by div6 and others, then
+makes it the default.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 75f5f8a56e0fdf6d32b3ae9c44c10bc0acd3857c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/sh/clk/cpg.c | 62 +++++++++++++++++++++-----------------------------
+ include/linux/sh_clk.h | 2 ++
+ 2 files changed, 28 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
+index 9386bd2..84aeeb8 100644
+--- a/drivers/sh/clk/cpg.c
++++ b/drivers/sh/clk/cpg.c
+@@ -66,11 +66,6 @@ int __init sh_clk_mstp_register(struct clk *clks, int nr)
+ return ret;
+ }
+
+-static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate)
+-{
+- return clk_rate_table_round(clk, clk->freq_table, rate);
+-}
+-
+ /*
+ * Div/mult table lookup helpers
+ */
+@@ -85,6 +80,27 @@ static inline struct clk_div_mult_table *clk_to_div_mult_table(struct clk *clk)
+ }
+
+ /*
++ * Common div ops
++ */
++static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate)
++{
++ return clk_rate_table_round(clk, clk->freq_table, rate);
++}
++
++static unsigned long sh_clk_div_recalc(struct clk *clk)
++{
++ struct clk_div_mult_table *table = clk_to_div_mult_table(clk);
++ unsigned int idx;
++
++ clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
++ table, clk->arch_flags ? &clk->arch_flags : NULL);
++
++ idx = (sh_clk_read(clk) >> clk->enable_bit) & clk->div_mask;
++
++ return clk->freq_table[idx].frequency;
++}
++
++/*
+ * div6 support
+ */
+ static int sh_clk_div6_divisors[64] = {
+@@ -103,19 +119,6 @@ static struct clk_div_table sh_clk_div6_table = {
+ .div_mult_table = &div6_div_mult_table,
+ };
+
+-static unsigned long sh_clk_div6_recalc(struct clk *clk)
+-{
+- struct clk_div_mult_table *table = clk_to_div_mult_table(clk);
+- unsigned int idx;
+-
+- clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
+- table, NULL);
+-
+- idx = sh_clk_read(clk) & clk->div_mask;
+-
+- return clk->freq_table[idx].frequency;
+-}
+-
+ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent)
+ {
+ struct clk_div_mult_table *table = clk_to_div_mult_table(clk);
+@@ -190,7 +193,7 @@ static void sh_clk_div6_disable(struct clk *clk)
+ }
+
+ static struct sh_clk_ops sh_clk_div6_clk_ops = {
+- .recalc = sh_clk_div6_recalc,
++ .recalc = sh_clk_div_recalc,
+ .round_rate = sh_clk_div_round_rate,
+ .set_rate = sh_clk_div6_set_rate,
+ .enable = sh_clk_div6_enable,
+@@ -198,7 +201,7 @@ static struct sh_clk_ops sh_clk_div6_clk_ops = {
+ };
+
+ static struct sh_clk_ops sh_clk_div6_reparent_clk_ops = {
+- .recalc = sh_clk_div6_recalc,
++ .recalc = sh_clk_div_recalc,
+ .round_rate = sh_clk_div_round_rate,
+ .set_rate = sh_clk_div6_set_rate,
+ .enable = sh_clk_div6_enable,
+@@ -287,19 +290,6 @@ int __init sh_clk_div6_reparent_register(struct clk *clks, int nr)
+ /*
+ * div4 support
+ */
+-static unsigned long sh_clk_div4_recalc(struct clk *clk)
+-{
+- struct clk_div_mult_table *table = clk_to_div_mult_table(clk);
+- unsigned int idx;
+-
+- clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
+- table, &clk->arch_flags);
+-
+- idx = (sh_clk_read(clk) >> clk->enable_bit) & clk->div_mask;
+-
+- return clk->freq_table[idx].frequency;
+-}
+-
+ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
+ {
+ struct clk_div_mult_table *table = clk_to_div_mult_table(clk);
+@@ -361,13 +351,13 @@ static void sh_clk_div4_disable(struct clk *clk)
+ }
+
+ static struct sh_clk_ops sh_clk_div4_clk_ops = {
+- .recalc = sh_clk_div4_recalc,
++ .recalc = sh_clk_div_recalc,
+ .set_rate = sh_clk_div4_set_rate,
+ .round_rate = sh_clk_div_round_rate,
+ };
+
+ static struct sh_clk_ops sh_clk_div4_enable_clk_ops = {
+- .recalc = sh_clk_div4_recalc,
++ .recalc = sh_clk_div_recalc,
+ .set_rate = sh_clk_div4_set_rate,
+ .round_rate = sh_clk_div_round_rate,
+ .enable = sh_clk_div4_enable,
+@@ -375,7 +365,7 @@ static struct sh_clk_ops sh_clk_div4_enable_clk_ops = {
+ };
+
+ static struct sh_clk_ops sh_clk_div4_reparent_clk_ops = {
+- .recalc = sh_clk_div4_recalc,
++ .recalc = sh_clk_div_recalc,
+ .set_rate = sh_clk_div4_set_rate,
+ .round_rate = sh_clk_div_round_rate,
+ .enable = sh_clk_div4_enable,
+diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h
+index d540b81..35a04f1 100644
+--- a/include/linux/sh_clk.h
++++ b/include/linux/sh_clk.h
+@@ -172,6 +172,7 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr,
+ _num_parents, _src_shift, _src_width) \
+ { \
+ .enable_reg = (void __iomem *)_reg, \
++ .enable_bit = 0, /* unused */ \
+ .flags = _flags, \
+ .div_mask = SH_CLK_DIV6_MSK, \
+ .parent_table = _parents, \
+@@ -184,6 +185,7 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr,
+ { \
+ .parent = _parent, \
+ .enable_reg = (void __iomem *)_reg, \
++ .enable_bit = 0, /* unused */ \
+ .div_mask = SH_CLK_DIV6_MSK, \
+ .flags = _flags, \
+ }
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0006-sh-clkfwk-Use-shared-sh_clk_div_set_rate.patch b/patches.marzen/0006-sh-clkfwk-Use-shared-sh_clk_div_set_rate.patch
new file mode 100644
index 0000000000000..49ad18a75d81f
--- /dev/null
+++ b/patches.marzen/0006-sh-clkfwk-Use-shared-sh_clk_div_set_rate.patch
@@ -0,0 +1,151 @@
+From df94ddc15bc18c4fd96707fce2b3983e6f013f83 Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Fri, 25 May 2012 15:52:10 +0900
+Subject: sh: clkfwk: Use shared sh_clk_div_set_rate()
+
+Follows the sh_clk_div_recalc() change.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 0fa22168e00106797f28b2655aaefd0d16a6e67b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/sh/clk/cpg.c | 70 +++++++++++++++++++++-------------------------------
+ 1 file changed, 28 insertions(+), 42 deletions(-)
+
+diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
+index 84aeeb8..29ee5f7 100644
+--- a/drivers/sh/clk/cpg.c
++++ b/drivers/sh/clk/cpg.c
+@@ -100,6 +100,28 @@ static unsigned long sh_clk_div_recalc(struct clk *clk)
+ return clk->freq_table[idx].frequency;
+ }
+
++static int sh_clk_div_set_rate(struct clk *clk, unsigned long rate)
++{
++ struct clk_div_table *dt = clk_to_div_table(clk);
++ unsigned long value;
++ int idx;
++
++ idx = clk_rate_table_find(clk, clk->freq_table, rate);
++ if (idx < 0)
++ return idx;
++
++ value = sh_clk_read(clk);
++ value &= ~(clk->div_mask << clk->enable_bit);
++ value |= (idx << clk->enable_bit);
++ sh_clk_write(value, clk);
++
++ /* XXX: Should use a post-change notifier */
++ if (dt->kick)
++ dt->kick(clk);
++
++ return 0;
++}
++
+ /*
+ * div6 support
+ */
+@@ -152,28 +174,12 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent)
+ return 0;
+ }
+
+-static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate)
+-{
+- unsigned long value;
+- int idx;
+-
+- idx = clk_rate_table_find(clk, clk->freq_table, rate);
+- if (idx < 0)
+- return idx;
+-
+- value = sh_clk_read(clk);
+- value &= ~clk->div_mask;
+- value |= idx;
+- sh_clk_write(value, clk);
+- return 0;
+-}
+-
+ static int sh_clk_div6_enable(struct clk *clk)
+ {
+ unsigned long value;
+ int ret;
+
+- ret = sh_clk_div6_set_rate(clk, clk->rate);
++ ret = sh_clk_div_set_rate(clk, clk->rate);
+ if (ret == 0) {
+ value = sh_clk_read(clk);
+ value &= ~0x100; /* clear stop bit to enable clock */
+@@ -195,7 +201,7 @@ static void sh_clk_div6_disable(struct clk *clk)
+ static struct sh_clk_ops sh_clk_div6_clk_ops = {
+ .recalc = sh_clk_div_recalc,
+ .round_rate = sh_clk_div_round_rate,
+- .set_rate = sh_clk_div6_set_rate,
++ .set_rate = sh_clk_div_set_rate,
+ .enable = sh_clk_div6_enable,
+ .disable = sh_clk_div6_disable,
+ };
+@@ -203,7 +209,7 @@ static struct sh_clk_ops sh_clk_div6_clk_ops = {
+ static struct sh_clk_ops sh_clk_div6_reparent_clk_ops = {
+ .recalc = sh_clk_div_recalc,
+ .round_rate = sh_clk_div_round_rate,
+- .set_rate = sh_clk_div6_set_rate,
++ .set_rate = sh_clk_div_set_rate,
+ .enable = sh_clk_div6_enable,
+ .disable = sh_clk_div6_disable,
+ .set_parent = sh_clk_div6_set_parent,
+@@ -319,26 +325,6 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
+ return 0;
+ }
+
+-static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
+-{
+- struct clk_div_table *dt = clk_to_div_table(clk);
+- unsigned long value;
+- int idx = clk_rate_table_find(clk, clk->freq_table, rate);
+- if (idx < 0)
+- return idx;
+-
+- value = sh_clk_read(clk);
+- value &= ~(clk->div_mask << clk->enable_bit);
+- value |= (idx << clk->enable_bit);
+- sh_clk_write(value, clk);
+-
+- /* XXX: Should use a post-change notifier */
+- if (dt->kick)
+- dt->kick(clk);
+-
+- return 0;
+-}
+-
+ static int sh_clk_div4_enable(struct clk *clk)
+ {
+ sh_clk_write(sh_clk_read(clk) & ~(1 << 8), clk);
+@@ -352,13 +338,13 @@ static void sh_clk_div4_disable(struct clk *clk)
+
+ static struct sh_clk_ops sh_clk_div4_clk_ops = {
+ .recalc = sh_clk_div_recalc,
+- .set_rate = sh_clk_div4_set_rate,
++ .set_rate = sh_clk_div_set_rate,
+ .round_rate = sh_clk_div_round_rate,
+ };
+
+ static struct sh_clk_ops sh_clk_div4_enable_clk_ops = {
+ .recalc = sh_clk_div_recalc,
+- .set_rate = sh_clk_div4_set_rate,
++ .set_rate = sh_clk_div_set_rate,
+ .round_rate = sh_clk_div_round_rate,
+ .enable = sh_clk_div4_enable,
+ .disable = sh_clk_div4_disable,
+@@ -366,7 +352,7 @@ static struct sh_clk_ops sh_clk_div4_enable_clk_ops = {
+
+ static struct sh_clk_ops sh_clk_div4_reparent_clk_ops = {
+ .recalc = sh_clk_div_recalc,
+- .set_rate = sh_clk_div4_set_rate,
++ .set_rate = sh_clk_div_set_rate,
+ .round_rate = sh_clk_div_round_rate,
+ .enable = sh_clk_div4_enable,
+ .disable = sh_clk_div4_disable,
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0007-sh-clkfwk-Use-shared-sh_clk_div_enable-disable.patch b/patches.marzen/0007-sh-clkfwk-Use-shared-sh_clk_div_enable-disable.patch
new file mode 100644
index 0000000000000..420a1b44271eb
--- /dev/null
+++ b/patches.marzen/0007-sh-clkfwk-Use-shared-sh_clk_div_enable-disable.patch
@@ -0,0 +1,186 @@
+From c4dd62f54d65dfd226383c7c2aab74d9b33e71f5 Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Fri, 25 May 2012 16:34:48 +0900
+Subject: sh: clkfwk: Use shared sh_clk_div_enable/disable().
+
+This introduces a new flag for clocks that need to have their divisor
+ratio set back to their initial mask at disable time to prevent
+interactivity problems with the clock stop bit (presently div6 only).
+With this in place it's possible to handle the corner case on top of the
+div4 op without any particular need for leaving things split out.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 764f4e4e33d18cde4dcaf8a0d860b749c6d6d08b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/sh/clk/cpg.c | 77 ++++++++++++++++++++++----------------------------
+ include/linux/sh_clk.h | 6 ++--
+ 2 files changed, 38 insertions(+), 45 deletions(-)
+
+diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
+index 29ee5f7..06537f2 100644
+--- a/drivers/sh/clk/cpg.c
++++ b/drivers/sh/clk/cpg.c
+@@ -14,6 +14,8 @@
+ #include <linux/io.h>
+ #include <linux/sh_clk.h>
+
++#define CPG_CKSTP_BIT BIT(8)
++
+ static unsigned int sh_clk_read(struct clk *clk)
+ {
+ if (clk->flags & CLK_ENABLE_REG_8BIT)
+@@ -122,6 +124,30 @@ static int sh_clk_div_set_rate(struct clk *clk, unsigned long rate)
+ return 0;
+ }
+
++static int sh_clk_div_enable(struct clk *clk)
++{
++ sh_clk_write(sh_clk_read(clk) & ~CPG_CKSTP_BIT, clk);
++ return 0;
++}
++
++static void sh_clk_div_disable(struct clk *clk)
++{
++ unsigned int val;
++
++ val = sh_clk_read(clk);
++ val |= CPG_CKSTP_BIT;
++
++ /*
++ * div6 clocks require the divisor field to be non-zero or the
++ * above CKSTP toggle silently fails. Ensure that the divisor
++ * array is reset to its initial state on disable.
++ */
++ if (clk->flags & CLK_MASK_DIV_ON_DISABLE)
++ val |= clk->div_mask;
++
++ sh_clk_write(val, clk);
++}
++
+ /*
+ * div6 support
+ */
+@@ -174,44 +200,20 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent)
+ return 0;
+ }
+
+-static int sh_clk_div6_enable(struct clk *clk)
+-{
+- unsigned long value;
+- int ret;
+-
+- ret = sh_clk_div_set_rate(clk, clk->rate);
+- if (ret == 0) {
+- value = sh_clk_read(clk);
+- value &= ~0x100; /* clear stop bit to enable clock */
+- sh_clk_write(value, clk);
+- }
+- return ret;
+-}
+-
+-static void sh_clk_div6_disable(struct clk *clk)
+-{
+- unsigned long value;
+-
+- value = sh_clk_read(clk);
+- value |= 0x100; /* stop clock */
+- value |= clk->div_mask; /* VDIV bits must be non-zero, overwrite divider */
+- sh_clk_write(value, clk);
+-}
+-
+ static struct sh_clk_ops sh_clk_div6_clk_ops = {
+ .recalc = sh_clk_div_recalc,
+ .round_rate = sh_clk_div_round_rate,
+ .set_rate = sh_clk_div_set_rate,
+- .enable = sh_clk_div6_enable,
+- .disable = sh_clk_div6_disable,
++ .enable = sh_clk_div_enable,
++ .disable = sh_clk_div_disable,
+ };
+
+ static struct sh_clk_ops sh_clk_div6_reparent_clk_ops = {
+ .recalc = sh_clk_div_recalc,
+ .round_rate = sh_clk_div_round_rate,
+ .set_rate = sh_clk_div_set_rate,
+- .enable = sh_clk_div6_enable,
+- .disable = sh_clk_div6_disable,
++ .enable = sh_clk_div_enable,
++ .disable = sh_clk_div_disable,
+ .set_parent = sh_clk_div6_set_parent,
+ };
+
+@@ -325,17 +327,6 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
+ return 0;
+ }
+
+-static int sh_clk_div4_enable(struct clk *clk)
+-{
+- sh_clk_write(sh_clk_read(clk) & ~(1 << 8), clk);
+- return 0;
+-}
+-
+-static void sh_clk_div4_disable(struct clk *clk)
+-{
+- sh_clk_write(sh_clk_read(clk) | (1 << 8), clk);
+-}
+-
+ static struct sh_clk_ops sh_clk_div4_clk_ops = {
+ .recalc = sh_clk_div_recalc,
+ .set_rate = sh_clk_div_set_rate,
+@@ -346,16 +337,16 @@ static struct sh_clk_ops sh_clk_div4_enable_clk_ops = {
+ .recalc = sh_clk_div_recalc,
+ .set_rate = sh_clk_div_set_rate,
+ .round_rate = sh_clk_div_round_rate,
+- .enable = sh_clk_div4_enable,
+- .disable = sh_clk_div4_disable,
++ .enable = sh_clk_div_enable,
++ .disable = sh_clk_div_disable,
+ };
+
+ static struct sh_clk_ops sh_clk_div4_reparent_clk_ops = {
+ .recalc = sh_clk_div_recalc,
+ .set_rate = sh_clk_div_set_rate,
+ .round_rate = sh_clk_div_round_rate,
+- .enable = sh_clk_div4_enable,
+- .disable = sh_clk_div4_disable,
++ .enable = sh_clk_div_enable,
++ .disable = sh_clk_div_disable,
+ .set_parent = sh_clk_div4_set_parent,
+ };
+
+diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h
+index 35a04f1..5091091 100644
+--- a/include/linux/sh_clk.h
++++ b/include/linux/sh_clk.h
+@@ -69,6 +69,8 @@ struct clk {
+ #define CLK_ENABLE_REG_16BIT BIT(2)
+ #define CLK_ENABLE_REG_8BIT BIT(3)
+
++#define CLK_MASK_DIV_ON_DISABLE BIT(4)
++
+ #define CLK_ENABLE_REG_MASK (CLK_ENABLE_REG_32BIT | \
+ CLK_ENABLE_REG_16BIT | \
+ CLK_ENABLE_REG_8BIT)
+@@ -173,7 +175,7 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr,
+ { \
+ .enable_reg = (void __iomem *)_reg, \
+ .enable_bit = 0, /* unused */ \
+- .flags = _flags, \
++ .flags = _flags | CLK_MASK_DIV_ON_DISABLE, \
+ .div_mask = SH_CLK_DIV6_MSK, \
+ .parent_table = _parents, \
+ .parent_num = _num_parents, \
+@@ -187,7 +189,7 @@ int sh_clk_div4_reparent_register(struct clk *clks, int nr,
+ .enable_reg = (void __iomem *)_reg, \
+ .enable_bit = 0, /* unused */ \
+ .div_mask = SH_CLK_DIV6_MSK, \
+- .flags = _flags, \
++ .flags = _flags | CLK_MASK_DIV_ON_DISABLE, \
+ }
+
+ int sh_clk_div6_register(struct clk *clks, int nr);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0008-sh-clkfwk-Consolidate-div6-div4-clk_ops-definitions.patch b/patches.marzen/0008-sh-clkfwk-Consolidate-div6-div4-clk_ops-definitions.patch
new file mode 100644
index 0000000000000..581bf9ad84759
--- /dev/null
+++ b/patches.marzen/0008-sh-clkfwk-Consolidate-div6-div4-clk_ops-definitions.patch
@@ -0,0 +1,106 @@
+From d50dd1ccae270ab558c081c9a7697137a92afdce Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Fri, 25 May 2012 16:43:42 +0900
+Subject: sh: clkfwk: Consolidate div6/div4 clk_ops definitions.
+
+Everything with the exception of the _reparent ops are now shared, so
+switch everything over to common types.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit e3c87607731e1a8937567e92a52eedee1bec622d)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/sh/clk/cpg.c | 42 +++++++++++++++++-------------------------
+ 1 file changed, 17 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
+index 06537f2..eeaec79 100644
+--- a/drivers/sh/clk/cpg.c
++++ b/drivers/sh/clk/cpg.c
+@@ -148,6 +148,20 @@ static void sh_clk_div_disable(struct clk *clk)
+ sh_clk_write(val, clk);
+ }
+
++static struct sh_clk_ops sh_clk_div_clk_ops = {
++ .recalc = sh_clk_div_recalc,
++ .set_rate = sh_clk_div_set_rate,
++ .round_rate = sh_clk_div_round_rate,
++};
++
++static struct sh_clk_ops sh_clk_div_enable_clk_ops = {
++ .recalc = sh_clk_div_recalc,
++ .set_rate = sh_clk_div_set_rate,
++ .round_rate = sh_clk_div_round_rate,
++ .enable = sh_clk_div_enable,
++ .disable = sh_clk_div_disable,
++};
++
+ /*
+ * div6 support
+ */
+@@ -200,14 +214,6 @@ static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent)
+ return 0;
+ }
+
+-static struct sh_clk_ops sh_clk_div6_clk_ops = {
+- .recalc = sh_clk_div_recalc,
+- .round_rate = sh_clk_div_round_rate,
+- .set_rate = sh_clk_div_set_rate,
+- .enable = sh_clk_div_enable,
+- .disable = sh_clk_div_disable,
+-};
+-
+ static struct sh_clk_ops sh_clk_div6_reparent_clk_ops = {
+ .recalc = sh_clk_div_recalc,
+ .round_rate = sh_clk_div_round_rate,
+@@ -286,7 +292,7 @@ static int __init sh_clk_div6_register_ops(struct clk *clks, int nr,
+
+ int __init sh_clk_div6_register(struct clk *clks, int nr)
+ {
+- return sh_clk_div6_register_ops(clks, nr, &sh_clk_div6_clk_ops);
++ return sh_clk_div6_register_ops(clks, nr, &sh_clk_div_enable_clk_ops);
+ }
+
+ int __init sh_clk_div6_reparent_register(struct clk *clks, int nr)
+@@ -327,20 +333,6 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
+ return 0;
+ }
+
+-static struct sh_clk_ops sh_clk_div4_clk_ops = {
+- .recalc = sh_clk_div_recalc,
+- .set_rate = sh_clk_div_set_rate,
+- .round_rate = sh_clk_div_round_rate,
+-};
+-
+-static struct sh_clk_ops sh_clk_div4_enable_clk_ops = {
+- .recalc = sh_clk_div_recalc,
+- .set_rate = sh_clk_div_set_rate,
+- .round_rate = sh_clk_div_round_rate,
+- .enable = sh_clk_div_enable,
+- .disable = sh_clk_div_disable,
+-};
+-
+ static struct sh_clk_ops sh_clk_div4_reparent_clk_ops = {
+ .recalc = sh_clk_div_recalc,
+ .set_rate = sh_clk_div_set_rate,
+@@ -385,14 +377,14 @@ static int __init sh_clk_div4_register_ops(struct clk *clks, int nr,
+ int __init sh_clk_div4_register(struct clk *clks, int nr,
+ struct clk_div4_table *table)
+ {
+- return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_clk_ops);
++ return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div_clk_ops);
+ }
+
+ int __init sh_clk_div4_enable_register(struct clk *clks, int nr,
+ struct clk_div4_table *table)
+ {
+ return sh_clk_div4_register_ops(clks, nr, table,
+- &sh_clk_div4_enable_clk_ops);
++ &sh_clk_div_enable_clk_ops);
+ }
+
+ int __init sh_clk_div4_reparent_register(struct clk *clks, int nr,
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0009-sh-clkfwk-Consolidate-div-clk-registration-helper.patch b/patches.marzen/0009-sh-clkfwk-Consolidate-div-clk-registration-helper.patch
new file mode 100644
index 0000000000000..bb9f3ea14c5fb
--- /dev/null
+++ b/patches.marzen/0009-sh-clkfwk-Consolidate-div-clk-registration-helper.patch
@@ -0,0 +1,245 @@
+From 14bb73c341fd8f669c5c48c59811c8e27f3fefce Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Fri, 25 May 2012 16:55:05 +0900
+Subject: sh: clkfwk: Consolidate div clk registration helper.
+
+This consolidates the div6/4 versions of the clk registration wrapper.
+The existing wrappers with their own sh_clk_ops are maintained for API
+compatability, though in the future it should be possible to be rid of
+them entirely.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 609d7558f232e583a31951c65a6ee43d81c65720)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/sh/clk/cpg.c | 182 +++++++++++++++++++++------------------------------
+ 1 file changed, 75 insertions(+), 107 deletions(-)
+
+diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
+index eeaec79..07e9fb4 100644
+--- a/drivers/sh/clk/cpg.c
++++ b/drivers/sh/clk/cpg.c
+@@ -162,6 +162,72 @@ static struct sh_clk_ops sh_clk_div_enable_clk_ops = {
+ .disable = sh_clk_div_disable,
+ };
+
++static int __init sh_clk_init_parent(struct clk *clk)
++{
++ u32 val;
++
++ if (clk->parent)
++ return 0;
++
++ if (!clk->parent_table || !clk->parent_num)
++ return 0;
++
++ if (!clk->src_width) {
++ pr_err("sh_clk_init_parent: cannot select parent clock\n");
++ return -EINVAL;
++ }
++
++ val = (sh_clk_read(clk) >> clk->src_shift);
++ val &= (1 << clk->src_width) - 1;
++
++ if (val >= clk->parent_num) {
++ pr_err("sh_clk_init_parent: parent table size failed\n");
++ return -EINVAL;
++ }
++
++ clk_reparent(clk, clk->parent_table[val]);
++ if (!clk->parent) {
++ pr_err("sh_clk_init_parent: unable to set parent");
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int __init sh_clk_div_register_ops(struct clk *clks, int nr,
++ struct clk_div_table *table, struct sh_clk_ops *ops)
++{
++ struct clk *clkp;
++ void *freq_table;
++ int nr_divs = table->div_mult_table->nr_divisors;
++ int freq_table_size = sizeof(struct cpufreq_frequency_table);
++ int ret = 0;
++ int k;
++
++ freq_table_size *= (nr_divs + 1);
++ freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL);
++ if (!freq_table) {
++ pr_err("%s: unable to alloc memory\n", __func__);
++ return -ENOMEM;
++ }
++
++ for (k = 0; !ret && (k < nr); k++) {
++ clkp = clks + k;
++
++ clkp->ops = ops;
++ clkp->priv = table;
++
++ clkp->freq_table = freq_table + (k * freq_table_size);
++ clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
++
++ ret = clk_register(clkp);
++ if (ret == 0)
++ ret = sh_clk_init_parent(clkp);
++ }
++
++ return ret;
++}
++
+ /*
+ * div6 support
+ */
+@@ -223,82 +289,16 @@ static struct sh_clk_ops sh_clk_div6_reparent_clk_ops = {
+ .set_parent = sh_clk_div6_set_parent,
+ };
+
+-static int __init sh_clk_init_parent(struct clk *clk)
+-{
+- u32 val;
+-
+- if (clk->parent)
+- return 0;
+-
+- if (!clk->parent_table || !clk->parent_num)
+- return 0;
+-
+- if (!clk->src_width) {
+- pr_err("sh_clk_init_parent: cannot select parent clock\n");
+- return -EINVAL;
+- }
+-
+- val = (sh_clk_read(clk) >> clk->src_shift);
+- val &= (1 << clk->src_width) - 1;
+-
+- if (val >= clk->parent_num) {
+- pr_err("sh_clk_init_parent: parent table size failed\n");
+- return -EINVAL;
+- }
+-
+- clk_reparent(clk, clk->parent_table[val]);
+- if (!clk->parent) {
+- pr_err("sh_clk_init_parent: unable to set parent");
+- return -EINVAL;
+- }
+-
+- return 0;
+-}
+-
+-static int __init sh_clk_div6_register_ops(struct clk *clks, int nr,
+- struct sh_clk_ops *ops)
+-{
+- struct clk *clkp;
+- void *freq_table;
+- struct clk_div_table *table = &sh_clk_div6_table;
+- int nr_divs = table->div_mult_table->nr_divisors;
+- int freq_table_size = sizeof(struct cpufreq_frequency_table);
+- int ret = 0;
+- int k;
+-
+- freq_table_size *= (nr_divs + 1);
+- freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL);
+- if (!freq_table) {
+- pr_err("sh_clk_div6_register: unable to alloc memory\n");
+- return -ENOMEM;
+- }
+-
+- for (k = 0; !ret && (k < nr); k++) {
+- clkp = clks + k;
+-
+- clkp->ops = ops;
+- clkp->priv = table;
+- clkp->freq_table = freq_table + (k * freq_table_size);
+- clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
+- ret = clk_register(clkp);
+- if (ret < 0)
+- break;
+-
+- ret = sh_clk_init_parent(clkp);
+- }
+-
+- return ret;
+-}
+-
+ int __init sh_clk_div6_register(struct clk *clks, int nr)
+ {
+- return sh_clk_div6_register_ops(clks, nr, &sh_clk_div_enable_clk_ops);
++ return sh_clk_div_register_ops(clks, nr, &sh_clk_div6_table,
++ &sh_clk_div_enable_clk_ops);
+ }
+
+ int __init sh_clk_div6_reparent_register(struct clk *clks, int nr)
+ {
+- return sh_clk_div6_register_ops(clks, nr,
+- &sh_clk_div6_reparent_clk_ops);
++ return sh_clk_div_register_ops(clks, nr, &sh_clk_div6_table,
++ &sh_clk_div6_reparent_clk_ops);
+ }
+
+ /*
+@@ -342,54 +342,22 @@ static struct sh_clk_ops sh_clk_div4_reparent_clk_ops = {
+ .set_parent = sh_clk_div4_set_parent,
+ };
+
+-static int __init sh_clk_div4_register_ops(struct clk *clks, int nr,
+- struct clk_div4_table *table, struct sh_clk_ops *ops)
+-{
+- struct clk *clkp;
+- void *freq_table;
+- int nr_divs = table->div_mult_table->nr_divisors;
+- int freq_table_size = sizeof(struct cpufreq_frequency_table);
+- int ret = 0;
+- int k;
+-
+- freq_table_size *= (nr_divs + 1);
+- freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL);
+- if (!freq_table) {
+- pr_err("sh_clk_div4_register: unable to alloc memory\n");
+- return -ENOMEM;
+- }
+-
+- for (k = 0; !ret && (k < nr); k++) {
+- clkp = clks + k;
+-
+- clkp->ops = ops;
+- clkp->priv = table;
+-
+- clkp->freq_table = freq_table + (k * freq_table_size);
+- clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
+-
+- ret = clk_register(clkp);
+- }
+-
+- return ret;
+-}
+-
+ int __init sh_clk_div4_register(struct clk *clks, int nr,
+ struct clk_div4_table *table)
+ {
+- return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div_clk_ops);
++ return sh_clk_div_register_ops(clks, nr, table, &sh_clk_div_clk_ops);
+ }
+
+ int __init sh_clk_div4_enable_register(struct clk *clks, int nr,
+ struct clk_div4_table *table)
+ {
+- return sh_clk_div4_register_ops(clks, nr, table,
+- &sh_clk_div_enable_clk_ops);
++ return sh_clk_div_register_ops(clks, nr, table,
++ &sh_clk_div_enable_clk_ops);
+ }
+
+ int __init sh_clk_div4_reparent_register(struct clk *clks, int nr,
+ struct clk_div4_table *table)
+ {
+- return sh_clk_div4_register_ops(clks, nr, table,
+- &sh_clk_div4_reparent_clk_ops);
++ return sh_clk_div_register_ops(clks, nr, table,
++ &sh_clk_div4_reparent_clk_ops);
+ }
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0010-irqdomain-Support-removal-of-IRQ-domains.patch b/patches.marzen/0010-irqdomain-Support-removal-of-IRQ-domains.patch
new file mode 100644
index 0000000000000..1a0d5128a3cef
--- /dev/null
+++ b/patches.marzen/0010-irqdomain-Support-removal-of-IRQ-domains.patch
@@ -0,0 +1,128 @@
+From 0ee607349ba34cf8cdb94370c297faed58f64e39 Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Sat, 19 May 2012 15:11:41 +0900
+Subject: irqdomain: Support removal of IRQ domains.
+
+Now that IRQ domains are being used by modules it's necessary to support
+removing them, too. This adds a new irq_domain_remove() routine for doing
+the bulk of the heavy lifting. It's left as an exercise to the caller to
+ensure all mappings have been appropriatey disposed of before attempting
+to remove the domain.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+(cherry picked from commit 58ee99ada293b5ed971a023304fcfbc1a0ccdb1c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/irqdomain.h | 4 +++-
+ kernel/irq/irqdomain.c | 61 +++++++++++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 62 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
+index c65740d..a796dbf 100644
+--- a/include/linux/irqdomain.h
++++ b/include/linux/irqdomain.h
+@@ -141,10 +141,12 @@ static inline struct irq_domain *irq_domain_add_legacy_isa(
+ return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops,
+ host_data);
+ }
++
++extern void irq_domain_remove(struct irq_domain *host);
++
+ extern struct irq_domain *irq_find_host(struct device_node *node);
+ extern void irq_set_default_host(struct irq_domain *host);
+
+-
+ extern unsigned int irq_create_mapping(struct irq_domain *host,
+ irq_hw_number_t hwirq);
+ extern void irq_dispose_mapping(unsigned int virq);
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index 0e0ba5f..9cae0b2 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -56,6 +56,12 @@ static struct irq_domain *irq_domain_alloc(struct device_node *of_node,
+ return domain;
+ }
+
++static void irq_domain_free(struct irq_domain *domain)
++{
++ of_node_put(domain->of_node);
++ kfree(domain);
++}
++
+ static void irq_domain_add(struct irq_domain *domain)
+ {
+ mutex_lock(&irq_domain_mutex);
+@@ -65,6 +71,58 @@ static void irq_domain_add(struct irq_domain *domain)
+ domain->revmap_type, domain);
+ }
+
++/**
++ * irq_domain_remove() - Remove an irq domain.
++ * @domain: domain to remove
++ *
++ * This routine is used to remove an irq domain. The caller must ensure
++ * that all mappings within the domain have been disposed of prior to
++ * use, depending on the revmap type.
++ */
++void irq_domain_remove(struct irq_domain *domain)
++{
++ mutex_lock(&irq_domain_mutex);
++
++ switch (domain->revmap_type) {
++ case IRQ_DOMAIN_MAP_LEGACY:
++ /*
++ * Legacy domains don't manage their own irq_desc
++ * allocations, we expect the caller to handle irq_desc
++ * freeing on their own.
++ */
++ break;
++ case IRQ_DOMAIN_MAP_TREE:
++ /*
++ * radix_tree_delete() takes care of destroying the root
++ * node when all entries are removed. Shout if there are
++ * any mappings left.
++ */
++ WARN_ON(domain->revmap_data.tree.height);
++ break;
++ case IRQ_DOMAIN_MAP_LINEAR:
++ kfree(domain->revmap_data.linear.revmap);
++ domain->revmap_data.linear.size = 0;
++ break;
++ case IRQ_DOMAIN_MAP_NOMAP:
++ break;
++ }
++
++ list_del(&domain->link);
++
++ /*
++ * If the going away domain is the default one, reset it.
++ */
++ if (unlikely(irq_default_domain == domain))
++ irq_set_default_host(NULL);
++
++ mutex_unlock(&irq_domain_mutex);
++
++ pr_debug("irq: Removed domain of type %d @0x%p\n",
++ domain->revmap_type, domain);
++
++ irq_domain_free(domain);
++}
++
+ static unsigned int irq_domain_legacy_revmap(struct irq_domain *domain,
+ irq_hw_number_t hwirq)
+ {
+@@ -117,8 +175,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+
+ if (WARN_ON(!irq_data || irq_data->domain)) {
+ mutex_unlock(&irq_domain_mutex);
+- of_node_put(domain->of_node);
+- kfree(domain);
++ irq_domain_free(domain);
+ return NULL;
+ }
+ }
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0011-irqdomain-Export-remaining-public-API-symbols.patch b/patches.marzen/0011-irqdomain-Export-remaining-public-API-symbols.patch
new file mode 100644
index 0000000000000..4489c8e283376
--- /dev/null
+++ b/patches.marzen/0011-irqdomain-Export-remaining-public-API-symbols.patch
@@ -0,0 +1,109 @@
+From fd54923383b7dee6af8b53a91d2c6768d2726d77 Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Sat, 19 May 2012 15:11:42 +0900
+Subject: irqdomain: Export remaining public API symbols.
+
+modules making use of irq domains at the very least need access to the
+add/remove/lookup routines, though there's nothing preventing them from
+using the remainder of the public API, either.
+
+The current set of exports seem primarily geared at DT-enabled platforms
+using DT-backed IRQ domains, where many of the API accesses are hidden
+away in OF code. The non-DT cases need to do most of this on their own.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+(cherry picked from commit ecd84eb20a08841197d6bbda5961dcf5f4e424fc)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ kernel/irq/irqdomain.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index 9cae0b2..01d4a0d 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -122,6 +122,7 @@ void irq_domain_remove(struct irq_domain *domain)
+
+ irq_domain_free(domain);
+ }
++EXPORT_SYMBOL_GPL(irq_domain_remove);
+
+ static unsigned int irq_domain_legacy_revmap(struct irq_domain *domain,
+ irq_hw_number_t hwirq)
+@@ -209,6 +210,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+ irq_domain_add(domain);
+ return domain;
+ }
++EXPORT_SYMBOL_GPL(irq_domain_add_legacy);
+
+ /**
+ * irq_domain_add_linear() - Allocate and register a legacy revmap irq_domain.
+@@ -238,6 +240,7 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
+ irq_domain_add(domain);
+ return domain;
+ }
++EXPORT_SYMBOL_GPL(irq_domain_add_linear);
+
+ struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
+ unsigned int max_irq,
+@@ -252,6 +255,7 @@ struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
+ }
+ return domain;
+ }
++EXPORT_SYMBOL_GPL(irq_domain_add_nomap);
+
+ /**
+ * irq_domain_add_tree()
+@@ -273,6 +277,7 @@ struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
+ }
+ return domain;
+ }
++EXPORT_SYMBOL_GPL(irq_domain_add_tree);
+
+ /**
+ * irq_find_host() - Locates a domain for a given device node
+@@ -320,6 +325,7 @@ void irq_set_default_host(struct irq_domain *domain)
+
+ irq_default_domain = domain;
+ }
++EXPORT_SYMBOL_GPL(irq_set_default_host);
+
+ static int irq_setup_virq(struct irq_domain *domain, unsigned int virq,
+ irq_hw_number_t hwirq)
+@@ -378,6 +384,7 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
+
+ return virq;
+ }
++EXPORT_SYMBOL_GPL(irq_create_direct_mapping);
+
+ /**
+ * irq_create_mapping() - Map a hardware interrupt into linux irq space
+@@ -617,6 +624,7 @@ unsigned int irq_radix_revmap_lookup(struct irq_domain *domain,
+ */
+ return irq_data ? irq_data->irq : irq_find_mapping(domain, hwirq);
+ }
++EXPORT_SYMBOL_GPL(irq_radix_revmap_lookup);
+
+ /**
+ * irq_radix_revmap_insert() - Insert a hw irq to linux irq number mapping.
+@@ -641,6 +649,7 @@ void irq_radix_revmap_insert(struct irq_domain *domain, unsigned int virq,
+ mutex_unlock(&revmap_trees_mutex);
+ }
+ }
++EXPORT_SYMBOL_GPL(irq_radix_revmap_insert);
+
+ /**
+ * irq_linear_revmap() - Find a linux irq from a hw irq number.
+@@ -674,6 +683,7 @@ unsigned int irq_linear_revmap(struct irq_domain *domain,
+
+ return revmap[hwirq];
+ }
++EXPORT_SYMBOL_GPL(irq_linear_revmap);
+
+ #ifdef CONFIG_IRQ_DOMAIN_DEBUG
+ static int virq_debug_show(struct seq_file *m, void *private)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0012-irqdomain-Make-irq_domain_simple_map-static.patch b/patches.marzen/0012-irqdomain-Make-irq_domain_simple_map-static.patch
new file mode 100644
index 0000000000000..17332a5efb4a3
--- /dev/null
+++ b/patches.marzen/0012-irqdomain-Make-irq_domain_simple_map-static.patch
@@ -0,0 +1,38 @@
+From 5cfad4570d46fe50c16ce73dcf3f2d6bf76f2b33 Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Sat, 19 May 2012 15:11:43 +0900
+Subject: irqdomain: Make irq_domain_simple_map() static.
+
+Presently irq_domain_simple_map() isn't labelled as static, but there's
+no definition for it in the public irqdomain header either. At present
+all in-tree ->map users have meaningful work to do, and all others are
+using irq_domain_simple_ops directly. Make it static for now, as it can
+always be exported and added to the public API later.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+(cherry picked from commit 5c5806e50b9fd4ca435acdf0eceddda64da9be5b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ kernel/irq/irqdomain.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index 01d4a0d..92e06442 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -758,8 +758,8 @@ static int __init irq_debugfs_init(void)
+ __initcall(irq_debugfs_init);
+ #endif /* CONFIG_IRQ_DOMAIN_DEBUG */
+
+-int irq_domain_simple_map(struct irq_domain *d, unsigned int irq,
+- irq_hw_number_t hwirq)
++static int irq_domain_simple_map(struct irq_domain *d, unsigned int irq,
++ irq_hw_number_t hwirq)
+ {
+ return 0;
+ }
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0013-irqdomain-Kill-off-duplicate-definitions.patch b/patches.marzen/0013-irqdomain-Kill-off-duplicate-definitions.patch
new file mode 100644
index 0000000000000..ad6a35bf3040d
--- /dev/null
+++ b/patches.marzen/0013-irqdomain-Kill-off-duplicate-definitions.patch
@@ -0,0 +1,35 @@
+From 4eb9577004521127daa39444ae35279e8f07eccd Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Sat, 19 May 2012 15:11:45 +0900
+Subject: irqdomain: Kill off duplicate definitions.
+
+Presently irqdomain.h has duplicate definitions for irq_find_host() and
+irq_set_default_host(), presumably from merge damage. Kill off the
+duplicates.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+(cherry picked from commit cb5557bec9f14d05204a9014ae1b23aca8b04f1d)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/irqdomain.h | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
+index a796dbf..5abb533 100644
+--- a/include/linux/irqdomain.h
++++ b/include/linux/irqdomain.h
+@@ -144,9 +144,6 @@ static inline struct irq_domain *irq_domain_add_legacy_isa(
+
+ extern void irq_domain_remove(struct irq_domain *host);
+
+-extern struct irq_domain *irq_find_host(struct device_node *node);
+-extern void irq_set_default_host(struct irq_domain *host);
+-
+ extern unsigned int irq_create_mapping(struct irq_domain *host,
+ irq_hw_number_t hwirq);
+ extern void irq_dispose_mapping(unsigned int virq);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0014-irqdomain-trivial-pr_fmt-conversion.patch b/patches.marzen/0014-irqdomain-trivial-pr_fmt-conversion.patch
new file mode 100644
index 0000000000000..8211a8768fc0c
--- /dev/null
+++ b/patches.marzen/0014-irqdomain-trivial-pr_fmt-conversion.patch
@@ -0,0 +1,142 @@
+From acccf0bbf24e13673a3d5d76e49f389d736d4882 Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Sat, 19 May 2012 15:11:47 +0900
+Subject: irqdomain: trivial pr_fmt conversion.
+
+Convert to pr_fmt before things start to get out of hand and some
+janitors start getting overly excited.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+(cherry picked from commit 54a9058860f2b7ed8d2fe5bf7be19bb901866dc2)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ kernel/irq/irqdomain.c | 32 +++++++++++++++++---------------
+ 1 file changed, 17 insertions(+), 15 deletions(-)
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index 92e06442..9a6e8a8 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -1,3 +1,5 @@
++#define pr_fmt(fmt) "irq: " fmt
++
+ #include <linux/debugfs.h>
+ #include <linux/hardirq.h>
+ #include <linux/interrupt.h>
+@@ -67,7 +69,7 @@ static void irq_domain_add(struct irq_domain *domain)
+ mutex_lock(&irq_domain_mutex);
+ list_add(&domain->link, &irq_domain_list);
+ mutex_unlock(&irq_domain_mutex);
+- pr_debug("irq: Allocated domain of type %d @0x%p\n",
++ pr_debug("Allocated domain of type %d @0x%p\n",
+ domain->revmap_type, domain);
+ }
+
+@@ -117,7 +119,7 @@ void irq_domain_remove(struct irq_domain *domain)
+
+ mutex_unlock(&irq_domain_mutex);
+
+- pr_debug("irq: Removed domain of type %d @0x%p\n",
++ pr_debug("Removed domain of type %d @0x%p\n",
+ domain->revmap_type, domain);
+
+ irq_domain_free(domain);
+@@ -321,7 +323,7 @@ EXPORT_SYMBOL_GPL(irq_find_host);
+ */
+ void irq_set_default_host(struct irq_domain *domain)
+ {
+- pr_debug("irq: Default domain set to @0x%p\n", domain);
++ pr_debug("Default domain set to @0x%p\n", domain);
+
+ irq_default_domain = domain;
+ }
+@@ -335,7 +337,7 @@ static int irq_setup_virq(struct irq_domain *domain, unsigned int virq,
+ irq_data->hwirq = hwirq;
+ irq_data->domain = domain;
+ if (domain->ops->map(domain, virq, hwirq)) {
+- pr_debug("irq: -> mapping failed, freeing\n");
++ pr_debug("irq-%i==>hwirq-0x%lx mapping failed\n", virq, hwirq);
+ irq_data->domain = NULL;
+ irq_data->hwirq = 0;
+ return -1;
+@@ -366,7 +368,7 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
+
+ virq = irq_alloc_desc_from(1, 0);
+ if (!virq) {
+- pr_debug("irq: create_direct virq allocation failed\n");
++ pr_debug("create_direct virq allocation failed\n");
+ return 0;
+ }
+ if (virq >= domain->revmap_data.nomap.max_irq) {
+@@ -375,7 +377,7 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
+ irq_free_desc(virq);
+ return 0;
+ }
+- pr_debug("irq: create_direct obtained virq %d\n", virq);
++ pr_debug("create_direct obtained virq %d\n", virq);
+
+ if (irq_setup_virq(domain, virq, virq)) {
+ irq_free_desc(virq);
+@@ -402,23 +404,23 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
+ unsigned int hint;
+ int virq;
+
+- pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq);
++ pr_debug("irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq);
+
+ /* Look for default domain if nececssary */
+ if (domain == NULL)
+ domain = irq_default_domain;
+ if (domain == NULL) {
+- printk(KERN_WARNING "irq_create_mapping called for"
+- " NULL domain, hwirq=%lx\n", hwirq);
++ pr_warning("irq_create_mapping called for"
++ " NULL domain, hwirq=%lx\n", hwirq);
+ WARN_ON(1);
+ return 0;
+ }
+- pr_debug("irq: -> using domain @%p\n", domain);
++ pr_debug("-> using domain @%p\n", domain);
+
+ /* Check if mapping already exists */
+ virq = irq_find_mapping(domain, hwirq);
+ if (virq) {
+- pr_debug("irq: -> existing mapping on virq %d\n", virq);
++ pr_debug("-> existing mapping on virq %d\n", virq);
+ return virq;
+ }
+
+@@ -434,7 +436,7 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
+ if (virq <= 0)
+ virq = irq_alloc_desc_from(1, 0);
+ if (virq <= 0) {
+- pr_debug("irq: -> virq allocation failed\n");
++ pr_debug("-> virq allocation failed\n");
+ return 0;
+ }
+
+@@ -444,7 +446,7 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
+ return 0;
+ }
+
+- pr_debug("irq: irq %lu on domain %s mapped to virtual irq %u\n",
++ pr_debug("irq %lu on domain %s mapped to virtual irq %u\n",
+ hwirq, domain->of_node ? domain->of_node->full_name : "null", virq);
+
+ return virq;
+@@ -473,8 +475,8 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
+ if (intsize > 0)
+ return intspec[0];
+ #endif
+- printk(KERN_WARNING "irq: no irq domain found for %s !\n",
+- controller->full_name);
++ pr_warning("no irq domain found for %s !\n",
++ controller->full_name);
+ return 0;
+ }
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0015-irqdomain-Document-size-parameter-of-irq_domain_add_.patch b/patches.marzen/0015-irqdomain-Document-size-parameter-of-irq_domain_add_.patch
new file mode 100644
index 0000000000000..c58ba4285e19a
--- /dev/null
+++ b/patches.marzen/0015-irqdomain-Document-size-parameter-of-irq_domain_add_.patch
@@ -0,0 +1,29 @@
+From b1308eaacaa94b41421129c2cd44b69e4e83f2de Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Sat, 19 May 2012 12:15:35 +0100
+Subject: irqdomain: Document size parameter of irq_domain_add_linear()
+
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+(cherry picked from commit a87487e687ceafdc696b8cb1fb27e37cc463586b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ kernel/irq/irqdomain.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index 9a6e8a8..41c1564 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -217,6 +217,7 @@ EXPORT_SYMBOL_GPL(irq_domain_add_legacy);
+ /**
+ * irq_domain_add_linear() - Allocate and register a legacy revmap irq_domain.
+ * @of_node: pointer to interrupt controller's device tree node.
++ * @size: Number of interrupts in the domain.
+ * @ops: map/unmap domain callbacks
+ * @host_data: Controller private data pointer
+ */
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0016-devicetree-add-helper-inline-for-retrieving-a-node-s.patch b/patches.marzen/0016-devicetree-add-helper-inline-for-retrieving-a-node-s.patch
new file mode 100644
index 0000000000000..24847e4eed646
--- /dev/null
+++ b/patches.marzen/0016-devicetree-add-helper-inline-for-retrieving-a-node-s.patch
@@ -0,0 +1,232 @@
+From e572a45ad1741b29429e38cfd2be60e23e1ebc57 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@secretlab.ca>
+Date: Fri, 15 Jun 2012 11:50:25 -0600
+Subject: devicetree: add helper inline for retrieving a node's full name
+
+The pattern (np ? np->full_name : "<none>") is rather common in the
+kernel, but can also make for quite long lines. This patch adds a new
+inline function, of_node_full_name() so that the test for a valid node
+pointer doesn't need to be open coded at all call sites.
+
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+Cc: Paul Mundt <lethal@linux-sh.org>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Rob Herring <rob.herring@calxeda.com>
+(cherry picked from commit 74a7f08448adea6cb47cd9b260c98ff168117e92)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/microblaze/pci/pci-common.c | 6 ++----
+ arch/powerpc/kernel/pci-common.c | 6 ++----
+ arch/powerpc/kernel/vio.c | 5 ++---
+ arch/powerpc/platforms/cell/iommu.c | 3 +--
+ arch/powerpc/platforms/pseries/iommu.c | 2 +-
+ arch/sparc/kernel/of_device_64.c | 2 +-
+ drivers/of/base.c | 2 +-
+ drivers/of/irq.c | 2 +-
+ include/linux/of.h | 10 ++++++++++
+ kernel/irq/irqdomain.c | 8 ++++----
+ 10 files changed, 25 insertions(+), 21 deletions(-)
+
+diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
+index d10403d..162b4e5 100644
+--- a/arch/microblaze/pci/pci-common.c
++++ b/arch/microblaze/pci/pci-common.c
+@@ -249,8 +249,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
+ } else {
+ pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
+ oirq.size, oirq.specifier[0], oirq.specifier[1],
+- oirq.controller ? oirq.controller->full_name :
+- "<default>");
++ of_node_full_name(oirq.controller));
+
+ virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+ oirq.size);
+@@ -1492,8 +1491,7 @@ static void __devinit pcibios_scan_phb(struct pci_controller *hose)
+ struct pci_bus *bus;
+ struct device_node *node = hose->dn;
+
+- pr_debug("PCI: Scanning PHB %s\n",
+- node ? node->full_name : "<NO NAME>");
++ pr_debug("PCI: Scanning PHB %s\n", of_node_full_name(node));
+
+ pcibios_setup_phb_resources(hose, &resources);
+
+diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
+index 8e78e93..886c254 100644
+--- a/arch/powerpc/kernel/pci-common.c
++++ b/arch/powerpc/kernel/pci-common.c
+@@ -248,8 +248,7 @@ static int pci_read_irq_line(struct pci_dev *pci_dev)
+ } else {
+ pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
+ oirq.size, oirq.specifier[0], oirq.specifier[1],
+- oirq.controller ? oirq.controller->full_name :
+- "<default>");
++ of_node_full_name(oirq.controller));
+
+ virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+ oirq.size);
+@@ -1628,8 +1627,7 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose)
+ struct device_node *node = hose->dn;
+ int mode;
+
+- pr_debug("PCI: Scanning PHB %s\n",
+- node ? node->full_name : "<NO NAME>");
++ pr_debug("PCI: Scanning PHB %s\n", of_node_full_name(node));
+
+ /* Get some IO space for the new PHB */
+ pcibios_setup_phb_io_space(hose);
+diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
+index a3a9990..ea6081a 100644
+--- a/arch/powerpc/kernel/vio.c
++++ b/arch/powerpc/kernel/vio.c
+@@ -1193,8 +1193,7 @@ static void __devinit vio_dev_release(struct device *dev)
+ struct iommu_table *tbl = get_iommu_table_base(dev);
+
+ if (tbl)
+- iommu_free_table(tbl, dev->of_node ?
+- dev->of_node->full_name : dev_name(dev));
++ iommu_free_table(tbl, of_node_full_name(dev->of_node));
+ of_node_put(dev->of_node);
+ kfree(to_vio_dev(dev));
+ }
+@@ -1330,7 +1329,7 @@ static ssize_t devspec_show(struct device *dev,
+ {
+ struct device_node *of_node = dev->of_node;
+
+- return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none");
++ return sprintf(buf, "%s\n", of_node_full_name(of_node));
+ }
+
+ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
+diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
+index b9f509a..b673200 100644
+--- a/arch/powerpc/platforms/cell/iommu.c
++++ b/arch/powerpc/platforms/cell/iommu.c
+@@ -552,8 +552,7 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev)
+ iommu = cell_iommu_for_node(dev_to_node(dev));
+ if (iommu == NULL || list_empty(&iommu->windows)) {
+ printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n",
+- dev->of_node ? dev->of_node->full_name : "?",
+- dev_to_node(dev));
++ of_node_full_name(dev->of_node), dev_to_node(dev));
+ return NULL;
+ }
+ window = list_entry(iommu->windows.next, struct iommu_window, list);
+diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
+index 2d311c0..6b58a39 100644
+--- a/arch/powerpc/platforms/pseries/iommu.c
++++ b/arch/powerpc/platforms/pseries/iommu.c
+@@ -1051,7 +1051,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
+ if (!pdn || !PCI_DN(pdn)) {
+ printk(KERN_WARNING "pci_dma_dev_setup_pSeriesLP: "
+ "no DMA window found for pci dev=%s dn=%s\n",
+- pci_name(dev), dn? dn->full_name : "<null>");
++ pci_name(dev), of_node_full_name(dn));
+ return;
+ }
+ pr_debug(" parent is %s\n", pdn->full_name);
+diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c
+index 7a3be6f..7bbdc26 100644
+--- a/arch/sparc/kernel/of_device_64.c
++++ b/arch/sparc/kernel/of_device_64.c
+@@ -580,7 +580,7 @@ static unsigned int __init build_one_device_irq(struct platform_device *op,
+ printk("%s: Apply [%s:%x] imap --> [%s:%x]\n",
+ op->dev.of_node->full_name,
+ pp->full_name, this_orig_irq,
+- (iret ? iret->full_name : "NULL"), irq);
++ of_node_full_name(iret), irq);
+
+ if (!iret)
+ break;
+diff --git a/drivers/of/base.c b/drivers/of/base.c
+index 5806449..6271c2e 100644
+--- a/drivers/of/base.c
++++ b/drivers/of/base.c
+@@ -1173,7 +1173,7 @@ static void of_alias_add(struct alias_prop *ap, struct device_node *np,
+ ap->stem[stem_len] = 0;
+ list_add_tail(&ap->link, &aliases_lookup);
+ pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
+- ap->alias, ap->stem, ap->id, np ? np->full_name : NULL);
++ ap->alias, ap->stem, ap->id, of_node_full_name(np));
+ }
+
+ /**
+diff --git a/drivers/of/irq.c b/drivers/of/irq.c
+index 9cf0060..ff8ab7b 100644
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -255,7 +255,7 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec,
+
+ skiplevel:
+ /* Iterate again with new parent */
+- pr_debug(" -> new parent: %s\n", newpar ? newpar->full_name : "<>");
++ pr_debug(" -> new parent: %s\n", of_node_full_name(newpar));
+ of_node_put(ipar);
+ ipar = newpar;
+ newpar = NULL;
+diff --git a/include/linux/of.h b/include/linux/of.h
+index fa7fb1d..284d117 100644
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -163,6 +163,11 @@ static inline int of_node_to_nid(struct device_node *np) { return -1; }
+ #define of_node_to_nid of_node_to_nid
+ #endif
+
++static inline const char* of_node_full_name(struct device_node *np)
++{
++ return np ? np->full_name : "<no-node>";
++}
++
+ extern struct device_node *of_find_node_by_name(struct device_node *from,
+ const char *name);
+ #define for_each_node_by_name(dn, name) \
+@@ -261,6 +266,11 @@ extern void of_detach_node(struct device_node *);
+ #define of_match_ptr(_ptr) (_ptr)
+ #else /* CONFIG_OF */
+
++static inline const char* of_node_full_name(struct device_node *np)
++{
++ return "<no-node>";
++}
++
+ static inline bool of_have_populated_dt(void)
+ {
+ return false;
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index 41c1564..38c5eb8 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -448,7 +448,7 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
+ }
+
+ pr_debug("irq %lu on domain %s mapped to virtual irq %u\n",
+- hwirq, domain->of_node ? domain->of_node->full_name : "null", virq);
++ hwirq, of_node_full_name(domain->of_node), virq);
+
+ return virq;
+ }
+@@ -477,7 +477,7 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
+ return intspec[0];
+ #endif
+ pr_warning("no irq domain found for %s !\n",
+- controller->full_name);
++ of_node_full_name(controller));
+ return 0;
+ }
+
+@@ -725,8 +725,8 @@ static int virq_debug_show(struct seq_file *m, void *private)
+ data = irq_desc_get_chip_data(desc);
+ seq_printf(m, data ? "0x%p " : " %p ", data);
+
+- if (desc->irq_data.domain && desc->irq_data.domain->of_node)
+- p = desc->irq_data.domain->of_node->full_name;
++ if (desc->irq_data.domain)
++ p = of_node_full_name(desc->irq_data.domain->of_node);
+ else
+ p = none;
+ seq_printf(m, "%s\n", p);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0017-irqdomain-Simple-NUMA-awareness.patch b/patches.marzen/0017-irqdomain-Simple-NUMA-awareness.patch
new file mode 100644
index 0000000000000..099c368676248
--- /dev/null
+++ b/patches.marzen/0017-irqdomain-Simple-NUMA-awareness.patch
@@ -0,0 +1,132 @@
+From 249521995c6f0647ab54b64f89103ba3389edfea Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Sun, 3 Jun 2012 22:04:34 -0700
+Subject: irqdomain: Simple NUMA awareness.
+
+While common irqdesc allocation is node aware, the irqdomain code is not.
+
+Presently we observe a number of regressions/inconsistencies on
+NUMA-capable platforms:
+
+- Platforms using irqdomains with legacy mappings, where the
+ irq_descs are allocated node-local and the irqdomain data
+ structure is not.
+
+- Drivers implementing irqdomains will lose node locality
+ regardless of the underlying struct device's node id.
+
+This plugs in NUMA node id proliferation across the various allocation
+callsites by way of_node_to_nid() node lookup. While of_node_to_nid()
+does the right thing for OF-capable platforms it doesn't presently handle
+the non-DT case. This is trivially dealt with by simply wraping in to
+numa_node_id() unconditionally.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Rob Herring <rob.herring@calxeda.com>
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+(cherry picked from commit 5ca4db61e859526b2dbee3bcea3626d3de49a0b2)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/of.h | 15 ++++++++++-----
+ kernel/irq/irqdomain.c | 13 ++++++++-----
+ 2 files changed, 18 insertions(+), 10 deletions(-)
+
+diff --git a/include/linux/of.h b/include/linux/of.h
+index 284d117..e24c5cc 100644
+--- a/include/linux/of.h
++++ b/include/linux/of.h
+@@ -21,6 +21,7 @@
+ #include <linux/kref.h>
+ #include <linux/mod_devicetable.h>
+ #include <linux/spinlock.h>
++#include <linux/topology.h>
+
+ #include <asm/byteorder.h>
+ #include <asm/errno.h>
+@@ -158,11 +159,6 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
+
+ #define OF_BAD_ADDR ((u64)-1)
+
+-#ifndef of_node_to_nid
+-static inline int of_node_to_nid(struct device_node *np) { return -1; }
+-#define of_node_to_nid of_node_to_nid
+-#endif
+-
+ static inline const char* of_node_full_name(struct device_node *np)
+ {
+ return np ? np->full_name : "<no-node>";
+@@ -361,6 +357,15 @@ static inline int of_machine_is_compatible(const char *compat)
+ #define of_match_node(_matches, _node) NULL
+ #endif /* CONFIG_OF */
+
++#ifndef of_node_to_nid
++static inline int of_node_to_nid(struct device_node *np)
++{
++ return numa_node_id();
++}
++
++#define of_node_to_nid of_node_to_nid
++#endif
++
+ /**
+ * of_property_read_bool - Findfrom a property
+ * @np: device node from which the property value is to be read.
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index 38c5eb8..79ae0eb 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -10,6 +10,7 @@
+ #include <linux/mutex.h>
+ #include <linux/of.h>
+ #include <linux/of_address.h>
++#include <linux/topology.h>
+ #include <linux/seq_file.h>
+ #include <linux/slab.h>
+ #include <linux/smp.h>
+@@ -45,7 +46,8 @@ static struct irq_domain *irq_domain_alloc(struct device_node *of_node,
+ {
+ struct irq_domain *domain;
+
+- domain = kzalloc(sizeof(*domain), GFP_KERNEL);
++ domain = kzalloc_node(sizeof(*domain), GFP_KERNEL,
++ of_node_to_nid(of_node));
+ if (WARN_ON(!domain))
+ return NULL;
+
+@@ -229,7 +231,8 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
+ struct irq_domain *domain;
+ unsigned int *revmap;
+
+- revmap = kzalloc(sizeof(*revmap) * size, GFP_KERNEL);
++ revmap = kzalloc_node(sizeof(*revmap) * size, GFP_KERNEL,
++ of_node_to_nid(of_node));
+ if (WARN_ON(!revmap))
+ return NULL;
+
+@@ -367,7 +370,7 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
+ BUG_ON(domain == NULL);
+ WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_NOMAP);
+
+- virq = irq_alloc_desc_from(1, 0);
++ virq = irq_alloc_desc_from(1, of_node_to_nid(domain->of_node));
+ if (!virq) {
+ pr_debug("create_direct virq allocation failed\n");
+ return 0;
+@@ -433,9 +436,9 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
+ hint = hwirq % nr_irqs;
+ if (hint == 0)
+ hint++;
+- virq = irq_alloc_desc_from(hint, 0);
++ virq = irq_alloc_desc_from(hint, of_node_to_nid(domain->of_node));
+ if (virq <= 0)
+- virq = irq_alloc_desc_from(1, 0);
++ virq = irq_alloc_desc_from(1, of_node_to_nid(domain->of_node));
+ if (virq <= 0) {
+ pr_debug("-> virq allocation failed\n");
+ return 0;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0018-irqdomain-Remove-unnecessary-test-for-IRQ_DOMAIN_MAP.patch b/patches.marzen/0018-irqdomain-Remove-unnecessary-test-for-IRQ_DOMAIN_MAP.patch
new file mode 100644
index 0000000000000..4e4191254c415
--- /dev/null
+++ b/patches.marzen/0018-irqdomain-Remove-unnecessary-test-for-IRQ_DOMAIN_MAP.patch
@@ -0,0 +1,39 @@
+From e023d517b8a6bdbb4083914ec6519fa6486d437d Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@secretlab.ca>
+Date: Sun, 3 Jun 2012 22:04:35 -0700
+Subject: irqdomain: Remove unnecessary test for IRQ_DOMAIN_MAP_LEGACY
+
+Where irq_domain_associate() is called in irq_create_mapping, there is
+no need to test for IRQ_DOMAIN_MAP_LEGACY because it is already tested
+for earlier in the routine.
+
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+Cc: Paul Mundt <lethal@linux-sh.org>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Rob Herring <rob.herring@calxeda.com>
+
+(cherry picked from commit 732557047128e5c200c3590efba39f10ac46bcb2)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ kernel/irq/irqdomain.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index 79ae0eb..b1f774c 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -445,8 +445,7 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
+ }
+
+ if (irq_setup_virq(domain, virq, hwirq)) {
+- if (domain->revmap_type != IRQ_DOMAIN_MAP_LEGACY)
+- irq_free_desc(virq);
++ irq_free_desc(virq);
+ return 0;
+ }
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0019-irqdomain-Make-ops-map-hook-optional.patch b/patches.marzen/0019-irqdomain-Make-ops-map-hook-optional.patch
new file mode 100644
index 0000000000000..6cb797bf1e7b1
--- /dev/null
+++ b/patches.marzen/0019-irqdomain-Make-ops-map-hook-optional.patch
@@ -0,0 +1,69 @@
+From 421754810bdf0283c6f75bffdc96a0795bdf340d Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@secretlab.ca>
+Date: Sun, 3 Jun 2012 22:04:39 -0700
+Subject: irqdomain: Make ops->map hook optional
+
+There isn't a really compelling reason to force ->map to be populated,
+so allow it to be left unset.
+
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Paul Mundt <lethal@linux-sh.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Rob Herring <rob.herring@calxeda.com>
+(cherry picked from commit aed98048bd1c83469d96932c1901e867d9ba519a)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ kernel/irq/irqdomain.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index b1f774c..d3968e9 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -205,7 +205,8 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+ * one can then use irq_create_mapping() to
+ * explicitly change them
+ */
+- ops->map(domain, irq, hwirq);
++ if (ops->map)
++ ops->map(domain, irq, hwirq);
+
+ /* Clear norequest flags */
+ irq_clear_status_flags(irq, IRQ_NOREQUEST);
+@@ -340,8 +341,8 @@ static int irq_setup_virq(struct irq_domain *domain, unsigned int virq,
+
+ irq_data->hwirq = hwirq;
+ irq_data->domain = domain;
+- if (domain->ops->map(domain, virq, hwirq)) {
+- pr_debug("irq-%i==>hwirq-0x%lx mapping failed\n", virq, hwirq);
++ if (domain->ops->map && domain->ops->map(domain, virq, hwirq)) {
++ pr_err("irq-%i==>hwirq-0x%lx mapping failed\n", virq, hwirq);
+ irq_data->domain = NULL;
+ irq_data->hwirq = 0;
+ return -1;
+@@ -763,12 +764,6 @@ static int __init irq_debugfs_init(void)
+ __initcall(irq_debugfs_init);
+ #endif /* CONFIG_IRQ_DOMAIN_DEBUG */
+
+-static int irq_domain_simple_map(struct irq_domain *d, unsigned int irq,
+- irq_hw_number_t hwirq)
+-{
+- return 0;
+-}
+-
+ /**
+ * irq_domain_xlate_onecell() - Generic xlate for direct one cell bindings
+ *
+@@ -831,7 +826,6 @@ int irq_domain_xlate_onetwocell(struct irq_domain *d,
+ EXPORT_SYMBOL_GPL(irq_domain_xlate_onetwocell);
+
+ const struct irq_domain_ops irq_domain_simple_ops = {
+- .map = irq_domain_simple_map,
+ .xlate = irq_domain_xlate_onetwocell,
+ };
+ EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0020-irq_domain-Standardise-legacy-linear-domain-selectio.patch b/patches.marzen/0020-irq_domain-Standardise-legacy-linear-domain-selectio.patch
new file mode 100644
index 0000000000000..e395c3d4cf086
--- /dev/null
+++ b/patches.marzen/0020-irq_domain-Standardise-legacy-linear-domain-selectio.patch
@@ -0,0 +1,109 @@
+From c9055637ff0ca4029e5bf18053b65172b27f63b0 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Thu, 5 Jul 2012 12:19:19 +0100
+Subject: irq_domain: Standardise legacy/linear domain selection
+
+A large proportion of interrupt controllers that support legacy mappings
+do so because non-DT systems need to use fixed IRQ numbers when registering
+devices via buses but can otherwise use a linear mapping. The interrupt
+controller itself typically is not affected by the mapping used and best
+practice is to use a linear mapping where possible so drivers frequently
+select at runtime depending on if a legacy range has been allocated to
+them.
+
+Standardise this behaviour by providing irq_domain_register_simple() which
+will allocate a linear mapping unless a positive first_irq is provided in
+which case it will fall back to a legacy mapping. This helps make best
+practice for irq_domain adoption clearer.
+
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+(cherry picked from commit 781d0f46d81e2c26c70649903b503bcfe817efc8)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ Documentation/IRQ-domain.txt | 5 +++++
+ include/linux/irqdomain.h | 5 +++++
+ kernel/irq/irqdomain.c | 30 ++++++++++++++++++++++++++++++
+ 3 files changed, 40 insertions(+)
+
+diff --git a/Documentation/IRQ-domain.txt b/Documentation/IRQ-domain.txt
+index 27dcaab..1401cec 100644
+--- a/Documentation/IRQ-domain.txt
++++ b/Documentation/IRQ-domain.txt
+@@ -93,6 +93,7 @@ Linux IRQ number into the hardware.
+ Most drivers cannot use this mapping.
+
+ ==== Legacy ====
++irq_domain_add_simple()
+ irq_domain_add_legacy()
+ irq_domain_add_legacy_isa()
+
+@@ -115,3 +116,7 @@ The legacy map should only be used if fixed IRQ mappings must be
+ supported. For example, ISA controllers would use the legacy map for
+ mapping Linux IRQs 0-15 so that existing ISA drivers get the correct IRQ
+ numbers.
++
++Most users of legacy mappings should use irq_domain_add_simple() which
++will use a legacy domain only if an IRQ range is supplied by the
++system and will otherwise use a linear domain mapping.
+diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
+index 5abb533..17b60be 100644
+--- a/include/linux/irqdomain.h
++++ b/include/linux/irqdomain.h
+@@ -112,6 +112,11 @@ struct irq_domain {
+ };
+
+ #ifdef CONFIG_IRQ_DOMAIN
++struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
++ unsigned int size,
++ unsigned int first_irq,
++ const struct irq_domain_ops *ops,
++ void *host_data);
+ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+ unsigned int size,
+ unsigned int first_irq,
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index d3968e9..0c51958 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -140,6 +140,36 @@ static unsigned int irq_domain_legacy_revmap(struct irq_domain *domain,
+ }
+
+ /**
++ * irq_domain_add_simple() - Allocate and register a simple irq_domain.
++ * @of_node: pointer to interrupt controller's device tree node.
++ * @size: total number of irqs in mapping
++ * @first_irq: first number of irq block assigned to the domain
++ * @ops: map/unmap domain callbacks
++ * @host_data: Controller private data pointer
++ *
++ * Allocates a legacy irq_domain if irq_base is positive or a linear
++ * domain otherwise.
++ *
++ * This is intended to implement the expected behaviour for most
++ * interrupt controllers which is that a linear mapping should
++ * normally be used unless the system requires a legacy mapping in
++ * order to support supplying interrupt numbers during non-DT
++ * registration of devices.
++ */
++struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
++ unsigned int size,
++ unsigned int first_irq,
++ const struct irq_domain_ops *ops,
++ void *host_data)
++{
++ if (first_irq > 0)
++ return irq_domain_add_legacy(of_node, size, first_irq, 0,
++ ops, host_data);
++ else
++ return irq_domain_add_linear(of_node, size, ops, host_data);
++}
++
++/**
+ * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain.
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @size: total number of irqs in legacy mapping
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0021-irq_domain-correct-a-minor-wrong-comment-for-linear-.patch b/patches.marzen/0021-irq_domain-correct-a-minor-wrong-comment-for-linear-.patch
new file mode 100644
index 0000000000000..fa0ed49f306f3
--- /dev/null
+++ b/patches.marzen/0021-irq_domain-correct-a-minor-wrong-comment-for-linear-.patch
@@ -0,0 +1,32 @@
+From 709c8d22171cc90cc30e4528312bcc0e31b870b2 Mon Sep 17 00:00:00 2001
+From: Dong Aisheng <dong.aisheng@linaro.org>
+Date: Wed, 20 Jun 2012 17:00:30 +0800
+Subject: irq_domain: correct a minor wrong comment for linear revmap
+
+The revmap type should be linear for irq_domain_add_linear function.
+
+Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org>
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+(cherry picked from commit 22076c7712be29a602de45b1c573f31adbd428a9)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ kernel/irq/irqdomain.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index 0c51958..622fdf4 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -248,7 +248,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+ EXPORT_SYMBOL_GPL(irq_domain_add_legacy);
+
+ /**
+- * irq_domain_add_linear() - Allocate and register a legacy revmap irq_domain.
++ * irq_domain_add_linear() - Allocate and register a linear revmap irq_domain.
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @size: Number of interrupts in the domain.
+ * @ops: map/unmap domain callbacks
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0022-irqdomain-Always-update-revmap-when-setting-up-a-vir.patch b/patches.marzen/0022-irqdomain-Always-update-revmap-when-setting-up-a-vir.patch
new file mode 100644
index 0000000000000..639979c989882
--- /dev/null
+++ b/patches.marzen/0022-irqdomain-Always-update-revmap-when-setting-up-a-vir.patch
@@ -0,0 +1,63 @@
+From 077e92f0d6cc5991a052116eb8d66539dd49a995 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@secretlab.ca>
+Date: Sun, 3 Jun 2012 22:04:36 -0700
+Subject: irqdomain: Always update revmap when setting up a virq
+
+At irq_setup_virq() time all of the data needed to update the reverse
+map is available, but the current code ignores it and relies upon the
+slow path to insert revmap records. This patch adds revmap updating
+to the setup path so the slow path will no longer be necessary.
+
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+Cc: Paul Mundt <lethal@linux-sh.org>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Rob Herring <rob.herring@calxeda.com>
+(cherry picked from commit 2a71a1a9da40dfbd5b23d4312aa1641385581f4a)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/powerpc/sysdev/xics/xics-common.c | 3 ---
+ kernel/irq/irqdomain.c | 12 ++++++++++++
+ 2 files changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
+index cd1d18d..9049d9f 100644
+--- a/arch/powerpc/sysdev/xics/xics-common.c
++++ b/arch/powerpc/sysdev/xics/xics-common.c
+@@ -329,9 +329,6 @@ static int xics_host_map(struct irq_domain *h, unsigned int virq,
+
+ pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
+
+- /* Insert the interrupt mapping into the radix tree for fast lookup */
+- irq_radix_revmap_insert(xics_host, virq, hw);
+-
+ /* They aren't all level sensitive but we just don't really know */
+ irq_set_status_flags(virq, IRQ_LEVEL);
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index 622fdf4..648177c 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -378,6 +378,18 @@ static int irq_setup_virq(struct irq_domain *domain, unsigned int virq,
+ return -1;
+ }
+
++ switch (domain->revmap_type) {
++ case IRQ_DOMAIN_MAP_LINEAR:
++ if (hwirq < domain->revmap_data.linear.size)
++ domain->revmap_data.linear.revmap[hwirq] = virq;
++ break;
++ case IRQ_DOMAIN_MAP_TREE:
++ mutex_lock(&revmap_trees_mutex);
++ irq_radix_revmap_insert(domain, virq, hwirq);
++ mutex_unlock(&revmap_trees_mutex);
++ break;
++ }
++
+ irq_clear_status_flags(virq, IRQ_NOREQUEST);
+
+ return 0;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0023-irqdomain-Split-disassociating-code-into-separate-fu.patch b/patches.marzen/0023-irqdomain-Split-disassociating-code-into-separate-fu.patch
new file mode 100644
index 0000000000000..e3a482d418298
--- /dev/null
+++ b/patches.marzen/0023-irqdomain-Split-disassociating-code-into-separate-fu.patch
@@ -0,0 +1,125 @@
+From d3a8f8cf4ad2e5416f53db8963f3ff153feec161 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@secretlab.ca>
+Date: Sun, 3 Jun 2012 22:04:35 -0700
+Subject: irqdomain: Split disassociating code into separate function
+
+This patch moves the irq disassociation code out into a separate
+function in preparation to extend irq_setup_virq to handle multiple
+irqs and rename it for use by interrupt controller drivers. The new
+function will be used by irq_setup_virq() in its error path.
+
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Paul Mundt <lethal@linux-sh.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Rob Herring <rob.herring@calxeda.com>
+(cherry picked from commit 913af2070731bfc1bd39bb35c5cd2fd66f5eff12)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ kernel/irq/irqdomain.c | 75 +++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 47 insertions(+), 28 deletions(-)
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index 648177c..091732c 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -364,6 +364,52 @@ void irq_set_default_host(struct irq_domain *domain)
+ }
+ EXPORT_SYMBOL_GPL(irq_set_default_host);
+
++static void irq_domain_disassociate_many(struct irq_domain *domain,
++ unsigned int irq_base, int count)
++{
++ /*
++ * disassociate in reverse order;
++ * not strictly necessary, but nice for unwinding
++ */
++ while (count--) {
++ int irq = irq_base + count;
++ struct irq_data *irq_data = irq_get_irq_data(irq);
++ irq_hw_number_t hwirq = irq_data->hwirq;
++
++ if (WARN_ON(!irq_data || irq_data->domain != domain))
++ continue;
++
++ irq_set_status_flags(irq, IRQ_NOREQUEST);
++
++ /* remove chip and handler */
++ irq_set_chip_and_handler(irq, NULL, NULL);
++
++ /* Make sure it's completed */
++ synchronize_irq(irq);
++
++ /* Tell the PIC about it */
++ if (domain->ops->unmap)
++ domain->ops->unmap(domain, irq);
++ smp_mb();
++
++ irq_data->domain = NULL;
++ irq_data->hwirq = 0;
++
++ /* Clear reverse map */
++ switch(domain->revmap_type) {
++ case IRQ_DOMAIN_MAP_LINEAR:
++ if (hwirq < domain->revmap_data.linear.size)
++ domain->revmap_data.linear.revmap[hwirq] = 0;
++ break;
++ case IRQ_DOMAIN_MAP_TREE:
++ mutex_lock(&revmap_trees_mutex);
++ radix_tree_delete(&domain->revmap_data.tree, hwirq);
++ mutex_unlock(&revmap_trees_mutex);
++ break;
++ }
++ }
++}
++
+ static int irq_setup_virq(struct irq_domain *domain, unsigned int virq,
+ irq_hw_number_t hwirq)
+ {
+@@ -556,7 +602,6 @@ void irq_dispose_mapping(unsigned int virq)
+ {
+ struct irq_data *irq_data = irq_get_irq_data(virq);
+ struct irq_domain *domain;
+- irq_hw_number_t hwirq;
+
+ if (!virq || !irq_data)
+ return;
+@@ -569,33 +614,7 @@ void irq_dispose_mapping(unsigned int virq)
+ if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
+ return;
+
+- irq_set_status_flags(virq, IRQ_NOREQUEST);
+-
+- /* remove chip and handler */
+- irq_set_chip_and_handler(virq, NULL, NULL);
+-
+- /* Make sure it's completed */
+- synchronize_irq(virq);
+-
+- /* Tell the PIC about it */
+- if (domain->ops->unmap)
+- domain->ops->unmap(domain, virq);
+- smp_mb();
+-
+- /* Clear reverse map */
+- hwirq = irq_data->hwirq;
+- switch(domain->revmap_type) {
+- case IRQ_DOMAIN_MAP_LINEAR:
+- if (hwirq < domain->revmap_data.linear.size)
+- domain->revmap_data.linear.revmap[hwirq] = 0;
+- break;
+- case IRQ_DOMAIN_MAP_TREE:
+- mutex_lock(&revmap_trees_mutex);
+- radix_tree_delete(&domain->revmap_data.tree, hwirq);
+- mutex_unlock(&revmap_trees_mutex);
+- break;
+- }
+-
++ irq_domain_disassociate_many(domain, virq, 1);
+ irq_free_desc(virq);
+ }
+ EXPORT_SYMBOL_GPL(irq_dispose_mapping);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0024-irqdomain-Support-for-static-IRQ-mapping-and-associa.patch b/patches.marzen/0024-irqdomain-Support-for-static-IRQ-mapping-and-associa.patch
new file mode 100644
index 0000000000000..f9f8697cbf9e5
--- /dev/null
+++ b/patches.marzen/0024-irqdomain-Support-for-static-IRQ-mapping-and-associa.patch
@@ -0,0 +1,239 @@
+From 5f4e2248df9a3128a3e81755f87b12dd211ead30 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@secretlab.ca>
+Date: Sun, 17 Jun 2012 16:17:04 -0600
+Subject: irqdomain: Support for static IRQ mapping and association.
+
+This adds a new strict mapping API for supporting creation of linux IRQs
+at existing positions within the domain. The new routines are as follows:
+
+For dynamic allocation and insertion to specified ranges:
+
+ - irq_create_identity_mapping()
+ - irq_create_strict_mappings()
+
+These will allocate and associate a range of linux IRQs at the specified
+location. This can be used by controllers that have their own static linux IRQ
+definitions to map a hwirq range to, as well as for platforms that wish to
+establish 1:1 identity mapping between linux and hwirq space.
+
+For insertion to specified ranges by platforms that do their own irq_desc
+management:
+
+ - irq_domain_associate()
+ - irq_domain_associate_many()
+
+These in turn call back in to the domain's ->map() routine, for further
+processing by the platform. Disassociation of IRQs get handled through
+irq_dispose_mapping() as normal.
+
+With these in place it should be possible to begin migration of legacy IRQ
+domains to linear ones, without requiring special handling for static vs
+dynamic IRQ definitions in DT vs non-DT paths. This also makes it possible
+for domains with static mappings to adopt whichever tree model best fits
+their needs, rather than simply restricting them to linear revmaps.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+[grant.likely: Reorganized irq_domain_associate{,_many} to have all logic in one place]
+[grant.likely: Add error checking for unallocated irq_descs at associate time]
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Rob Herring <rob.herring@calxeda.com>(cherry picked from commit 98aa468e045a0091a7c34d9f5205a629634fabf4)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/irqdomain.h | 19 ++++++++
+ kernel/irq/irqdomain.c | 113 ++++++++++++++++++++++++++++++++++++----------
+ 2 files changed, 107 insertions(+), 25 deletions(-)
+
+diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
+index 17b60be..eab8a0e 100644
+--- a/include/linux/irqdomain.h
++++ b/include/linux/irqdomain.h
+@@ -149,12 +149,31 @@ static inline struct irq_domain *irq_domain_add_legacy_isa(
+
+ extern void irq_domain_remove(struct irq_domain *host);
+
++extern int irq_domain_associate_many(struct irq_domain *domain,
++ unsigned int irq_base,
++ irq_hw_number_t hwirq_base, int count);
++static inline int irq_domain_associate(struct irq_domain *domain, unsigned int irq,
++ irq_hw_number_t hwirq)
++{
++ return irq_domain_associate_many(domain, irq, hwirq, 1);
++}
++
+ extern unsigned int irq_create_mapping(struct irq_domain *host,
+ irq_hw_number_t hwirq);
+ extern void irq_dispose_mapping(unsigned int virq);
+ extern unsigned int irq_find_mapping(struct irq_domain *host,
+ irq_hw_number_t hwirq);
+ extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
++extern int irq_create_strict_mappings(struct irq_domain *domain,
++ unsigned int irq_base,
++ irq_hw_number_t hwirq_base, int count);
++
++static inline int irq_create_identity_mapping(struct irq_domain *host,
++ irq_hw_number_t hwirq)
++{
++ return irq_create_strict_mappings(host, hwirq, hwirq, 1);
++}
++
+ extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
+ irq_hw_number_t hwirq);
+ extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index 091732c..a07d924 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -410,36 +410,61 @@ static void irq_domain_disassociate_many(struct irq_domain *domain,
+ }
+ }
+
+-static int irq_setup_virq(struct irq_domain *domain, unsigned int virq,
+- irq_hw_number_t hwirq)
++int irq_domain_associate_many(struct irq_domain *domain, unsigned int irq_base,
++ irq_hw_number_t hwirq_base, int count)
+ {
+- struct irq_data *irq_data = irq_get_irq_data(virq);
++ unsigned int virq = irq_base;
++ irq_hw_number_t hwirq = hwirq_base;
++ int i;
+
+- irq_data->hwirq = hwirq;
+- irq_data->domain = domain;
+- if (domain->ops->map && domain->ops->map(domain, virq, hwirq)) {
+- pr_err("irq-%i==>hwirq-0x%lx mapping failed\n", virq, hwirq);
+- irq_data->domain = NULL;
+- irq_data->hwirq = 0;
+- return -1;
+- }
++ pr_debug("%s(%s, irqbase=%i, hwbase=%i, count=%i)\n", __func__,
++ of_node_full_name(domain->of_node), irq_base, (int)hwirq_base, count);
+
+- switch (domain->revmap_type) {
+- case IRQ_DOMAIN_MAP_LINEAR:
+- if (hwirq < domain->revmap_data.linear.size)
+- domain->revmap_data.linear.revmap[hwirq] = virq;
+- break;
+- case IRQ_DOMAIN_MAP_TREE:
+- mutex_lock(&revmap_trees_mutex);
+- irq_radix_revmap_insert(domain, virq, hwirq);
+- mutex_unlock(&revmap_trees_mutex);
+- break;
+- }
++ for (i = 0; i < count; i++) {
++ struct irq_data *irq_data = irq_get_irq_data(virq + i);
++
++ if (WARN(!irq_data, "error: irq_desc not allocated; "
++ "irq=%i hwirq=0x%x\n", virq + i, (int)hwirq + i))
++ return -EINVAL;
++ if (WARN(irq_data->domain, "error: irq_desc already associated; "
++ "irq=%i hwirq=0x%x\n", virq + i, (int)hwirq + i))
++ return -EINVAL;
++ };
++
++ for (i = 0; i < count; i++, virq++, hwirq++) {
++ struct irq_data *irq_data = irq_get_irq_data(virq);
++
++ irq_data->hwirq = hwirq;
++ irq_data->domain = domain;
++ if (domain->ops->map && domain->ops->map(domain, virq, hwirq)) {
++ pr_err("irq-%i==>hwirq-0x%lx mapping failed\n", virq, hwirq);
++ irq_data->domain = NULL;
++ irq_data->hwirq = 0;
++ goto err_unmap;
++ }
++
++ switch (domain->revmap_type) {
++ case IRQ_DOMAIN_MAP_LINEAR:
++ if (hwirq < domain->revmap_data.linear.size)
++ domain->revmap_data.linear.revmap[hwirq] = virq;
++ break;
++ case IRQ_DOMAIN_MAP_TREE:
++ mutex_lock(&revmap_trees_mutex);
++ irq_radix_revmap_insert(domain, virq, hwirq);
++ mutex_unlock(&revmap_trees_mutex);
++ break;
++ }
+
+- irq_clear_status_flags(virq, IRQ_NOREQUEST);
++ irq_clear_status_flags(virq, IRQ_NOREQUEST);
++ }
+
+ return 0;
++
++ err_unmap:
++ irq_domain_disassociate_many(domain, irq_base, i);
++ return -EINVAL;
+ }
++EXPORT_SYMBOL_GPL(irq_domain_associate_many);
+
+ /**
+ * irq_create_direct_mapping() - Allocate an irq for direct mapping
+@@ -472,7 +497,7 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
+ }
+ pr_debug("create_direct obtained virq %d\n", virq);
+
+- if (irq_setup_virq(domain, virq, virq)) {
++ if (irq_domain_associate(domain, virq, virq)) {
+ irq_free_desc(virq);
+ return 0;
+ }
+@@ -533,7 +558,7 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
+ return 0;
+ }
+
+- if (irq_setup_virq(domain, virq, hwirq)) {
++ if (irq_domain_associate(domain, virq, hwirq)) {
+ irq_free_desc(virq);
+ return 0;
+ }
+@@ -545,6 +570,44 @@ unsigned int irq_create_mapping(struct irq_domain *domain,
+ }
+ EXPORT_SYMBOL_GPL(irq_create_mapping);
+
++/**
++ * irq_create_strict_mappings() - Map a range of hw irqs to fixed linux irqs
++ * @domain: domain owning the interrupt range
++ * @irq_base: beginning of linux IRQ range
++ * @hwirq_base: beginning of hardware IRQ range
++ * @count: Number of interrupts to map
++ *
++ * This routine is used for allocating and mapping a range of hardware
++ * irqs to linux irqs where the linux irq numbers are at pre-defined
++ * locations. For use by controllers that already have static mappings
++ * to insert in to the domain.
++ *
++ * Non-linear users can use irq_create_identity_mapping() for IRQ-at-a-time
++ * domain insertion.
++ *
++ * 0 is returned upon success, while any failure to establish a static
++ * mapping is treated as an error.
++ */
++int irq_create_strict_mappings(struct irq_domain *domain, unsigned int irq_base,
++ irq_hw_number_t hwirq_base, int count)
++{
++ int ret;
++
++ ret = irq_alloc_descs(irq_base, irq_base, count,
++ of_node_to_nid(domain->of_node));
++ if (unlikely(ret < 0))
++ return ret;
++
++ ret = irq_domain_associate_many(domain, irq_base, hwirq_base, count);
++ if (unlikely(ret < 0)) {
++ irq_free_descs(irq_base, count);
++ return ret;
++ }
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(irq_create_strict_mappings);
++
+ unsigned int irq_create_of_mapping(struct device_node *controller,
+ const u32 *intspec, unsigned int intsize)
+ {
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0025-irqdomain-Eliminate-dedicated-radix-lookup-functions.patch b/patches.marzen/0025-irqdomain-Eliminate-dedicated-radix-lookup-functions.patch
new file mode 100644
index 0000000000000..e4d1ae380517d
--- /dev/null
+++ b/patches.marzen/0025-irqdomain-Eliminate-dedicated-radix-lookup-functions.patch
@@ -0,0 +1,146 @@
+From 5b89c7072aeb8b3f6f16a675fafb342c2dd3e1b6 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@secretlab.ca>
+Date: Sun, 3 Jun 2012 22:04:37 -0700
+Subject: irqdomain: Eliminate dedicated radix lookup functions
+
+In preparation to remove the slow revmap path, eliminate the public
+radix revmap lookup functions. This simplifies the code and makes the
+slowpath removal patch a lot simpler.
+
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+Cc: Paul Mundt <lethal@linux-sh.org>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Rob Herring <rob.herring@calxeda.com>
+(cherry picked from commit d6b0d1f7058f7cf818138cd7fd116dca3f3576d9)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/powerpc/sysdev/xics/icp-hv.c | 2 +-
+ arch/powerpc/sysdev/xics/icp-native.c | 2 +-
+ include/linux/irqdomain.h | 4 ---
+ kernel/irq/irqdomain.c | 60 +----------------------------------
+ 4 files changed, 3 insertions(+), 65 deletions(-)
+
+diff --git a/arch/powerpc/sysdev/xics/icp-hv.c b/arch/powerpc/sysdev/xics/icp-hv.c
+index 762c5ca..df0fc58 100644
+--- a/arch/powerpc/sysdev/xics/icp-hv.c
++++ b/arch/powerpc/sysdev/xics/icp-hv.c
+@@ -115,7 +115,7 @@ static unsigned int icp_hv_get_irq(void)
+ if (vec == XICS_IRQ_SPURIOUS)
+ return NO_IRQ;
+
+- irq = irq_radix_revmap_lookup(xics_host, vec);
++ irq = irq_find_mapping(xics_host, vec);
+ if (likely(irq != NO_IRQ)) {
+ xics_push_cppr(vec);
+ return irq;
+diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c
+index 4c79b6f..48861d3 100644
+--- a/arch/powerpc/sysdev/xics/icp-native.c
++++ b/arch/powerpc/sysdev/xics/icp-native.c
+@@ -119,7 +119,7 @@ static unsigned int icp_native_get_irq(void)
+ if (vec == XICS_IRQ_SPURIOUS)
+ return NO_IRQ;
+
+- irq = irq_radix_revmap_lookup(xics_host, vec);
++ irq = irq_find_mapping(xics_host, vec);
+ if (likely(irq != NO_IRQ)) {
+ xics_push_cppr(vec);
+ return irq;
+diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
+index eab8a0e..0d5b17b 100644
+--- a/include/linux/irqdomain.h
++++ b/include/linux/irqdomain.h
+@@ -174,10 +174,6 @@ static inline int irq_create_identity_mapping(struct irq_domain *host,
+ return irq_create_strict_mappings(host, hwirq, hwirq, 1);
+ }
+
+-extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
+- irq_hw_number_t hwirq);
+-extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
+- irq_hw_number_t hwirq);
+ extern unsigned int irq_linear_revmap(struct irq_domain *host,
+ irq_hw_number_t hwirq);
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index a07d924..f540bb1 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -450,7 +450,7 @@ int irq_domain_associate_many(struct irq_domain *domain, unsigned int irq_base,
+ break;
+ case IRQ_DOMAIN_MAP_TREE:
+ mutex_lock(&revmap_trees_mutex);
+- irq_radix_revmap_insert(domain, virq, hwirq);
++ radix_tree_insert(&domain->revmap_data.tree, hwirq, irq_data);
+ mutex_unlock(&revmap_trees_mutex);
+ break;
+ }
+@@ -724,64 +724,6 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
+ EXPORT_SYMBOL_GPL(irq_find_mapping);
+
+ /**
+- * irq_radix_revmap_lookup() - Find a linux irq from a hw irq number.
+- * @domain: domain owning this hardware interrupt
+- * @hwirq: hardware irq number in that domain space
+- *
+- * This is a fast path, for use by irq controller code that uses radix tree
+- * revmaps
+- */
+-unsigned int irq_radix_revmap_lookup(struct irq_domain *domain,
+- irq_hw_number_t hwirq)
+-{
+- struct irq_data *irq_data;
+-
+- if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_TREE))
+- return irq_find_mapping(domain, hwirq);
+-
+- /*
+- * Freeing an irq can delete nodes along the path to
+- * do the lookup via call_rcu.
+- */
+- rcu_read_lock();
+- irq_data = radix_tree_lookup(&domain->revmap_data.tree, hwirq);
+- rcu_read_unlock();
+-
+- /*
+- * If found in radix tree, then fine.
+- * Else fallback to linear lookup - this should not happen in practice
+- * as it means that we failed to insert the node in the radix tree.
+- */
+- return irq_data ? irq_data->irq : irq_find_mapping(domain, hwirq);
+-}
+-EXPORT_SYMBOL_GPL(irq_radix_revmap_lookup);
+-
+-/**
+- * irq_radix_revmap_insert() - Insert a hw irq to linux irq number mapping.
+- * @domain: domain owning this hardware interrupt
+- * @virq: linux irq number
+- * @hwirq: hardware irq number in that domain space
+- *
+- * This is for use by irq controllers that use a radix tree reverse
+- * mapping for fast lookup.
+- */
+-void irq_radix_revmap_insert(struct irq_domain *domain, unsigned int virq,
+- irq_hw_number_t hwirq)
+-{
+- struct irq_data *irq_data = irq_get_irq_data(virq);
+-
+- if (WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_TREE))
+- return;
+-
+- if (virq) {
+- mutex_lock(&revmap_trees_mutex);
+- radix_tree_insert(&domain->revmap_data.tree, hwirq, irq_data);
+- mutex_unlock(&revmap_trees_mutex);
+- }
+-}
+-EXPORT_SYMBOL_GPL(irq_radix_revmap_insert);
+-
+-/**
+ * irq_linear_revmap() - Find a linux irq from a hw irq number.
+ * @domain: domain owning this hardware interrupt
+ * @hwirq: hardware irq number in that domain space
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0026-irqdomain-Fix-irq_create_direct_mapping-to-test-irq_.patch b/patches.marzen/0026-irqdomain-Fix-irq_create_direct_mapping-to-test-irq_.patch
new file mode 100644
index 0000000000000..6aa1f06bf98f7
--- /dev/null
+++ b/patches.marzen/0026-irqdomain-Fix-irq_create_direct_mapping-to-test-irq_.patch
@@ -0,0 +1,39 @@
+From 669724cfa76709814c46bac8ba50f1a52d15ffd7 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@secretlab.ca>
+Date: Sun, 3 Jun 2012 22:04:38 -0700
+Subject: irqdomain: Fix irq_create_direct_mapping() to test irq_domain type.
+
+irq_create_direct_mapping can only be used with the NOMAP type. Make
+the function test to ensure it is passed the correct type of
+irq_domain.
+
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+Cc: Paul Mundt <lethal@linux-sh.org>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Rob Herring <rob.herring@calxeda.com>
+(cherry picked from commit 9844a5524ec532aee826c35e3031637c7fc8287b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ kernel/irq/irqdomain.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index f540bb1..c0e638b 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -481,8 +481,8 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
+ if (domain == NULL)
+ domain = irq_default_domain;
+
+- BUG_ON(domain == NULL);
+- WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_NOMAP);
++ if (WARN_ON(!domain || domain->revmap_type != IRQ_DOMAIN_MAP_NOMAP))
++ return 0;
+
+ virq = irq_alloc_desc_from(1, of_node_to_nid(domain->of_node));
+ if (!virq) {
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0027-irqdomain-eliminate-slow-path-revmap-lookups.patch b/patches.marzen/0027-irqdomain-eliminate-slow-path-revmap-lookups.patch
new file mode 100644
index 0000000000000..d416e80d713d4
--- /dev/null
+++ b/patches.marzen/0027-irqdomain-eliminate-slow-path-revmap-lookups.patch
@@ -0,0 +1,142 @@
+From 026250e1fad07349b34213260492cecee3b32eae Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@secretlab.ca>
+Date: Sun, 3 Jun 2012 22:04:39 -0700
+Subject: irqdomain: eliminate slow-path revmap lookups
+
+With the current state of irq_domain, the reverse map is always updated
+when new IRQs get mapped. This means that the irq_find_mapping() function
+can be simplified to execute the revmap lookup functions unconditionally
+
+This patch adds lookup functions for the revmaps that don't yet have one
+and removes the slow path lookup code path.
+
+v8: Broke out unrelated changes into separate patches. Rebased on Paul's irq
+ association patches.
+v7: Rebased to irqdomain/next for v3.4 and applied before the removal of 'hint'
+v6: Remove the slow path entirely. The only place where the slow path
+ could get called is for a linear mapping if the hwirq number is larger
+ than the linear revmap size. There shouldn't be any interrupt
+ controllers that do that.
+v5: rewrite to not use a ->revmap() callback. It is simpler, smaller,
+ safer and faster to open code each of the revmap lookups directly into
+ irq_find_mapping() via a switch statement.
+v4: Fix build failure on incorrect variable reference.
+
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Milton Miller <miltonm@bga.com>
+Cc: Paul Mundt <lethal@linux-sh.org>
+Cc: Rob Herring <rob.herring@calxeda.com>
+(cherry picked from commit 4c0946c47463defa681b83294383dc996d255bb7)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ kernel/irq/irqdomain.c | 65 +++++++++++++++++++-------------------------------
+ 1 file changed, 25 insertions(+), 40 deletions(-)
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index c0e638b..170724a 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -686,16 +686,11 @@ EXPORT_SYMBOL_GPL(irq_dispose_mapping);
+ * irq_find_mapping() - Find a linux irq from an hw irq number.
+ * @domain: domain owning this hardware interrupt
+ * @hwirq: hardware irq number in that domain space
+- *
+- * This is a slow path, for use by generic code. It's expected that an
+- * irq controller implementation directly calls the appropriate low level
+- * mapping function.
+ */
+ unsigned int irq_find_mapping(struct irq_domain *domain,
+ irq_hw_number_t hwirq)
+ {
+- unsigned int i;
+- unsigned int hint = hwirq % nr_irqs;
++ struct irq_data *data;
+
+ /* Look for default domain if nececssary */
+ if (domain == NULL)
+@@ -703,22 +698,25 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
+ if (domain == NULL)
+ return 0;
+
+- /* legacy -> bail early */
+- if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
++ switch (domain->revmap_type) {
++ case IRQ_DOMAIN_MAP_LEGACY:
+ return irq_domain_legacy_revmap(domain, hwirq);
+-
+- /* Slow path does a linear search of the map */
+- if (hint == 0)
+- hint = 1;
+- i = hint;
+- do {
+- struct irq_data *data = irq_get_irq_data(i);
++ case IRQ_DOMAIN_MAP_LINEAR:
++ return irq_linear_revmap(domain, hwirq);
++ case IRQ_DOMAIN_MAP_TREE:
++ rcu_read_lock();
++ data = radix_tree_lookup(&domain->revmap_data.tree, hwirq);
++ rcu_read_unlock();
++ if (data)
++ return data->irq;
++ break;
++ case IRQ_DOMAIN_MAP_NOMAP:
++ data = irq_get_irq_data(hwirq);
+ if (data && (data->domain == domain) && (data->hwirq == hwirq))
+- return i;
+- i++;
+- if (i >= nr_irqs)
+- i = 1;
+- } while(i != hint);
++ return hwirq;
++ break;
++ }
++
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(irq_find_mapping);
+@@ -728,32 +726,19 @@ EXPORT_SYMBOL_GPL(irq_find_mapping);
+ * @domain: domain owning this hardware interrupt
+ * @hwirq: hardware irq number in that domain space
+ *
+- * This is a fast path, for use by irq controller code that uses linear
+- * revmaps. It does fallback to the slow path if the revmap doesn't exist
+- * yet and will create the revmap entry with appropriate locking
++ * This is a fast path that can be called directly by irq controller code to
++ * save a handful of instructions.
+ */
+ unsigned int irq_linear_revmap(struct irq_domain *domain,
+ irq_hw_number_t hwirq)
+ {
+- unsigned int *revmap;
++ BUG_ON(domain->revmap_type != IRQ_DOMAIN_MAP_LINEAR);
+
+- if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_LINEAR))
+- return irq_find_mapping(domain, hwirq);
+-
+- /* Check revmap bounds */
+- if (unlikely(hwirq >= domain->revmap_data.linear.size))
+- return irq_find_mapping(domain, hwirq);
+-
+- /* Check if revmap was allocated */
+- revmap = domain->revmap_data.linear.revmap;
+- if (unlikely(revmap == NULL))
+- return irq_find_mapping(domain, hwirq);
+-
+- /* Fill up revmap with slow path if no mapping found */
+- if (unlikely(!revmap[hwirq]))
+- revmap[hwirq] = irq_find_mapping(domain, hwirq);
++ /* Check revmap bounds; complain if exceeded */
++ if (WARN_ON(hwirq >= domain->revmap_data.linear.size))
++ return 0;
+
+- return revmap[hwirq];
++ return domain->revmap_data.linear.revmap[hwirq];
+ }
+ EXPORT_SYMBOL_GPL(irq_linear_revmap);
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0028-irqdomain-Improve-diagnostics-when-a-domain-mapping-.patch b/patches.marzen/0028-irqdomain-Improve-diagnostics-when-a-domain-mapping-.patch
new file mode 100644
index 0000000000000..feaa1b5eae03d
--- /dev/null
+++ b/patches.marzen/0028-irqdomain-Improve-diagnostics-when-a-domain-mapping-.patch
@@ -0,0 +1,56 @@
+From 6a3157b4d4a0df782066f610807c4288ed52ec43 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Fri, 20 Jul 2012 10:33:19 +0100
+Subject: irqdomain: Improve diagnostics when a domain mapping fails
+
+When the map operation fails log the error code we get and add a WARN_ON()
+so we get a backtrace (which should help work out which interrupt is the
+source of the issue).
+
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+(cherry picked from commit f5a1ad057e6da5d0fc9c5677ff44797d193d3e62)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ kernel/irq/irqdomain.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index 170724a..49a7772 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -415,7 +415,7 @@ int irq_domain_associate_many(struct irq_domain *domain, unsigned int irq_base,
+ {
+ unsigned int virq = irq_base;
+ irq_hw_number_t hwirq = hwirq_base;
+- int i;
++ int i, ret;
+
+ pr_debug("%s(%s, irqbase=%i, hwbase=%i, count=%i)\n", __func__,
+ of_node_full_name(domain->of_node), irq_base, (int)hwirq_base, count);
+@@ -436,11 +436,16 @@ int irq_domain_associate_many(struct irq_domain *domain, unsigned int irq_base,
+
+ irq_data->hwirq = hwirq;
+ irq_data->domain = domain;
+- if (domain->ops->map && domain->ops->map(domain, virq, hwirq)) {
+- pr_err("irq-%i==>hwirq-0x%lx mapping failed\n", virq, hwirq);
+- irq_data->domain = NULL;
+- irq_data->hwirq = 0;
+- goto err_unmap;
++ if (domain->ops->map) {
++ ret = domain->ops->map(domain, virq, hwirq);
++ if (ret != 0) {
++ pr_err("irq-%i==>hwirq-0x%lx mapping failed: %d\n",
++ virq, hwirq, ret);
++ WARN_ON(1);
++ irq_data->domain = NULL;
++ irq_data->hwirq = 0;
++ goto err_unmap;
++ }
+ }
+
+ switch (domain->revmap_type) {
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0029-ARM-mach-shmobile-Introduce-INTC_IRQ_PINS_16H.patch b/patches.marzen/0029-ARM-mach-shmobile-Introduce-INTC_IRQ_PINS_16H.patch
new file mode 100644
index 0000000000000..755bc2eb6b828
--- /dev/null
+++ b/patches.marzen/0029-ARM-mach-shmobile-Introduce-INTC_IRQ_PINS_16H.patch
@@ -0,0 +1,83 @@
+From f2f3cb0fe8263325798302e1b431e38cf4e153e8 Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Wed, 28 Mar 2012 19:22:46 +0900
+Subject: ARM: mach-shmobile: Introduce INTC_IRQ_PINS_16H
+
+Add INTC_IRQ_PINS_16H to allow broken out support of the
+the high 16 external interrupt pins. On SoCs with 32 external
+interrupt pins the interrupt vectors for the low 16 and the
+high 16 interrupt pins are sparesly populated. The low 16 are
+at 0x0200 and high 16 are at 0x3200 which with current macros
+results in a separation of 384 linux interrupts. This sparse
+population makes it unsuitable with a single IRQ domain to
+cover the full IRQ range, so this macro breaks out the 32 pins
+into two separate 16 bit controllers to allow two independent
+INTC instances with two separate IRQ domains.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit d7e7e4ffc64f700e876a9f3b2727febaa2041221)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/include/mach/intc.h | 44 ++++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/include/mach/intc.h b/arch/arm/mach-shmobile/include/mach/intc.h
+index 8b22258..a5603c7 100644
+--- a/arch/arm/mach-shmobile/include/mach/intc.h
++++ b/arch/arm/mach-shmobile/include/mach/intc.h
+@@ -142,6 +142,50 @@ static struct intc_desc p ## _desc __initdata = { \
+ p ## _sense_registers, p ## _ack_registers) \
+ }
+
++#define INTC_IRQ_PINS_16H(p, base, vect, str) \
++ \
++static struct resource p ## _resources[] __initdata = { \
++ [0] = { \
++ .start = base, \
++ .end = base + 0x64, \
++ .flags = IORESOURCE_MEM, \
++ }, \
++}; \
++ \
++enum { \
++ p ## _UNUSED = 0, \
++ INTC_IRQ_PINS_ENUM_16H(p), \
++}; \
++ \
++static struct intc_vect p ## _vectors[] __initdata = { \
++ INTC_IRQ_PINS_VECT_16H(p, vect), \
++}; \
++ \
++static struct intc_mask_reg p ## _mask_registers[] __initdata = { \
++ INTC_IRQ_PINS_MASK_16H(p, base), \
++}; \
++ \
++static struct intc_prio_reg p ## _prio_registers[] __initdata = { \
++ INTC_IRQ_PINS_PRIO_16H(p, base), \
++}; \
++ \
++static struct intc_sense_reg p ## _sense_registers[] __initdata = { \
++ INTC_IRQ_PINS_SENSE_16H(p, base), \
++}; \
++ \
++static struct intc_mask_reg p ## _ack_registers[] __initdata = { \
++ INTC_IRQ_PINS_ACK_16H(p, base), \
++}; \
++ \
++static struct intc_desc p ## _desc __initdata = { \
++ .name = str, \
++ .resource = p ## _resources, \
++ .num_resources = ARRAY_SIZE(p ## _resources), \
++ .hw = INTC_HW_DESC(p ## _vectors, NULL, \
++ p ## _mask_registers, p ## _prio_registers, \
++ p ## _sense_registers, p ## _ack_registers) \
++}
++
+ #define INTC_IRQ_PINS_32(p, base, vect, str) \
+ \
+ static struct resource p ## _resources[] __initdata = { \
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0030-sh-intc-Kill-off-special-reservation-interface.patch b/patches.marzen/0030-sh-intc-Kill-off-special-reservation-interface.patch
new file mode 100644
index 0000000000000..9387903484eba
--- /dev/null
+++ b/patches.marzen/0030-sh-intc-Kill-off-special-reservation-interface.patch
@@ -0,0 +1,72 @@
+From cba1bcc0a91c91fb5b503e6a718801a0eca41b3f Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Tue, 22 May 2012 19:07:55 +0900
+Subject: sh: intc: Kill off special reservation interface.
+
+At present reserving the IRLs in the IRQ bitmap in addition to the
+dropping of the legacy IRQ pre-allocation prevent IRL IRQs from being
+allocated for the x3proto board.
+
+The only reason to permit reservations was to lock down possible hardware
+vectors prior to dynamic IRQ scanning, but this doesn't matter much given
+that the hardware controller configuration is sorted before we get around
+to doing any dynamic IRQ allocation anyways. Beyond that, all of the
+tables are __init annotated, so quite a bit more work would need to be
+done to support reconfiguring things like IRL controllers on the fly,
+much more than would ever make it worth the hassle.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 5f19f14fed7786652b9617c633db101d26a42251)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/sh/kernel/cpu/sh4a/setup-shx3.c | 3 ---
+ drivers/sh/intc/dynamic.c | 8 --------
+ include/linux/sh_intc.h | 1 -
+ 3 files changed, 12 deletions(-)
+
+diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+index bb20880..674531e 100644
+--- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c
++++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+@@ -484,9 +484,6 @@ void __init plat_irq_setup_pins(int mode)
+
+ void __init plat_irq_setup(void)
+ {
+- reserve_intc_vectors(vectors_irq, ARRAY_SIZE(vectors_irq));
+- reserve_intc_vectors(vectors_irl, ARRAY_SIZE(vectors_irl));
+-
+ register_intc_controller(&intc_desc);
+ }
+
+diff --git a/drivers/sh/intc/dynamic.c b/drivers/sh/intc/dynamic.c
+index 5fea1ee..14eb01e 100644
+--- a/drivers/sh/intc/dynamic.c
++++ b/drivers/sh/intc/dynamic.c
+@@ -55,11 +55,3 @@ void destroy_irq(unsigned int irq)
+ {
+ irq_free_desc(irq);
+ }
+-
+-void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs)
+-{
+- int i;
+-
+- for (i = 0; i < nr_vecs; i++)
+- irq_reserve_irq(evt2irq(vectors[i].vect));
+-}
+diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h
+index 6aed080..3238328 100644
+--- a/include/linux/sh_intc.h
++++ b/include/linux/sh_intc.h
+@@ -133,7 +133,6 @@ struct intc_desc symbol __initdata = { \
+ }
+
+ int register_intc_controller(struct intc_desc *desc);
+-void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs);
+ int intc_set_priority(unsigned int irq, unsigned int prio);
+ int intc_irq_lookup(const char *chipname, intc_enum enum_id);
+ void intc_finalize(void);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0031-sh-intc-Allocate-subgroup-virq-backing-desc-directly.patch b/patches.marzen/0031-sh-intc-Allocate-subgroup-virq-backing-desc-directly.patch
new file mode 100644
index 0000000000000..55c10a8e5d1b4
--- /dev/null
+++ b/patches.marzen/0031-sh-intc-Allocate-subgroup-virq-backing-desc-directly.patch
@@ -0,0 +1,41 @@
+From 42251498a3ddced1d93aae4fc44936663d7079a5 Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Thu, 24 May 2012 19:24:18 +0900
+Subject: sh: intc: Allocate subgroup virq backing desc directly.
+
+This switches to using irq_alloc_desc() directly for subgroup IRQs.
+We still need to call activate_irq() on these in order to make them
+requestable, at least up until these get moved in to their own irq
+domain..
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 123df01e8e046d6065089e1bff29aa3fc48d4420)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/sh/intc/virq.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c
+index 93cec21..f30ac93 100644
+--- a/drivers/sh/intc/virq.c
++++ b/drivers/sh/intc/virq.c
+@@ -219,12 +219,14 @@ restart:
+ if (radix_tree_deref_retry(entry))
+ goto restart;
+
+- irq = create_irq();
++ irq = irq_alloc_desc(numa_node_id());
+ if (unlikely(irq < 0)) {
+ pr_err("no more free IRQs, bailing..\n");
+ break;
+ }
+
++ activate_irq(irq);
++
+ pr_info("Setting up a chained VIRQ from %d -> %d\n",
+ irq, entry->pirq);
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0032-sh-intc-initial-irqdomain-support.patch b/patches.marzen/0032-sh-intc-initial-irqdomain-support.patch
new file mode 100644
index 0000000000000..be492d9dee3c5
--- /dev/null
+++ b/patches.marzen/0032-sh-intc-initial-irqdomain-support.patch
@@ -0,0 +1,195 @@
+From 53b1c0647bb113f4c1edfdfc8c40b7bf8f258628 Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Wed, 1 Aug 2012 17:13:46 +0900
+Subject: sh: intc: initial irqdomain support.
+
+Trivial support for irq domains, using either a linear map or radix tree
+depending on the vector layout.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 1d6a21b0a672fb29b01ccf397d478e0541e17716)
+
+Conflicts:
+ drivers/sh/intc/Makefile
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/sh/intc/Kconfig | 4 +++
+ drivers/sh/intc/Makefile | 2 +-
+ drivers/sh/intc/core.c | 11 +++++---
+ drivers/sh/intc/internals.h | 5 ++++
+ drivers/sh/intc/irqdomain.c | 68 +++++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 85 insertions(+), 5 deletions(-)
+ create mode 100644 drivers/sh/intc/irqdomain.c
+
+diff --git a/drivers/sh/intc/Kconfig b/drivers/sh/intc/Kconfig
+index c88cbcc..a305731 100644
+--- a/drivers/sh/intc/Kconfig
++++ b/drivers/sh/intc/Kconfig
+@@ -1,3 +1,7 @@
++config SH_INTC
++ def_bool y
++ select IRQ_DOMAIN
++
+ comment "Interrupt controller options"
+
+ config INTC_USERIMASK
+diff --git a/drivers/sh/intc/Makefile b/drivers/sh/intc/Makefile
+index bb5df86..44cf2cd 100644
+--- a/drivers/sh/intc/Makefile
++++ b/drivers/sh/intc/Makefile
+@@ -1,4 +1,4 @@
+-obj-y := access.o chip.o core.o dynamic.o handle.o virq.o
++obj-y := access.o chip.o core.o dynamic.o handle.o irqdomain.o virq.o
+
+ obj-$(CONFIG_INTC_BALANCING) += balancing.o
+ obj-$(CONFIG_INTC_USERIMASK) += userimask.o
+diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c
+index 7e562cc..2374468 100644
+--- a/drivers/sh/intc/core.c
++++ b/drivers/sh/intc/core.c
+@@ -25,6 +25,7 @@
+ #include <linux/stat.h>
+ #include <linux/interrupt.h>
+ #include <linux/sh_intc.h>
++#include <linux/irqdomain.h>
+ #include <linux/device.h>
+ #include <linux/syscore_ops.h>
+ #include <linux/list.h>
+@@ -310,6 +311,8 @@ int __init register_intc_controller(struct intc_desc *desc)
+
+ BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
+
++ intc_irq_domain_init(d, hw);
++
+ /* register the vectors one by one */
+ for (i = 0; i < hw->nr_vectors; i++) {
+ struct intc_vect *vect = hw->vectors + i;
+@@ -319,8 +322,8 @@ int __init register_intc_controller(struct intc_desc *desc)
+ if (!vect->enum_id)
+ continue;
+
+- res = irq_alloc_desc_at(irq, numa_node_id());
+- if (res != irq && res != -EEXIST) {
++ res = irq_create_identity_mapping(d->domain, irq);
++ if (unlikely(res)) {
+ pr_err("can't get irq_desc for %d\n", irq);
+ continue;
+ }
+@@ -340,8 +343,8 @@ int __init register_intc_controller(struct intc_desc *desc)
+ * IRQ support, each vector still needs to have
+ * its own backing irq_desc.
+ */
+- res = irq_alloc_desc_at(irq2, numa_node_id());
+- if (res != irq2 && res != -EEXIST) {
++ res = irq_create_identity_mapping(d->domain, irq2);
++ if (unlikely(res)) {
+ pr_err("can't get irq_desc for %d\n", irq2);
+ continue;
+ }
+diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h
+index f034a97..7dff08e 100644
+--- a/drivers/sh/intc/internals.h
++++ b/drivers/sh/intc/internals.h
+@@ -1,5 +1,6 @@
+ #include <linux/sh_intc.h>
+ #include <linux/irq.h>
++#include <linux/irqdomain.h>
+ #include <linux/list.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+@@ -66,6 +67,7 @@ struct intc_desc_int {
+ unsigned int nr_sense;
+ struct intc_window *window;
+ unsigned int nr_windows;
++ struct irq_domain *domain;
+ struct irq_chip chip;
+ bool skip_suspend;
+ };
+@@ -187,6 +189,9 @@ unsigned long intc_get_ack_handle(unsigned int irq);
+ void intc_enable_disable_enum(struct intc_desc *desc, struct intc_desc_int *d,
+ intc_enum enum_id, int enable);
+
++/* irqdomain.c */
++void intc_irq_domain_init(struct intc_desc_int *d, struct intc_hw_desc *hw);
++
+ /* virq.c */
+ void intc_subgroup_init(struct intc_desc *desc, struct intc_desc_int *d);
+ void intc_irq_xlate_set(unsigned int irq, intc_enum id, struct intc_desc_int *d);
+diff --git a/drivers/sh/intc/irqdomain.c b/drivers/sh/intc/irqdomain.c
+new file mode 100644
+index 0000000..3968f1c
+--- /dev/null
++++ b/drivers/sh/intc/irqdomain.c
+@@ -0,0 +1,68 @@
++/*
++ * IRQ domain support for SH INTC subsystem
++ *
++ * Copyright (C) 2012 Paul Mundt
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License. See the file "COPYING" in the main directory of this archive
++ * for more details.
++ */
++#define pr_fmt(fmt) "intc: " fmt
++
++#include <linux/irqdomain.h>
++#include <linux/sh_intc.h>
++#include <linux/export.h>
++#include "internals.h"
++
++/**
++ * intc_irq_domain_evt_xlate() - Generic xlate for vectored IRQs.
++ *
++ * This takes care of exception vector to hwirq translation through
++ * by way of evt2irq() translation.
++ *
++ * Note: For platforms that use a flat vector space without INTEVT this
++ * basically just mimics irq_domain_xlate_onecell() by way of a nopped
++ * out evt2irq() implementation.
++ */
++static int intc_evt_xlate(struct irq_domain *d, struct device_node *ctrlr,
++ const u32 *intspec, unsigned int intsize,
++ unsigned long *out_hwirq, unsigned int *out_type)
++{
++ if (WARN_ON(intsize < 1))
++ return -EINVAL;
++
++ *out_hwirq = evt2irq(intspec[0]);
++ *out_type = IRQ_TYPE_NONE;
++
++ return 0;
++}
++
++static const struct irq_domain_ops intc_evt_ops = {
++ .xlate = intc_evt_xlate,
++};
++
++void __init intc_irq_domain_init(struct intc_desc_int *d,
++ struct intc_hw_desc *hw)
++{
++ unsigned int irq_base, irq_end;
++
++ /*
++ * Quick linear revmap check
++ */
++ irq_base = evt2irq(hw->vectors[0].vect);
++ irq_end = evt2irq(hw->vectors[hw->nr_vectors - 1].vect);
++
++ /*
++ * Linear domains have a hard-wired assertion that IRQs start at
++ * 0 in order to make some performance optimizations. Lamely
++ * restrict the linear case to these conditions here, taking the
++ * tree penalty for linear cases with non-zero hwirq bases.
++ */
++ if (irq_base == 0 && irq_end == (irq_base + hw->nr_vectors - 1))
++ d->domain = irq_domain_add_linear(NULL, hw->nr_vectors,
++ &intc_evt_ops, NULL);
++ else
++ d->domain = irq_domain_add_tree(NULL, &intc_evt_ops, NULL);
++
++ BUG_ON(!d->domain);
++}
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0033-sh-intc-Handle-domain-association-for-sparseirq-pre-.patch b/patches.marzen/0033-sh-intc-Handle-domain-association-for-sparseirq-pre-.patch
new file mode 100644
index 0000000000000..9a4f4614299c1
--- /dev/null
+++ b/patches.marzen/0033-sh-intc-Handle-domain-association-for-sparseirq-pre-.patch
@@ -0,0 +1,76 @@
+From f4c7cdd9100a1141390e3cea9c3ef8a104c420ae Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Thu, 9 Aug 2012 12:59:40 +0900
+Subject: sh: intc: Handle domain association for sparseirq pre-allocated
+ vectors.
+
+Presently it's assumed that the irqdomain code handles the irq_desc
+allocation for us, but this isn't necessarily the case when we've
+pre-allocated IRQs via sparseirq. Previously we had a -EEXIST check in
+the code that attempted to trap these cases and simply update them
+in-place, but this behaviour was inadvertently lost in the transition to
+irqdomains.
+
+This simply restores the previous behaviour, first attempting to let the
+irqdomain core fetch the allocation for us, and falling back to an
+in-place domain association in the extant IRQ case. Fixes up regressions
+on platforms that pre-allocate legacy IRQs (specifically ARM-based
+SH-Mobile platforms, as SH stopped pre-allocating vectors some time ago).
+
+Reported-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 1026023705b0baa2b37df2a0d1da0022fc7b985e)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/sh/intc/core.c | 27 +++++++++++++++++++++++----
+ 1 file changed, 23 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c
+index 2374468..32c26d7 100644
+--- a/drivers/sh/intc/core.c
++++ b/drivers/sh/intc/core.c
+@@ -324,8 +324,16 @@ int __init register_intc_controller(struct intc_desc *desc)
+
+ res = irq_create_identity_mapping(d->domain, irq);
+ if (unlikely(res)) {
+- pr_err("can't get irq_desc for %d\n", irq);
+- continue;
++ if (res == -EEXIST) {
++ res = irq_domain_associate(d->domain, irq, irq);
++ if (unlikely(res)) {
++ pr_err("domain association failure\n");
++ continue;
++ }
++ } else {
++ pr_err("can't identity map IRQ %d\n", irq);
++ continue;
++ }
+ }
+
+ intc_irq_xlate_set(irq, vect->enum_id, d);
+@@ -345,8 +353,19 @@ int __init register_intc_controller(struct intc_desc *desc)
+ */
+ res = irq_create_identity_mapping(d->domain, irq2);
+ if (unlikely(res)) {
+- pr_err("can't get irq_desc for %d\n", irq2);
+- continue;
++ if (res == -EEXIST) {
++ res = irq_domain_associate(d->domain,
++ irq, irq);
++ if (unlikely(res)) {
++ pr_err("domain association "
++ "failure\n");
++ continue;
++ }
++ } else {
++ pr_err("can't identity map IRQ %d\n",
++ irq);
++ continue;
++ }
+ }
+
+ vect2->enum_id = 0;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0034-sh-intc-Fix-up-multi-evt-irq-association.patch b/patches.marzen/0034-sh-intc-Fix-up-multi-evt-irq-association.patch
new file mode 100644
index 0000000000000..adc6c6ebf22a3
--- /dev/null
+++ b/patches.marzen/0034-sh-intc-Fix-up-multi-evt-irq-association.patch
@@ -0,0 +1,32 @@
+From e36191f0adc5ef8bafb24f3612367b5648ee279a Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Mon, 20 Aug 2012 14:51:50 +0900
+Subject: sh: intc: Fix up multi-evt irq association.
+
+In the multi-evt case we were accidentally associating the parent IRQ,
+fix this up.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit d4b7c5db429fbfd3c79120b27ccf66d583606b57)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/sh/intc/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c
+index 32c26d7..8f32a13 100644
+--- a/drivers/sh/intc/core.c
++++ b/drivers/sh/intc/core.c
+@@ -355,7 +355,7 @@ int __init register_intc_controller(struct intc_desc *desc)
+ if (unlikely(res)) {
+ if (res == -EEXIST) {
+ res = irq_domain_associate(d->domain,
+- irq, irq);
++ irq2, irq2);
+ if (unlikely(res)) {
+ pr_err("domain association "
+ "failure\n");
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0035-ARM-mach-shmobile-Introduce-shmobile_setup_delay.patch b/patches.marzen/0035-ARM-mach-shmobile-Introduce-shmobile_setup_delay.patch
new file mode 100644
index 0000000000000..3ab427317247c
--- /dev/null
+++ b/patches.marzen/0035-ARM-mach-shmobile-Introduce-shmobile_setup_delay.patch
@@ -0,0 +1,70 @@
+From faa2b6a185dbc63fb27624543fb4e6dc3498eb90 Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Wed, 28 Mar 2012 19:22:30 +0900
+Subject: ARM: mach-shmobile: Introduce shmobile_setup_delay()
+
+Add the function shmobile_setup_delay() to let platforms
+configure their maximum loops per jiffy delay. With this
+jiffies calculation done the dependency on early timer
+is removed.
+
+In the future this allows us to assign timers
+using the regular driver model via the device tree.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 0f2c9f20e4e339de30cfd5613dfa9505e7b9c58b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/include/mach/common.h | 2 ++
+ arch/arm/mach-shmobile/timer.c | 17 +++++++++++++++++
+ 2 files changed, 19 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
+index c85e6ec..ff5f12f 100644
+--- a/arch/arm/mach-shmobile/include/mach/common.h
++++ b/arch/arm/mach-shmobile/include/mach/common.h
+@@ -3,6 +3,8 @@
+
+ extern void shmobile_earlytimer_init(void);
+ extern struct sys_timer shmobile_timer;
++extern void shmobile_setup_delay(unsigned int max_cpu_core_mhz,
++ unsigned int mult, unsigned int div);
+ struct twd_local_timer;
+ extern void shmobile_setup_console(void);
+ extern void shmobile_secondary_vector(void);
+diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c
+index 8b79e79..cba39d8 100644
+--- a/arch/arm/mach-shmobile/timer.c
++++ b/arch/arm/mach-shmobile/timer.c
+@@ -19,9 +19,26 @@
+ *
+ */
+ #include <linux/platform_device.h>
++#include <linux/delay.h>
+ #include <asm/mach/time.h>
+ #include <asm/smp_twd.h>
+
++void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz,
++ unsigned int mult, unsigned int div)
++{
++ /* calculate a worst-case loops-per-jiffy value
++ * based on maximum cpu core mhz setting and the
++ * __delay() implementation in arch/arm/lib/delay.S
++ *
++ * this will result in a longer delay than expected
++ * when the cpu core runs on lower frequencies.
++ */
++
++ unsigned int value = (1000000 * mult) / (HZ * div);
++
++ lpj_fine = max_cpu_core_mhz * value;
++}
++
+ static void __init shmobile_late_time_init(void)
+ {
+ /*
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0036-ARM-mach-shmobile-Use-0x3400-as-INTCS-vector-offset.patch b/patches.marzen/0036-ARM-mach-shmobile-Use-0x3400-as-INTCS-vector-offset.patch
new file mode 100644
index 0000000000000..f2a1a78228e31
--- /dev/null
+++ b/patches.marzen/0036-ARM-mach-shmobile-Use-0x3400-as-INTCS-vector-offset.patch
@@ -0,0 +1,43 @@
+From 08bdac8dff053868074871b3bc6318d6d95d476e Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Wed, 28 Mar 2012 19:22:54 +0900
+Subject: ARM: mach-shmobile: Use 0x3400 as INTCS vector offset
+
+Update mach-shmobile to use 0x3400 as INTCS_VECT_BASE.
+
+Since the ARM architecture a little while back added support
+for 10 bit irqs we can now undo the previously merged commit
+9b7c23adb350a108737a993c9c781463c1439dc6 and use 0x3400 as
+INTCS vector base.
+
+This change is necessary to avoid overlapping of interrupt
+ranges so separate IRQ domains can be used for different INTC
+instances. Without this fix the vectors used by various INTC
+instances are overlapping on for instance sh7372 which works
+at the moment but breaks upcoming IRQ domain support.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 1ee8299a9ec1ce5137a044c7768293007b9a3267)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/include/mach/irqs.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h
+index 4e686cc2..06a5da3 100644
+--- a/arch/arm/mach-shmobile/include/mach/irqs.h
++++ b/arch/arm/mach-shmobile/include/mach/irqs.h
+@@ -7,7 +7,7 @@
+ #define gic_spi(nr) ((nr) + 32)
+
+ /* INTCS */
+-#define INTCS_VECT_BASE 0x2200
++#define INTCS_VECT_BASE 0x3400
+ #define INTCS_VECT(n, vect) INTC_VECT((n), INTCS_VECT_BASE + (vect))
+ #define intcs_evt2irq(evt) evt2irq(INTCS_VECT_BASE + (evt))
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0037-ARM-provide-a-late_initcall-hook-for-platform-initia.patch b/patches.marzen/0037-ARM-provide-a-late_initcall-hook-for-platform-initia.patch
new file mode 100644
index 0000000000000..5ced9d5e5efe3
--- /dev/null
+++ b/patches.marzen/0037-ARM-provide-a-late_initcall-hook-for-platform-initia.patch
@@ -0,0 +1,55 @@
+From 8635adab79f5f8e8287e93cc19442556cab55d06 Mon Sep 17 00:00:00 2001
+From: Shawn Guo <shawn.guo@linaro.org>
+Date: Wed, 25 Apr 2012 22:24:44 +0800
+Subject: ARM: provide a late_initcall hook for platform initialization
+
+This allows platforms to set up things that need to be done at
+late_initcall time.
+
+Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
+Tested-by: Robert Lee <rob.lee@linaro.org>
+Tested-by: Stephen Warren <swarren@wwwdotorg.org>
+Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
+Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
+(cherry picked from commit 90de41375ccf8373c0a39d04547f3e3c65d90ec0)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/include/asm/mach/arch.h | 1 +
+ arch/arm/kernel/setup.c | 8 ++++++++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
+index d7692ca..0b1c94b 100644
+--- a/arch/arm/include/asm/mach/arch.h
++++ b/arch/arm/include/asm/mach/arch.h
+@@ -43,6 +43,7 @@ struct machine_desc {
+ void (*init_irq)(void);
+ struct sys_timer *timer; /* system tick timer */
+ void (*init_machine)(void);
++ void (*init_late)(void);
+ #ifdef CONFIG_MULTI_IRQ_HANDLER
+ void (*handle_irq)(struct pt_regs *);
+ #endif
+diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
+index ebfac78..549f036 100644
+--- a/arch/arm/kernel/setup.c
++++ b/arch/arm/kernel/setup.c
+@@ -800,6 +800,14 @@ static int __init customize_machine(void)
+ }
+ arch_initcall(customize_machine);
+
++static int __init init_machine_late(void)
++{
++ if (machine_desc->init_late)
++ machine_desc->init_late();
++ return 0;
++}
++late_initcall(init_machine_late);
++
+ #ifdef CONFIG_KEXEC
+ static inline unsigned long long get_total_mem(void)
+ {
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0038-ARM-shmobile-use-machine-specific-hook-for-late-init.patch b/patches.marzen/0038-ARM-shmobile-use-machine-specific-hook-for-late-init.patch
new file mode 100644
index 0000000000000..695b5f9187bdf
--- /dev/null
+++ b/patches.marzen/0038-ARM-shmobile-use-machine-specific-hook-for-late-init.patch
@@ -0,0 +1,219 @@
+From 7f963c76f63cde6c48ce88a3b6a964b316e6d8ed Mon Sep 17 00:00:00 2001
+From: Shawn Guo <shawn.guo@linaro.org>
+Date: Thu, 26 Apr 2012 21:58:41 +0800
+Subject: ARM: shmobile: use machine specific hook for late init
+
+Cc: Paul Mundt <lethal@linux-sh.org>
+Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
+Acked-by: Magnus Damm <damm@opensource.se>
+Acked-by: "Rafael J. Wysocki" <rjw@sisk.pl>
+(cherry picked from commit 21cc1b7ede3cf456cf1d51f8a906093261f7c111)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/Makefile | 2 +-
+ arch/arm/mach-shmobile/board-ag5evm.c | 1 +
+ arch/arm/mach-shmobile/board-ap4evb.c | 1 +
+ arch/arm/mach-shmobile/board-bonito.c | 1 +
+ arch/arm/mach-shmobile/board-g3evm.c | 1 +
+ arch/arm/mach-shmobile/board-g4evm.c | 1 +
+ arch/arm/mach-shmobile/board-kota2.c | 1 +
+ arch/arm/mach-shmobile/board-mackerel.c | 1 +
+ arch/arm/mach-shmobile/board-marzen.c | 1 +
+ arch/arm/mach-shmobile/common.c | 24 ++++++++++++++++++++++++
+ arch/arm/mach-shmobile/cpuidle.c | 3 +--
+ arch/arm/mach-shmobile/include/mach/common.h | 14 ++++++++++++++
+ arch/arm/mach-shmobile/suspend.c | 3 +--
+ 13 files changed, 49 insertions(+), 5 deletions(-)
+ create mode 100644 arch/arm/mach-shmobile/common.c
+
+diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
+index e7c2590..93d62fb 100644
+--- a/arch/arm/mach-shmobile/Makefile
++++ b/arch/arm/mach-shmobile/Makefile
+@@ -3,7 +3,7 @@
+ #
+
+ # Common objects
+-obj-y := timer.o console.o clock.o
++obj-y := timer.o console.o clock.o common.o
+
+ # CPU objects
+ obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o
+diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
+index 0891ec6..5a6f22f 100644
+--- a/arch/arm/mach-shmobile/board-ag5evm.c
++++ b/arch/arm/mach-shmobile/board-ag5evm.c
+@@ -580,5 +580,6 @@ MACHINE_START(AG5EVM, "ag5evm")
+ .init_irq = sh73a0_init_irq,
+ .handle_irq = gic_handle_irq,
+ .init_machine = ag5evm_init,
++ .init_late = shmobile_init_late,
+ .timer = &shmobile_timer,
+ MACHINE_END
+diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
+index b56dde2..522866d 100644
+--- a/arch/arm/mach-shmobile/board-ap4evb.c
++++ b/arch/arm/mach-shmobile/board-ap4evb.c
+@@ -1440,5 +1440,6 @@ MACHINE_START(AP4EVB, "ap4evb")
+ .init_irq = sh7372_init_irq,
+ .handle_irq = shmobile_handle_irq_intc,
+ .init_machine = ap4evb_init,
++ .init_late = shmobile_init_late,
+ .timer = &shmobile_timer,
+ MACHINE_END
+diff --git a/arch/arm/mach-shmobile/board-bonito.c b/arch/arm/mach-shmobile/board-bonito.c
+index 81fd95f..e6b1fd3 100644
+--- a/arch/arm/mach-shmobile/board-bonito.c
++++ b/arch/arm/mach-shmobile/board-bonito.c
+@@ -500,5 +500,6 @@ MACHINE_START(BONITO, "bonito")
+ .init_irq = r8a7740_init_irq,
+ .handle_irq = shmobile_handle_irq_intc,
+ .init_machine = bonito_init,
++ .init_late = shmobile_init_late,
+ .timer = &shmobile_timer,
+ MACHINE_END
+diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c
+index 39b6cf8..796fa00 100644
+--- a/arch/arm/mach-shmobile/board-g3evm.c
++++ b/arch/arm/mach-shmobile/board-g3evm.c
+@@ -338,5 +338,6 @@ MACHINE_START(G3EVM, "g3evm")
+ .init_irq = sh7367_init_irq,
+ .handle_irq = shmobile_handle_irq_intc,
+ .init_machine = g3evm_init,
++ .init_late = shmobile_init_late,
+ .timer = &shmobile_timer,
+ MACHINE_END
+diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
+index 0e5a39c..f125732 100644
+--- a/arch/arm/mach-shmobile/board-g4evm.c
++++ b/arch/arm/mach-shmobile/board-g4evm.c
+@@ -381,5 +381,6 @@ MACHINE_START(G4EVM, "g4evm")
+ .init_irq = sh7377_init_irq,
+ .handle_irq = shmobile_handle_irq_intc,
+ .init_machine = g4evm_init,
++ .init_late = shmobile_init_late,
+ .timer = &shmobile_timer,
+ MACHINE_END
+diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c
+index 200dcd4..f60f1b2 100644
+--- a/arch/arm/mach-shmobile/board-kota2.c
++++ b/arch/arm/mach-shmobile/board-kota2.c
+@@ -521,5 +521,6 @@ MACHINE_START(KOTA2, "kota2")
+ .init_irq = sh73a0_init_irq,
+ .handle_irq = gic_handle_irq,
+ .init_machine = kota2_init,
++ .init_late = shmobile_init_late,
+ .timer = &shmobile_timer,
+ MACHINE_END
+diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
+index 8c6202b..656d351 100644
+--- a/arch/arm/mach-shmobile/board-mackerel.c
++++ b/arch/arm/mach-shmobile/board-mackerel.c
+@@ -1605,5 +1605,6 @@ MACHINE_START(MACKEREL, "mackerel")
+ .init_irq = sh7372_init_irq,
+ .handle_irq = shmobile_handle_irq_intc,
+ .init_machine = mackerel_init,
++ .init_late = shmobile_init_late,
+ .timer = &shmobile_timer,
+ MACHINE_END
+diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c
+index ef0e13b..14de378 100644
+--- a/arch/arm/mach-shmobile/board-marzen.c
++++ b/arch/arm/mach-shmobile/board-marzen.c
+@@ -98,5 +98,6 @@ MACHINE_START(MARZEN, "marzen")
+ .init_irq = r8a7779_init_irq,
+ .handle_irq = gic_handle_irq,
+ .init_machine = marzen_init,
++ .init_late = shmobile_init_late,
+ .timer = &shmobile_timer,
+ MACHINE_END
+diff --git a/arch/arm/mach-shmobile/common.c b/arch/arm/mach-shmobile/common.c
+new file mode 100644
+index 0000000..608aba9
+--- /dev/null
++++ b/arch/arm/mach-shmobile/common.c
+@@ -0,0 +1,24 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ *
++ */
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <mach/common.h>
++
++void __init shmobile_init_late(void)
++{
++ shmobile_suspend_init();
++ shmobile_cpuidle_init();
++}
+diff --git a/arch/arm/mach-shmobile/cpuidle.c b/arch/arm/mach-shmobile/cpuidle.c
+index 7e65591..7b541e9 100644
+--- a/arch/arm/mach-shmobile/cpuidle.c
++++ b/arch/arm/mach-shmobile/cpuidle.c
+@@ -46,7 +46,7 @@ static struct cpuidle_driver shmobile_cpuidle_driver = {
+
+ void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv);
+
+-static int shmobile_cpuidle_init(void)
++int shmobile_cpuidle_init(void)
+ {
+ struct cpuidle_device *dev = &shmobile_cpuidle_dev;
+ struct cpuidle_driver *drv = &shmobile_cpuidle_driver;
+@@ -65,4 +65,3 @@ static int shmobile_cpuidle_init(void)
+
+ return 0;
+ }
+-late_initcall(shmobile_cpuidle_init);
+diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
+index ff5f12f..01e2bc0 100644
+--- a/arch/arm/mach-shmobile/include/mach/common.h
++++ b/arch/arm/mach-shmobile/include/mach/common.h
+@@ -85,4 +85,18 @@ extern int r8a7779_boot_secondary(unsigned int cpu);
+ extern void r8a7779_smp_prepare_cpus(void);
+ extern void r8a7779_register_twd(void);
+
++extern void shmobile_init_late(void);
++
++#ifdef CONFIG_SUSPEND
++int shmobile_suspend_init(void);
++#else
++static inline int shmobile_suspend_init(void) { return 0; }
++#endif
++
++#ifdef CONFIG_CPU_IDLE
++int shmobile_cpuidle_init(void);
++#else
++static inline int shmobile_cpuidle_init(void) { return 0; }
++#endif
++
+ #endif /* __ARCH_MACH_COMMON_H */
+diff --git a/arch/arm/mach-shmobile/suspend.c b/arch/arm/mach-shmobile/suspend.c
+index 4d1b86a..47d83f7 100644
+--- a/arch/arm/mach-shmobile/suspend.c
++++ b/arch/arm/mach-shmobile/suspend.c
+@@ -39,9 +39,8 @@ struct platform_suspend_ops shmobile_suspend_ops = {
+ .valid = suspend_valid_only_mem,
+ };
+
+-static int __init shmobile_suspend_init(void)
++int __init shmobile_suspend_init(void)
+ {
+ suspend_set_ops(&shmobile_suspend_ops);
+ return 0;
+ }
+-late_initcall(shmobile_suspend_init);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0039-ARM-mach-shmobile-Use-preset_lpj-with-calibrate_dela.patch b/patches.marzen/0039-ARM-mach-shmobile-Use-preset_lpj-with-calibrate_dela.patch
new file mode 100644
index 0000000000000..0bd9433030594
--- /dev/null
+++ b/patches.marzen/0039-ARM-mach-shmobile-Use-preset_lpj-with-calibrate_dela.patch
@@ -0,0 +1,46 @@
+From d85b38a67ee3f87c9ac4d814d091f6bacd77745a Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Thu, 10 May 2012 00:37:48 +0200
+Subject: ARM / mach-shmobile: Use preset_lpj with calibrate_delay()
+
+Update the mach-shmobile shared delay calibration code for late
+timers. All existing in-tree non-DT socs are however using early
+timers today and they are unaffected by this change.
+
+The patch modifies shmobile_setup_delay() from using lpj_fine
+to preset_lpj. This change allows us to preset the worst case
+loops-per-jiffy value to all CPU cores on the system.
+
+The old code which made use of lpj_fine did not affect the
+secondary CPU cores which made it impossible to boot on SMP
+without early timers.
+
+Needed for SMP SoCs using late timers like EMEV2 or any other
+mach-shmobile SMP SoC that makes use of late timers via DT.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 173bf69a7af142e0325fa514954f6eeb2d20cc1d)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/timer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c
+index cba39d8..a689197 100644
+--- a/arch/arm/mach-shmobile/timer.c
++++ b/arch/arm/mach-shmobile/timer.c
+@@ -36,7 +36,8 @@ void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz,
+
+ unsigned int value = (1000000 * mult) / (HZ * div);
+
+- lpj_fine = max_cpu_core_mhz * value;
++ if (!preset_lpj)
++ preset_lpj = max_cpu_core_mhz * value;
+ }
+
+ static void __init shmobile_late_time_init(void)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0040-ARM-shmobile-r8a7740-add-MERAM-work-around.patch b/patches.marzen/0040-ARM-shmobile-r8a7740-add-MERAM-work-around.patch
new file mode 100644
index 0000000000000..9ccc16d68c336
--- /dev/null
+++ b/patches.marzen/0040-ARM-shmobile-r8a7740-add-MERAM-work-around.patch
@@ -0,0 +1,72 @@
+From 357b31146983e768c408a833731f6b5c614286df Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 12 Jun 2012 02:36:21 -0700
+Subject: ARM: shmobile: r8a7740: add MERAM work-around
+
+r8a7740 chip has lasting errata on MERAM buffer, and this patch adds
+its work-around on setup-r8a7740.c
+It solved CEU/VIO6C/2D-DMAC/VCP1/VPU5F/JPU/DISP memroy access error.
+
+But MERAM driver can't control this issue,
+since this work-around requires access to non-MERAM register address.
+So, This it will be called as board specific code at this point.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit d49679e5928709bce8937dce396458b139c4b34d)
+
+Conflicts:
+ arch/arm/mach-shmobile/board-armadillo800eva.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/include/mach/common.h | 1 +
+ arch/arm/mach-shmobile/setup-r8a7740.c | 18 ++++++++++++++++++
+ 2 files changed, 19 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
+index 01e2bc0..45e61da 100644
+--- a/arch/arm/mach-shmobile/include/mach/common.h
++++ b/arch/arm/mach-shmobile/include/mach/common.h
+@@ -77,6 +77,7 @@ extern void r8a7779_add_standard_devices(void);
+ extern void r8a7779_clock_init(void);
+ extern void r8a7779_pinmux_init(void);
+ extern void r8a7779_pm_init(void);
++extern void r8a7740_meram_workaround(void);
+
+ extern unsigned int r8a7779_get_core_count(void);
+ extern int r8a7779_platform_cpu_kill(unsigned int cpu);
+diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
+index 14edb5c..4ba8721 100644
+--- a/arch/arm/mach-shmobile/setup-r8a7740.c
++++ b/arch/arm/mach-shmobile/setup-r8a7740.c
+@@ -317,6 +317,24 @@ static struct platform_device *r8a7740_late_devices[] __initdata = {
+ &i2c1_device,
+ };
+
++/*
++ * r8a7740 chip has lasting errata on MERAM buffer.
++ * this is work-around for it.
++ * see
++ * "Media RAM (MERAM)" on r8a7740 documentation
++ */
++#define MEBUFCNTR 0xFE950098
++void r8a7740_meram_workaround(void)
++{
++ void __iomem *reg;
++
++ reg = ioremap_nocache(MEBUFCNTR, 4);
++ if (reg) {
++ iowrite32(0x01600164, reg);
++ iounmap(reg);
++ }
++}
++
+ #define ICCR 0x0004
+ #define ICSTART 0x0070
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0041-ARM-shmobile-add-common-extra-gpio-functions.patch b/patches.marzen/0041-ARM-shmobile-add-common-extra-gpio-functions.patch
new file mode 100644
index 0000000000000..3c63f44308a0d
--- /dev/null
+++ b/patches.marzen/0041-ARM-shmobile-add-common-extra-gpio-functions.patch
@@ -0,0 +1,73 @@
+From 2a3e278e5c92a6143bc2a57f5c2d5093e26f4208 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 25 Jun 2012 03:41:09 -0700
+Subject: ARM: shmobile: add common extra gpio functions
+
+Current gpio frame work doesn't have the method to control
+just pull up/down/free, but some SH-ARM boards need such kind of operation.
+This patch adds common extra gpio functions for SH-ARM.
+
+But these functions should be replaced by correct
+gpio function in the future.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 4f3d7f65e9d541566c87de2af2d3b066bae78116)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/include/mach/gpio.h | 32 ++++++++++++++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/include/mach/gpio.h b/arch/arm/mach-shmobile/include/mach/gpio.h
+index de795b4..844507d 100644
+--- a/arch/arm/mach-shmobile/include/mach/gpio.h
++++ b/arch/arm/mach-shmobile/include/mach/gpio.h
+@@ -13,6 +13,7 @@
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/sh_pfc.h>
++#include <linux/io.h>
+
+ #ifdef CONFIG_GPIOLIB
+
+@@ -27,4 +28,35 @@ static inline int irq_to_gpio(unsigned int irq)
+
+ #endif /* CONFIG_GPIOLIB */
+
++/*
++ * FIXME !!
++ *
++ * current gpio frame work doesn't have
++ * the method to control only pull up/down/free.
++ * this function should be replaced by correct gpio function
++ */
++static inline void __init gpio_direction_none(u32 addr)
++{
++ __raw_writeb(0x00, addr);
++}
++
++static inline void __init gpio_request_pullup(u32 addr)
++{
++ u8 data = __raw_readb(addr);
++
++ data &= 0x0F;
++ data |= 0xC0;
++ __raw_writeb(data, addr);
++}
++
++static inline void __init gpio_request_pulldown(u32 addr)
++{
++ u8 data = __raw_readb(addr);
++
++ data &= 0x0F;
++ data |= 0xA0;
++
++ __raw_writeb(data, addr);
++}
++
+ #endif /* __ASM_ARCH_GPIO_H */
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0042-ARM-mach-shmobile-add-fixed-voltage-regulators-to-ma.patch b/patches.marzen/0042-ARM-mach-shmobile-add-fixed-voltage-regulators-to-ma.patch
new file mode 100644
index 0000000000000..161d66af12daf
--- /dev/null
+++ b/patches.marzen/0042-ARM-mach-shmobile-add-fixed-voltage-regulators-to-ma.patch
@@ -0,0 +1,55 @@
+From 585b51f2c85ca9c6523a2fca74cc9c6beae3a00a Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 27 Jun 2012 00:32:32 +0200
+Subject: ARM: mach-shmobile: add fixed voltage regulators to marzen
+
+On marzen provide a dummy regulator for the smsc911x driver.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit b354e2272ac6fddd19cfd5732bda23974f7b4ee6)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-marzen.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c
+index 14de378..3a528cf 100644
+--- a/arch/arm/mach-shmobile/board-marzen.c
++++ b/arch/arm/mach-shmobile/board-marzen.c
+@@ -27,6 +27,8 @@
+ #include <linux/io.h>
+ #include <linux/gpio.h>
+ #include <linux/dma-mapping.h>
++#include <linux/regulator/fixed.h>
++#include <linux/regulator/machine.h>
+ #include <linux/smsc911x.h>
+ #include <mach/hardware.h>
+ #include <mach/r8a7779.h>
+@@ -37,6 +39,12 @@
+ #include <asm/hardware/gic.h>
+ #include <asm/traps.h>
+
++/* Dummy supplies, where voltage doesn't matter */
++static struct regulator_consumer_supply dummy_supplies[] = {
++ REGULATOR_SUPPLY("vddvario", "smsc911x"),
++ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
++};
++
+ /* SMSC LAN89218 */
+ static struct resource smsc911x_resources[] = {
+ [0] = {
+@@ -73,6 +81,8 @@ static struct platform_device *marzen_devices[] __initdata = {
+
+ static void __init marzen_init(void)
+ {
++ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
++
+ r8a7779_pinmux_init();
+
+ /* SCIF2 (CN18: DEBUG0) */
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0043-ARM-shmobile-marzen-fixup-smsc911x-id-for-regulator.patch b/patches.marzen/0043-ARM-shmobile-marzen-fixup-smsc911x-id-for-regulator.patch
new file mode 100644
index 0000000000000..ceb74d7f9ef76
--- /dev/null
+++ b/patches.marzen/0043-ARM-shmobile-marzen-fixup-smsc911x-id-for-regulator.patch
@@ -0,0 +1,33 @@
+From b7bf36d36b723ef18c515a031fb762d72ce06c38 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Wed, 29 Aug 2012 18:58:01 -0700
+Subject: ARM: shmobile: marzen: fixup smsc911x id for regulator
+
+dummy_supplies for smsc911x are registered as "smsc911x".
+smsc911x driver needs id = -1
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+(cherry picked from commit 497dcf6fc355f0734faf851662b6957386715d24)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-marzen.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c
+index 3a528cf..fcf5a47 100644
+--- a/arch/arm/mach-shmobile/board-marzen.c
++++ b/arch/arm/mach-shmobile/board-marzen.c
+@@ -67,7 +67,7 @@ static struct smsc911x_platform_config smsc911x_platdata = {
+
+ static struct platform_device eth_device = {
+ .name = "smsc911x",
+- .id = 0,
++ .id = -1,
+ .dev = {
+ .platform_data = &smsc911x_platdata,
+ },
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0044-ARM-shmobile-r8a7779-Route-all-interrupts-to-ARM.patch b/patches.marzen/0044-ARM-shmobile-r8a7779-Route-all-interrupts-to-ARM.patch
new file mode 100644
index 0000000000000..5cfb75432ad99
--- /dev/null
+++ b/patches.marzen/0044-ARM-shmobile-r8a7779-Route-all-interrupts-to-ARM.patch
@@ -0,0 +1,46 @@
+From d84794f3aa3f4214afb08fa52df3ad592965ddba Mon Sep 17 00:00:00 2001
+From: Phil Edworthy <phil.edworthy@renesas.com>
+Date: Sat, 23 Jun 2012 01:12:09 +0200
+Subject: ARM: shmobile: r8a7779: Route all interrupts to ARM
+
+Without this, the interrupts for I2C, VIN, GPIO, SDHC, HSCIF and
+HPB-DMAC are sent to the SH processor.
+
+Signed-off-by: Phil Edworthy <phil.edworthy@renesas.com>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 86f887c105b909a2cea7b06f2136d66b3438b038)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/intc-r8a7779.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/intc-r8a7779.c b/arch/arm/mach-shmobile/intc-r8a7779.c
+index 550b23d..f04fad4 100644
+--- a/arch/arm/mach-shmobile/intc-r8a7779.c
++++ b/arch/arm/mach-shmobile/intc-r8a7779.c
+@@ -35,6 +35,9 @@
+ #define INT2SMSKCR3 0xfe7822ac
+ #define INT2SMSKCR4 0xfe7822b0
+
++#define INT2NTSR0 0xfe700060
++#define INT2NTSR1 0xfe700064
++
+ static int r8a7779_set_wake(struct irq_data *data, unsigned int on)
+ {
+ return 0; /* always allow wakeup */
+@@ -49,6 +52,10 @@ void __init r8a7779_init_irq(void)
+ gic_init(0, 29, gic_dist_base, gic_cpu_base);
+ gic_arch_extn.irq_set_wake = r8a7779_set_wake;
+
++ /* route all interrupts to ARM */
++ __raw_writel(0xffffffff, INT2NTSR0);
++ __raw_writel(0x3fffffff, INT2NTSR1);
++
+ /* unmask all known interrupts in INTCS2 */
+ __raw_writel(0xfffffff0, INT2SMSKCR0);
+ __raw_writel(0xfff7ffff, INT2SMSKCR1);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0045-dmaengine-Fixup-dmaengine_prep_slave_single-to-be-ac.patch b/patches.marzen/0045-dmaengine-Fixup-dmaengine_prep_slave_single-to-be-ac.patch
new file mode 100644
index 0000000000000..ec873b00fe72b
--- /dev/null
+++ b/patches.marzen/0045-dmaengine-Fixup-dmaengine_prep_slave_single-to-be-ac.patch
@@ -0,0 +1,52 @@
+From 35d53ddd33da54b2ac40aa2b73e93832f9f72c28 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Wed, 25 Apr 2012 20:50:53 +0200
+Subject: dmaengine: Fixup dmaengine_prep_slave_single() to be actually useful
+
+dmaengine_prep_slave_single() is a helper function which is supposed to be used
+to prepare a transfer of a single contingous buffer. Currently the function
+takes a pointer to such a buffer from which it builds a scatterlist and passes
+it on to device_prep_slave_sg. The dmaengine framework requires that any
+scatterlist that is passed to device_prep_slave_sg is mapped and it may not be
+unmapped until the DMA operation has completed. This is not the here and any use
+of dmaengine_prep_slave_single() will lead to undefined behaviour (Most likely a
+system crash).
+
+This patch changes dmaengine_prep_slave_single() to take a dma_addr_t instead of
+a pointer to a buffer and moves the responsibility of mapping and unmapping the
+buffer up to the caller.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Acked-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit 922ee08baad2052d0759f100e026d49798c51fef)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/dmaengine.h | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index f9a2e5e..d3fec58 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -615,11 +615,13 @@ static inline int dmaengine_slave_config(struct dma_chan *chan,
+ }
+
+ static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single(
+- struct dma_chan *chan, void *buf, size_t len,
++ struct dma_chan *chan, dma_addr_t buf, size_t len,
+ enum dma_transfer_direction dir, unsigned long flags)
+ {
+ struct scatterlist sg;
+- sg_init_one(&sg, buf, len);
++ sg_init_table(&sg, 1);
++ sg_dma_address(&sg) = buf;
++ sg_dma_len(&sg) = len;
+
+ return chan->device->device_prep_slave_sg(chan, &sg, 1,
+ dir, flags, NULL);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0046-dma-dmaengine-add-slave-req-id-in-slave_config.patch b/patches.marzen/0046-dma-dmaengine-add-slave-req-id-in-slave_config.patch
new file mode 100644
index 0000000000000..ce43120a6e234
--- /dev/null
+++ b/patches.marzen/0046-dma-dmaengine-add-slave-req-id-in-slave_config.patch
@@ -0,0 +1,47 @@
+From a41ee881d86159d8d44d481f10c3288bdbc38a47 Mon Sep 17 00:00:00 2001
+From: Laxman Dewangan <ldewangan@nvidia.com>
+Date: Wed, 6 Jun 2012 10:55:26 +0530
+Subject: dma: dmaengine: add slave req id in slave_config
+
+The DMA controller like Nvidia's Tegra Dma controller
+supports the different slave requestor id from different slave.
+This need to be configure in dma controller to handle the request
+properly.
+
+Adding the slave-id in the slave configuration so that information
+can be passed from client when configuring for slave.
+
+Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit 4fd1e324b7b5f80bd521b58593ada74ef89e80c4)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/dmaengine.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index d3fec58..2fad917 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -338,6 +338,9 @@ enum dma_slave_buswidth {
+ * @device_fc: Flow Controller Settings. Only valid for slave channels. Fill
+ * with 'true' if peripheral should be flow controller. Direction will be
+ * selected at Runtime.
++ * @slave_id: Slave requester id. Only valid for slave channels. The dma
++ * slave peripheral will have unique id as dma requester which need to be
++ * pass as slave config.
+ *
+ * This struct is passed in as configuration data to a DMA engine
+ * in order to set up a certain channel for DMA transport at runtime.
+@@ -365,6 +368,7 @@ struct dma_slave_config {
+ u32 src_maxburst;
+ u32 dst_maxburst;
+ bool device_fc;
++ unsigned int slave_id;
+ };
+
+ static inline const char *dma_chan_name(struct dma_chan *chan)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0047-dmaengine-Add-wrapper-for-device_tx_status-callback.patch b/patches.marzen/0047-dmaengine-Add-wrapper-for-device_tx_status-callback.patch
new file mode 100644
index 0000000000000..aaf2660cd86a1
--- /dev/null
+++ b/patches.marzen/0047-dmaengine-Add-wrapper-for-device_tx_status-callback.patch
@@ -0,0 +1,42 @@
+From c5e667d5b33e041c7dff155e548083c2a176c31a Mon Sep 17 00:00:00 2001
+From: Lars-Peter Clausen <lars@metafoo.de>
+Date: Mon, 11 Jun 2012 20:11:40 +0200
+Subject: dmaengine: Add wrapper for device_tx_status callback
+
+This patch adds a small inline wrapper for the devivce_tx_status callback of a
+dma device. This makes the source code of users of this function a bit more
+compact and a bit more legible.
+
+E.g.:
+-status = chan->device->device_tx_status(chan, cookie, &state)
++status = dmaengine_tx_status(chan, cookie, &state)
+
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit 3052cc2c92f11875d111d5b7b9b3ad535b3128b9)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/dmaengine.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index 2fad917..d1d6ef2 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -662,6 +662,12 @@ static inline int dmaengine_resume(struct dma_chan *chan)
+ return dmaengine_device_control(chan, DMA_RESUME, 0);
+ }
+
++static inline enum dma_status dmaengine_tx_status(struct dma_chan *chan,
++ dma_cookie_t cookie, struct dma_tx_state *state)
++{
++ return chan->device->device_tx_status(chan, cookie, state);
++}
++
+ static inline dma_cookie_t dmaengine_submit(struct dma_async_tx_descriptor *desc)
+ {
+ return desc->tx_submit(desc);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0048-dma-move-shdma-driver-to-an-own-directory.patch b/patches.marzen/0048-dma-move-shdma-driver-to-an-own-directory.patch
new file mode 100644
index 0000000000000..062ec15e5d17f
--- /dev/null
+++ b/patches.marzen/0048-dma-move-shdma-driver-to-an-own-directory.patch
@@ -0,0 +1,66 @@
+From 35a2e575d9dbacd1fdd88ca6c032d9c87de43622 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Mon, 2 Jul 2012 22:30:53 +0200
+Subject: dma: move shdma driver to an own directory
+
+The shdma driver is going to be split into multiple files. To make this more
+convenient move it to an own directory.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit e95be94b8c25220aca09ed78c176f9b55a1482c8)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/dma/Makefile | 2 +-
+ drivers/dma/sh/Makefile | 1 +
+ drivers/dma/{ => sh}/shdma.c | 2 +-
+ drivers/dma/{ => sh}/shdma.h | 0
+ 4 files changed, 3 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/dma/sh/Makefile
+ rename drivers/dma/{ => sh}/shdma.c (99%)
+ rename drivers/dma/{ => sh}/shdma.h (100%)
+
+diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
+index 86b795b..59c10e5 100644
+--- a/drivers/dma/Makefile
++++ b/drivers/dma/Makefile
+@@ -14,7 +14,7 @@ obj-$(CONFIG_DW_DMAC) += dw_dmac.o
+ obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
+ obj-$(CONFIG_MX3_IPU) += ipu/
+ obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
+-obj-$(CONFIG_SH_DMAE) += shdma.o
++obj-$(CONFIG_SH_DMAE) += sh/
+ obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o
+ obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/
+ obj-$(CONFIG_IMX_SDMA) += imx-sdma.o
+diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile
+new file mode 100644
+index 0000000..ad4981a
+--- /dev/null
++++ b/drivers/dma/sh/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_SH_DMAE) += shdma.o
+diff --git a/drivers/dma/shdma.c b/drivers/dma/sh/shdma.c
+similarity index 99%
+rename from drivers/dma/shdma.c
+rename to drivers/dma/sh/shdma.c
+index 19d7a8d..8ab4a1f 100644
+--- a/drivers/dma/shdma.c
++++ b/drivers/dma/sh/shdma.c
+@@ -31,7 +31,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/rculist.h>
+
+-#include "dmaengine.h"
++#include "../dmaengine.h"
+ #include "shdma.h"
+
+ /* DMA descriptor control */
+diff --git a/drivers/dma/shdma.h b/drivers/dma/sh/shdma.h
+similarity index 100%
+rename from drivers/dma/shdma.h
+rename to drivers/dma/sh/shdma.h
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0049-dmaengine-add-an-shdma-base-library.patch b/patches.marzen/0049-dmaengine-add-an-shdma-base-library.patch
new file mode 100644
index 0000000000000..9907b4f9a9519
--- /dev/null
+++ b/patches.marzen/0049-dmaengine-add-an-shdma-base-library.patch
@@ -0,0 +1,1036 @@
+From cb331142a15a186173bb23463c591780e82f0a67 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 9 May 2012 17:09:13 +0200
+Subject: dmaengine: add an shdma-base library
+
+This patch extracts code from shdma.c, that does not directly deal with
+hardware implementation details and can be re-used with diverse DMA
+controller variants, found on SH-based SoCs.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Cc: Sascha Hauer <s.hauer@pengutronix.de>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit 9a7b8e002e331d0599127f16613c32f425a14f2c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/dma/sh/Makefile | 1 +
+ drivers/dma/sh/shdma-base.c | 868 ++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/shdma-base.h | 123 +++++++
+ 3 files changed, 992 insertions(+)
+ create mode 100644 drivers/dma/sh/shdma-base.c
+ create mode 100644 include/linux/shdma-base.h
+
+diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile
+index ad4981a..54ae957 100644
+--- a/drivers/dma/sh/Makefile
++++ b/drivers/dma/sh/Makefile
+@@ -1 +1,2 @@
++obj-$(CONFIG_SH_DMAE) += shdma-base.o
+ obj-$(CONFIG_SH_DMAE) += shdma.o
+diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c
+new file mode 100644
+index 0000000..ff060d0
+--- /dev/null
++++ b/drivers/dma/sh/shdma-base.c
+@@ -0,0 +1,868 @@
++/*
++ * Dmaengine driver base library for DMA controllers, found on SH-based SoCs
++ *
++ * extracted from shdma.c
++ *
++ * Copyright (C) 2011-2012 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
++ * Copyright (C) 2009 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
++ * Copyright (C) 2009 Renesas Solutions, Inc. All rights reserved.
++ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
++ *
++ * This is free software; you can redistribute it and/or modify
++ * it under the terms of version 2 of the GNU General Public License as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/delay.h>
++#include <linux/shdma-base.h>
++#include <linux/dmaengine.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/pm_runtime.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++
++#include "../dmaengine.h"
++
++/* DMA descriptor control */
++enum shdma_desc_status {
++ DESC_IDLE,
++ DESC_PREPARED,
++ DESC_SUBMITTED,
++ DESC_COMPLETED, /* completed, have to call callback */
++ DESC_WAITING, /* callback called, waiting for ack / re-submit */
++};
++
++#define NR_DESCS_PER_CHANNEL 32
++
++#define to_shdma_chan(c) container_of(c, struct shdma_chan, dma_chan)
++#define to_shdma_dev(d) container_of(d, struct shdma_dev, dma_dev)
++
++/*
++ * For slave DMA we assume, that there is a finite number of DMA slaves in the
++ * system, and that each such slave can only use a finite number of channels.
++ * We use slave channel IDs to make sure, that no such slave channel ID is
++ * allocated more than once.
++ */
++static unsigned int slave_num = 256;
++module_param(slave_num, uint, 0444);
++
++/* A bitmask with slave_num bits */
++static unsigned long *shdma_slave_used;
++
++/* Called under spin_lock_irq(&schan->chan_lock") */
++static void shdma_chan_xfer_ld_queue(struct shdma_chan *schan)
++{
++ struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device);
++ const struct shdma_ops *ops = sdev->ops;
++ struct shdma_desc *sdesc;
++
++ /* DMA work check */
++ if (ops->channel_busy(schan))
++ return;
++
++ /* Find the first not transferred descriptor */
++ list_for_each_entry(sdesc, &schan->ld_queue, node)
++ if (sdesc->mark == DESC_SUBMITTED) {
++ ops->start_xfer(schan, sdesc);
++ break;
++ }
++}
++
++static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx)
++{
++ struct shdma_desc *chunk, *c, *desc =
++ container_of(tx, struct shdma_desc, async_tx),
++ *last = desc;
++ struct shdma_chan *schan = to_shdma_chan(tx->chan);
++ struct shdma_slave *slave = tx->chan->private;
++ dma_async_tx_callback callback = tx->callback;
++ dma_cookie_t cookie;
++ bool power_up;
++
++ spin_lock_irq(&schan->chan_lock);
++
++ power_up = list_empty(&schan->ld_queue);
++
++ cookie = dma_cookie_assign(tx);
++
++ /* Mark all chunks of this descriptor as submitted, move to the queue */
++ list_for_each_entry_safe(chunk, c, desc->node.prev, node) {
++ /*
++ * All chunks are on the global ld_free, so, we have to find
++ * the end of the chain ourselves
++ */
++ if (chunk != desc && (chunk->mark == DESC_IDLE ||
++ chunk->async_tx.cookie > 0 ||
++ chunk->async_tx.cookie == -EBUSY ||
++ &chunk->node == &schan->ld_free))
++ break;
++ chunk->mark = DESC_SUBMITTED;
++ /* Callback goes to the last chunk */
++ chunk->async_tx.callback = NULL;
++ chunk->cookie = cookie;
++ list_move_tail(&chunk->node, &schan->ld_queue);
++ last = chunk;
++
++ dev_dbg(schan->dev, "submit #%d@%p on %d\n",
++ tx->cookie, &last->async_tx, schan->id);
++ }
++
++ last->async_tx.callback = callback;
++ last->async_tx.callback_param = tx->callback_param;
++
++ if (power_up) {
++ int ret;
++ schan->pm_state = SHDMA_PM_BUSY;
++
++ ret = pm_runtime_get(schan->dev);
++
++ spin_unlock_irq(&schan->chan_lock);
++ if (ret < 0)
++ dev_err(schan->dev, "%s(): GET = %d\n", __func__, ret);
++
++ pm_runtime_barrier(schan->dev);
++
++ spin_lock_irq(&schan->chan_lock);
++
++ /* Have we been reset, while waiting? */
++ if (schan->pm_state != SHDMA_PM_ESTABLISHED) {
++ struct shdma_dev *sdev =
++ to_shdma_dev(schan->dma_chan.device);
++ const struct shdma_ops *ops = sdev->ops;
++ dev_dbg(schan->dev, "Bring up channel %d\n",
++ schan->id);
++ /*
++ * TODO: .xfer_setup() might fail on some platforms.
++ * Make it int then, on error remove chunks from the
++ * queue again
++ */
++ ops->setup_xfer(schan, slave);
++
++ if (schan->pm_state == SHDMA_PM_PENDING)
++ shdma_chan_xfer_ld_queue(schan);
++ schan->pm_state = SHDMA_PM_ESTABLISHED;
++ }
++ } else {
++ /*
++ * Tell .device_issue_pending() not to run the queue, interrupts
++ * will do it anyway
++ */
++ schan->pm_state = SHDMA_PM_PENDING;
++ }
++
++ spin_unlock_irq(&schan->chan_lock);
++
++ return cookie;
++}
++
++/* Called with desc_lock held */
++static struct shdma_desc *shdma_get_desc(struct shdma_chan *schan)
++{
++ struct shdma_desc *sdesc;
++
++ list_for_each_entry(sdesc, &schan->ld_free, node)
++ if (sdesc->mark != DESC_PREPARED) {
++ BUG_ON(sdesc->mark != DESC_IDLE);
++ list_del(&sdesc->node);
++ return sdesc;
++ }
++
++ return NULL;
++}
++
++static int shdma_alloc_chan_resources(struct dma_chan *chan)
++{
++ struct shdma_chan *schan = to_shdma_chan(chan);
++ struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device);
++ const struct shdma_ops *ops = sdev->ops;
++ struct shdma_desc *desc;
++ struct shdma_slave *slave = chan->private;
++ int ret, i;
++
++ /*
++ * This relies on the guarantee from dmaengine that alloc_chan_resources
++ * never runs concurrently with itself or free_chan_resources.
++ */
++ if (slave) {
++ if (slave->slave_id >= slave_num) {
++ ret = -EINVAL;
++ goto evalid;
++ }
++
++ if (test_and_set_bit(slave->slave_id, shdma_slave_used)) {
++ ret = -EBUSY;
++ goto etestused;
++ }
++
++ ret = ops->set_slave(schan, slave);
++ if (ret < 0)
++ goto esetslave;
++ }
++
++ schan->desc = kcalloc(NR_DESCS_PER_CHANNEL,
++ sdev->desc_size, GFP_KERNEL);
++ if (!schan->desc) {
++ ret = -ENOMEM;
++ goto edescalloc;
++ }
++ schan->desc_num = NR_DESCS_PER_CHANNEL;
++
++ for (i = 0; i < NR_DESCS_PER_CHANNEL; i++) {
++ desc = ops->embedded_desc(schan->desc, i);
++ dma_async_tx_descriptor_init(&desc->async_tx,
++ &schan->dma_chan);
++ desc->async_tx.tx_submit = shdma_tx_submit;
++ desc->mark = DESC_IDLE;
++
++ list_add(&desc->node, &schan->ld_free);
++ }
++
++ return NR_DESCS_PER_CHANNEL;
++
++edescalloc:
++ if (slave)
++esetslave:
++ clear_bit(slave->slave_id, shdma_slave_used);
++etestused:
++evalid:
++ chan->private = NULL;
++ return ret;
++}
++
++static dma_async_tx_callback __ld_cleanup(struct shdma_chan *schan, bool all)
++{
++ struct shdma_desc *desc, *_desc;
++ /* Is the "exposed" head of a chain acked? */
++ bool head_acked = false;
++ dma_cookie_t cookie = 0;
++ dma_async_tx_callback callback = NULL;
++ void *param = NULL;
++ unsigned long flags;
++
++ spin_lock_irqsave(&schan->chan_lock, flags);
++ list_for_each_entry_safe(desc, _desc, &schan->ld_queue, node) {
++ struct dma_async_tx_descriptor *tx = &desc->async_tx;
++
++ BUG_ON(tx->cookie > 0 && tx->cookie != desc->cookie);
++ BUG_ON(desc->mark != DESC_SUBMITTED &&
++ desc->mark != DESC_COMPLETED &&
++ desc->mark != DESC_WAITING);
++
++ /*
++ * queue is ordered, and we use this loop to (1) clean up all
++ * completed descriptors, and to (2) update descriptor flags of
++ * any chunks in a (partially) completed chain
++ */
++ if (!all && desc->mark == DESC_SUBMITTED &&
++ desc->cookie != cookie)
++ break;
++
++ if (tx->cookie > 0)
++ cookie = tx->cookie;
++
++ if (desc->mark == DESC_COMPLETED && desc->chunks == 1) {
++ if (schan->dma_chan.completed_cookie != desc->cookie - 1)
++ dev_dbg(schan->dev,
++ "Completing cookie %d, expected %d\n",
++ desc->cookie,
++ schan->dma_chan.completed_cookie + 1);
++ schan->dma_chan.completed_cookie = desc->cookie;
++ }
++
++ /* Call callback on the last chunk */
++ if (desc->mark == DESC_COMPLETED && tx->callback) {
++ desc->mark = DESC_WAITING;
++ callback = tx->callback;
++ param = tx->callback_param;
++ dev_dbg(schan->dev, "descriptor #%d@%p on %d callback\n",
++ tx->cookie, tx, schan->id);
++ BUG_ON(desc->chunks != 1);
++ break;
++ }
++
++ if (tx->cookie > 0 || tx->cookie == -EBUSY) {
++ if (desc->mark == DESC_COMPLETED) {
++ BUG_ON(tx->cookie < 0);
++ desc->mark = DESC_WAITING;
++ }
++ head_acked = async_tx_test_ack(tx);
++ } else {
++ switch (desc->mark) {
++ case DESC_COMPLETED:
++ desc->mark = DESC_WAITING;
++ /* Fall through */
++ case DESC_WAITING:
++ if (head_acked)
++ async_tx_ack(&desc->async_tx);
++ }
++ }
++
++ dev_dbg(schan->dev, "descriptor %p #%d completed.\n",
++ tx, tx->cookie);
++
++ if (((desc->mark == DESC_COMPLETED ||
++ desc->mark == DESC_WAITING) &&
++ async_tx_test_ack(&desc->async_tx)) || all) {
++ /* Remove from ld_queue list */
++ desc->mark = DESC_IDLE;
++
++ list_move(&desc->node, &schan->ld_free);
++
++ if (list_empty(&schan->ld_queue)) {
++ dev_dbg(schan->dev, "Bring down channel %d\n", schan->id);
++ pm_runtime_put(schan->dev);
++ schan->pm_state = SHDMA_PM_ESTABLISHED;
++ }
++ }
++ }
++
++ if (all && !callback)
++ /*
++ * Terminating and the loop completed normally: forgive
++ * uncompleted cookies
++ */
++ schan->dma_chan.completed_cookie = schan->dma_chan.cookie;
++
++ spin_unlock_irqrestore(&schan->chan_lock, flags);
++
++ if (callback)
++ callback(param);
++
++ return callback;
++}
++
++/*
++ * shdma_chan_ld_cleanup - Clean up link descriptors
++ *
++ * Clean up the ld_queue of DMA channel.
++ */
++static void shdma_chan_ld_cleanup(struct shdma_chan *schan, bool all)
++{
++ while (__ld_cleanup(schan, all))
++ ;
++}
++
++/*
++ * shdma_free_chan_resources - Free all resources of the channel.
++ */
++static void shdma_free_chan_resources(struct dma_chan *chan)
++{
++ struct shdma_chan *schan = to_shdma_chan(chan);
++ struct shdma_dev *sdev = to_shdma_dev(chan->device);
++ const struct shdma_ops *ops = sdev->ops;
++ LIST_HEAD(list);
++
++ /* Protect against ISR */
++ spin_lock_irq(&schan->chan_lock);
++ ops->halt_channel(schan);
++ spin_unlock_irq(&schan->chan_lock);
++
++ /* Now no new interrupts will occur */
++
++ /* Prepared and not submitted descriptors can still be on the queue */
++ if (!list_empty(&schan->ld_queue))
++ shdma_chan_ld_cleanup(schan, true);
++
++ if (chan->private) {
++ /* The caller is holding dma_list_mutex */
++ struct shdma_slave *slave = chan->private;
++ clear_bit(slave->slave_id, shdma_slave_used);
++ chan->private = NULL;
++ }
++
++ spin_lock_irq(&schan->chan_lock);
++
++ list_splice_init(&schan->ld_free, &list);
++ schan->desc_num = 0;
++
++ spin_unlock_irq(&schan->chan_lock);
++
++ kfree(schan->desc);
++}
++
++/**
++ * shdma_add_desc - get, set up and return one transfer descriptor
++ * @schan: DMA channel
++ * @flags: DMA transfer flags
++ * @dst: destination DMA address, incremented when direction equals
++ * DMA_DEV_TO_MEM or DMA_MEM_TO_MEM
++ * @src: source DMA address, incremented when direction equals
++ * DMA_MEM_TO_DEV or DMA_MEM_TO_MEM
++ * @len: DMA transfer length
++ * @first: if NULL, set to the current descriptor and cookie set to -EBUSY
++ * @direction: needed for slave DMA to decide which address to keep constant,
++ * equals DMA_MEM_TO_MEM for MEMCPY
++ * Returns 0 or an error
++ * Locks: called with desc_lock held
++ */
++static struct shdma_desc *shdma_add_desc(struct shdma_chan *schan,
++ unsigned long flags, dma_addr_t *dst, dma_addr_t *src, size_t *len,
++ struct shdma_desc **first, enum dma_transfer_direction direction)
++{
++ struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device);
++ const struct shdma_ops *ops = sdev->ops;
++ struct shdma_desc *new;
++ size_t copy_size = *len;
++
++ if (!copy_size)
++ return NULL;
++
++ /* Allocate the link descriptor from the free list */
++ new = shdma_get_desc(schan);
++ if (!new) {
++ dev_err(schan->dev, "No free link descriptor available\n");
++ return NULL;
++ }
++
++ ops->desc_setup(schan, new, *src, *dst, &copy_size);
++
++ if (!*first) {
++ /* First desc */
++ new->async_tx.cookie = -EBUSY;
++ *first = new;
++ } else {
++ /* Other desc - invisible to the user */
++ new->async_tx.cookie = -EINVAL;
++ }
++
++ dev_dbg(schan->dev,
++ "chaining (%u/%u)@%x -> %x with %p, cookie %d\n",
++ copy_size, *len, *src, *dst, &new->async_tx,
++ new->async_tx.cookie);
++
++ new->mark = DESC_PREPARED;
++ new->async_tx.flags = flags;
++ new->direction = direction;
++
++ *len -= copy_size;
++ if (direction == DMA_MEM_TO_MEM || direction == DMA_MEM_TO_DEV)
++ *src += copy_size;
++ if (direction == DMA_MEM_TO_MEM || direction == DMA_DEV_TO_MEM)
++ *dst += copy_size;
++
++ return new;
++}
++
++/*
++ * shdma_prep_sg - prepare transfer descriptors from an SG list
++ *
++ * Common routine for public (MEMCPY) and slave DMA. The MEMCPY case is also
++ * converted to scatter-gather to guarantee consistent locking and a correct
++ * list manipulation. For slave DMA direction carries the usual meaning, and,
++ * logically, the SG list is RAM and the addr variable contains slave address,
++ * e.g., the FIFO I/O register. For MEMCPY direction equals DMA_MEM_TO_MEM
++ * and the SG list contains only one element and points at the source buffer.
++ */
++static struct dma_async_tx_descriptor *shdma_prep_sg(struct shdma_chan *schan,
++ struct scatterlist *sgl, unsigned int sg_len, dma_addr_t *addr,
++ enum dma_transfer_direction direction, unsigned long flags)
++{
++ struct scatterlist *sg;
++ struct shdma_desc *first = NULL, *new = NULL /* compiler... */;
++ LIST_HEAD(tx_list);
++ int chunks = 0;
++ unsigned long irq_flags;
++ int i;
++
++ for_each_sg(sgl, sg, sg_len, i)
++ chunks += DIV_ROUND_UP(sg_dma_len(sg), schan->max_xfer_len);
++
++ /* Have to lock the whole loop to protect against concurrent release */
++ spin_lock_irqsave(&schan->chan_lock, irq_flags);
++
++ /*
++ * Chaining:
++ * first descriptor is what user is dealing with in all API calls, its
++ * cookie is at first set to -EBUSY, at tx-submit to a positive
++ * number
++ * if more than one chunk is needed further chunks have cookie = -EINVAL
++ * the last chunk, if not equal to the first, has cookie = -ENOSPC
++ * all chunks are linked onto the tx_list head with their .node heads
++ * only during this function, then they are immediately spliced
++ * back onto the free list in form of a chain
++ */
++ for_each_sg(sgl, sg, sg_len, i) {
++ dma_addr_t sg_addr = sg_dma_address(sg);
++ size_t len = sg_dma_len(sg);
++
++ if (!len)
++ goto err_get_desc;
++
++ do {
++ dev_dbg(schan->dev, "Add SG #%d@%p[%d], dma %llx\n",
++ i, sg, len, (unsigned long long)sg_addr);
++
++ if (direction == DMA_DEV_TO_MEM)
++ new = shdma_add_desc(schan, flags,
++ &sg_addr, addr, &len, &first,
++ direction);
++ else
++ new = shdma_add_desc(schan, flags,
++ addr, &sg_addr, &len, &first,
++ direction);
++ if (!new)
++ goto err_get_desc;
++
++ new->chunks = chunks--;
++ list_add_tail(&new->node, &tx_list);
++ } while (len);
++ }
++
++ if (new != first)
++ new->async_tx.cookie = -ENOSPC;
++
++ /* Put them back on the free list, so, they don't get lost */
++ list_splice_tail(&tx_list, &schan->ld_free);
++
++ spin_unlock_irqrestore(&schan->chan_lock, irq_flags);
++
++ return &first->async_tx;
++
++err_get_desc:
++ list_for_each_entry(new, &tx_list, node)
++ new->mark = DESC_IDLE;
++ list_splice(&tx_list, &schan->ld_free);
++
++ spin_unlock_irqrestore(&schan->chan_lock, irq_flags);
++
++ return NULL;
++}
++
++static struct dma_async_tx_descriptor *shdma_prep_memcpy(
++ struct dma_chan *chan, dma_addr_t dma_dest, dma_addr_t dma_src,
++ size_t len, unsigned long flags)
++{
++ struct shdma_chan *schan = to_shdma_chan(chan);
++ struct scatterlist sg;
++
++ if (!chan || !len)
++ return NULL;
++
++ BUG_ON(!schan->desc_num);
++
++ sg_init_table(&sg, 1);
++ sg_set_page(&sg, pfn_to_page(PFN_DOWN(dma_src)), len,
++ offset_in_page(dma_src));
++ sg_dma_address(&sg) = dma_src;
++ sg_dma_len(&sg) = len;
++
++ return shdma_prep_sg(schan, &sg, 1, &dma_dest, DMA_MEM_TO_MEM, flags);
++}
++
++static struct dma_async_tx_descriptor *shdma_prep_slave_sg(
++ struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len,
++ enum dma_transfer_direction direction, unsigned long flags, void *context)
++{
++ struct shdma_chan *schan = to_shdma_chan(chan);
++ struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device);
++ const struct shdma_ops *ops = sdev->ops;
++ struct shdma_slave *slave = chan->private;
++ dma_addr_t slave_addr;
++
++ if (!chan)
++ return NULL;
++
++ BUG_ON(!schan->desc_num);
++
++ /* Someone calling slave DMA on a generic channel? */
++ if (!slave || !sg_len) {
++ dev_warn(schan->dev, "%s: bad parameter: %p, %d, %d\n",
++ __func__, slave, sg_len, slave ? slave->slave_id : -1);
++ return NULL;
++ }
++
++ slave_addr = ops->slave_addr(schan);
++
++ return shdma_prep_sg(schan, sgl, sg_len, &slave_addr,
++ direction, flags);
++}
++
++static int shdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
++ unsigned long arg)
++{
++ struct shdma_chan *schan = to_shdma_chan(chan);
++ struct shdma_dev *sdev = to_shdma_dev(chan->device);
++ const struct shdma_ops *ops = sdev->ops;
++ unsigned long flags;
++
++ /* Only supports DMA_TERMINATE_ALL */
++ if (cmd != DMA_TERMINATE_ALL)
++ return -ENXIO;
++
++ if (!chan)
++ return -EINVAL;
++
++ spin_lock_irqsave(&schan->chan_lock, flags);
++
++ ops->halt_channel(schan);
++
++ spin_unlock_irqrestore(&schan->chan_lock, flags);
++
++ shdma_chan_ld_cleanup(schan, true);
++
++ return 0;
++}
++
++static void shdma_issue_pending(struct dma_chan *chan)
++{
++ struct shdma_chan *schan = to_shdma_chan(chan);
++
++ spin_lock_irq(&schan->chan_lock);
++ if (schan->pm_state == SHDMA_PM_ESTABLISHED)
++ shdma_chan_xfer_ld_queue(schan);
++ else
++ schan->pm_state = SHDMA_PM_PENDING;
++ spin_unlock_irq(&schan->chan_lock);
++}
++
++static enum dma_status shdma_tx_status(struct dma_chan *chan,
++ dma_cookie_t cookie,
++ struct dma_tx_state *txstate)
++{
++ struct shdma_chan *schan = to_shdma_chan(chan);
++ enum dma_status status;
++ unsigned long flags;
++
++ shdma_chan_ld_cleanup(schan, false);
++
++ spin_lock_irqsave(&schan->chan_lock, flags);
++
++ status = dma_cookie_status(chan, cookie, txstate);
++
++ /*
++ * If we don't find cookie on the queue, it has been aborted and we have
++ * to report error
++ */
++ if (status != DMA_SUCCESS) {
++ struct shdma_desc *sdesc;
++ status = DMA_ERROR;
++ list_for_each_entry(sdesc, &schan->ld_queue, node)
++ if (sdesc->cookie == cookie) {
++ status = DMA_IN_PROGRESS;
++ break;
++ }
++ }
++
++ spin_unlock_irqrestore(&schan->chan_lock, flags);
++
++ return status;
++}
++
++/* Called from error IRQ or NMI */
++bool shdma_reset(struct shdma_dev *sdev)
++{
++ const struct shdma_ops *ops = sdev->ops;
++ struct shdma_chan *schan;
++ unsigned int handled = 0;
++ int i;
++
++ /* Reset all channels */
++ shdma_for_each_chan(schan, sdev, i) {
++ struct shdma_desc *sdesc;
++ LIST_HEAD(dl);
++
++ if (!schan)
++ continue;
++
++ spin_lock(&schan->chan_lock);
++
++ /* Stop the channel */
++ ops->halt_channel(schan);
++
++ list_splice_init(&schan->ld_queue, &dl);
++
++ if (!list_empty(&dl)) {
++ dev_dbg(schan->dev, "Bring down channel %d\n", schan->id);
++ pm_runtime_put(schan->dev);
++ }
++ schan->pm_state = SHDMA_PM_ESTABLISHED;
++
++ spin_unlock(&schan->chan_lock);
++
++ /* Complete all */
++ list_for_each_entry(sdesc, &dl, node) {
++ struct dma_async_tx_descriptor *tx = &sdesc->async_tx;
++ sdesc->mark = DESC_IDLE;
++ if (tx->callback)
++ tx->callback(tx->callback_param);
++ }
++
++ spin_lock(&schan->chan_lock);
++ list_splice(&dl, &schan->ld_free);
++ spin_unlock(&schan->chan_lock);
++
++ handled++;
++ }
++
++ return !!handled;
++}
++EXPORT_SYMBOL(shdma_reset);
++
++static irqreturn_t chan_irq(int irq, void *dev)
++{
++ struct shdma_chan *schan = dev;
++ const struct shdma_ops *ops =
++ to_shdma_dev(schan->dma_chan.device)->ops;
++ irqreturn_t ret;
++
++ spin_lock(&schan->chan_lock);
++
++ ret = ops->chan_irq(schan, irq) ? IRQ_WAKE_THREAD : IRQ_NONE;
++
++ spin_unlock(&schan->chan_lock);
++
++ return ret;
++}
++
++static irqreturn_t chan_irqt(int irq, void *dev)
++{
++ struct shdma_chan *schan = dev;
++ const struct shdma_ops *ops =
++ to_shdma_dev(schan->dma_chan.device)->ops;
++ struct shdma_desc *sdesc;
++
++ spin_lock_irq(&schan->chan_lock);
++ list_for_each_entry(sdesc, &schan->ld_queue, node) {
++ if (sdesc->mark == DESC_SUBMITTED &&
++ ops->desc_completed(schan, sdesc)) {
++ dev_dbg(schan->dev, "done #%d@%p\n",
++ sdesc->async_tx.cookie, &sdesc->async_tx);
++ sdesc->mark = DESC_COMPLETED;
++ break;
++ }
++ }
++ /* Next desc */
++ shdma_chan_xfer_ld_queue(schan);
++ spin_unlock_irq(&schan->chan_lock);
++
++ shdma_chan_ld_cleanup(schan, false);
++
++ return IRQ_HANDLED;
++}
++
++int shdma_request_irq(struct shdma_chan *schan, int irq,
++ unsigned long flags, const char *name)
++{
++ int ret = request_threaded_irq(irq, chan_irq, chan_irqt,
++ flags, name, schan);
++
++ schan->irq = ret < 0 ? ret : irq;
++
++ return ret;
++}
++EXPORT_SYMBOL(shdma_request_irq);
++
++void shdma_free_irq(struct shdma_chan *schan)
++{
++ if (schan->irq >= 0)
++ free_irq(schan->irq, schan);
++}
++EXPORT_SYMBOL(shdma_free_irq);
++
++void shdma_chan_probe(struct shdma_dev *sdev,
++ struct shdma_chan *schan, int id)
++{
++ schan->pm_state = SHDMA_PM_ESTABLISHED;
++
++ /* reference struct dma_device */
++ schan->dma_chan.device = &sdev->dma_dev;
++ dma_cookie_init(&schan->dma_chan);
++
++ schan->dev = sdev->dma_dev.dev;
++ schan->id = id;
++
++ if (!schan->max_xfer_len)
++ schan->max_xfer_len = PAGE_SIZE;
++
++ spin_lock_init(&schan->chan_lock);
++
++ /* Init descripter manage list */
++ INIT_LIST_HEAD(&schan->ld_queue);
++ INIT_LIST_HEAD(&schan->ld_free);
++
++ /* Add the channel to DMA device channel list */
++ list_add_tail(&schan->dma_chan.device_node,
++ &sdev->dma_dev.channels);
++ sdev->schan[sdev->dma_dev.chancnt++] = schan;
++}
++EXPORT_SYMBOL(shdma_chan_probe);
++
++void shdma_chan_remove(struct shdma_chan *schan)
++{
++ list_del(&schan->dma_chan.device_node);
++}
++EXPORT_SYMBOL(shdma_chan_remove);
++
++int shdma_init(struct device *dev, struct shdma_dev *sdev,
++ int chan_num)
++{
++ struct dma_device *dma_dev = &sdev->dma_dev;
++
++ /*
++ * Require all call-backs for now, they can trivially be made optional
++ * later as required
++ */
++ if (!sdev->ops ||
++ !sdev->desc_size ||
++ !sdev->ops->embedded_desc ||
++ !sdev->ops->start_xfer ||
++ !sdev->ops->setup_xfer ||
++ !sdev->ops->set_slave ||
++ !sdev->ops->desc_setup ||
++ !sdev->ops->slave_addr ||
++ !sdev->ops->channel_busy ||
++ !sdev->ops->halt_channel ||
++ !sdev->ops->desc_completed)
++ return -EINVAL;
++
++ sdev->schan = kcalloc(chan_num, sizeof(*sdev->schan), GFP_KERNEL);
++ if (!sdev->schan)
++ return -ENOMEM;
++
++ INIT_LIST_HEAD(&dma_dev->channels);
++
++ /* Common and MEMCPY operations */
++ dma_dev->device_alloc_chan_resources
++ = shdma_alloc_chan_resources;
++ dma_dev->device_free_chan_resources = shdma_free_chan_resources;
++ dma_dev->device_prep_dma_memcpy = shdma_prep_memcpy;
++ dma_dev->device_tx_status = shdma_tx_status;
++ dma_dev->device_issue_pending = shdma_issue_pending;
++
++ /* Compulsory for DMA_SLAVE fields */
++ dma_dev->device_prep_slave_sg = shdma_prep_slave_sg;
++ dma_dev->device_control = shdma_control;
++
++ dma_dev->dev = dev;
++
++ return 0;
++}
++EXPORT_SYMBOL(shdma_init);
++
++void shdma_cleanup(struct shdma_dev *sdev)
++{
++ kfree(sdev->schan);
++}
++EXPORT_SYMBOL(shdma_cleanup);
++
++static int __init shdma_enter(void)
++{
++ shdma_slave_used = kzalloc(DIV_ROUND_UP(slave_num, BITS_PER_LONG) *
++ sizeof(long), GFP_KERNEL);
++ if (!shdma_slave_used)
++ return -ENOMEM;
++ return 0;
++}
++module_init(shdma_enter);
++
++static void __exit shdma_exit(void)
++{
++ kfree(shdma_slave_used);
++}
++module_exit(shdma_exit);
++
++MODULE_LICENSE("GPL v2");
++MODULE_DESCRIPTION("SH-DMA driver base library");
++MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
+diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h
+new file mode 100644
+index 0000000..83efd13
+--- /dev/null
++++ b/include/linux/shdma-base.h
+@@ -0,0 +1,123 @@
++/*
++ * Dmaengine driver base library for DMA controllers, found on SH-based SoCs
++ *
++ * extracted from shdma.c and headers
++ *
++ * Copyright (C) 2011-2012 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
++ * Copyright (C) 2009 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
++ * Copyright (C) 2009 Renesas Solutions, Inc. All rights reserved.
++ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
++ *
++ * This is free software; you can redistribute it and/or modify
++ * it under the terms of version 2 of the GNU General Public License as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef SHDMA_BASE_H
++#define SHDMA_BASE_H
++
++#include <linux/dmaengine.h>
++#include <linux/interrupt.h>
++#include <linux/list.h>
++#include <linux/types.h>
++
++/**
++ * shdma_pm_state - DMA channel PM state
++ * SHDMA_PM_ESTABLISHED: either idle or during data transfer
++ * SHDMA_PM_BUSY: during the transfer preparation, when we have to
++ * drop the lock temporarily
++ * SHDMA_PM_PENDING: transfers pending
++ */
++enum shdma_pm_state {
++ SHDMA_PM_ESTABLISHED,
++ SHDMA_PM_BUSY,
++ SHDMA_PM_PENDING,
++};
++
++struct device;
++
++/*
++ * Drivers, using this library are expected to embed struct shdma_dev,
++ * struct shdma_chan, struct shdma_desc, and struct shdma_slave
++ * in their respective device, channel, descriptor and slave objects.
++ */
++
++struct shdma_slave {
++ unsigned int slave_id;
++};
++
++struct shdma_desc {
++ struct list_head node;
++ struct dma_async_tx_descriptor async_tx;
++ enum dma_transfer_direction direction;
++ dma_cookie_t cookie;
++ int chunks;
++ int mark;
++};
++
++struct shdma_chan {
++ spinlock_t chan_lock; /* Channel operation lock */
++ struct list_head ld_queue; /* Link descriptors queue */
++ struct list_head ld_free; /* Free link descriptors */
++ struct dma_chan dma_chan; /* DMA channel */
++ struct device *dev; /* Channel device */
++ void *desc; /* buffer for descriptor array */
++ int desc_num; /* desc count */
++ size_t max_xfer_len; /* max transfer length */
++ int id; /* Raw id of this channel */
++ int irq; /* Channel IRQ */
++ enum shdma_pm_state pm_state;
++};
++
++/**
++ * struct shdma_ops - simple DMA driver operations
++ * desc_completed: return true, if this is the descriptor, that just has
++ * completed (atomic)
++ * halt_channel: stop DMA channel operation (atomic)
++ * channel_busy: return true, if the channel is busy (atomic)
++ * slave_addr: return slave DMA address
++ * desc_setup: set up the hardware specific descriptor portion (atomic)
++ * set_slave: bind channel to a slave
++ * setup_xfer: configure channel hardware for operation (atomic)
++ * start_xfer: start the DMA transfer (atomic)
++ * embedded_desc: return Nth struct shdma_desc pointer from the
++ * descriptor array
++ * chan_irq: process channel IRQ, return true if a transfer has
++ * completed (atomic)
++ */
++struct shdma_ops {
++ bool (*desc_completed)(struct shdma_chan *, struct shdma_desc *);
++ void (*halt_channel)(struct shdma_chan *);
++ bool (*channel_busy)(struct shdma_chan *);
++ dma_addr_t (*slave_addr)(struct shdma_chan *);
++ int (*desc_setup)(struct shdma_chan *, struct shdma_desc *,
++ dma_addr_t, dma_addr_t, size_t *);
++ int (*set_slave)(struct shdma_chan *, struct shdma_slave *);
++ void (*setup_xfer)(struct shdma_chan *, struct shdma_slave *);
++ void (*start_xfer)(struct shdma_chan *, struct shdma_desc *);
++ struct shdma_desc *(*embedded_desc)(void *, int);
++ bool (*chan_irq)(struct shdma_chan *, int);
++};
++
++struct shdma_dev {
++ struct dma_device dma_dev;
++ struct shdma_chan **schan;
++ const struct shdma_ops *ops;
++ size_t desc_size;
++};
++
++#define shdma_for_each_chan(c, d, i) for (i = 0, c = (d)->schan[0]; \
++ i < (d)->dma_dev.chancnt; c = (d)->schan[++i])
++
++int shdma_request_irq(struct shdma_chan *, int,
++ unsigned long, const char *);
++void shdma_free_irq(struct shdma_chan *);
++bool shdma_reset(struct shdma_dev *sdev);
++void shdma_chan_probe(struct shdma_dev *sdev,
++ struct shdma_chan *schan, int id);
++void shdma_chan_remove(struct shdma_chan *schan);
++int shdma_init(struct device *dev, struct shdma_dev *sdev,
++ int chan_num);
++void shdma_cleanup(struct shdma_dev *sdev);
++
++#endif
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0050-dma-shdma-prepare-for-conversion-to-the-shdma-base-l.patch b/patches.marzen/0050-dma-shdma-prepare-for-conversion-to-the-shdma-base-l.patch
new file mode 100644
index 0000000000000..c035e948cf9cf
--- /dev/null
+++ b/patches.marzen/0050-dma-shdma-prepare-for-conversion-to-the-shdma-base-l.patch
@@ -0,0 +1,44 @@
+From ede599a5d672322a39cf12cc4fdb59fe67898908 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 9 May 2012 17:09:14 +0200
+Subject: dma: shdma: prepare for conversion to the shdma base library
+
+By placing an anonymous union at the top of struct sh_dmae_slave we can
+transparently prepare all device and client drivers for the upcoming
+shdma-base conversion.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit 5902c9a7a2a9c2520af54af1ba7a9c7831664a17)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/sh_dma.h | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/sh_dma.h b/include/linux/sh_dma.h
+index 425450b..e081e8e 100644
+--- a/include/linux/sh_dma.h
++++ b/include/linux/sh_dma.h
+@@ -10,12 +10,16 @@
+ #ifndef SH_DMA_H
+ #define SH_DMA_H
+
+-#include <linux/list.h>
+ #include <linux/dmaengine.h>
++#include <linux/list.h>
++#include <linux/shdma-base.h>
+
+ /* Used by slave DMA clients to request DMA to/from a specific peripheral */
+ struct sh_dmae_slave {
+- unsigned int slave_id; /* Set by the platform */
++ union {
++ unsigned int slave_id; /* Set by the platform */
++ struct shdma_slave shdma_slave;
++ };
+ struct device *dma_dev; /* Set by the platform */
+ const struct sh_dmae_slave_config *config; /* Set by the driver */
+ };
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0051-ASoC-fsi-prepare-for-conversion-to-the-shdma-base-li.patch b/patches.marzen/0051-ASoC-fsi-prepare-for-conversion-to-the-shdma-base-li.patch
new file mode 100644
index 0000000000000..bba8d95b89fca
--- /dev/null
+++ b/patches.marzen/0051-ASoC-fsi-prepare-for-conversion-to-the-shdma-base-li.patch
@@ -0,0 +1,30 @@
+From 6381d33c361574132c3152d0cfa56278a67d40f7 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 9 May 2012 17:09:20 +0200
+Subject: ASoC: fsi: prepare for conversion to the shdma base library
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Cc: Liam Girdwood <lrg@ti.com>
+Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit b8373147ed3ca01a968d81f22688f2836a9aeb6b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -1533,8 +1533,8 @@ static void fsi_handler_init(struct fsi_
+ fsi->capture.priv = fsi;
+
+ if (fsi->info->tx_id) {
+- fsi->playback.slave.slave_id = fsi->info->tx_id;
+- fsi->playback.handler = &fsi_dma_push_handler;
++ fsi->playback.slave.shdma_slave.slave_id = fsi->info->tx_id;
++ fsi->playback.handler = &fsi_dma_push_handler;
+ }
+ }
+
diff --git a/patches.marzen/0052-usb-renesas_usbhs-prepare-for-conversion-to-the-shdm.patch b/patches.marzen/0052-usb-renesas_usbhs-prepare-for-conversion-to-the-shdm.patch
new file mode 100644
index 0000000000000..4a3b49df3679c
--- /dev/null
+++ b/patches.marzen/0052-usb-renesas_usbhs-prepare-for-conversion-to-the-shdm.patch
@@ -0,0 +1,55 @@
+From a840c360c6d890060307ee970d8630f9bf812af1 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 9 May 2012 17:09:19 +0200
+Subject: usb: renesas_usbhs: prepare for conversion to the shdma base library
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit f19b7e0db7744dd1ed6052cc58a90b74a29772b8)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/usb/renesas_usbhs/fifo.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
+index 6ec7f83..fc597a4 100644
+--- a/drivers/usb/renesas_usbhs/fifo.c
++++ b/drivers/usb/renesas_usbhs/fifo.c
+@@ -994,7 +994,7 @@ static bool usbhsf_dma_filter(struct dma_chan *chan, void *param)
+ *
+ * usbhs doesn't recognize id = 0 as valid DMA
+ */
+- if (0 == slave->slave_id)
++ if (0 == slave->shdma_slave.slave_id)
+ return false;
+
+ chan->private = slave;
+@@ -1173,8 +1173,8 @@ int usbhs_fifo_probe(struct usbhs_priv *priv)
+ fifo->port = D0FIFO;
+ fifo->sel = D0FIFOSEL;
+ fifo->ctr = D0FIFOCTR;
+- fifo->tx_slave.slave_id = usbhs_get_dparam(priv, d0_tx_id);
+- fifo->rx_slave.slave_id = usbhs_get_dparam(priv, d0_rx_id);
++ fifo->tx_slave.shdma_slave.slave_id = usbhs_get_dparam(priv, d0_tx_id);
++ fifo->rx_slave.shdma_slave.slave_id = usbhs_get_dparam(priv, d0_rx_id);
+
+ /* D1FIFO */
+ fifo = usbhsf_get_d1fifo(priv);
+@@ -1182,8 +1182,8 @@ int usbhs_fifo_probe(struct usbhs_priv *priv)
+ fifo->port = D1FIFO;
+ fifo->sel = D1FIFOSEL;
+ fifo->ctr = D1FIFOCTR;
+- fifo->tx_slave.slave_id = usbhs_get_dparam(priv, d1_tx_id);
+- fifo->rx_slave.slave_id = usbhs_get_dparam(priv, d1_rx_id);
++ fifo->tx_slave.shdma_slave.slave_id = usbhs_get_dparam(priv, d1_tx_id);
++ fifo->rx_slave.shdma_slave.slave_id = usbhs_get_dparam(priv, d1_rx_id);
+
+ return 0;
+ }
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0053-dma-shdma-convert-to-the-shdma-base-library.patch b/patches.marzen/0053-dma-shdma-convert-to-the-shdma-base-library.patch
new file mode 100644
index 0000000000000..674d5484dc134
--- /dev/null
+++ b/patches.marzen/0053-dma-shdma-convert-to-the-shdma-base-library.patch
@@ -0,0 +1,1561 @@
+From 67976cd109fc26028e9fbcede6badbf236d865e8 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 9 May 2012 17:09:21 +0200
+Subject: dma: shdma: convert to the shdma base library
+
+The shdma base library has originally been extracted from the shdma driver,
+which now can be converted to actually use it.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit ce3a1ab74264b860450709e4bd0dcfc2d0bfc7f8)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/dma/sh/shdma.c | 1122 ++++++++++++------------------------------------
+ drivers/dma/sh/shdma.h | 44 +-
+ include/linux/sh_dma.h | 33 +-
+ 3 files changed, 302 insertions(+), 897 deletions(-)
+
+diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c
+index 8ab4a1f..c393b35 100644
+--- a/drivers/dma/sh/shdma.c
++++ b/drivers/dma/sh/shdma.c
+@@ -3,6 +3,7 @@
+ *
+ * base is drivers/dma/flsdma.c
+ *
++ * Copyright (C) 2011-2012 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ * Copyright (C) 2009 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
+ * Copyright (C) 2009 Renesas Solutions, Inc. All rights reserved.
+ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+@@ -34,18 +35,12 @@
+ #include "../dmaengine.h"
+ #include "shdma.h"
+
+-/* DMA descriptor control */
+-enum sh_dmae_desc_status {
+- DESC_IDLE,
+- DESC_PREPARED,
+- DESC_SUBMITTED,
+- DESC_COMPLETED, /* completed, have to call callback */
+- DESC_WAITING, /* callback called, waiting for ack / re-submit */
+-};
++#define SH_DMAE_DRV_NAME "sh-dma-engine"
+
+-#define NR_DESCS_PER_CHANNEL 32
+ /* Default MEMCPY transfer size = 2^2 = 4 bytes */
+ #define LOG2_DEFAULT_XFER_SIZE 2
++#define SH_DMA_SLAVE_NUMBER 256
++#define SH_DMA_TCR_MAX (16 * 1024 * 1024 - 1)
+
+ /*
+ * Used for write-side mutual exclusion for the global device list,
+@@ -54,18 +49,12 @@ enum sh_dmae_desc_status {
+ static DEFINE_SPINLOCK(sh_dmae_lock);
+ static LIST_HEAD(sh_dmae_devices);
+
+-/* A bitmask with bits enough for enum sh_dmae_slave_chan_id */
+-static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SH_DMA_SLAVE_NUMBER)];
+-
+-static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all);
+-static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan);
+-
+ static void chclr_write(struct sh_dmae_chan *sh_dc, u32 data)
+ {
+ struct sh_dmae_device *shdev = to_sh_dev(sh_dc);
+
+ __raw_writel(data, shdev->chan_reg +
+- shdev->pdata->channel[sh_dc->id].chclr_offset);
++ shdev->pdata->channel[sh_dc->shdma_chan.id].chclr_offset);
+ }
+
+ static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg)
+@@ -155,11 +144,11 @@ static int sh_dmae_rst(struct sh_dmae_device *shdev)
+ spin_unlock_irqrestore(&sh_dmae_lock, flags);
+
+ if (dmaor & (DMAOR_AE | DMAOR_NMIF)) {
+- dev_warn(shdev->common.dev, "Can't initialize DMAOR.\n");
++ dev_warn(shdev->shdma_dev.dma_dev.dev, "Can't initialize DMAOR.\n");
+ return -EIO;
+ }
+ if (shdev->pdata->dmaor_init & ~dmaor)
+- dev_warn(shdev->common.dev,
++ dev_warn(shdev->shdma_dev.dma_dev.dev,
+ "DMAOR=0x%x hasn't latched the initial value 0x%x.\n",
+ dmaor, shdev->pdata->dmaor_init);
+ return 0;
+@@ -224,15 +213,6 @@ static void dmae_start(struct sh_dmae_chan *sh_chan)
+ chcr_write(sh_chan, chcr & ~CHCR_TE);
+ }
+
+-static void dmae_halt(struct sh_dmae_chan *sh_chan)
+-{
+- struct sh_dmae_device *shdev = to_sh_dev(sh_chan);
+- u32 chcr = chcr_read(sh_chan);
+-
+- chcr &= ~(CHCR_DE | CHCR_TE | shdev->chcr_ie_bit);
+- chcr_write(sh_chan, chcr);
+-}
+-
+ static void dmae_init(struct sh_dmae_chan *sh_chan)
+ {
+ /*
+@@ -261,7 +241,7 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val)
+ {
+ struct sh_dmae_device *shdev = to_sh_dev(sh_chan);
+ struct sh_dmae_pdata *pdata = shdev->pdata;
+- const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id];
++ const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->shdma_chan.id];
+ u16 __iomem *addr = shdev->dmars;
+ unsigned int shift = chan_pdata->dmars_bit;
+
+@@ -282,706 +262,142 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val)
+ return 0;
+ }
+
+-static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx)
++static void sh_dmae_start_xfer(struct shdma_chan *schan,
++ struct shdma_desc *sdesc)
+ {
+- struct sh_desc *desc = tx_to_sh_desc(tx), *chunk, *last = desc, *c;
+- struct sh_dmae_chan *sh_chan = to_sh_chan(tx->chan);
+- struct sh_dmae_slave *param = tx->chan->private;
+- dma_async_tx_callback callback = tx->callback;
+- dma_cookie_t cookie;
+- bool power_up;
+-
+- spin_lock_irq(&sh_chan->desc_lock);
+-
+- if (list_empty(&sh_chan->ld_queue))
+- power_up = true;
+- else
+- power_up = false;
+-
+- cookie = dma_cookie_assign(tx);
+-
+- /* Mark all chunks of this descriptor as submitted, move to the queue */
+- list_for_each_entry_safe(chunk, c, desc->node.prev, node) {
+- /*
+- * All chunks are on the global ld_free, so, we have to find
+- * the end of the chain ourselves
+- */
+- if (chunk != desc && (chunk->mark == DESC_IDLE ||
+- chunk->async_tx.cookie > 0 ||
+- chunk->async_tx.cookie == -EBUSY ||
+- &chunk->node == &sh_chan->ld_free))
+- break;
+- chunk->mark = DESC_SUBMITTED;
+- /* Callback goes to the last chunk */
+- chunk->async_tx.callback = NULL;
+- chunk->cookie = cookie;
+- list_move_tail(&chunk->node, &sh_chan->ld_queue);
+- last = chunk;
+- }
+-
+- last->async_tx.callback = callback;
+- last->async_tx.callback_param = tx->callback_param;
+-
+- dev_dbg(sh_chan->dev, "submit #%d@%p on %d: %x[%d] -> %x\n",
+- tx->cookie, &last->async_tx, sh_chan->id,
+- desc->hw.sar, desc->hw.tcr, desc->hw.dar);
+-
+- if (power_up) {
+- sh_chan->pm_state = DMAE_PM_BUSY;
+-
+- pm_runtime_get(sh_chan->dev);
+-
+- spin_unlock_irq(&sh_chan->desc_lock);
+-
+- pm_runtime_barrier(sh_chan->dev);
+-
+- spin_lock_irq(&sh_chan->desc_lock);
+-
+- /* Have we been reset, while waiting? */
+- if (sh_chan->pm_state != DMAE_PM_ESTABLISHED) {
+- dev_dbg(sh_chan->dev, "Bring up channel %d\n",
+- sh_chan->id);
+- if (param) {
+- const struct sh_dmae_slave_config *cfg =
+- param->config;
+-
+- dmae_set_dmars(sh_chan, cfg->mid_rid);
+- dmae_set_chcr(sh_chan, cfg->chcr);
+- } else {
+- dmae_init(sh_chan);
+- }
+-
+- if (sh_chan->pm_state == DMAE_PM_PENDING)
+- sh_chan_xfer_ld_queue(sh_chan);
+- sh_chan->pm_state = DMAE_PM_ESTABLISHED;
+- }
+- } else {
+- sh_chan->pm_state = DMAE_PM_PENDING;
+- }
+-
+- spin_unlock_irq(&sh_chan->desc_lock);
+-
+- return cookie;
++ struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan,
++ shdma_chan);
++ struct sh_dmae_desc *sh_desc = container_of(sdesc,
++ struct sh_dmae_desc, shdma_desc);
++ dev_dbg(sh_chan->shdma_chan.dev, "Queue #%d to %d: %u@%x -> %x\n",
++ sdesc->async_tx.cookie, sh_chan->shdma_chan.id,
++ sh_desc->hw.tcr, sh_desc->hw.sar, sh_desc->hw.dar);
++ /* Get the ld start address from ld_queue */
++ dmae_set_reg(sh_chan, &sh_desc->hw);
++ dmae_start(sh_chan);
+ }
+
+-/* Called with desc_lock held */
+-static struct sh_desc *sh_dmae_get_desc(struct sh_dmae_chan *sh_chan)
++static bool sh_dmae_channel_busy(struct shdma_chan *schan)
+ {
+- struct sh_desc *desc;
+-
+- list_for_each_entry(desc, &sh_chan->ld_free, node)
+- if (desc->mark != DESC_PREPARED) {
+- BUG_ON(desc->mark != DESC_IDLE);
+- list_del(&desc->node);
+- return desc;
+- }
+-
+- return NULL;
++ struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan,
++ shdma_chan);
++ return dmae_is_busy(sh_chan);
+ }
+
+-static const struct sh_dmae_slave_config *sh_dmae_find_slave(
+- struct sh_dmae_chan *sh_chan, struct sh_dmae_slave *param)
++static void sh_dmae_setup_xfer(struct shdma_chan *schan,
++ struct shdma_slave *sslave)
+ {
+- struct sh_dmae_device *shdev = to_sh_dev(sh_chan);
+- struct sh_dmae_pdata *pdata = shdev->pdata;
+- int i;
++ struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan,
++ shdma_chan);
+
+- if (param->slave_id >= SH_DMA_SLAVE_NUMBER)
+- return NULL;
+-
+- for (i = 0; i < pdata->slave_num; i++)
+- if (pdata->slave[i].slave_id == param->slave_id)
+- return pdata->slave + i;
+-
+- return NULL;
+-}
+-
+-static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
+-{
+- struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
+- struct sh_desc *desc;
+- struct sh_dmae_slave *param = chan->private;
+- int ret;
++ if (sslave) {
++ struct sh_dmae_slave *slave = container_of(sslave,
++ struct sh_dmae_slave, shdma_slave);
++ const struct sh_dmae_slave_config *cfg =
++ slave->config;
+
+- /*
+- * This relies on the guarantee from dmaengine that alloc_chan_resources
+- * never runs concurrently with itself or free_chan_resources.
+- */
+- if (param) {
+- const struct sh_dmae_slave_config *cfg;
+-
+- cfg = sh_dmae_find_slave(sh_chan, param);
+- if (!cfg) {
+- ret = -EINVAL;
+- goto efindslave;
+- }
+-
+- if (test_and_set_bit(param->slave_id, sh_dmae_slave_used)) {
+- ret = -EBUSY;
+- goto etestused;
+- }
+-
+- param->config = cfg;
+- }
+-
+- while (sh_chan->descs_allocated < NR_DESCS_PER_CHANNEL) {
+- desc = kzalloc(sizeof(struct sh_desc), GFP_KERNEL);
+- if (!desc)
+- break;
+- dma_async_tx_descriptor_init(&desc->async_tx,
+- &sh_chan->common);
+- desc->async_tx.tx_submit = sh_dmae_tx_submit;
+- desc->mark = DESC_IDLE;
+-
+- list_add(&desc->node, &sh_chan->ld_free);
+- sh_chan->descs_allocated++;
+- }
+-
+- if (!sh_chan->descs_allocated) {
+- ret = -ENOMEM;
+- goto edescalloc;
+- }
+-
+- return sh_chan->descs_allocated;
+-
+-edescalloc:
+- if (param)
+- clear_bit(param->slave_id, sh_dmae_slave_used);
+-etestused:
+-efindslave:
+- chan->private = NULL;
+- return ret;
+-}
+-
+-/*
+- * sh_dma_free_chan_resources - Free all resources of the channel.
+- */
+-static void sh_dmae_free_chan_resources(struct dma_chan *chan)
+-{
+- struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
+- struct sh_desc *desc, *_desc;
+- LIST_HEAD(list);
+-
+- /* Protect against ISR */
+- spin_lock_irq(&sh_chan->desc_lock);
+- dmae_halt(sh_chan);
+- spin_unlock_irq(&sh_chan->desc_lock);
+-
+- /* Now no new interrupts will occur */
+-
+- /* Prepared and not submitted descriptors can still be on the queue */
+- if (!list_empty(&sh_chan->ld_queue))
+- sh_dmae_chan_ld_cleanup(sh_chan, true);
+-
+- if (chan->private) {
+- /* The caller is holding dma_list_mutex */
+- struct sh_dmae_slave *param = chan->private;
+- clear_bit(param->slave_id, sh_dmae_slave_used);
+- chan->private = NULL;
+- }
+-
+- spin_lock_irq(&sh_chan->desc_lock);
+-
+- list_splice_init(&sh_chan->ld_free, &list);
+- sh_chan->descs_allocated = 0;
+-
+- spin_unlock_irq(&sh_chan->desc_lock);
+-
+- list_for_each_entry_safe(desc, _desc, &list, node)
+- kfree(desc);
+-}
+-
+-/**
+- * sh_dmae_add_desc - get, set up and return one transfer descriptor
+- * @sh_chan: DMA channel
+- * @flags: DMA transfer flags
+- * @dest: destination DMA address, incremented when direction equals
+- * DMA_DEV_TO_MEM
+- * @src: source DMA address, incremented when direction equals
+- * DMA_MEM_TO_DEV
+- * @len: DMA transfer length
+- * @first: if NULL, set to the current descriptor and cookie set to -EBUSY
+- * @direction: needed for slave DMA to decide which address to keep constant,
+- * equals DMA_MEM_TO_MEM for MEMCPY
+- * Returns 0 or an error
+- * Locks: called with desc_lock held
+- */
+-static struct sh_desc *sh_dmae_add_desc(struct sh_dmae_chan *sh_chan,
+- unsigned long flags, dma_addr_t *dest, dma_addr_t *src, size_t *len,
+- struct sh_desc **first, enum dma_transfer_direction direction)
+-{
+- struct sh_desc *new;
+- size_t copy_size;
+-
+- if (!*len)
+- return NULL;
+-
+- /* Allocate the link descriptor from the free list */
+- new = sh_dmae_get_desc(sh_chan);
+- if (!new) {
+- dev_err(sh_chan->dev, "No free link descriptor available\n");
+- return NULL;
+- }
+-
+- copy_size = min(*len, (size_t)SH_DMA_TCR_MAX + 1);
+-
+- new->hw.sar = *src;
+- new->hw.dar = *dest;
+- new->hw.tcr = copy_size;
+-
+- if (!*first) {
+- /* First desc */
+- new->async_tx.cookie = -EBUSY;
+- *first = new;
++ dmae_set_dmars(sh_chan, cfg->mid_rid);
++ dmae_set_chcr(sh_chan, cfg->chcr);
+ } else {
+- /* Other desc - invisible to the user */
+- new->async_tx.cookie = -EINVAL;
++ dmae_init(sh_chan);
+ }
+-
+- dev_dbg(sh_chan->dev,
+- "chaining (%u/%u)@%x -> %x with %p, cookie %d, shift %d\n",
+- copy_size, *len, *src, *dest, &new->async_tx,
+- new->async_tx.cookie, sh_chan->xmit_shift);
+-
+- new->mark = DESC_PREPARED;
+- new->async_tx.flags = flags;
+- new->direction = direction;
+-
+- *len -= copy_size;
+- if (direction == DMA_MEM_TO_MEM || direction == DMA_MEM_TO_DEV)
+- *src += copy_size;
+- if (direction == DMA_MEM_TO_MEM || direction == DMA_DEV_TO_MEM)
+- *dest += copy_size;
+-
+- return new;
+ }
+
+-/*
+- * sh_dmae_prep_sg - prepare transfer descriptors from an SG list
+- *
+- * Common routine for public (MEMCPY) and slave DMA. The MEMCPY case is also
+- * converted to scatter-gather to guarantee consistent locking and a correct
+- * list manipulation. For slave DMA direction carries the usual meaning, and,
+- * logically, the SG list is RAM and the addr variable contains slave address,
+- * e.g., the FIFO I/O register. For MEMCPY direction equals DMA_MEM_TO_MEM
+- * and the SG list contains only one element and points at the source buffer.
+- */
+-static struct dma_async_tx_descriptor *sh_dmae_prep_sg(struct sh_dmae_chan *sh_chan,
+- struct scatterlist *sgl, unsigned int sg_len, dma_addr_t *addr,
+- enum dma_transfer_direction direction, unsigned long flags)
++static const struct sh_dmae_slave_config *dmae_find_slave(
++ struct sh_dmae_chan *sh_chan, struct sh_dmae_slave *slave)
+ {
+- struct scatterlist *sg;
+- struct sh_desc *first = NULL, *new = NULL /* compiler... */;
+- LIST_HEAD(tx_list);
+- int chunks = 0;
+- unsigned long irq_flags;
++ struct sh_dmae_device *shdev = to_sh_dev(sh_chan);
++ struct sh_dmae_pdata *pdata = shdev->pdata;
++ const struct sh_dmae_slave_config *cfg;
+ int i;
+
+- if (!sg_len)
++ if (slave->shdma_slave.slave_id >= SH_DMA_SLAVE_NUMBER)
+ return NULL;
+
+- for_each_sg(sgl, sg, sg_len, i)
+- chunks += (sg_dma_len(sg) + SH_DMA_TCR_MAX) /
+- (SH_DMA_TCR_MAX + 1);
+-
+- /* Have to lock the whole loop to protect against concurrent release */
+- spin_lock_irqsave(&sh_chan->desc_lock, irq_flags);
+-
+- /*
+- * Chaining:
+- * first descriptor is what user is dealing with in all API calls, its
+- * cookie is at first set to -EBUSY, at tx-submit to a positive
+- * number
+- * if more than one chunk is needed further chunks have cookie = -EINVAL
+- * the last chunk, if not equal to the first, has cookie = -ENOSPC
+- * all chunks are linked onto the tx_list head with their .node heads
+- * only during this function, then they are immediately spliced
+- * back onto the free list in form of a chain
+- */
+- for_each_sg(sgl, sg, sg_len, i) {
+- dma_addr_t sg_addr = sg_dma_address(sg);
+- size_t len = sg_dma_len(sg);
+-
+- if (!len)
+- goto err_get_desc;
+-
+- do {
+- dev_dbg(sh_chan->dev, "Add SG #%d@%p[%d], dma %llx\n",
+- i, sg, len, (unsigned long long)sg_addr);
+-
+- if (direction == DMA_DEV_TO_MEM)
+- new = sh_dmae_add_desc(sh_chan, flags,
+- &sg_addr, addr, &len, &first,
+- direction);
+- else
+- new = sh_dmae_add_desc(sh_chan, flags,
+- addr, &sg_addr, &len, &first,
+- direction);
+- if (!new)
+- goto err_get_desc;
+-
+- new->chunks = chunks--;
+- list_add_tail(&new->node, &tx_list);
+- } while (len);
+- }
+-
+- if (new != first)
+- new->async_tx.cookie = -ENOSPC;
+-
+- /* Put them back on the free list, so, they don't get lost */
+- list_splice_tail(&tx_list, &sh_chan->ld_free);
+-
+- spin_unlock_irqrestore(&sh_chan->desc_lock, irq_flags);
+-
+- return &first->async_tx;
+-
+-err_get_desc:
+- list_for_each_entry(new, &tx_list, node)
+- new->mark = DESC_IDLE;
+- list_splice(&tx_list, &sh_chan->ld_free);
+-
+- spin_unlock_irqrestore(&sh_chan->desc_lock, irq_flags);
++ for (i = 0, cfg = pdata->slave; i < pdata->slave_num; i++, cfg++)
++ if (cfg->slave_id == slave->shdma_slave.slave_id)
++ return cfg;
+
+ return NULL;
+ }
+
+-static struct dma_async_tx_descriptor *sh_dmae_prep_memcpy(
+- struct dma_chan *chan, dma_addr_t dma_dest, dma_addr_t dma_src,
+- size_t len, unsigned long flags)
++static int sh_dmae_set_slave(struct shdma_chan *schan,
++ struct shdma_slave *sslave)
+ {
+- struct sh_dmae_chan *sh_chan;
+- struct scatterlist sg;
+-
+- if (!chan || !len)
+- return NULL;
+-
+- sh_chan = to_sh_chan(chan);
+-
+- sg_init_table(&sg, 1);
+- sg_set_page(&sg, pfn_to_page(PFN_DOWN(dma_src)), len,
+- offset_in_page(dma_src));
+- sg_dma_address(&sg) = dma_src;
+- sg_dma_len(&sg) = len;
+-
+- return sh_dmae_prep_sg(sh_chan, &sg, 1, &dma_dest, DMA_MEM_TO_MEM,
+- flags);
+-}
+-
+-static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg(
+- struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len,
+- enum dma_transfer_direction direction, unsigned long flags,
+- void *context)
+-{
+- struct sh_dmae_slave *param;
+- struct sh_dmae_chan *sh_chan;
+- dma_addr_t slave_addr;
+-
+- if (!chan)
+- return NULL;
+-
+- sh_chan = to_sh_chan(chan);
+- param = chan->private;
+-
+- /* Someone calling slave DMA on a public channel? */
+- if (!param || !sg_len) {
+- dev_warn(sh_chan->dev, "%s: bad parameter: %p, %d, %d\n",
+- __func__, param, sg_len, param ? param->slave_id : -1);
+- return NULL;
+- }
+-
+- slave_addr = param->config->addr;
+-
+- /*
+- * if (param != NULL), this is a successfully requested slave channel,
+- * therefore param->config != NULL too.
+- */
+- return sh_dmae_prep_sg(sh_chan, sgl, sg_len, &slave_addr,
+- direction, flags);
+-}
+-
+-static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+- unsigned long arg)
+-{
+- struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
+- unsigned long flags;
+-
+- /* Only supports DMA_TERMINATE_ALL */
+- if (cmd != DMA_TERMINATE_ALL)
+- return -ENXIO;
+-
+- if (!chan)
+- return -EINVAL;
+-
+- spin_lock_irqsave(&sh_chan->desc_lock, flags);
+- dmae_halt(sh_chan);
+-
+- if (!list_empty(&sh_chan->ld_queue)) {
+- /* Record partial transfer */
+- struct sh_desc *desc = list_entry(sh_chan->ld_queue.next,
+- struct sh_desc, node);
+- desc->partial = (desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) <<
+- sh_chan->xmit_shift;
+- }
+- spin_unlock_irqrestore(&sh_chan->desc_lock, flags);
++ struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan,
++ shdma_chan);
++ struct sh_dmae_slave *slave = container_of(sslave, struct sh_dmae_slave,
++ shdma_slave);
++ const struct sh_dmae_slave_config *cfg = dmae_find_slave(sh_chan, slave);
++ if (!cfg)
++ return -ENODEV;
+
+- sh_dmae_chan_ld_cleanup(sh_chan, true);
++ slave->config = cfg;
+
+ return 0;
+ }
+
+-static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all)
++static void dmae_halt(struct sh_dmae_chan *sh_chan)
+ {
+- struct sh_desc *desc, *_desc;
+- /* Is the "exposed" head of a chain acked? */
+- bool head_acked = false;
+- dma_cookie_t cookie = 0;
+- dma_async_tx_callback callback = NULL;
+- void *param = NULL;
+- unsigned long flags;
+-
+- spin_lock_irqsave(&sh_chan->desc_lock, flags);
+- list_for_each_entry_safe(desc, _desc, &sh_chan->ld_queue, node) {
+- struct dma_async_tx_descriptor *tx = &desc->async_tx;
+-
+- BUG_ON(tx->cookie > 0 && tx->cookie != desc->cookie);
+- BUG_ON(desc->mark != DESC_SUBMITTED &&
+- desc->mark != DESC_COMPLETED &&
+- desc->mark != DESC_WAITING);
+-
+- /*
+- * queue is ordered, and we use this loop to (1) clean up all
+- * completed descriptors, and to (2) update descriptor flags of
+- * any chunks in a (partially) completed chain
+- */
+- if (!all && desc->mark == DESC_SUBMITTED &&
+- desc->cookie != cookie)
+- break;
+-
+- if (tx->cookie > 0)
+- cookie = tx->cookie;
+-
+- if (desc->mark == DESC_COMPLETED && desc->chunks == 1) {
+- if (sh_chan->common.completed_cookie != desc->cookie - 1)
+- dev_dbg(sh_chan->dev,
+- "Completing cookie %d, expected %d\n",
+- desc->cookie,
+- sh_chan->common.completed_cookie + 1);
+- sh_chan->common.completed_cookie = desc->cookie;
+- }
+-
+- /* Call callback on the last chunk */
+- if (desc->mark == DESC_COMPLETED && tx->callback) {
+- desc->mark = DESC_WAITING;
+- callback = tx->callback;
+- param = tx->callback_param;
+- dev_dbg(sh_chan->dev, "descriptor #%d@%p on %d callback\n",
+- tx->cookie, tx, sh_chan->id);
+- BUG_ON(desc->chunks != 1);
+- break;
+- }
+-
+- if (tx->cookie > 0 || tx->cookie == -EBUSY) {
+- if (desc->mark == DESC_COMPLETED) {
+- BUG_ON(tx->cookie < 0);
+- desc->mark = DESC_WAITING;
+- }
+- head_acked = async_tx_test_ack(tx);
+- } else {
+- switch (desc->mark) {
+- case DESC_COMPLETED:
+- desc->mark = DESC_WAITING;
+- /* Fall through */
+- case DESC_WAITING:
+- if (head_acked)
+- async_tx_ack(&desc->async_tx);
+- }
+- }
+-
+- dev_dbg(sh_chan->dev, "descriptor %p #%d completed.\n",
+- tx, tx->cookie);
+-
+- if (((desc->mark == DESC_COMPLETED ||
+- desc->mark == DESC_WAITING) &&
+- async_tx_test_ack(&desc->async_tx)) || all) {
+- /* Remove from ld_queue list */
+- desc->mark = DESC_IDLE;
+-
+- list_move(&desc->node, &sh_chan->ld_free);
+-
+- if (list_empty(&sh_chan->ld_queue)) {
+- dev_dbg(sh_chan->dev, "Bring down channel %d\n", sh_chan->id);
+- pm_runtime_put(sh_chan->dev);
+- }
+- }
+- }
+-
+- if (all && !callback)
+- /*
+- * Terminating and the loop completed normally: forgive
+- * uncompleted cookies
+- */
+- sh_chan->common.completed_cookie = sh_chan->common.cookie;
+-
+- spin_unlock_irqrestore(&sh_chan->desc_lock, flags);
+-
+- if (callback)
+- callback(param);
++ struct sh_dmae_device *shdev = to_sh_dev(sh_chan);
++ u32 chcr = chcr_read(sh_chan);
+
+- return callback;
++ chcr &= ~(CHCR_DE | CHCR_TE | shdev->chcr_ie_bit);
++ chcr_write(sh_chan, chcr);
+ }
+
+-/*
+- * sh_chan_ld_cleanup - Clean up link descriptors
+- *
+- * This function cleans up the ld_queue of DMA channel.
+- */
+-static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all)
++static int sh_dmae_desc_setup(struct shdma_chan *schan,
++ struct shdma_desc *sdesc,
++ dma_addr_t src, dma_addr_t dst, size_t *len)
+ {
+- while (__ld_cleanup(sh_chan, all))
+- ;
+-}
++ struct sh_dmae_desc *sh_desc = container_of(sdesc,
++ struct sh_dmae_desc, shdma_desc);
+
+-/* Called under spin_lock_irq(&sh_chan->desc_lock) */
+-static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
+-{
+- struct sh_desc *desc;
++ if (*len > schan->max_xfer_len)
++ *len = schan->max_xfer_len;
+
+- /* DMA work check */
+- if (dmae_is_busy(sh_chan))
+- return;
+-
+- /* Find the first not transferred descriptor */
+- list_for_each_entry(desc, &sh_chan->ld_queue, node)
+- if (desc->mark == DESC_SUBMITTED) {
+- dev_dbg(sh_chan->dev, "Queue #%d to %d: %u@%x -> %x\n",
+- desc->async_tx.cookie, sh_chan->id,
+- desc->hw.tcr, desc->hw.sar, desc->hw.dar);
+- /* Get the ld start address from ld_queue */
+- dmae_set_reg(sh_chan, &desc->hw);
+- dmae_start(sh_chan);
+- break;
+- }
+-}
++ sh_desc->hw.sar = src;
++ sh_desc->hw.dar = dst;
++ sh_desc->hw.tcr = *len;
+
+-static void sh_dmae_memcpy_issue_pending(struct dma_chan *chan)
+-{
+- struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
+-
+- spin_lock_irq(&sh_chan->desc_lock);
+- if (sh_chan->pm_state == DMAE_PM_ESTABLISHED)
+- sh_chan_xfer_ld_queue(sh_chan);
+- else
+- sh_chan->pm_state = DMAE_PM_PENDING;
+- spin_unlock_irq(&sh_chan->desc_lock);
++ return 0;
+ }
+
+-static enum dma_status sh_dmae_tx_status(struct dma_chan *chan,
+- dma_cookie_t cookie,
+- struct dma_tx_state *txstate)
++static void sh_dmae_halt(struct shdma_chan *schan)
+ {
+- struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
+- enum dma_status status;
+- unsigned long flags;
+-
+- sh_dmae_chan_ld_cleanup(sh_chan, false);
+-
+- spin_lock_irqsave(&sh_chan->desc_lock, flags);
+-
+- status = dma_cookie_status(chan, cookie, txstate);
+-
+- /*
+- * If we don't find cookie on the queue, it has been aborted and we have
+- * to report error
+- */
+- if (status != DMA_SUCCESS) {
+- struct sh_desc *desc;
+- status = DMA_ERROR;
+- list_for_each_entry(desc, &sh_chan->ld_queue, node)
+- if (desc->cookie == cookie) {
+- status = DMA_IN_PROGRESS;
+- break;
+- }
+- }
+-
+- spin_unlock_irqrestore(&sh_chan->desc_lock, flags);
+-
+- return status;
++ struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan,
++ shdma_chan);
++ dmae_halt(sh_chan);
+ }
+
+-static irqreturn_t sh_dmae_interrupt(int irq, void *data)
++static bool sh_dmae_chan_irq(struct shdma_chan *schan, int irq)
+ {
+- irqreturn_t ret = IRQ_NONE;
+- struct sh_dmae_chan *sh_chan = data;
+- u32 chcr;
+-
+- spin_lock(&sh_chan->desc_lock);
+-
+- chcr = chcr_read(sh_chan);
++ struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan,
++ shdma_chan);
+
+- if (chcr & CHCR_TE) {
+- /* DMA stop */
+- dmae_halt(sh_chan);
+-
+- ret = IRQ_HANDLED;
+- tasklet_schedule(&sh_chan->tasklet);
+- }
++ if (!(chcr_read(sh_chan) & CHCR_TE))
++ return false;
+
+- spin_unlock(&sh_chan->desc_lock);
++ /* DMA stop */
++ dmae_halt(sh_chan);
+
+- return ret;
++ return true;
+ }
+
+ /* Called from error IRQ or NMI */
+ static bool sh_dmae_reset(struct sh_dmae_device *shdev)
+ {
+- unsigned int handled = 0;
+- int i;
++ bool ret;
+
+ /* halt the dma controller */
+ sh_dmae_ctl_stop(shdev);
+
+ /* We cannot detect, which channel caused the error, have to reset all */
+- for (i = 0; i < SH_DMAC_MAX_CHANNELS; i++) {
+- struct sh_dmae_chan *sh_chan = shdev->chan[i];
+- struct sh_desc *desc;
+- LIST_HEAD(dl);
+-
+- if (!sh_chan)
+- continue;
+-
+- spin_lock(&sh_chan->desc_lock);
+-
+- /* Stop the channel */
+- dmae_halt(sh_chan);
+-
+- list_splice_init(&sh_chan->ld_queue, &dl);
+-
+- if (!list_empty(&dl)) {
+- dev_dbg(sh_chan->dev, "Bring down channel %d\n", sh_chan->id);
+- pm_runtime_put(sh_chan->dev);
+- }
+- sh_chan->pm_state = DMAE_PM_ESTABLISHED;
+-
+- spin_unlock(&sh_chan->desc_lock);
+-
+- /* Complete all */
+- list_for_each_entry(desc, &dl, node) {
+- struct dma_async_tx_descriptor *tx = &desc->async_tx;
+- desc->mark = DESC_IDLE;
+- if (tx->callback)
+- tx->callback(tx->callback_param);
+- }
+-
+- spin_lock(&sh_chan->desc_lock);
+- list_splice(&dl, &sh_chan->ld_free);
+- spin_unlock(&sh_chan->desc_lock);
+-
+- handled++;
+- }
++ ret = shdma_reset(&shdev->shdma_dev);
+
+ sh_dmae_rst(shdev);
+
+- return !!handled;
++ return ret;
+ }
+
+ static irqreturn_t sh_dmae_err(int irq, void *data)
+@@ -991,35 +407,24 @@ static irqreturn_t sh_dmae_err(int irq, void *data)
+ if (!(dmaor_read(shdev) & DMAOR_AE))
+ return IRQ_NONE;
+
+- sh_dmae_reset(data);
++ sh_dmae_reset(shdev);
+ return IRQ_HANDLED;
+ }
+
+-static void dmae_do_tasklet(unsigned long data)
++static bool sh_dmae_desc_completed(struct shdma_chan *schan,
++ struct shdma_desc *sdesc)
+ {
+- struct sh_dmae_chan *sh_chan = (struct sh_dmae_chan *)data;
+- struct sh_desc *desc;
++ struct sh_dmae_chan *sh_chan = container_of(schan,
++ struct sh_dmae_chan, shdma_chan);
++ struct sh_dmae_desc *sh_desc = container_of(sdesc,
++ struct sh_dmae_desc, shdma_desc);
+ u32 sar_buf = sh_dmae_readl(sh_chan, SAR);
+ u32 dar_buf = sh_dmae_readl(sh_chan, DAR);
+
+- spin_lock_irq(&sh_chan->desc_lock);
+- list_for_each_entry(desc, &sh_chan->ld_queue, node) {
+- if (desc->mark == DESC_SUBMITTED &&
+- ((desc->direction == DMA_DEV_TO_MEM &&
+- (desc->hw.dar + desc->hw.tcr) == dar_buf) ||
+- (desc->hw.sar + desc->hw.tcr) == sar_buf)) {
+- dev_dbg(sh_chan->dev, "done #%d@%p dst %u\n",
+- desc->async_tx.cookie, &desc->async_tx,
+- desc->hw.dar);
+- desc->mark = DESC_COMPLETED;
+- break;
+- }
+- }
+- /* Next desc */
+- sh_chan_xfer_ld_queue(sh_chan);
+- spin_unlock_irq(&sh_chan->desc_lock);
+-
+- sh_dmae_chan_ld_cleanup(sh_chan, false);
++ return (sdesc->direction == DMA_DEV_TO_MEM &&
++ (sh_desc->hw.dar + sh_desc->hw.tcr) == dar_buf) ||
++ (sdesc->direction != DMA_DEV_TO_MEM &&
++ (sh_desc->hw.sar + sh_desc->hw.tcr) == sar_buf);
+ }
+
+ static bool sh_dmae_nmi_notify(struct sh_dmae_device *shdev)
+@@ -1073,97 +478,174 @@ static struct notifier_block sh_dmae_nmi_notifier __read_mostly = {
+ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
+ int irq, unsigned long flags)
+ {
+- int err;
+ const struct sh_dmae_channel *chan_pdata = &shdev->pdata->channel[id];
+- struct platform_device *pdev = to_platform_device(shdev->common.dev);
+- struct sh_dmae_chan *new_sh_chan;
++ struct shdma_dev *sdev = &shdev->shdma_dev;
++ struct platform_device *pdev = to_platform_device(sdev->dma_dev.dev);
++ struct sh_dmae_chan *sh_chan;
++ struct shdma_chan *schan;
++ int err;
+
+- /* alloc channel */
+- new_sh_chan = kzalloc(sizeof(struct sh_dmae_chan), GFP_KERNEL);
+- if (!new_sh_chan) {
+- dev_err(shdev->common.dev,
++ sh_chan = kzalloc(sizeof(struct sh_dmae_chan), GFP_KERNEL);
++ if (!sh_chan) {
++ dev_err(sdev->dma_dev.dev,
+ "No free memory for allocating dma channels!\n");
+ return -ENOMEM;
+ }
+
+- new_sh_chan->pm_state = DMAE_PM_ESTABLISHED;
+-
+- /* reference struct dma_device */
+- new_sh_chan->common.device = &shdev->common;
+- dma_cookie_init(&new_sh_chan->common);
++ schan = &sh_chan->shdma_chan;
++ schan->max_xfer_len = SH_DMA_TCR_MAX + 1;
+
+- new_sh_chan->dev = shdev->common.dev;
+- new_sh_chan->id = id;
+- new_sh_chan->irq = irq;
+- new_sh_chan->base = shdev->chan_reg + chan_pdata->offset / sizeof(u32);
++ shdma_chan_probe(sdev, schan, id);
+
+- /* Init DMA tasklet */
+- tasklet_init(&new_sh_chan->tasklet, dmae_do_tasklet,
+- (unsigned long)new_sh_chan);
+-
+- spin_lock_init(&new_sh_chan->desc_lock);
+-
+- /* Init descripter manage list */
+- INIT_LIST_HEAD(&new_sh_chan->ld_queue);
+- INIT_LIST_HEAD(&new_sh_chan->ld_free);
+-
+- /* Add the channel to DMA device channel list */
+- list_add_tail(&new_sh_chan->common.device_node,
+- &shdev->common.channels);
+- shdev->common.chancnt++;
++ sh_chan->base = shdev->chan_reg + chan_pdata->offset / sizeof(u32);
+
++ /* set up channel irq */
+ if (pdev->id >= 0)
+- snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id),
+- "sh-dmae%d.%d", pdev->id, new_sh_chan->id);
++ snprintf(sh_chan->dev_id, sizeof(sh_chan->dev_id),
++ "sh-dmae%d.%d", pdev->id, id);
+ else
+- snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id),
+- "sh-dma%d", new_sh_chan->id);
++ snprintf(sh_chan->dev_id, sizeof(sh_chan->dev_id),
++ "sh-dma%d", id);
+
+- /* set up channel irq */
+- err = request_irq(irq, &sh_dmae_interrupt, flags,
+- new_sh_chan->dev_id, new_sh_chan);
++ err = shdma_request_irq(schan, irq, flags, sh_chan->dev_id);
+ if (err) {
+- dev_err(shdev->common.dev, "DMA channel %d request_irq error "
+- "with return %d\n", id, err);
++ dev_err(sdev->dma_dev.dev,
++ "DMA channel %d request_irq error %d\n",
++ id, err);
+ goto err_no_irq;
+ }
+
+- shdev->chan[id] = new_sh_chan;
++ shdev->chan[id] = sh_chan;
+ return 0;
+
+ err_no_irq:
+ /* remove from dmaengine device node */
+- list_del(&new_sh_chan->common.device_node);
+- kfree(new_sh_chan);
++ shdma_chan_remove(schan);
++ kfree(sh_chan);
+ return err;
+ }
+
+ static void sh_dmae_chan_remove(struct sh_dmae_device *shdev)
+ {
++ struct dma_device *dma_dev = &shdev->shdma_dev.dma_dev;
++ struct shdma_chan *schan;
+ int i;
+
+- for (i = shdev->common.chancnt - 1 ; i >= 0 ; i--) {
+- if (shdev->chan[i]) {
+- struct sh_dmae_chan *sh_chan = shdev->chan[i];
++ shdma_for_each_chan(schan, &shdev->shdma_dev, i) {
++ struct sh_dmae_chan *sh_chan = container_of(schan,
++ struct sh_dmae_chan, shdma_chan);
++ BUG_ON(!schan);
+
+- free_irq(sh_chan->irq, sh_chan);
++ shdma_free_irq(&sh_chan->shdma_chan);
+
+- list_del(&sh_chan->common.device_node);
+- kfree(sh_chan);
+- shdev->chan[i] = NULL;
++ shdma_chan_remove(schan);
++ kfree(sh_chan);
++ }
++ dma_dev->chancnt = 0;
++}
++
++static void sh_dmae_shutdown(struct platform_device *pdev)
++{
++ struct sh_dmae_device *shdev = platform_get_drvdata(pdev);
++ sh_dmae_ctl_stop(shdev);
++}
++
++static int sh_dmae_runtime_suspend(struct device *dev)
++{
++ return 0;
++}
++
++static int sh_dmae_runtime_resume(struct device *dev)
++{
++ struct sh_dmae_device *shdev = dev_get_drvdata(dev);
++
++ return sh_dmae_rst(shdev);
++}
++
++#ifdef CONFIG_PM
++static int sh_dmae_suspend(struct device *dev)
++{
++ return 0;
++}
++
++static int sh_dmae_resume(struct device *dev)
++{
++ struct sh_dmae_device *shdev = dev_get_drvdata(dev);
++ int i, ret;
++
++ ret = sh_dmae_rst(shdev);
++ if (ret < 0)
++ dev_err(dev, "Failed to reset!\n");
++
++ for (i = 0; i < shdev->pdata->channel_num; i++) {
++ struct sh_dmae_chan *sh_chan = shdev->chan[i];
++ struct sh_dmae_slave *param = sh_chan->shdma_chan.dma_chan.private;
++
++ if (!sh_chan->shdma_chan.desc_num)
++ continue;
++
++ if (param) {
++ const struct sh_dmae_slave_config *cfg = param->config;
++ dmae_set_dmars(sh_chan, cfg->mid_rid);
++ dmae_set_chcr(sh_chan, cfg->chcr);
++ } else {
++ dmae_init(sh_chan);
+ }
+ }
+- shdev->common.chancnt = 0;
++
++ return 0;
+ }
++#else
++#define sh_dmae_suspend NULL
++#define sh_dmae_resume NULL
++#endif
+
+-static int __init sh_dmae_probe(struct platform_device *pdev)
++const struct dev_pm_ops sh_dmae_pm = {
++ .suspend = sh_dmae_suspend,
++ .resume = sh_dmae_resume,
++ .runtime_suspend = sh_dmae_runtime_suspend,
++ .runtime_resume = sh_dmae_runtime_resume,
++};
++
++static dma_addr_t sh_dmae_slave_addr(struct shdma_chan *schan)
++{
++ struct sh_dmae_slave *param = schan->dma_chan.private;
++
++ /*
++ * Implicit BUG_ON(!param)
++ * if (param != NULL), this is a successfully requested slave channel,
++ * therefore param->config != NULL too.
++ */
++ return param->config->addr;
++}
++
++static struct shdma_desc *sh_dmae_embedded_desc(void *buf, int i)
++{
++ return &((struct sh_dmae_desc *)buf)[i].shdma_desc;
++}
++
++static const struct shdma_ops sh_dmae_shdma_ops = {
++ .desc_completed = sh_dmae_desc_completed,
++ .halt_channel = sh_dmae_halt,
++ .channel_busy = sh_dmae_channel_busy,
++ .slave_addr = sh_dmae_slave_addr,
++ .desc_setup = sh_dmae_desc_setup,
++ .set_slave = sh_dmae_set_slave,
++ .setup_xfer = sh_dmae_setup_xfer,
++ .start_xfer = sh_dmae_start_xfer,
++ .embedded_desc = sh_dmae_embedded_desc,
++ .chan_irq = sh_dmae_chan_irq,
++};
++
++static int __devinit sh_dmae_probe(struct platform_device *pdev)
+ {
+ struct sh_dmae_pdata *pdata = pdev->dev.platform_data;
+ unsigned long irqflags = IRQF_DISABLED,
+- chan_flag[SH_DMAC_MAX_CHANNELS] = {};
+- int errirq, chan_irq[SH_DMAC_MAX_CHANNELS];
++ chan_flag[SH_DMAE_MAX_CHANNELS] = {};
++ int errirq, chan_irq[SH_DMAE_MAX_CHANNELS];
+ int err, i, irq_cnt = 0, irqres = 0, irq_cap = 0;
+ struct sh_dmae_device *shdev;
++ struct dma_device *dma_dev;
+ struct resource *chan, *dmars, *errirq_res, *chanirq_res;
+
+ /* get platform data */
+@@ -1211,6 +693,8 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
+ goto ealloc;
+ }
+
++ dma_dev = &shdev->shdma_dev.dma_dev;
++
+ shdev->chan_reg = ioremap(chan->start, resource_size(chan));
+ if (!shdev->chan_reg)
+ goto emapchan;
+@@ -1220,8 +704,23 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
+ goto emapdmars;
+ }
+
++ if (!pdata->slave_only)
++ dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask);
++ if (pdata->slave && pdata->slave_num)
++ dma_cap_set(DMA_SLAVE, dma_dev->cap_mask);
++
++ /* Default transfer size of 32 bytes requires 32-byte alignment */
++ dma_dev->copy_align = LOG2_DEFAULT_XFER_SIZE;
++
++ shdev->shdma_dev.ops = &sh_dmae_shdma_ops;
++ shdev->shdma_dev.desc_size = sizeof(struct sh_dmae_desc);
++ err = shdma_init(&pdev->dev, &shdev->shdma_dev,
++ pdata->channel_num);
++ if (err < 0)
++ goto eshdma;
++
+ /* platform data */
+- shdev->pdata = pdata;
++ shdev->pdata = pdev->dev.platform_data;
+
+ if (pdata->chcr_offset)
+ shdev->chcr_offset = pdata->chcr_offset;
+@@ -1235,10 +734,10 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
+
+ platform_set_drvdata(pdev, shdev);
+
+- shdev->common.dev = &pdev->dev;
+-
+ pm_runtime_enable(&pdev->dev);
+- pm_runtime_get_sync(&pdev->dev);
++ err = pm_runtime_get_sync(&pdev->dev);
++ if (err < 0)
++ dev_err(&pdev->dev, "%s(): GET = %d\n", __func__, err);
+
+ spin_lock_irq(&sh_dmae_lock);
+ list_add_tail_rcu(&shdev->node, &sh_dmae_devices);
+@@ -1249,27 +748,6 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
+ if (err)
+ goto rst_err;
+
+- INIT_LIST_HEAD(&shdev->common.channels);
+-
+- if (!pdata->slave_only)
+- dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask);
+- if (pdata->slave && pdata->slave_num)
+- dma_cap_set(DMA_SLAVE, shdev->common.cap_mask);
+-
+- shdev->common.device_alloc_chan_resources
+- = sh_dmae_alloc_chan_resources;
+- shdev->common.device_free_chan_resources = sh_dmae_free_chan_resources;
+- shdev->common.device_prep_dma_memcpy = sh_dmae_prep_memcpy;
+- shdev->common.device_tx_status = sh_dmae_tx_status;
+- shdev->common.device_issue_pending = sh_dmae_memcpy_issue_pending;
+-
+- /* Compulsory for DMA_SLAVE fields */
+- shdev->common.device_prep_slave_sg = sh_dmae_prep_slave_sg;
+- shdev->common.device_control = sh_dmae_control;
+-
+- /* Default transfer size of 32 bytes requires 32-byte alignment */
+- shdev->common.copy_align = LOG2_DEFAULT_XFER_SIZE;
+-
+ #if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
+ chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+
+@@ -1301,7 +779,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
+ !platform_get_resource(pdev, IORESOURCE_IRQ, 1)) {
+ /* Special case - all multiplexed */
+ for (; irq_cnt < pdata->channel_num; irq_cnt++) {
+- if (irq_cnt < SH_DMAC_MAX_CHANNELS) {
++ if (irq_cnt < SH_DMAE_MAX_CHANNELS) {
+ chan_irq[irq_cnt] = chanirq_res->start;
+ chan_flag[irq_cnt] = IRQF_SHARED;
+ } else {
+@@ -1312,7 +790,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
+ } else {
+ do {
+ for (i = chanirq_res->start; i <= chanirq_res->end; i++) {
+- if (irq_cnt >= SH_DMAC_MAX_CHANNELS) {
++ if (irq_cnt >= SH_DMAE_MAX_CHANNELS) {
+ irq_cap = 1;
+ break;
+ }
+@@ -1328,7 +806,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
+ chan_irq[irq_cnt++] = i;
+ }
+
+- if (irq_cnt >= SH_DMAC_MAX_CHANNELS)
++ if (irq_cnt >= SH_DMAE_MAX_CHANNELS)
+ break;
+
+ chanirq_res = platform_get_resource(pdev,
+@@ -1346,14 +824,19 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
+ if (irq_cap)
+ dev_notice(&pdev->dev, "Attempting to register %d DMA "
+ "channels when a maximum of %d are supported.\n",
+- pdata->channel_num, SH_DMAC_MAX_CHANNELS);
++ pdata->channel_num, SH_DMAE_MAX_CHANNELS);
+
+ pm_runtime_put(&pdev->dev);
+
+- dma_async_device_register(&shdev->common);
++ err = dma_async_device_register(&shdev->shdma_dev.dma_dev);
++ if (err < 0)
++ goto edmadevreg;
+
+ return err;
+
++edmadevreg:
++ pm_runtime_get(&pdev->dev);
++
+ chan_probe_err:
+ sh_dmae_chan_remove(shdev);
+
+@@ -1369,10 +852,11 @@ rst_err:
+ pm_runtime_put(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+
++ platform_set_drvdata(pdev, NULL);
++ shdma_cleanup(&shdev->shdma_dev);
++eshdma:
+ if (dmars)
+ iounmap(shdev->dmars);
+-
+- platform_set_drvdata(pdev, NULL);
+ emapdmars:
+ iounmap(shdev->chan_reg);
+ synchronize_rcu();
+@@ -1387,13 +871,14 @@ ermrdmars:
+ return err;
+ }
+
+-static int __exit sh_dmae_remove(struct platform_device *pdev)
++static int __devexit sh_dmae_remove(struct platform_device *pdev)
+ {
+ struct sh_dmae_device *shdev = platform_get_drvdata(pdev);
++ struct dma_device *dma_dev = &shdev->shdma_dev.dma_dev;
+ struct resource *res;
+ int errirq = platform_get_irq(pdev, 0);
+
+- dma_async_device_unregister(&shdev->common);
++ dma_async_device_unregister(dma_dev);
+
+ if (errirq > 0)
+ free_irq(errirq, shdev);
+@@ -1402,11 +887,11 @@ static int __exit sh_dmae_remove(struct platform_device *pdev)
+ list_del_rcu(&shdev->node);
+ spin_unlock_irq(&sh_dmae_lock);
+
+- /* channel data remove */
+- sh_dmae_chan_remove(shdev);
+-
+ pm_runtime_disable(&pdev->dev);
+
++ sh_dmae_chan_remove(shdev);
++ shdma_cleanup(&shdev->shdma_dev);
++
+ if (shdev->dmars)
+ iounmap(shdev->dmars);
+ iounmap(shdev->chan_reg);
+@@ -1426,77 +911,14 @@ static int __exit sh_dmae_remove(struct platform_device *pdev)
+ return 0;
+ }
+
+-static void sh_dmae_shutdown(struct platform_device *pdev)
+-{
+- struct sh_dmae_device *shdev = platform_get_drvdata(pdev);
+- sh_dmae_ctl_stop(shdev);
+-}
+-
+-static int sh_dmae_runtime_suspend(struct device *dev)
+-{
+- return 0;
+-}
+-
+-static int sh_dmae_runtime_resume(struct device *dev)
+-{
+- struct sh_dmae_device *shdev = dev_get_drvdata(dev);
+-
+- return sh_dmae_rst(shdev);
+-}
+-
+-#ifdef CONFIG_PM
+-static int sh_dmae_suspend(struct device *dev)
+-{
+- return 0;
+-}
+-
+-static int sh_dmae_resume(struct device *dev)
+-{
+- struct sh_dmae_device *shdev = dev_get_drvdata(dev);
+- int i, ret;
+-
+- ret = sh_dmae_rst(shdev);
+- if (ret < 0)
+- dev_err(dev, "Failed to reset!\n");
+-
+- for (i = 0; i < shdev->pdata->channel_num; i++) {
+- struct sh_dmae_chan *sh_chan = shdev->chan[i];
+- struct sh_dmae_slave *param = sh_chan->common.private;
+-
+- if (!sh_chan->descs_allocated)
+- continue;
+-
+- if (param) {
+- const struct sh_dmae_slave_config *cfg = param->config;
+- dmae_set_dmars(sh_chan, cfg->mid_rid);
+- dmae_set_chcr(sh_chan, cfg->chcr);
+- } else {
+- dmae_init(sh_chan);
+- }
+- }
+-
+- return 0;
+-}
+-#else
+-#define sh_dmae_suspend NULL
+-#define sh_dmae_resume NULL
+-#endif
+-
+-const struct dev_pm_ops sh_dmae_pm = {
+- .suspend = sh_dmae_suspend,
+- .resume = sh_dmae_resume,
+- .runtime_suspend = sh_dmae_runtime_suspend,
+- .runtime_resume = sh_dmae_runtime_resume,
+-};
+-
+ static struct platform_driver sh_dmae_driver = {
+- .remove = __exit_p(sh_dmae_remove),
+- .shutdown = sh_dmae_shutdown,
+- .driver = {
++ .driver = {
+ .owner = THIS_MODULE,
+- .name = "sh-dma-engine",
+ .pm = &sh_dmae_pm,
++ .name = SH_DMAE_DRV_NAME,
+ },
++ .remove = __devexit_p(sh_dmae_remove),
++ .shutdown = sh_dmae_shutdown,
+ };
+
+ static int __init sh_dmae_init(void)
+@@ -1521,4 +943,4 @@ module_exit(sh_dmae_exit);
+ MODULE_AUTHOR("Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>");
+ MODULE_DESCRIPTION("Renesas SH DMA Engine driver");
+ MODULE_LICENSE("GPL");
+-MODULE_ALIAS("platform:sh-dma-engine");
++MODULE_ALIAS("platform:" SH_DMAE_DRV_NAME);
+diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h
+index 0b1d2c1..840e47d 100644
+--- a/drivers/dma/sh/shdma.h
++++ b/drivers/dma/sh/shdma.h
+@@ -13,42 +13,27 @@
+ #ifndef __DMA_SHDMA_H
+ #define __DMA_SHDMA_H
+
++#include <linux/shdma-base.h>
+ #include <linux/dmaengine.h>
+ #include <linux/interrupt.h>
+ #include <linux/list.h>
+
+-#define SH_DMAC_MAX_CHANNELS 20
+-#define SH_DMA_SLAVE_NUMBER 256
+-#define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */
++#define SH_DMAE_MAX_CHANNELS 20
++#define SH_DMAE_TCR_MAX 0x00FFFFFF /* 16MB */
+
+ struct device;
+
+-enum dmae_pm_state {
+- DMAE_PM_ESTABLISHED,
+- DMAE_PM_BUSY,
+- DMAE_PM_PENDING,
+-};
+-
+ struct sh_dmae_chan {
+- spinlock_t desc_lock; /* Descriptor operation lock */
+- struct list_head ld_queue; /* Link descriptors queue */
+- struct list_head ld_free; /* Link descriptors free */
+- struct dma_chan common; /* DMA common channel */
+- struct device *dev; /* Channel device */
+- struct tasklet_struct tasklet; /* Tasklet */
+- int descs_allocated; /* desc count */
++ struct shdma_chan shdma_chan;
+ int xmit_shift; /* log_2(bytes_per_xfer) */
+- int irq;
+- int id; /* Raw id of this channel */
+ u32 __iomem *base;
+ char dev_id[16]; /* unique name per DMAC of channel */
+ int pm_error;
+- enum dmae_pm_state pm_state;
+ };
+
+ struct sh_dmae_device {
+- struct dma_device common;
+- struct sh_dmae_chan *chan[SH_DMAC_MAX_CHANNELS];
++ struct shdma_dev shdma_dev;
++ struct sh_dmae_chan *chan[SH_DMAE_MAX_CHANNELS];
+ struct sh_dmae_pdata *pdata;
+ struct list_head node;
+ u32 __iomem *chan_reg;
+@@ -57,10 +42,21 @@ struct sh_dmae_device {
+ u32 chcr_ie_bit;
+ };
+
+-#define to_sh_chan(chan) container_of(chan, struct sh_dmae_chan, common)
++struct sh_dmae_regs {
++ u32 sar; /* SAR / source address */
++ u32 dar; /* DAR / destination address */
++ u32 tcr; /* TCR / transfer count */
++};
++
++struct sh_dmae_desc {
++ struct sh_dmae_regs hw;
++ struct shdma_desc shdma_desc;
++};
++
++#define to_sh_chan(chan) container_of(chan, struct sh_dmae_chan, shdma_chan)
+ #define to_sh_desc(lh) container_of(lh, struct sh_desc, node)
+ #define tx_to_sh_desc(tx) container_of(tx, struct sh_desc, async_tx)
+-#define to_sh_dev(chan) container_of(chan->common.device,\
+- struct sh_dmae_device, common)
++#define to_sh_dev(chan) container_of(chan->shdma_chan.dma_chan.device,\
++ struct sh_dmae_device, shdma_dev.dma_dev)
+
+ #endif /* __DMA_SHDMA_H */
+diff --git a/include/linux/sh_dma.h b/include/linux/sh_dma.h
+index e081e8e..7c8ca41 100644
+--- a/include/linux/sh_dma.h
++++ b/include/linux/sh_dma.h
+@@ -13,34 +13,21 @@
+ #include <linux/dmaengine.h>
+ #include <linux/list.h>
+ #include <linux/shdma-base.h>
++#include <linux/types.h>
++
++struct device;
+
+ /* Used by slave DMA clients to request DMA to/from a specific peripheral */
+ struct sh_dmae_slave {
+- union {
+- unsigned int slave_id; /* Set by the platform */
+- struct shdma_slave shdma_slave;
+- };
+- struct device *dma_dev; /* Set by the platform */
+- const struct sh_dmae_slave_config *config; /* Set by the driver */
+-};
+-
+-struct sh_dmae_regs {
+- u32 sar; /* SAR / source address */
+- u32 dar; /* DAR / destination address */
+- u32 tcr; /* TCR / transfer count */
+-};
+-
+-struct sh_desc {
+- struct sh_dmae_regs hw;
+- struct list_head node;
+- struct dma_async_tx_descriptor async_tx;
+- enum dma_transfer_direction direction;
+- dma_cookie_t cookie;
+- size_t partial;
+- int chunks;
+- int mark;
++ struct shdma_slave shdma_slave; /* Set by the platform */
++ struct device *dma_dev; /* Set by the platform */
++ const struct sh_dmae_slave_config *config; /* Set by the driver */
+ };
+
++/*
++ * Supplied by platforms to specify, how a DMA channel has to be configured for
++ * a certain peripheral
++ */
+ struct sh_dmae_slave_config {
+ unsigned int slave_id;
+ dma_addr_t addr;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0054-dmaengine-shdma-prepare-to-stop-using-struct-dma_cha.patch b/patches.marzen/0054-dmaengine-shdma-prepare-to-stop-using-struct-dma_cha.patch
new file mode 100644
index 0000000000000..4e64c5a7c6189
--- /dev/null
+++ b/patches.marzen/0054-dmaengine-shdma-prepare-to-stop-using-struct-dma_cha.patch
@@ -0,0 +1,183 @@
+From a2071a25b2853b85f682b5a37d87faa4659141c6 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 5 Jul 2012 12:29:40 +0200
+Subject: dmaengine: shdma: prepare to stop using struct dma_chan::private
+
+Using struct dma_chan::private is deprecated. To update the shdma driver to
+stop using it we first have to eliminate internal runtime uses of it. After
+that we will also be able to stop using it for channel configuration.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit ecf90fbbdc66cde6f5fa25d88541112b9baac459)
+
+Conflicts:
+ drivers/dma/sh/shdma.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/dma/sh/shdma-base.c | 9 +++++----
+ drivers/dma/sh/shdma.c | 24 ++++++++++--------------
+ drivers/dma/sh/shdma.h | 2 ++
+ include/linux/sh_dma.h | 2 --
+ include/linux/shdma-base.h | 1 +
+ 5 files changed, 18 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c
+index ff060d0..f75ebfa 100644
+--- a/drivers/dma/sh/shdma-base.c
++++ b/drivers/dma/sh/shdma-base.c
+@@ -76,7 +76,7 @@ static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx)
+ container_of(tx, struct shdma_desc, async_tx),
+ *last = desc;
+ struct shdma_chan *schan = to_shdma_chan(tx->chan);
+- struct shdma_slave *slave = tx->chan->private;
++ struct shdma_slave *slave = schan->slave;
+ dma_async_tx_callback callback = tx->callback;
+ dma_cookie_t cookie;
+ bool power_up;
+@@ -208,6 +208,7 @@ static int shdma_alloc_chan_resources(struct dma_chan *chan)
+ goto edescalloc;
+ }
+ schan->desc_num = NR_DESCS_PER_CHANNEL;
++ schan->slave = slave;
+
+ for (i = 0; i < NR_DESCS_PER_CHANNEL; i++) {
+ desc = ops->embedded_desc(schan->desc, i);
+@@ -365,9 +366,9 @@ static void shdma_free_chan_resources(struct dma_chan *chan)
+ if (!list_empty(&schan->ld_queue))
+ shdma_chan_ld_cleanup(schan, true);
+
+- if (chan->private) {
++ if (schan->slave) {
+ /* The caller is holding dma_list_mutex */
+- struct shdma_slave *slave = chan->private;
++ struct shdma_slave *slave = schan->slave;
+ clear_bit(slave->slave_id, shdma_slave_used);
+ chan->private = NULL;
+ }
+@@ -558,7 +559,7 @@ static struct dma_async_tx_descriptor *shdma_prep_slave_sg(
+ struct shdma_chan *schan = to_shdma_chan(chan);
+ struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device);
+ const struct shdma_ops *ops = sdev->ops;
+- struct shdma_slave *slave = chan->private;
++ struct shdma_slave *slave = schan->slave;
+ dma_addr_t slave_addr;
+
+ if (!chan)
+diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c
+index c393b35..305e77a 100644
+--- a/drivers/dma/sh/shdma.c
++++ b/drivers/dma/sh/shdma.c
+@@ -291,10 +291,8 @@ static void sh_dmae_setup_xfer(struct shdma_chan *schan,
+ shdma_chan);
+
+ if (sslave) {
+- struct sh_dmae_slave *slave = container_of(sslave,
+- struct sh_dmae_slave, shdma_slave);
+ const struct sh_dmae_slave_config *cfg =
+- slave->config;
++ sh_chan->config;
+
+ dmae_set_dmars(sh_chan, cfg->mid_rid);
+ dmae_set_chcr(sh_chan, cfg->chcr);
+@@ -326,13 +324,11 @@ static int sh_dmae_set_slave(struct shdma_chan *schan,
+ {
+ struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan,
+ shdma_chan);
+- struct sh_dmae_slave *slave = container_of(sslave, struct sh_dmae_slave,
+- shdma_slave);
+ const struct sh_dmae_slave_config *cfg = dmae_find_slave(sh_chan, slave);
+ if (!cfg)
+ return -ENODEV;
+
+- slave->config = cfg;
++ sh_chan->config = cfg;
+
+ return 0;
+ }
+@@ -579,13 +575,12 @@ static int sh_dmae_resume(struct device *dev)
+
+ for (i = 0; i < shdev->pdata->channel_num; i++) {
+ struct sh_dmae_chan *sh_chan = shdev->chan[i];
+- struct sh_dmae_slave *param = sh_chan->shdma_chan.dma_chan.private;
+
+ if (!sh_chan->shdma_chan.desc_num)
+ continue;
+
+- if (param) {
+- const struct sh_dmae_slave_config *cfg = param->config;
++ if (sh_chan->shdma_chan.slave) {
++ const struct sh_dmae_slave_config *cfg = sh_chan->config;
+ dmae_set_dmars(sh_chan, cfg->mid_rid);
+ dmae_set_chcr(sh_chan, cfg->chcr);
+ } else {
+@@ -609,14 +604,15 @@ const struct dev_pm_ops sh_dmae_pm = {
+
+ static dma_addr_t sh_dmae_slave_addr(struct shdma_chan *schan)
+ {
+- struct sh_dmae_slave *param = schan->dma_chan.private;
++ struct sh_dmae_chan *sh_chan = container_of(schan,
++ struct sh_dmae_chan, shdma_chan);
+
+ /*
+- * Implicit BUG_ON(!param)
+- * if (param != NULL), this is a successfully requested slave channel,
+- * therefore param->config != NULL too.
++ * Implicit BUG_ON(!sh_chan->config)
++ * This is an exclusive slave DMA operation, may only be called after a
++ * successful slave configuration.
+ */
+- return param->config->addr;
++ return sh_chan->config->addr;
+ }
+
+ static struct shdma_desc *sh_dmae_embedded_desc(void *buf, int i)
+diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h
+index 840e47d..9314e93 100644
+--- a/drivers/dma/sh/shdma.h
++++ b/drivers/dma/sh/shdma.h
+@@ -13,6 +13,7 @@
+ #ifndef __DMA_SHDMA_H
+ #define __DMA_SHDMA_H
+
++#include <linux/sh_dma.h>
+ #include <linux/shdma-base.h>
+ #include <linux/dmaengine.h>
+ #include <linux/interrupt.h>
+@@ -25,6 +26,7 @@ struct device;
+
+ struct sh_dmae_chan {
+ struct shdma_chan shdma_chan;
++ const struct sh_dmae_slave_config *config; /* Slave DMA configuration */
+ int xmit_shift; /* log_2(bytes_per_xfer) */
+ u32 __iomem *base;
+ char dev_id[16]; /* unique name per DMAC of channel */
+diff --git a/include/linux/sh_dma.h b/include/linux/sh_dma.h
+index 7c8ca41..a79f10a 100644
+--- a/include/linux/sh_dma.h
++++ b/include/linux/sh_dma.h
+@@ -20,8 +20,6 @@ struct device;
+ /* Used by slave DMA clients to request DMA to/from a specific peripheral */
+ struct sh_dmae_slave {
+ struct shdma_slave shdma_slave; /* Set by the platform */
+- struct device *dma_dev; /* Set by the platform */
+- const struct sh_dmae_slave_config *config; /* Set by the driver */
+ };
+
+ /*
+diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h
+index 83efd13..c3a19e9 100644
+--- a/include/linux/shdma-base.h
++++ b/include/linux/shdma-base.h
+@@ -66,6 +66,7 @@ struct shdma_chan {
+ size_t max_xfer_len; /* max transfer length */
+ int id; /* Raw id of this channel */
+ int irq; /* Channel IRQ */
++ struct shdma_slave *slave; /* Client data for slave DMA */
+ enum shdma_pm_state pm_state;
+ };
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0055-dmaengine-shdma-cosmetic-simplify-a-static-function.patch b/patches.marzen/0055-dmaengine-shdma-cosmetic-simplify-a-static-function.patch
new file mode 100644
index 0000000000000..96374c2ea4e16
--- /dev/null
+++ b/patches.marzen/0055-dmaengine-shdma-cosmetic-simplify-a-static-function.patch
@@ -0,0 +1,58 @@
+From fc5aa8d8ebed522f219c9a368306cbe41fe75ca9 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 5 Jul 2012 12:29:37 +0200
+Subject: dmaengine: shdma: (cosmetic) simplify a static function
+
+dmae_find_slave() needs only the slave_id field from the slave object, no
+need to pass the pointer to the object, pass the slave_id directly.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit 341f4dc5dcecbf60f038055db177845b9af480ed)
+
+Conflicts:
+ drivers/dma/sh/shdma.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/dma/sh/shdma.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c
+index 305e77a..9f0a2e5 100644
+--- a/drivers/dma/sh/shdma.c
++++ b/drivers/dma/sh/shdma.c
+@@ -302,18 +302,18 @@ static void sh_dmae_setup_xfer(struct shdma_chan *schan,
+ }
+
+ static const struct sh_dmae_slave_config *dmae_find_slave(
+- struct sh_dmae_chan *sh_chan, struct sh_dmae_slave *slave)
++ struct sh_dmae_chan *sh_chan, unsigned int slave_id)
+ {
+ struct sh_dmae_device *shdev = to_sh_dev(sh_chan);
+ struct sh_dmae_pdata *pdata = shdev->pdata;
+ const struct sh_dmae_slave_config *cfg;
+ int i;
+
+- if (slave->shdma_slave.slave_id >= SH_DMA_SLAVE_NUMBER)
++ if (slave_id >= SH_DMA_SLAVE_NUMBER)
+ return NULL;
+
+ for (i = 0, cfg = pdata->slave; i < pdata->slave_num; i++, cfg++)
+- if (cfg->slave_id == slave->shdma_slave.slave_id)
++ if (cfg->slave_id == slave_id)
+ return cfg;
+
+ return NULL;
+@@ -324,7 +324,7 @@ static int sh_dmae_set_slave(struct shdma_chan *schan,
+ {
+ struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan,
+ shdma_chan);
+- const struct sh_dmae_slave_config *cfg = dmae_find_slave(sh_chan, slave);
++ const struct sh_dmae_slave_config *cfg = dmae_find_slave(sh_chan, sslave->slave_id);
+ if (!cfg)
+ return -ENODEV;
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0056-dma-sh-use-an-integer-slave-ID-to-improve-API-compat.patch b/patches.marzen/0056-dma-sh-use-an-integer-slave-ID-to-improve-API-compat.patch
new file mode 100644
index 0000000000000..d7aba34506d97
--- /dev/null
+++ b/patches.marzen/0056-dma-sh-use-an-integer-slave-ID-to-improve-API-compat.patch
@@ -0,0 +1,220 @@
+From 994962e925ac52b6a5c870d02f537c5e3dd535ca Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 5 Jul 2012 12:29:41 +0200
+Subject: dma: sh: use an integer slave ID to improve API compatibility
+
+Initially struct shdma_slave has been introduced with the only member - an
+unsigned slave ID - to describe common properties of DMA slaves in an
+extensible way. However, experience shows, that a slave ID is indeed the
+only parameter, needed to identify DMA slaves. This is also, what is used
+by the core dmaengine API in struct dma_slave_config. We switch to using
+the slave_id directly, instead of passing a pointer to struct shdma_slave
+to improve compatibility with the core. We also make the slave_id signed
+for easier error checking.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit c2cdb7e4d16394fc51dc5c2c5b3e7c3733bdfaac)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/dma/sh/shdma-base.c | 25 +++++++++++++------------
+ drivers/dma/sh/shdma.c | 12 ++++++------
+ include/linux/sh_dma.h | 8 ++++----
+ include/linux/shdma-base.h | 8 ++++----
+ 4 files changed, 27 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c
+index f75ebfa..73db282 100644
+--- a/drivers/dma/sh/shdma-base.c
++++ b/drivers/dma/sh/shdma-base.c
+@@ -76,7 +76,6 @@ static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx)
+ container_of(tx, struct shdma_desc, async_tx),
+ *last = desc;
+ struct shdma_chan *schan = to_shdma_chan(tx->chan);
+- struct shdma_slave *slave = schan->slave;
+ dma_async_tx_callback callback = tx->callback;
+ dma_cookie_t cookie;
+ bool power_up;
+@@ -138,7 +137,7 @@ static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx)
+ * Make it int then, on error remove chunks from the
+ * queue again
+ */
+- ops->setup_xfer(schan, slave);
++ ops->setup_xfer(schan, schan->slave_id);
+
+ if (schan->pm_state == SHDMA_PM_PENDING)
+ shdma_chan_xfer_ld_queue(schan);
+@@ -186,7 +185,7 @@ static int shdma_alloc_chan_resources(struct dma_chan *chan)
+ * never runs concurrently with itself or free_chan_resources.
+ */
+ if (slave) {
+- if (slave->slave_id >= slave_num) {
++ if (slave->slave_id < 0 || slave->slave_id >= slave_num) {
+ ret = -EINVAL;
+ goto evalid;
+ }
+@@ -196,9 +195,13 @@ static int shdma_alloc_chan_resources(struct dma_chan *chan)
+ goto etestused;
+ }
+
+- ret = ops->set_slave(schan, slave);
++ ret = ops->set_slave(schan, slave->slave_id);
+ if (ret < 0)
+ goto esetslave;
++
++ schan->slave_id = slave->slave_id;
++ } else {
++ schan->slave_id = -EINVAL;
+ }
+
+ schan->desc = kcalloc(NR_DESCS_PER_CHANNEL,
+@@ -208,7 +211,6 @@ static int shdma_alloc_chan_resources(struct dma_chan *chan)
+ goto edescalloc;
+ }
+ schan->desc_num = NR_DESCS_PER_CHANNEL;
+- schan->slave = slave;
+
+ for (i = 0; i < NR_DESCS_PER_CHANNEL; i++) {
+ desc = ops->embedded_desc(schan->desc, i);
+@@ -366,10 +368,9 @@ static void shdma_free_chan_resources(struct dma_chan *chan)
+ if (!list_empty(&schan->ld_queue))
+ shdma_chan_ld_cleanup(schan, true);
+
+- if (schan->slave) {
++ if (schan->slave_id >= 0) {
+ /* The caller is holding dma_list_mutex */
+- struct shdma_slave *slave = schan->slave;
+- clear_bit(slave->slave_id, shdma_slave_used);
++ clear_bit(schan->slave_id, shdma_slave_used);
+ chan->private = NULL;
+ }
+
+@@ -559,7 +560,7 @@ static struct dma_async_tx_descriptor *shdma_prep_slave_sg(
+ struct shdma_chan *schan = to_shdma_chan(chan);
+ struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device);
+ const struct shdma_ops *ops = sdev->ops;
+- struct shdma_slave *slave = schan->slave;
++ int slave_id = schan->slave_id;
+ dma_addr_t slave_addr;
+
+ if (!chan)
+@@ -568,9 +569,9 @@ static struct dma_async_tx_descriptor *shdma_prep_slave_sg(
+ BUG_ON(!schan->desc_num);
+
+ /* Someone calling slave DMA on a generic channel? */
+- if (!slave || !sg_len) {
+- dev_warn(schan->dev, "%s: bad parameter: %p, %d, %d\n",
+- __func__, slave, sg_len, slave ? slave->slave_id : -1);
++ if (slave_id < 0 || !sg_len) {
++ dev_warn(schan->dev, "%s: bad parameter: len=%d, id=%d\n",
++ __func__, sg_len, slave_id);
+ return NULL;
+ }
+
+diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c
+index 9f0a2e5..9a10d8b 100644
+--- a/drivers/dma/sh/shdma.c
++++ b/drivers/dma/sh/shdma.c
+@@ -285,12 +285,12 @@ static bool sh_dmae_channel_busy(struct shdma_chan *schan)
+ }
+
+ static void sh_dmae_setup_xfer(struct shdma_chan *schan,
+- struct shdma_slave *sslave)
++ int slave_id)
+ {
+ struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan,
+ shdma_chan);
+
+- if (sslave) {
++ if (slave_id >= 0) {
+ const struct sh_dmae_slave_config *cfg =
+ sh_chan->config;
+
+@@ -302,7 +302,7 @@ static void sh_dmae_setup_xfer(struct shdma_chan *schan,
+ }
+
+ static const struct sh_dmae_slave_config *dmae_find_slave(
+- struct sh_dmae_chan *sh_chan, unsigned int slave_id)
++ struct sh_dmae_chan *sh_chan, int slave_id)
+ {
+ struct sh_dmae_device *shdev = to_sh_dev(sh_chan);
+ struct sh_dmae_pdata *pdata = shdev->pdata;
+@@ -320,11 +320,11 @@ static const struct sh_dmae_slave_config *dmae_find_slave(
+ }
+
+ static int sh_dmae_set_slave(struct shdma_chan *schan,
+- struct shdma_slave *sslave)
++ int slave_id)
+ {
+ struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan,
+ shdma_chan);
+- const struct sh_dmae_slave_config *cfg = dmae_find_slave(sh_chan, sslave->slave_id);
++ const struct sh_dmae_slave_config *cfg = dmae_find_slave(sh_chan, slave_id);
+ if (!cfg)
+ return -ENODEV;
+
+@@ -579,7 +579,7 @@ static int sh_dmae_resume(struct device *dev)
+ if (!sh_chan->shdma_chan.desc_num)
+ continue;
+
+- if (sh_chan->shdma_chan.slave) {
++ if (sh_chan->shdma_chan.slave_id >= 0) {
+ const struct sh_dmae_slave_config *cfg = sh_chan->config;
+ dmae_set_dmars(sh_chan, cfg->mid_rid);
+ dmae_set_chcr(sh_chan, cfg->chcr);
+diff --git a/include/linux/sh_dma.h b/include/linux/sh_dma.h
+index a79f10a..4e83f3e 100644
+--- a/include/linux/sh_dma.h
++++ b/include/linux/sh_dma.h
+@@ -27,10 +27,10 @@ struct sh_dmae_slave {
+ * a certain peripheral
+ */
+ struct sh_dmae_slave_config {
+- unsigned int slave_id;
+- dma_addr_t addr;
+- u32 chcr;
+- char mid_rid;
++ int slave_id;
++ dma_addr_t addr;
++ u32 chcr;
++ char mid_rid;
+ };
+
+ struct sh_dmae_channel {
+diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h
+index c3a19e9..6263ad2 100644
+--- a/include/linux/shdma-base.h
++++ b/include/linux/shdma-base.h
+@@ -43,7 +43,7 @@ struct device;
+ */
+
+ struct shdma_slave {
+- unsigned int slave_id;
++ int slave_id;
+ };
+
+ struct shdma_desc {
+@@ -66,7 +66,7 @@ struct shdma_chan {
+ size_t max_xfer_len; /* max transfer length */
+ int id; /* Raw id of this channel */
+ int irq; /* Channel IRQ */
+- struct shdma_slave *slave; /* Client data for slave DMA */
++ int slave_id; /* Client ID for slave DMA */
+ enum shdma_pm_state pm_state;
+ };
+
+@@ -93,8 +93,8 @@ struct shdma_ops {
+ dma_addr_t (*slave_addr)(struct shdma_chan *);
+ int (*desc_setup)(struct shdma_chan *, struct shdma_desc *,
+ dma_addr_t, dma_addr_t, size_t *);
+- int (*set_slave)(struct shdma_chan *, struct shdma_slave *);
+- void (*setup_xfer)(struct shdma_chan *, struct shdma_slave *);
++ int (*set_slave)(struct shdma_chan *, int);
++ void (*setup_xfer)(struct shdma_chan *, int);
+ void (*start_xfer)(struct shdma_chan *, struct shdma_desc *);
+ struct shdma_desc *(*embedded_desc)(void *, int);
+ bool (*chan_irq)(struct shdma_chan *, int);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0057-dma-sh-provide-a-migration-path-for-slave-drivers-to.patch b/patches.marzen/0057-dma-sh-provide-a-migration-path-for-slave-drivers-to.patch
new file mode 100644
index 0000000000000..b1aa4af404953
--- /dev/null
+++ b/patches.marzen/0057-dma-sh-provide-a-migration-path-for-slave-drivers-to.patch
@@ -0,0 +1,231 @@
+From 3f976e575c229dad477f66090af9286700b35b3e Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 5 Jul 2012 12:29:42 +0200
+Subject: dma: sh: provide a migration path for slave drivers to stop using
+ .private
+
+This patch extends the sh dmaengine driver to support the preferred channel
+selection and configuration method, instead of using the "private" field
+from struct dma_chan. We add a standard filter function to be used by
+slave drivers instead of implementing their own ones, and add support for
+the DMA_SLAVE_CONFIG control operation, which must accompany the new
+channel selection method. We still support the legacy .private channel
+allocation method to cater for a smooth driver migration.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+[applied a trvial checkpath fix]
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit 1ff8df4f5388ad66bd7d0199b5839a2e3345c055)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/dma/sh/shdma-base.c | 114 ++++++++++++++++++++++++++++++++++----------
+ drivers/dma/sh/shdma.c | 5 +-
+ include/linux/sh_dma.h | 2 +
+ include/linux/shdma-base.h | 2 +-
+ 4 files changed, 95 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c
+index 73db282..27f5c78 100644
+--- a/drivers/dma/sh/shdma-base.c
++++ b/drivers/dma/sh/shdma-base.c
+@@ -171,6 +171,65 @@ static struct shdma_desc *shdma_get_desc(struct shdma_chan *schan)
+ return NULL;
+ }
+
++static int shdma_setup_slave(struct shdma_chan *schan, int slave_id)
++{
++ struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device);
++ const struct shdma_ops *ops = sdev->ops;
++ int ret;
++
++ if (slave_id < 0 || slave_id >= slave_num)
++ return -EINVAL;
++
++ if (test_and_set_bit(slave_id, shdma_slave_used))
++ return -EBUSY;
++
++ ret = ops->set_slave(schan, slave_id, false);
++ if (ret < 0) {
++ clear_bit(slave_id, shdma_slave_used);
++ return ret;
++ }
++
++ schan->slave_id = slave_id;
++
++ return 0;
++}
++
++/*
++ * This is the standard shdma filter function to be used as a replacement to the
++ * "old" method, using the .private pointer. If for some reason you allocate a
++ * channel without slave data, use something like ERR_PTR(-EINVAL) as a filter
++ * parameter. If this filter is used, the slave driver, after calling
++ * dma_request_channel(), will also have to call dmaengine_slave_config() with
++ * .slave_id, .direction, and either .src_addr or .dst_addr set.
++ * NOTE: this filter doesn't support multiple DMAC drivers with the DMA_SLAVE
++ * capability! If this becomes a requirement, hardware glue drivers, using this
++ * services would have to provide their own filters, which first would check
++ * the device driver, similar to how other DMAC drivers, e.g., sa11x0-dma.c, do
++ * this, and only then, in case of a match, call this common filter.
++ */
++bool shdma_chan_filter(struct dma_chan *chan, void *arg)
++{
++ struct shdma_chan *schan = to_shdma_chan(chan);
++ struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device);
++ const struct shdma_ops *ops = sdev->ops;
++ int slave_id = (int)arg;
++ int ret;
++
++ if (slave_id < 0)
++ /* No slave requested - arbitrary channel */
++ return true;
++
++ if (slave_id >= slave_num)
++ return false;
++
++ ret = ops->set_slave(schan, slave_id, true);
++ if (ret < 0)
++ return false;
++
++ return true;
++}
++EXPORT_SYMBOL(shdma_chan_filter);
++
+ static int shdma_alloc_chan_resources(struct dma_chan *chan)
+ {
+ struct shdma_chan *schan = to_shdma_chan(chan);
+@@ -185,21 +244,10 @@ static int shdma_alloc_chan_resources(struct dma_chan *chan)
+ * never runs concurrently with itself or free_chan_resources.
+ */
+ if (slave) {
+- if (slave->slave_id < 0 || slave->slave_id >= slave_num) {
+- ret = -EINVAL;
+- goto evalid;
+- }
+-
+- if (test_and_set_bit(slave->slave_id, shdma_slave_used)) {
+- ret = -EBUSY;
+- goto etestused;
+- }
+-
+- ret = ops->set_slave(schan, slave->slave_id);
++ /* Legacy mode: .private is set in filter */
++ ret = shdma_setup_slave(schan, slave->slave_id);
+ if (ret < 0)
+ goto esetslave;
+-
+- schan->slave_id = slave->slave_id;
+ } else {
+ schan->slave_id = -EINVAL;
+ }
+@@ -228,8 +276,6 @@ edescalloc:
+ if (slave)
+ esetslave:
+ clear_bit(slave->slave_id, shdma_slave_used);
+-etestused:
+-evalid:
+ chan->private = NULL;
+ return ret;
+ }
+@@ -587,22 +633,40 @@ static int shdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+ struct shdma_chan *schan = to_shdma_chan(chan);
+ struct shdma_dev *sdev = to_shdma_dev(chan->device);
+ const struct shdma_ops *ops = sdev->ops;
++ struct dma_slave_config *config;
+ unsigned long flags;
+-
+- /* Only supports DMA_TERMINATE_ALL */
+- if (cmd != DMA_TERMINATE_ALL)
+- return -ENXIO;
++ int ret;
+
+ if (!chan)
+ return -EINVAL;
+
+- spin_lock_irqsave(&schan->chan_lock, flags);
+-
+- ops->halt_channel(schan);
+-
+- spin_unlock_irqrestore(&schan->chan_lock, flags);
++ switch (cmd) {
++ case DMA_TERMINATE_ALL:
++ spin_lock_irqsave(&schan->chan_lock, flags);
++ ops->halt_channel(schan);
++ spin_unlock_irqrestore(&schan->chan_lock, flags);
+
+- shdma_chan_ld_cleanup(schan, true);
++ shdma_chan_ld_cleanup(schan, true);
++ break;
++ case DMA_SLAVE_CONFIG:
++ /*
++ * So far only .slave_id is used, but the slave drivers are
++ * encouraged to also set a transfer direction and an address.
++ */
++ if (!arg)
++ return -EINVAL;
++ /*
++ * We could lock this, but you shouldn't be configuring the
++ * channel, while using it...
++ */
++ config = (struct dma_slave_config *)arg;
++ ret = shdma_setup_slave(schan, config->slave_id);
++ if (ret < 0)
++ return ret;
++ break;
++ default:
++ return -ENXIO;
++ }
+
+ return 0;
+ }
+diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c
+index 9a10d8b..027c9be 100644
+--- a/drivers/dma/sh/shdma.c
++++ b/drivers/dma/sh/shdma.c
+@@ -320,7 +320,7 @@ static const struct sh_dmae_slave_config *dmae_find_slave(
+ }
+
+ static int sh_dmae_set_slave(struct shdma_chan *schan,
+- int slave_id)
++ int slave_id, bool try)
+ {
+ struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan,
+ shdma_chan);
+@@ -328,7 +328,8 @@ static int sh_dmae_set_slave(struct shdma_chan *schan,
+ if (!cfg)
+ return -ENODEV;
+
+- sh_chan->config = cfg;
++ if (!try)
++ sh_chan->config = cfg;
+
+ return 0;
+ }
+diff --git a/include/linux/sh_dma.h b/include/linux/sh_dma.h
+index 4e83f3e..b64d6be 100644
+--- a/include/linux/sh_dma.h
++++ b/include/linux/sh_dma.h
+@@ -99,4 +99,6 @@ struct sh_dmae_pdata {
+ #define CHCR_TE 0x00000002
+ #define CHCR_IE 0x00000004
+
++bool shdma_chan_filter(struct dma_chan *chan, void *arg);
++
+ #endif
+diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h
+index 6263ad2..93f9821 100644
+--- a/include/linux/shdma-base.h
++++ b/include/linux/shdma-base.h
+@@ -93,7 +93,7 @@ struct shdma_ops {
+ dma_addr_t (*slave_addr)(struct shdma_chan *);
+ int (*desc_setup)(struct shdma_chan *, struct shdma_desc *,
+ dma_addr_t, dma_addr_t, size_t *);
+- int (*set_slave)(struct shdma_chan *, int);
++ int (*set_slave)(struct shdma_chan *, int, bool);
+ void (*setup_xfer)(struct shdma_chan *, int);
+ void (*start_xfer)(struct shdma_chan *, struct shdma_desc *);
+ struct shdma_desc *(*embedded_desc)(void *, int);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0058-dmaengine-shdma-restore-partial-transfer-calculation.patch b/patches.marzen/0058-dmaengine-shdma-restore-partial-transfer-calculation.patch
new file mode 100644
index 0000000000000..8352cb6d0451b
--- /dev/null
+++ b/patches.marzen/0058-dmaengine-shdma-restore-partial-transfer-calculation.patch
@@ -0,0 +1,101 @@
+From b1cb8efea85092e5441a428691a36d9fec40ca0f Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Mon, 30 Jul 2012 21:28:27 +0200
+Subject: dmaengine: shdma: restore partial transfer calculation
+
+The recent shdma driver split has mistakenly removed support for partial
+DMA transfer size calculation on forced termination. This patch restores
+it.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Acked-by: Vinod Koul <vinod.koul@linux.intel.com>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 4f46f8ac80416b0e8fd3aba6a0d842205fb29140)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/dma/sh/shdma-base.c | 9 +++++++++
+ drivers/dma/sh/shdma.c | 12 ++++++++++++
+ include/linux/shdma-base.h | 2 ++
+ 3 files changed, 23 insertions(+)
+
+diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c
+index 27f5c78..f4cd946 100644
+--- a/drivers/dma/sh/shdma-base.c
++++ b/drivers/dma/sh/shdma-base.c
+@@ -483,6 +483,7 @@ static struct shdma_desc *shdma_add_desc(struct shdma_chan *schan,
+ new->mark = DESC_PREPARED;
+ new->async_tx.flags = flags;
+ new->direction = direction;
++ new->partial = 0;
+
+ *len -= copy_size;
+ if (direction == DMA_MEM_TO_MEM || direction == DMA_MEM_TO_DEV)
+@@ -644,6 +645,14 @@ static int shdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+ case DMA_TERMINATE_ALL:
+ spin_lock_irqsave(&schan->chan_lock, flags);
+ ops->halt_channel(schan);
++
++ if (ops->get_partial && !list_empty(&schan->ld_queue)) {
++ /* Record partial transfer */
++ struct shdma_desc *desc = list_first_entry(&schan->ld_queue,
++ struct shdma_desc, node);
++ desc->partial = ops->get_partial(schan, desc);
++ }
++
+ spin_unlock_irqrestore(&schan->chan_lock, flags);
+
+ shdma_chan_ld_cleanup(schan, true);
+diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c
+index 027c9be..f41bcc5 100644
+--- a/drivers/dma/sh/shdma.c
++++ b/drivers/dma/sh/shdma.c
+@@ -381,6 +381,17 @@ static bool sh_dmae_chan_irq(struct shdma_chan *schan, int irq)
+ return true;
+ }
+
++static size_t sh_dmae_get_partial(struct shdma_chan *schan,
++ struct shdma_desc *sdesc)
++{
++ struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan,
++ shdma_chan);
++ struct sh_dmae_desc *sh_desc = container_of(sdesc,
++ struct sh_dmae_desc, shdma_desc);
++ return (sh_desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) <<
++ sh_chan->xmit_shift;
++}
++
+ /* Called from error IRQ or NMI */
+ static bool sh_dmae_reset(struct sh_dmae_device *shdev)
+ {
+@@ -632,6 +643,7 @@ static const struct shdma_ops sh_dmae_shdma_ops = {
+ .start_xfer = sh_dmae_start_xfer,
+ .embedded_desc = sh_dmae_embedded_desc,
+ .chan_irq = sh_dmae_chan_irq,
++ .get_partial = sh_dmae_get_partial,
+ };
+
+ static int __devinit sh_dmae_probe(struct platform_device *pdev)
+diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h
+index 93f9821..a3728bf 100644
+--- a/include/linux/shdma-base.h
++++ b/include/linux/shdma-base.h
+@@ -50,6 +50,7 @@ struct shdma_desc {
+ struct list_head node;
+ struct dma_async_tx_descriptor async_tx;
+ enum dma_transfer_direction direction;
++ size_t partial;
+ dma_cookie_t cookie;
+ int chunks;
+ int mark;
+@@ -98,6 +99,7 @@ struct shdma_ops {
+ void (*start_xfer)(struct shdma_chan *, struct shdma_desc *);
+ struct shdma_desc *(*embedded_desc)(void *, int);
+ bool (*chan_irq)(struct shdma_chan *, int);
++ size_t (*get_partial)(struct shdma_chan *, struct shdma_desc *);
+ };
+
+ struct shdma_dev {
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0059-serial-sh-sci-modify-sci_break_ctl.patch b/patches.marzen/0059-serial-sh-sci-modify-sci_break_ctl.patch
new file mode 100644
index 0000000000000..0b342ddc24cff
--- /dev/null
+++ b/patches.marzen/0059-serial-sh-sci-modify-sci_break_ctl.patch
@@ -0,0 +1,77 @@
+From f51d4dcccbe271ab892444ddb9821b2e8b976c04 Mon Sep 17 00:00:00 2001
+From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com>
+Date: Fri, 6 Apr 2012 09:59:14 +0900
+Subject: serial: sh-sci: modify sci_break_ctl()
+
+SCIF modules which have SCSPTR can output the break signal. Now that we
+have a way of determining port features/capabilities, add trivial break
+control via SCSPTR support. Tested on sh7757lcr.
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Reviewed-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit bbb4ce50f3169b08764f9965fd5b9655646d545a)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/tty/serial/sh-sci.c | 30 ++++++++++++++++++++++++++----
+ include/linux/serial_sci.h | 2 ++
+ 2 files changed, 28 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
+index 3158e17..3e471fc 100644
+--- a/drivers/tty/serial/sh-sci.c
++++ b/drivers/tty/serial/sh-sci.c
+@@ -1564,10 +1564,32 @@ static void sci_enable_ms(struct uart_port *port)
+
+ static void sci_break_ctl(struct uart_port *port, int break_state)
+ {
+- /*
+- * Not supported by hardware. Most parts couple break and rx
+- * interrupts together, with break detection always enabled.
+- */
++ struct sci_port *s = to_sci_port(port);
++ unsigned short scscr, scsptr;
++
++ switch (s->cfg->regtype) {
++ case SCIx_SH4_SCIF_REGTYPE:
++ scsptr = serial_port_in(port, SCSPTR);
++ scscr = serial_port_in(port, SCSCR);
++
++ if (break_state == -1) {
++ scsptr = (scsptr | SCSPTR_SPB2IO) & ~SCSPTR_SPB2DT;
++ scscr &= ~SCSCR_TE;
++ } else {
++ scsptr = (scsptr | SCSPTR_SPB2DT) & ~SCSPTR_SPB2IO;
++ scscr |= SCSCR_TE;
++ }
++
++ serial_port_out(port, SCSPTR, scsptr);
++ serial_port_out(port, SCSCR, scscr);
++ break;
++ default:
++ /*
++ * Not supported by hardware. Most parts couple break and rx
++ * interrupts together, with break detection always enabled.
++ */
++ break;
++ }
+ }
+
+ #ifdef CONFIG_SERIAL_SH_SCI_DMA
+diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h
+index 7877907..eb763ad 100644
+--- a/include/linux/serial_sci.h
++++ b/include/linux/serial_sci.h
+@@ -52,6 +52,8 @@ enum {
+ /* SCSPTR, optional */
+ #define SCSPTR_RTSIO (1 << 7)
+ #define SCSPTR_CTSIO (1 << 5)
++#define SCSPTR_SPB2IO (1 << 1)
++#define SCSPTR_SPB2DT (1 << 0)
+
+ /* Offsets into the sci_port->irqs array */
+ enum {
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0060-serial-sh-sci-Update-break_ctl-handling-for-all-SCSP.patch b/patches.marzen/0060-serial-sh-sci-Update-break_ctl-handling-for-all-SCSP.patch
new file mode 100644
index 0000000000000..807ce53b01bf2
--- /dev/null
+++ b/patches.marzen/0060-serial-sh-sci-Update-break_ctl-handling-for-all-SCSP.patch
@@ -0,0 +1,77 @@
+From 771d21f0510973f1da8789ad877a0fa806aa1ec7 Mon Sep 17 00:00:00 2001
+From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com>
+Date: Thu, 12 Apr 2012 19:19:21 +0900
+Subject: serial: sh-sci: Update break_ctl handling for all SCSPTR-capable
+ regtypes.
+
+This updates the earlier break_ctl support regardless of regtype so long
+as the requisite SCSPTR exists. This is the same approach used by
+sci_init_pins() for providing a generic solution now that we're able to
+detect register capabilities on a per-port basis.
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit a4e02f6d83d4fcdb13bcaba76878fc5ea0da9911)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/tty/serial/sh-sci.c | 36 ++++++++++++++++++------------------
+ 1 file changed, 18 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
+index 3e471fc..be31d85 100644
+--- a/drivers/tty/serial/sh-sci.c
++++ b/drivers/tty/serial/sh-sci.c
+@@ -1565,31 +1565,31 @@ static void sci_enable_ms(struct uart_port *port)
+ static void sci_break_ctl(struct uart_port *port, int break_state)
+ {
+ struct sci_port *s = to_sci_port(port);
++ struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR;
+ unsigned short scscr, scsptr;
+
+- switch (s->cfg->regtype) {
+- case SCIx_SH4_SCIF_REGTYPE:
+- scsptr = serial_port_in(port, SCSPTR);
+- scscr = serial_port_in(port, SCSCR);
+-
+- if (break_state == -1) {
+- scsptr = (scsptr | SCSPTR_SPB2IO) & ~SCSPTR_SPB2DT;
+- scscr &= ~SCSCR_TE;
+- } else {
+- scsptr = (scsptr | SCSPTR_SPB2DT) & ~SCSPTR_SPB2IO;
+- scscr |= SCSCR_TE;
+- }
+-
+- serial_port_out(port, SCSPTR, scsptr);
+- serial_port_out(port, SCSCR, scscr);
+- break;
+- default:
++ /* check wheter the port has SCSPTR */
++ if (!reg->size) {
+ /*
+ * Not supported by hardware. Most parts couple break and rx
+ * interrupts together, with break detection always enabled.
+ */
+- break;
++ return;
+ }
++
++ scsptr = serial_port_in(port, SCSPTR);
++ scscr = serial_port_in(port, SCSCR);
++
++ if (break_state == -1) {
++ scsptr = (scsptr | SCSPTR_SPB2IO) & ~SCSPTR_SPB2DT;
++ scscr &= ~SCSCR_TE;
++ } else {
++ scsptr = (scsptr | SCSPTR_SPB2DT) & ~SCSPTR_SPB2IO;
++ scscr |= SCSCR_TE;
++ }
++
++ serial_port_out(port, SCSPTR, scsptr);
++ serial_port_out(port, SCSCR, scscr);
+ }
+
+ #ifdef CONFIG_SERIAL_SH_SCI_DMA
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0061-serial-sh-sci-Fix-for-port-types-without-BRI-interru.patch b/patches.marzen/0061-serial-sh-sci-Fix-for-port-types-without-BRI-interru.patch
new file mode 100644
index 0000000000000..990a00fa3cdc7
--- /dev/null
+++ b/patches.marzen/0061-serial-sh-sci-Fix-for-port-types-without-BRI-interru.patch
@@ -0,0 +1,63 @@
+From 0491f004737edadd928f7d46f5e9f0f8f5f054e0 Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Fri, 18 May 2012 18:21:06 +0900
+Subject: serial: sh-sci: Fix for port types without BRI interrupts.
+
+In doing the evt2irq() + muxed vector conversion for various port types
+it became apparent that some of the legacy port types will presently
+error out due to the irq requesting logic attempting to acquire the
+non-existent BRI IRQ. This adds some sanity checks to the request/free
+path to ensure that non-existence of a source in itself is not an error.
+
+This should restore functionality for legacy PORT_SCI ports.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 0e8963de1fe95e7fbc30c79c1dbc7cb1ea0cf699)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/tty/serial/sh-sci.c | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
+index be31d85..4604153 100644
+--- a/drivers/tty/serial/sh-sci.c
++++ b/drivers/tty/serial/sh-sci.c
+@@ -1052,9 +1052,17 @@ static int sci_request_irq(struct sci_port *port)
+ if (SCIx_IRQ_IS_MUXED(port)) {
+ i = SCIx_MUX_IRQ;
+ irq = up->irq;
+- } else
++ } else {
+ irq = port->cfg->irqs[i];
+
++ /*
++ * Certain port types won't support all of the
++ * available interrupt sources.
++ */
++ if (unlikely(!irq))
++ continue;
++ }
++
+ desc = sci_irq_desc + i;
+ port->irqstr[j] = kasprintf(GFP_KERNEL, "%s:%s",
+ dev_name(up->dev), desc->desc);
+@@ -1094,6 +1102,15 @@ static void sci_free_irq(struct sci_port *port)
+ * IRQ first.
+ */
+ for (i = 0; i < SCIx_NR_IRQS; i++) {
++ unsigned int irq = port->cfg->irqs[i];
++
++ /*
++ * Certain port types won't support all of the available
++ * interrupt sources.
++ */
++ if (unlikely(!irq))
++ continue;
++
+ free_irq(port->cfg->irqs[i], port);
+ kfree(port->irqstr[i]);
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0062-serial-sh-sci-Fix-probe-error-paths.patch b/patches.marzen/0062-serial-sh-sci-Fix-probe-error-paths.patch
new file mode 100644
index 0000000000000..fc41e2d061649
--- /dev/null
+++ b/patches.marzen/0062-serial-sh-sci-Fix-probe-error-paths.patch
@@ -0,0 +1,102 @@
+From 61760a1e6363eeb42b29b76176e3ec4ac837753b Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Wed, 13 Jun 2012 00:28:23 +0200
+Subject: serial: sh-sci: Fix probe error paths
+
+When probing fails, the driver must not try to cleanup resources that
+have not been initialized. Fix this.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 6dae14216c85eea13db7b12c469475c5d30e5499)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/tty/serial/sh-sci.c | 36 +++++++++++++++++++++++-------------
+ 1 file changed, 23 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
+index 4604153..27df2ad 100644
+--- a/drivers/tty/serial/sh-sci.c
++++ b/drivers/tty/serial/sh-sci.c
+@@ -2179,6 +2179,16 @@ static int __devinit sci_init_single(struct platform_device *dev,
+ return 0;
+ }
+
++static void sci_cleanup_single(struct sci_port *port)
++{
++ sci_free_gpios(port);
++
++ clk_put(port->iclk);
++ clk_put(port->fclk);
++
++ pm_runtime_disable(port->port.dev);
++}
++
+ #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
+ static void serial_console_putchar(struct uart_port *port, int ch)
+ {
+@@ -2360,14 +2370,10 @@ static int sci_remove(struct platform_device *dev)
+ cpufreq_unregister_notifier(&port->freq_transition,
+ CPUFREQ_TRANSITION_NOTIFIER);
+
+- sci_free_gpios(port);
+-
+ uart_remove_one_port(&sci_uart_driver, &port->port);
+
+- clk_put(port->iclk);
+- clk_put(port->fclk);
++ sci_cleanup_single(port);
+
+- pm_runtime_disable(&dev->dev);
+ return 0;
+ }
+
+@@ -2392,7 +2398,13 @@ static int __devinit sci_probe_single(struct platform_device *dev,
+ if (ret)
+ return ret;
+
+- return uart_add_one_port(&sci_uart_driver, &sciport->port);
++ ret = uart_add_one_port(&sci_uart_driver, &sciport->port);
++ if (ret) {
++ sci_cleanup_single(sciport);
++ return ret;
++ }
++
++ return 0;
+ }
+
+ static int __devinit sci_probe(struct platform_device *dev)
+@@ -2413,24 +2425,22 @@ static int __devinit sci_probe(struct platform_device *dev)
+
+ ret = sci_probe_single(dev, dev->id, p, sp);
+ if (ret)
+- goto err_unreg;
++ return ret;
+
+ sp->freq_transition.notifier_call = sci_notifier;
+
+ ret = cpufreq_register_notifier(&sp->freq_transition,
+ CPUFREQ_TRANSITION_NOTIFIER);
+- if (unlikely(ret < 0))
+- goto err_unreg;
++ if (unlikely(ret < 0)) {
++ sci_cleanup_single(sp);
++ return ret;
++ }
+
+ #ifdef CONFIG_SH_STANDARD_BIOS
+ sh_bios_gdb_detach();
+ #endif
+
+ return 0;
+-
+-err_unreg:
+- sci_remove(dev);
+- return ret;
+ }
+
+ static int sci_suspend(struct device *dev)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0063-serial-sh-sci-Make-probe-fail-for-ports-that-exceed-.patch b/patches.marzen/0063-serial-sh-sci-Make-probe-fail-for-ports-that-exceed-.patch
new file mode 100644
index 0000000000000..7ca587c33cb57
--- /dev/null
+++ b/patches.marzen/0063-serial-sh-sci-Make-probe-fail-for-ports-that-exceed-.patch
@@ -0,0 +1,39 @@
+From e78402772bb6c357710275ae6958fd9eaab70036 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Wed, 13 Jun 2012 00:28:24 +0200
+Subject: serial: sh-sci: Make probe fail for ports that exceed the maximum
+ count
+
+The driver supports a maximum number of ports configurable at compile
+time. Make sure the probe() method fails when registering a port that
+exceeds the maximum instead of returning success without registering the
+port.
+
+This fixes a crash at system suspend time, when the driver tried to
+suspend a non-registered port using the UART core.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit b6c5ef6f6d3e46d6200b141c30ac000a11b851df)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/tty/serial/sh-sci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
+index 27df2ad..1bd9163 100644
+--- a/drivers/tty/serial/sh-sci.c
++++ b/drivers/tty/serial/sh-sci.c
+@@ -2391,7 +2391,7 @@ static int __devinit sci_probe_single(struct platform_device *dev,
+ index+1, SCI_NPORTS);
+ dev_notice(&dev->dev, "Consider bumping "
+ "CONFIG_SERIAL_SH_SCI_NR_UARTS!\n");
+- return 0;
++ return -EINVAL;
+ }
+
+ ret = sci_init_single(dev, sciport, index, p);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0064-serial-sh-sci-prepare-for-conversion-to-the-shdma-ba.patch b/patches.marzen/0064-serial-sh-sci-prepare-for-conversion-to-the-shdma-ba.patch
new file mode 100644
index 0000000000000..75ad2f363dca8
--- /dev/null
+++ b/patches.marzen/0064-serial-sh-sci-prepare-for-conversion-to-the-shdma-ba.patch
@@ -0,0 +1,53 @@
+From d9a397f8913cef21e0cc251856d5e3e709d057f8 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 9 May 2012 17:09:17 +0200
+Subject: serial: sh-sci: prepare for conversion to the shdma base library
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Cc: Alan Cox <alan@linux.intel.com>
+Acked-by: Paul Mundt <lethal@linux-sh.org>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit d6fa5a4e7ab605370fd6c982782f84ef2e6660e7)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/tty/serial/sh-sci.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
+index 1bd9163..d4d8c94 100644
+--- a/drivers/tty/serial/sh-sci.c
++++ b/drivers/tty/serial/sh-sci.c
+@@ -1615,9 +1615,9 @@ static bool filter(struct dma_chan *chan, void *slave)
+ struct sh_dmae_slave *param = slave;
+
+ dev_dbg(chan->device->dev, "%s: slave ID %d\n", __func__,
+- param->slave_id);
++ param->shdma_slave.slave_id);
+
+- chan->private = param;
++ chan->private = &param->shdma_slave;
+ return true;
+ }
+
+@@ -1656,7 +1656,7 @@ static void sci_request_dma(struct uart_port *port)
+ param = &s->param_tx;
+
+ /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */
+- param->slave_id = s->cfg->dma_slave_tx;
++ param->shdma_slave.slave_id = s->cfg->dma_slave_tx;
+
+ s->cookie_tx = -EINVAL;
+ chan = dma_request_channel(mask, filter, param);
+@@ -1684,7 +1684,7 @@ static void sci_request_dma(struct uart_port *port)
+ param = &s->param_rx;
+
+ /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */
+- param->slave_id = s->cfg->dma_slave_rx;
++ param->shdma_slave.slave_id = s->cfg->dma_slave_rx;
+
+ chan = dma_request_channel(mask, filter, param);
+ dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0065-serial-sh-sci-fix-compilation-breakage-when-DMA-is-e.patch b/patches.marzen/0065-serial-sh-sci-fix-compilation-breakage-when-DMA-is-e.patch
new file mode 100644
index 0000000000000..543dee31535c1
--- /dev/null
+++ b/patches.marzen/0065-serial-sh-sci-fix-compilation-breakage-when-DMA-is-e.patch
@@ -0,0 +1,51 @@
+From 3e91d8139916610c1a34ff1359fb866b2bc82bab Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Mon, 30 Jul 2012 21:28:47 +0200
+Subject: serial: sh-sci: fix compilation breakage, when DMA is enabled
+
+A recent commit:
+
+commit d6fa5a4e7ab605370fd6c982782f84ef2e6660e7
+Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ serial: sh-sci: prepare for conversion to the shdma base library
+
+is not sufficient to update the sh-sci driver to the new shdma driver
+layout. This caused compilation breakage, when CONFIG_SERIAL_SH_SCI_DMA
+is enabled. This patch trivially fixes the problem by updating the DMA
+descriptor manipulation code.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 4dc4c51675c137c30838425ecc8d471ff5eb138b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/tty/serial/sh-sci.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
+index d4d8c94..9be296c 100644
+--- a/drivers/tty/serial/sh-sci.c
++++ b/drivers/tty/serial/sh-sci.c
+@@ -25,6 +25,7 @@
+
+ #include <linux/module.h>
+ #include <linux/errno.h>
++#include <linux/sh_dma.h>
+ #include <linux/timer.h>
+ #include <linux/interrupt.h>
+ #include <linux/tty.h>
+@@ -1410,8 +1411,8 @@ static void work_fn_rx(struct work_struct *work)
+ /* Handle incomplete DMA receive */
+ struct tty_struct *tty = port->state->port.tty;
+ struct dma_chan *chan = s->chan_rx;
+- struct sh_desc *sh_desc = container_of(desc, struct sh_desc,
+- async_tx);
++ struct shdma_desc *sh_desc = container_of(desc,
++ struct shdma_desc, async_tx);
+ unsigned long flags;
+ int count;
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0066-net-smsc911x-Repair-broken-failure-paths.patch b/patches.marzen/0066-net-smsc911x-Repair-broken-failure-paths.patch
new file mode 100644
index 0000000000000..5c96ddc5c9786
--- /dev/null
+++ b/patches.marzen/0066-net-smsc911x-Repair-broken-failure-paths.patch
@@ -0,0 +1,53 @@
+From 925ce819e01d210634e6108067368107fe17fd8c Mon Sep 17 00:00:00 2001
+From: Lee Jones <lee.jones@linaro.org>
+Date: Tue, 29 May 2012 18:47:37 +0000
+Subject: net/smsc911x: Repair broken failure paths
+
+Current failure paths attempt to free resources which we failed to request
+and disable resources which we failed to enable ones. This leads to kernel
+oops/panic. This patch does some simple re-ordering to prevent this from
+happening.
+
+Cc: netdev@vger.kernel.org
+Signed-off-by: Lee Jones <lee.jones@linaro.org>
+Acked-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 2e1d4a065a77d076a679df22a4eddbc7e33cad98)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/net/ethernet/smsc/smsc911x.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
+index cd3defb..245c700 100644
+--- a/drivers/net/ethernet/smsc/smsc911x.c
++++ b/drivers/net/ethernet/smsc/smsc911x.c
+@@ -2389,11 +2389,11 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
+
+ retval = smsc911x_request_resources(pdev);
+ if (retval)
+- goto out_return_resources;
++ goto out_request_resources_fail;
+
+ retval = smsc911x_enable_resources(pdev);
+ if (retval)
+- goto out_disable_resources;
++ goto out_enable_resources_fail;
+
+ if (pdata->ioaddr == NULL) {
+ SMSC_WARN(pdata, probe, "Error smsc911x base address invalid");
+@@ -2500,8 +2500,9 @@ out_free_irq:
+ free_irq(dev->irq, dev);
+ out_disable_resources:
+ (void)smsc911x_disable_resources(pdev);
+-out_return_resources:
++out_enable_resources_fail:
+ smsc911x_free_resources(pdev);
++out_request_resources_fail:
+ platform_set_drvdata(pdev, NULL);
+ iounmap(pdata->ioaddr);
+ free_netdev(dev);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0067-smsc911x.c-encapsulate-enable-irq-calls.patch b/patches.marzen/0067-smsc911x.c-encapsulate-enable-irq-calls.patch
new file mode 100644
index 0000000000000..b80d5b0d7db53
--- /dev/null
+++ b/patches.marzen/0067-smsc911x.c-encapsulate-enable-irq-calls.patch
@@ -0,0 +1,70 @@
+From 89b2c2592f45401b0862a70a6d71e4c81274c1a3 Mon Sep 17 00:00:00 2001
+From: Matthias Brugger <mbrugger@iseebcn.com>
+Date: Fri, 22 Jun 2012 01:10:15 +0000
+Subject: smsc911x.c: encapsulate enable irq calls
+
+We encapsulate enbale irq functionality in a function call.
+As on probe the interrupts will be disabled twice, we delete
+one.
+
+Signed-off-by: Matthias Brugger <mbrugger@iseebcn.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit 8e27628ecf883b9e5825103e40e6f86bf8225f1a)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/net/ethernet/smsc/smsc911x.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
+index 245c700..759e9b4 100644
+--- a/drivers/net/ethernet/smsc/smsc911x.c
++++ b/drivers/net/ethernet/smsc/smsc911x.c
+@@ -1442,6 +1442,14 @@ smsc911x_set_hw_mac_address(struct smsc911x_data *pdata, u8 dev_addr[6])
+ smsc911x_mac_write(pdata, ADDRL, mac_low32);
+ }
+
++static void smsc911x_disable_irq_chip(struct net_device *dev)
++{
++ struct smsc911x_data *pdata = netdev_priv(dev);
++
++ smsc911x_reg_write(pdata, INT_EN, 0);
++ smsc911x_reg_write(pdata, INT_STS, 0xFFFFFFFF);
++}
++
+ static int smsc911x_open(struct net_device *dev)
+ {
+ struct smsc911x_data *pdata = netdev_priv(dev);
+@@ -1494,8 +1502,7 @@ static int smsc911x_open(struct net_device *dev)
+ spin_unlock_irq(&pdata->mac_lock);
+
+ /* Initialise irqs, but leave all sources disabled */
+- smsc911x_reg_write(pdata, INT_EN, 0);
+- smsc911x_reg_write(pdata, INT_STS, 0xFFFFFFFF);
++ smsc911x_disable_irq_chip(dev);
+
+ /* Set interrupt deassertion to 100uS */
+ intcfg = ((10 << 24) | INT_CFG_IRQ_EN_);
+@@ -2214,9 +2221,6 @@ static int __devinit smsc911x_init(struct net_device *dev)
+ if (smsc911x_soft_reset(pdata))
+ return -ENODEV;
+
+- /* Disable all interrupt sources until we bring the device up */
+- smsc911x_reg_write(pdata, INT_EN, 0);
+-
+ ether_setup(dev);
+ dev->flags |= IFF_MULTICAST;
+ netif_napi_add(dev, &pdata->napi, smsc911x_poll, SMSC_NAPI_WEIGHT);
+@@ -2433,8 +2437,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
+ smsc911x_reg_write(pdata, INT_CFG, intcfg);
+
+ /* Ensure interrupts are globally disabled before connecting ISR */
+- smsc911x_reg_write(pdata, INT_EN, 0);
+- smsc911x_reg_write(pdata, INT_STS, 0xFFFFFFFF);
++ smsc911x_disable_irq_chip(dev);
+
+ retval = request_irq(dev->irq, smsc911x_irqhandler,
+ irq_flags | IRQF_SHARED, dev->name, dev);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0068-clocksource-sh_tmu-Convert-timer-lock-to-raw-spinloc.patch b/patches.marzen/0068-clocksource-sh_tmu-Convert-timer-lock-to-raw-spinloc.patch
new file mode 100644
index 0000000000000..d7ad043eb4275
--- /dev/null
+++ b/patches.marzen/0068-clocksource-sh_tmu-Convert-timer-lock-to-raw-spinloc.patch
@@ -0,0 +1,47 @@
+From 3dc719e07177476e63995abda41f8d86f7c6056d Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Fri, 25 May 2012 13:39:09 +0900
+Subject: clocksource: sh_tmu: Convert timer lock to raw spinlock.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit c2225a57e596a308424e59abc7e864f866fe4493)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/clocksource/sh_tmu.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
+index 97f54b6..852b3f1 100644
+--- a/drivers/clocksource/sh_tmu.c
++++ b/drivers/clocksource/sh_tmu.c
+@@ -45,7 +45,7 @@ struct sh_tmu_priv {
+ struct clocksource cs;
+ };
+
+-static DEFINE_SPINLOCK(sh_tmu_lock);
++static DEFINE_RAW_SPINLOCK(sh_tmu_lock);
+
+ #define TSTR -1 /* shared register */
+ #define TCOR 0 /* channel register */
+@@ -95,7 +95,7 @@ static void sh_tmu_start_stop_ch(struct sh_tmu_priv *p, int start)
+ unsigned long flags, value;
+
+ /* start stop register shared by multiple timer channels */
+- spin_lock_irqsave(&sh_tmu_lock, flags);
++ raw_spin_lock_irqsave(&sh_tmu_lock, flags);
+ value = sh_tmu_read(p, TSTR);
+
+ if (start)
+@@ -104,7 +104,7 @@ static void sh_tmu_start_stop_ch(struct sh_tmu_priv *p, int start)
+ value &= ~(1 << cfg->timer_bit);
+
+ sh_tmu_write(p, TSTR, value);
+- spin_unlock_irqrestore(&sh_tmu_lock, flags);
++ raw_spin_unlock_irqrestore(&sh_tmu_lock, flags);
+ }
+
+ static int sh_tmu_enable(struct sh_tmu_priv *p)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0069-mmc-tmio-use-MMC-opcode-defines-instead-of-numbers.patch b/patches.marzen/0069-mmc-tmio-use-MMC-opcode-defines-instead-of-numbers.patch
new file mode 100644
index 0000000000000..792f03263dc4f
--- /dev/null
+++ b/patches.marzen/0069-mmc-tmio-use-MMC-opcode-defines-instead-of-numbers.patch
@@ -0,0 +1,52 @@
+From 611af69d5a747a3c8d6268a006dd0d913257fe02 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 20 Jun 2012 19:10:35 +0200
+Subject: mmc: tmio: use MMC opcode defines instead of numbers
+
+mmc.h defines macros for most frequently used MMC opcodes. Use them instead
+of hard-coded numbers.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 0f506a96693d8ad4aeccbd98dbd54a3c7357cfa8)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_pio.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index 9a7996a..0ad3917 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -36,6 +36,7 @@
+ #include <linux/mfd/tmio.h>
+ #include <linux/mmc/cd-gpio.h>
+ #include <linux/mmc/host.h>
++#include <linux/mmc/mmc.h>
+ #include <linux/mmc/tmio.h>
+ #include <linux/module.h>
+ #include <linux/pagemap.h>
+@@ -305,8 +306,8 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command
+ int c = cmd->opcode;
+ u32 irq_mask = TMIO_MASK_CMD;
+
+- /* Command 12 is handled by hardware */
+- if (cmd->opcode == 12 && !cmd->arg) {
++ /* CMD12 is handled by hardware */
++ if (cmd->opcode == MMC_STOP_TRANSMISSION && !cmd->arg) {
+ sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x001);
+ return 0;
+ }
+@@ -449,7 +450,7 @@ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host)
+ }
+
+ if (stop) {
+- if (stop->opcode == 12 && !stop->arg)
++ if (stop->opcode == MMC_STOP_TRANSMISSION && !stop->arg)
+ sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x000);
+ else
+ BUG();
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0070-mmc-cd-gpio-pass-IRQF_ONESHOT-to-request_threaded_ir.patch b/patches.marzen/0070-mmc-cd-gpio-pass-IRQF_ONESHOT-to-request_threaded_ir.patch
new file mode 100644
index 0000000000000..325a3c169f92c
--- /dev/null
+++ b/patches.marzen/0070-mmc-cd-gpio-pass-IRQF_ONESHOT-to-request_threaded_ir.patch
@@ -0,0 +1,43 @@
+From a43c0fe8cb2e7a3312b979c3b1fe1ab5b762994a Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Tue, 10 Jul 2012 22:54:11 -0400
+Subject: mmc: cd-gpio: pass IRQF_ONESHOT to request_threaded_irq()
+
+Fix a boot regression on Mackerel boards with sh_mobile_sdhi
+in existing kernels causing:
+
+genirq: Threaded irq requested with handler=NULL and !ONESHOT for irq XXX
+
+caused by 1c6c6952 (genirq: Reject bogus threaded irq requests).
+
+This is backported from Guennadi's patch:
+"mmc: extend and rename cd-gpio helpers to handle more slot GPIO functions"
+
+Reported-by: Rafael J. Wysocki <rjw@sisk.pl>
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 623b51fc8642fd3c795fa9903be3adaa537ad9c5)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/core/cd-gpio.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c
+index f13e38d..8f5dc08 100644
+--- a/drivers/mmc/core/cd-gpio.c
++++ b/drivers/mmc/core/cd-gpio.c
+@@ -50,8 +50,8 @@ int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio)
+ goto egpioreq;
+
+ ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt,
+- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+- cd->label, host);
++ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
++ IRQF_ONESHOT, cd->label, host);
+ if (ret < 0)
+ goto eirqreq;
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0071-mmc-extend-and-rename-cd-gpio-helpers-to-handle-more.patch b/patches.marzen/0071-mmc-extend-and-rename-cd-gpio-helpers-to-handle-more.patch
new file mode 100644
index 0000000000000..7a17b5a007027
--- /dev/null
+++ b/patches.marzen/0071-mmc-extend-and-rename-cd-gpio-helpers-to-handle-more.patch
@@ -0,0 +1,199 @@
+From 06a2252e0baf7bc5e4dd3b8c31898edcc838b518 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Mon, 30 Apr 2012 23:31:57 +0200
+Subject: mmc: extend and rename cd-gpio helpers to handle more slot GPIO
+ functions
+
+GPIOs can be used in MMC/SD-card slots not only for hotplug detection, but
+also to implement the write-protection pin. Rename cd-gpio helpers to
+slot-gpio to make addition of further slot GPIO functions possible.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit fd0ea65d3e675e479e022b6cfc9ebe1864c76afc)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/core/Makefile | 2 +-
+ drivers/mmc/core/{cd-gpio.c => slot-gpio.c} | 48 ++++++++++++++--------------
+ drivers/mmc/host/tmio_mmc_pio.c | 6 ++--
+ include/linux/mmc/{cd-gpio.h => slot-gpio.h} | 8 ++---
+ 4 files changed, 32 insertions(+), 32 deletions(-)
+ rename drivers/mmc/core/{cd-gpio.c => slot-gpio.c} (53%)
+ rename include/linux/mmc/{cd-gpio.h => slot-gpio.h} (68%)
+
+diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
+index dca4428..38ed210 100644
+--- a/drivers/mmc/core/Makefile
++++ b/drivers/mmc/core/Makefile
+@@ -7,6 +7,6 @@ mmc_core-y := core.o bus.o host.o \
+ mmc.o mmc_ops.o sd.o sd_ops.o \
+ sdio.o sdio_ops.o sdio_bus.o \
+ sdio_cis.o sdio_io.o sdio_irq.o \
+- quirks.o cd-gpio.o
++ quirks.o slot-gpio.o
+
+ mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
+diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/slot-gpio.c
+similarity index 53%
+rename from drivers/mmc/core/cd-gpio.c
+rename to drivers/mmc/core/slot-gpio.c
+index 8f5dc08..9796710 100644
+--- a/drivers/mmc/core/cd-gpio.c
++++ b/drivers/mmc/core/slot-gpio.c
+@@ -12,72 +12,72 @@
+ #include <linux/gpio.h>
+ #include <linux/interrupt.h>
+ #include <linux/jiffies.h>
+-#include <linux/mmc/cd-gpio.h>
+ #include <linux/mmc/host.h>
++#include <linux/mmc/slot-gpio.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+
+-struct mmc_cd_gpio {
+- unsigned int gpio;
+- char label[0];
++struct mmc_gpio {
++ unsigned int cd_gpio;
++ char cd_label[0];
+ };
+
+-static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id)
++static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
+ {
+ /* Schedule a card detection after a debounce timeout */
+ mmc_detect_change(dev_id, msecs_to_jiffies(100));
+ return IRQ_HANDLED;
+ }
+
+-int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio)
++int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
+ {
+ size_t len = strlen(dev_name(host->parent)) + 4;
+- struct mmc_cd_gpio *cd;
++ struct mmc_gpio *ctx;
+ int irq = gpio_to_irq(gpio);
+ int ret;
+
+ if (irq < 0)
+ return irq;
+
+- cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL);
+- if (!cd)
++ ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL);
++ if (!ctx)
+ return -ENOMEM;
+
+- snprintf(cd->label, len, "%s cd", dev_name(host->parent));
++ snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
+
+- ret = gpio_request_one(gpio, GPIOF_DIR_IN, cd->label);
++ ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label);
+ if (ret < 0)
+ goto egpioreq;
+
+- ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt,
+- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
+- IRQF_ONESHOT, cd->label, host);
++ ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
++ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
++ ctx->cd_label, host);
+ if (ret < 0)
+ goto eirqreq;
+
+- cd->gpio = gpio;
++ ctx->cd_gpio = gpio;
+ host->hotplug.irq = irq;
+- host->hotplug.handler_priv = cd;
++ host->hotplug.handler_priv = ctx;
+
+ return 0;
+
+ eirqreq:
+ gpio_free(gpio);
+ egpioreq:
+- kfree(cd);
++ kfree(ctx);
+ return ret;
+ }
+-EXPORT_SYMBOL(mmc_cd_gpio_request);
++EXPORT_SYMBOL(mmc_gpio_request_cd);
+
+-void mmc_cd_gpio_free(struct mmc_host *host)
++void mmc_gpio_free_cd(struct mmc_host *host)
+ {
+- struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
++ struct mmc_gpio *ctx = host->hotplug.handler_priv;
+
+- if (!cd)
++ if (!ctx)
+ return;
+
+ free_irq(host->hotplug.irq, host);
+- gpio_free(cd->gpio);
+- kfree(cd);
++ gpio_free(ctx->cd_gpio);
++ kfree(ctx);
+ }
+-EXPORT_SYMBOL(mmc_cd_gpio_free);
++EXPORT_SYMBOL(mmc_gpio_free_cd);
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index 0ad3917..7ffc489 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -34,9 +34,9 @@
+ #include <linux/io.h>
+ #include <linux/irq.h>
+ #include <linux/mfd/tmio.h>
+-#include <linux/mmc/cd-gpio.h>
+ #include <linux/mmc/host.h>
+ #include <linux/mmc/mmc.h>
++#include <linux/mmc/slot-gpio.h>
+ #include <linux/mmc/tmio.h>
+ #include <linux/module.h>
+ #include <linux/pagemap.h>
+@@ -977,7 +977,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ tmio_mmc_enable_mmc_irqs(_host, irq_mask);
+
+ if (pdata->flags & TMIO_MMC_USE_GPIO_CD) {
+- ret = mmc_cd_gpio_request(mmc, pdata->cd_gpio);
++ ret = mmc_gpio_request_cd(mmc, pdata->cd_gpio);
+ if (ret < 0) {
+ tmio_mmc_host_remove(_host);
+ return ret;
+@@ -1009,7 +1009,7 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
+ * This means we can miss a card-eject, but this is anyway
+ * possible, because of delayed processing of hotplug events.
+ */
+- mmc_cd_gpio_free(mmc);
++ mmc_gpio_free_cd(mmc);
+
+ if (!host->native_hotplug)
+ pm_runtime_get_sync(&pdev->dev);
+diff --git a/include/linux/mmc/cd-gpio.h b/include/linux/mmc/slot-gpio.h
+similarity index 68%
+rename from include/linux/mmc/cd-gpio.h
+rename to include/linux/mmc/slot-gpio.h
+index cefaba0..edfaa32 100644
+--- a/include/linux/mmc/cd-gpio.h
++++ b/include/linux/mmc/slot-gpio.h
+@@ -8,11 +8,11 @@
+ * published by the Free Software Foundation.
+ */
+
+-#ifndef MMC_CD_GPIO_H
+-#define MMC_CD_GPIO_H
++#ifndef MMC_SLOT_GPIO_H
++#define MMC_SLOT_GPIO_H
+
+ struct mmc_host;
+-int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio);
+-void mmc_cd_gpio_free(struct mmc_host *host);
++int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
++void mmc_gpio_free_cd(struct mmc_host *host);
+
+ #endif
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0072-mmc-tmio-Don-t-access-hardware-registers-after-stopp.patch b/patches.marzen/0072-mmc-tmio-Don-t-access-hardware-registers-after-stopp.patch
new file mode 100644
index 0000000000000..a3be21ce973b7
--- /dev/null
+++ b/patches.marzen/0072-mmc-tmio-Don-t-access-hardware-registers-after-stopp.patch
@@ -0,0 +1,66 @@
+From b1c9b658ce7354835934388f45df16bfd25a37fc Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Tue, 12 Jun 2012 23:29:35 +0200
+Subject: mmc: tmio: Don't access hardware registers after stopping clocks
+
+The tmio_mmc_set_ios() function configures the MMC power, clock and bus
+width. When the mmc core requests the driver to power off the card, we
+inform runtime PM, that the controller can be suspended. This can lead
+to the MSTP clock being turned off.
+
+Writing to any 16-bit hardware registers with the MSTP clock off leads
+to timeouts and errors being printed to the kernel log. This can occur
+both when stopping the MMC clock and when configuring the bus width.
+
+To fix this, stop the MMC clock before calling put_runtime_pm(), and
+skip bus width configuration when power is off.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Tested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 6de707f200f73af7a58b58b3a5b956cff7b6e228)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_pio.c | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index 7ffc489..4f26edf 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -811,19 +811,21 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ if (host->set_pwr && ios->power_mode == MMC_POWER_OFF)
+ host->set_pwr(host->pdev, 0);
+ if (host->power) {
++ tmio_mmc_clk_stop(host);
+ host->power = false;
+ pm_runtime_put(dev);
+ }
+- tmio_mmc_clk_stop(host);
+ }
+
+- switch (ios->bus_width) {
+- case MMC_BUS_WIDTH_1:
+- sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0);
+- break;
+- case MMC_BUS_WIDTH_4:
+- sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0);
+- break;
++ if (host->power) {
++ switch (ios->bus_width) {
++ case MMC_BUS_WIDTH_1:
++ sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0);
++ break;
++ case MMC_BUS_WIDTH_4:
++ sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0);
++ break;
++ }
+ }
+
+ /* Let things settle. delay taken from winCE driver */
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0073-mmc-tmio-don-t-needlessly-enable-interrupts-during-p.patch b/patches.marzen/0073-mmc-tmio-don-t-needlessly-enable-interrupts-during-p.patch
new file mode 100644
index 0000000000000..0ccb9cd52163a
--- /dev/null
+++ b/patches.marzen/0073-mmc-tmio-don-t-needlessly-enable-interrupts-during-p.patch
@@ -0,0 +1,60 @@
+From 13b6cca29fb687ec7821001eb9bc38ba8a6270a1 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 20 Jun 2012 19:10:30 +0200
+Subject: mmc: tmio: don't needlessly enable interrupts during probing
+
+We don't have to force-enable MMC interrupts in our .probe() method,
+mmc_add_host() will trigger card detection, that will enable all the
+necessary interrupts.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit e0337cc8b02fcb3f725746735db84d6d1b6b9196)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_pio.c | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index 4f26edf..4318c1a 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -951,6 +951,17 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+
+ _host->sdcard_irq_mask = sd_ctrl_read32(_host, CTL_IRQ_MASK);
+ tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);
++
++ /* Unmask the IRQs we want to know about */
++ if (!_host->chan_rx)
++ irq_mask |= TMIO_MASK_READOP;
++ if (!_host->chan_tx)
++ irq_mask |= TMIO_MASK_WRITEOP;
++ if (!_host->native_hotplug)
++ irq_mask &= ~(TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT);
++
++ _host->sdcard_irq_mask &= ~irq_mask;
++
+ if (pdata->flags & TMIO_MMC_SDIO_IRQ)
+ tmio_mmc_enable_sdio_irq(mmc, 0);
+
+@@ -968,16 +979,6 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+
+ dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
+
+- /* Unmask the IRQs we want to know about */
+- if (!_host->chan_rx)
+- irq_mask |= TMIO_MASK_READOP;
+- if (!_host->chan_tx)
+- irq_mask |= TMIO_MASK_WRITEOP;
+- if (!_host->native_hotplug)
+- irq_mask &= ~(TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT);
+-
+- tmio_mmc_enable_mmc_irqs(_host, irq_mask);
+-
+ if (pdata->flags & TMIO_MMC_USE_GPIO_CD) {
+ ret = mmc_gpio_request_cd(mmc, pdata->cd_gpio);
+ if (ret < 0) {
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0074-mmc-sdhi-implement-tmio-mmc-clock-enable-update-and-.patch b/patches.marzen/0074-mmc-sdhi-implement-tmio-mmc-clock-enable-update-and-.patch
new file mode 100644
index 0000000000000..a5ee7203d1faa
--- /dev/null
+++ b/patches.marzen/0074-mmc-sdhi-implement-tmio-mmc-clock-enable-update-and-.patch
@@ -0,0 +1,66 @@
+From 9000384872b9fb65e1fb9b7042da31d2d4023c7b Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 20 Jun 2012 19:10:32 +0200
+Subject: mmc: sdhi: implement tmio-mmc clock enable-update and disable
+ callbacks
+
+Instead of delivering one static clock frequency value, read from the
+hardware during probing, enable the tmio-mmc driver to re-read the
+frequency dynamically.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 56c492879318f43b1a7911675ff30fb0ede123b5)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mobile_sdhi.c | 24 +++++++++++++++++++++++-
+ 1 file changed, 23 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index 934b68e..d8b167c 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -39,6 +39,27 @@ struct sh_mobile_sdhi {
+ struct tmio_mmc_dma dma_priv;
+ };
+
++static int sh_mobile_sdhi_clk_enable(struct platform_device *pdev, unsigned int *f)
++{
++ struct mmc_host *mmc = dev_get_drvdata(&pdev->dev);
++ struct tmio_mmc_host *host = mmc_priv(mmc);
++ struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
++ int ret = clk_enable(priv->clk);
++ if (ret < 0)
++ return ret;
++
++ *f = clk_get_rate(priv->clk);
++ return 0;
++}
++
++static void sh_mobile_sdhi_clk_disable(struct platform_device *pdev)
++{
++ struct mmc_host *mmc = dev_get_drvdata(&pdev->dev);
++ struct tmio_mmc_host *host = mmc_priv(mmc);
++ struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
++ clk_disable(priv->clk);
++}
++
+ static void sh_mobile_sdhi_set_pwr(struct platform_device *pdev, int state)
+ {
+ struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
+@@ -132,9 +153,10 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+ goto eclkget;
+ }
+
+- mmc_data->hclk = clk_get_rate(priv->clk);
+ mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
+ mmc_data->get_cd = sh_mobile_sdhi_get_cd;
++ mmc_data->clk_enable = sh_mobile_sdhi_clk_enable;
++ mmc_data->clk_disable = sh_mobile_sdhi_clk_disable;
+ mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
+ if (p) {
+ mmc_data->flags = p->tmio_flags;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0075-mmc-tmio-add-callbacks-to-enable-update-and-disable-.patch b/patches.marzen/0075-mmc-tmio-add-callbacks-to-enable-update-and-disable-.patch
new file mode 100644
index 0000000000000..bf6f327b3aaa6
--- /dev/null
+++ b/patches.marzen/0075-mmc-tmio-add-callbacks-to-enable-update-and-disable-.patch
@@ -0,0 +1,120 @@
+From 2351d645d302b589c88ca21a2ea3198fd7bfa752 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 20 Jun 2012 19:10:31 +0200
+Subject: mmc: tmio: add callbacks to enable-update and disable the interface
+ clock
+
+Every time the clock is enabled after possibly being disabled, we have
+to re-read its frequency and update our configuration.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 8c102a964655b1a8df41b1f9e2355657471a45e3)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_pio.c | 35 ++++++++++++++++++++++++++++++++---
+ include/linux/mfd/tmio.h | 3 +++
+ 2 files changed, 35 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index 4318c1a..c6c0334 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -752,6 +752,22 @@ fail:
+ mmc_request_done(mmc, mrq);
+ }
+
++static int tmio_mmc_clk_update(struct mmc_host *mmc)
++{
++ struct tmio_mmc_host *host = mmc_priv(mmc);
++ struct tmio_mmc_data *pdata = host->pdata;
++ int ret;
++
++ if (!pdata->clk_enable)
++ return -ENOTSUPP;
++
++ ret = pdata->clk_enable(host->pdev, &mmc->f_max);
++ if (!ret)
++ mmc->f_min = mmc->f_max / 512;
++
++ return ret;
++}
++
+ /* Set MMC clock / power.
+ * Note: This controller uses a simple divider scheme therefore it cannot
+ * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
+@@ -798,6 +814,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ */
+ if (ios->power_mode == MMC_POWER_ON && ios->clock) {
+ if (!host->power) {
++ tmio_mmc_clk_update(mmc);
+ pm_runtime_get_sync(dev);
+ host->power = true;
+ }
+@@ -811,9 +828,12 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ if (host->set_pwr && ios->power_mode == MMC_POWER_OFF)
+ host->set_pwr(host->pdev, 0);
+ if (host->power) {
++ struct tmio_mmc_data *pdata = host->pdata;
+ tmio_mmc_clk_stop(host);
+ host->power = false;
+ pm_runtime_put(dev);
++ if (pdata->clk_disable)
++ pdata->clk_disable(host->pdev);
+ }
+ }
+
+@@ -907,8 +927,6 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+
+ mmc->ops = &tmio_mmc_ops;
+ mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities;
+- mmc->f_max = pdata->hclk;
+- mmc->f_min = mmc->f_max / 512;
+ mmc->max_segs = 32;
+ mmc->max_blk_size = 512;
+ mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) *
+@@ -930,6 +948,11 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ if (ret < 0)
+ goto pm_disable;
+
++ if (tmio_mmc_clk_update(mmc) < 0) {
++ mmc->f_max = pdata->hclk;
++ mmc->f_min = mmc->f_max / 512;
++ }
++
+ /*
+ * There are 4 different scenarios for the card detection:
+ * 1) an external gpio irq handles the cd (best for power savings)
+@@ -975,7 +998,13 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ /* See if we also get DMA */
+ tmio_mmc_request_dma(_host, pdata);
+
+- mmc_add_host(mmc);
++ ret = mmc_add_host(mmc);
++ if (pdata->clk_disable)
++ pdata->clk_disable(pdev);
++ if (ret < 0) {
++ tmio_mmc_host_remove(_host);
++ return ret;
++ }
+
+ dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
+
+diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
+index f5171db..b332c4c 100644
+--- a/include/linux/mfd/tmio.h
++++ b/include/linux/mfd/tmio.h
+@@ -110,6 +110,9 @@ struct tmio_mmc_data {
+ void (*set_clk_div)(struct platform_device *host, int state);
+ int (*get_cd)(struct platform_device *host);
+ int (*write16_hook)(struct tmio_mmc_host *host, int addr);
++ /* clock management callbacks */
++ int (*clk_enable)(struct platform_device *pdev, unsigned int *f);
++ void (*clk_disable)(struct platform_device *pdev);
+ };
+
+ /*
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0076-mmc-sdhi-do-not-install-dummy-callbacks.patch b/patches.marzen/0076-mmc-sdhi-do-not-install-dummy-callbacks.patch
new file mode 100644
index 0000000000000..dba509b359093
--- /dev/null
+++ b/patches.marzen/0076-mmc-sdhi-do-not-install-dummy-callbacks.patch
@@ -0,0 +1,62 @@
+From 399a8f308acebcabaa5c10f336668cd3f73ac273 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 20 Jun 2012 19:10:34 +0200
+Subject: mmc: sdhi: do not install dummy callbacks
+
+Currently the SDHI glue for the TMIO MMC driver installs dummy .get_cd() and
+.set_pwr() callbacks even if the platform didn't supply them. This is not
+necessary, since the TMIO MMC driver itself checks for NULL callbacks. This
+is also dubious if the platform provides a regulator for SD-card power
+switching. It is better to only install those callbacks, if they are really
+provided by the platform.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 71da63e767c393c0ebbd3c65df428df0ce42a16c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mobile_sdhi.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index d8b167c..42f07fa 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -64,18 +64,14 @@ static void sh_mobile_sdhi_set_pwr(struct platform_device *pdev, int state)
+ {
+ struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
+
+- if (p && p->set_pwr)
+- p->set_pwr(pdev, state);
++ p->set_pwr(pdev, state);
+ }
+
+ static int sh_mobile_sdhi_get_cd(struct platform_device *pdev)
+ {
+ struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
+
+- if (p && p->get_cd)
+- return p->get_cd(pdev);
+- else
+- return -ENOSYS;
++ return p->get_cd(pdev);
+ }
+
+ static int sh_mobile_sdhi_wait_idle(struct tmio_mmc_host *host)
+@@ -153,8 +149,10 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+ goto eclkget;
+ }
+
+- mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
+- mmc_data->get_cd = sh_mobile_sdhi_get_cd;
++ if (p->set_pwr)
++ mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
++ if (p->get_cd)
++ mmc_data->get_cd = sh_mobile_sdhi_get_cd;
+ mmc_data->clk_enable = sh_mobile_sdhi_clk_enable;
+ mmc_data->clk_disable = sh_mobile_sdhi_clk_disable;
+ mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0077-mmc-add-a-function-to-get-regulators-supplying-card-.patch b/patches.marzen/0077-mmc-add-a-function-to-get-regulators-supplying-card-.patch
new file mode 100644
index 0000000000000..983f2ae756636
--- /dev/null
+++ b/patches.marzen/0077-mmc-add-a-function-to-get-regulators-supplying-card-.patch
@@ -0,0 +1,112 @@
+From 23b39f743c1d33128add46201409eb6709b10a4f Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 20 Jun 2012 02:28:43 -0400
+Subject: mmc: add a function to get regulators, supplying card's power
+
+Add a function to get regulators, supplying card's Vdd and Vccq on a
+specific host. If a Vdd supplying regulator is found, the function checks,
+whether a valid OCR mask can be obtained from it. The Vccq regulator is
+optional. A failure to get it is not fatal.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Reviwed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit e137788dd115dd9d21759a768dba5fff9685e587)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/core/core.c | 23 +++++++++++++++++++++++
+ include/linux/mmc/host.h | 16 ++++++++++++++--
+ 2 files changed, 37 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index ba821fe..1db77e7 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -1012,6 +1012,29 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
+ }
+ EXPORT_SYMBOL(mmc_regulator_set_ocr);
+
++int mmc_regulator_get_supply(struct mmc_host *mmc)
++{
++ struct device *dev = mmc_dev(mmc);
++ struct regulator *supply;
++ int ret;
++
++ supply = devm_regulator_get(dev, "vmmc");
++ mmc->supply.vmmc = supply;
++ mmc->supply.vqmmc = devm_regulator_get(dev, "vqmmc");
++
++ if (IS_ERR(supply))
++ return PTR_ERR(supply);
++
++ ret = mmc_regulator_get_ocrmask(supply);
++ if (ret > 0)
++ mmc->ocr_avail = ret;
++ else
++ dev_warn(mmc_dev(mmc), "Failed getting OCR mask: %d\n", ret);
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(mmc_regulator_get_supply);
++
+ #endif /* CONFIG_REGULATOR */
+
+ /*
+diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
+index 0707d22..9deb725 100644
+--- a/include/linux/mmc/host.h
++++ b/include/linux/mmc/host.h
+@@ -155,6 +155,13 @@ struct mmc_hotplug {
+ void *handler_priv;
+ };
+
++struct regulator;
++
++struct mmc_supply {
++ struct regulator *vmmc; /* Card power supply */
++ struct regulator *vqmmc; /* Optional Vccq supply */
++};
++
+ struct mmc_host {
+ struct device *parent;
+ struct device class_dev;
+@@ -309,6 +316,7 @@ struct mmc_host {
+ #ifdef CONFIG_REGULATOR
+ bool regulator_enabled; /* regulator state */
+ #endif
++ struct mmc_supply supply;
+
+ struct dentry *debugfs_root;
+
+@@ -357,13 +365,12 @@ static inline void mmc_signal_sdio_irq(struct mmc_host *host)
+ wake_up_process(host->sdio_irq_thread);
+ }
+
+-struct regulator;
+-
+ #ifdef CONFIG_REGULATOR
+ int mmc_regulator_get_ocrmask(struct regulator *supply);
+ int mmc_regulator_set_ocr(struct mmc_host *mmc,
+ struct regulator *supply,
+ unsigned short vdd_bit);
++int mmc_regulator_get_supply(struct mmc_host *mmc);
+ #else
+ static inline int mmc_regulator_get_ocrmask(struct regulator *supply)
+ {
+@@ -376,6 +383,11 @@ static inline int mmc_regulator_set_ocr(struct mmc_host *mmc,
+ {
+ return 0;
+ }
++
++static inline int mmc_regulator_get_supply(struct mmc_host *mmc)
++{
++ return 0;
++}
+ #endif
+
+ int mmc_card_awake(struct mmc_host *host);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0078-mmc-tmio-add-regulator-support.patch b/patches.marzen/0078-mmc-tmio-add-regulator-support.patch
new file mode 100644
index 0000000000000..7c18978e52d5f
--- /dev/null
+++ b/patches.marzen/0078-mmc-tmio-add-regulator-support.patch
@@ -0,0 +1,95 @@
+From 2f82c1eaa54c5b6eb2d1bc04cd04add57ca9ad05 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 20 Jun 2012 19:10:33 +0200
+Subject: mmc: tmio: add regulator support
+
+Currently the TMIO MMC driver derives the OCR mask from the platform data
+and uses a platform callback to turn card power on and off. This patch adds
+regulator support to the driver.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Cc: Liam Girdwood <lrg@ti.com>
+Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit b958a67c6bbe0a886bebc618aac7a059cdbab418)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_pio.c | 37 +++++++++++++++++++++++++++++--------
+ 1 file changed, 29 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index c6c0334..b5c32b4 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -768,6 +768,18 @@ static int tmio_mmc_clk_update(struct mmc_host *mmc)
+ return ret;
+ }
+
++static void tmio_mmc_set_power(struct tmio_mmc_host *host, struct mmc_ios *ios)
++{
++ struct mmc_host *mmc = host->mmc;
++
++ if (host->set_pwr)
++ host->set_pwr(host->pdev, ios->power_mode != MMC_POWER_OFF);
++ if (!IS_ERR(mmc->supply.vmmc))
++ /* Errors ignored... */
++ mmc_regulator_set_ocr(mmc, mmc->supply.vmmc,
++ ios->power_mode ? ios->vdd : 0);
++}
++
+ /* Set MMC clock / power.
+ * Note: This controller uses a simple divider scheme therefore it cannot
+ * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
+@@ -820,13 +832,12 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ }
+ tmio_mmc_set_clock(host, ios->clock);
+ /* power up SD bus */
+- if (host->set_pwr)
+- host->set_pwr(host->pdev, 1);
++ tmio_mmc_set_power(host, ios);
+ /* start bus clock */
+ tmio_mmc_clk_start(host);
+ } else if (ios->power_mode != MMC_POWER_UP) {
+- if (host->set_pwr && ios->power_mode == MMC_POWER_OFF)
+- host->set_pwr(host->pdev, 0);
++ if (ios->power_mode == MMC_POWER_OFF)
++ tmio_mmc_set_power(host, ios);
+ if (host->power) {
+ struct tmio_mmc_data *pdata = host->pdata;
+ tmio_mmc_clk_stop(host);
+@@ -888,6 +899,19 @@ static const struct mmc_host_ops tmio_mmc_ops = {
+ .enable_sdio_irq = tmio_mmc_enable_sdio_irq,
+ };
+
++static void tmio_mmc_init_ocr(struct tmio_mmc_host *host)
++{
++ struct tmio_mmc_data *pdata = host->pdata;
++ struct mmc_host *mmc = host->mmc;
++
++ mmc_regulator_get_supply(mmc);
++
++ if (!mmc->ocr_avail)
++ mmc->ocr_avail = pdata->ocr_mask ? : MMC_VDD_32_33 | MMC_VDD_33_34;
++ else if (pdata->ocr_mask)
++ dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
++}
++
+ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ struct platform_device *pdev,
+ struct tmio_mmc_data *pdata)
+@@ -933,10 +957,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ mmc->max_segs;
+ mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+ mmc->max_seg_size = mmc->max_req_size;
+- if (pdata->ocr_mask)
+- mmc->ocr_avail = pdata->ocr_mask;
+- else
+- mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
++ tmio_mmc_init_ocr(_host);
+
+ _host->native_hotplug = !(pdata->flags & TMIO_MMC_USE_GPIO_CD ||
+ mmc->caps & MMC_CAP_NEEDS_POLL ||
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0079-mmc-tmio-remove-a-duplicated-comment-line.patch b/patches.marzen/0079-mmc-tmio-remove-a-duplicated-comment-line.patch
new file mode 100644
index 0000000000000..e7c85da77123d
--- /dev/null
+++ b/patches.marzen/0079-mmc-tmio-remove-a-duplicated-comment-line.patch
@@ -0,0 +1,29 @@
+From edc14a6a575b9ed664f5618b40bb720801514acc Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 20 Jun 2012 19:10:36 +0200
+Subject: mmc: tmio: remove a duplicated comment line
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 944640d0fffb2ee2961a24c3747b1fc87c4157a8)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_pio.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index b5c32b4..b204012f 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -984,7 +984,6 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ * While we increment the runtime PM counter for all scenarios when
+ * the mmc core activates us by calling an appropriate set_ios(), we
+ * must additionally ensure that in case 2) the tmio mmc hardware stays
+- * additionally ensure that in case 2) the tmio mmc hardware stays
+ * powered on during runtime for the card detection to work.
+ */
+ if (_host->native_hotplug)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0080-mmc-tmio-support-caps2-flags.patch b/patches.marzen/0080-mmc-tmio-support-caps2-flags.patch
new file mode 100644
index 0000000000000..ce76873aba016
--- /dev/null
+++ b/patches.marzen/0080-mmc-tmio-support-caps2-flags.patch
@@ -0,0 +1,45 @@
+From 84ff72e8bc8a05f00821fa782bda46ba105ce831 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 23 May 2012 10:44:37 +0200
+Subject: mmc: tmio: support caps2 flags
+
+Allow tmio mmc glue drivers to pass mmc_host::caps2 flags down to
+the mmc layer.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 02cb3221d5bb351ad9f7469453dcca7594a0fabf)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_pio.c | 1 +
+ include/linux/mfd/tmio.h | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index b204012f..f8df021 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -951,6 +951,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+
+ mmc->ops = &tmio_mmc_ops;
+ mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities;
++ mmc->caps2 = pdata->capabilities2;
+ mmc->max_segs = 32;
+ mmc->max_blk_size = 512;
+ mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) *
+diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
+index b332c4c..d83af39 100644
+--- a/include/linux/mfd/tmio.h
++++ b/include/linux/mfd/tmio.h
+@@ -101,6 +101,7 @@ struct tmio_mmc_host;
+ struct tmio_mmc_data {
+ unsigned int hclk;
+ unsigned long capabilities;
++ unsigned long capabilities2;
+ unsigned long flags;
+ u32 ocr_mask; /* available voltages */
+ struct tmio_mmc_dma *dma;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0081-mmc-sh_mobile_sdhi-support-caps2-flags.patch b/patches.marzen/0081-mmc-sh_mobile_sdhi-support-caps2-flags.patch
new file mode 100644
index 0000000000000..d88c5291f99e5
--- /dev/null
+++ b/patches.marzen/0081-mmc-sh_mobile_sdhi-support-caps2-flags.patch
@@ -0,0 +1,44 @@
+From ab7669dbefddb9148fbda646fe4746a1a33f914f Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 23 May 2012 11:05:33 +0200
+Subject: mmc: sh_mobile_sdhi: support caps2 flags
+
+Let SDHI platforms specify mmc_host::caps2 flags in their platform data.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit d7d8d500bc03891c4a86da49858c46e2db256581)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mobile_sdhi.c | 1 +
+ include/linux/mmc/sh_mobile_sdhi.h | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index 42f07fa..1e7c5c4 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -162,6 +162,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+ mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
+ mmc_data->ocr_mask = p->tmio_ocr_mask;
+ mmc_data->capabilities |= p->tmio_caps;
++ mmc_data->capabilities2 |= p->tmio_caps2;
+ mmc_data->cd_gpio = p->cd_gpio;
+
+ if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) {
+diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
+index e94e620..b65679f 100644
+--- a/include/linux/mmc/sh_mobile_sdhi.h
++++ b/include/linux/mmc/sh_mobile_sdhi.h
+@@ -23,6 +23,7 @@ struct sh_mobile_sdhi_info {
+ int dma_slave_rx;
+ unsigned long tmio_flags;
+ unsigned long tmio_caps;
++ unsigned long tmio_caps2;
+ u32 tmio_ocr_mask; /* available MMC voltages */
+ unsigned int cd_gpio;
+ struct tmio_mmc_data *pdata;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0082-mmc-sdhi-add-OF-support-make-platform-data-optional.patch b/patches.marzen/0082-mmc-sdhi-add-OF-support-make-platform-data-optional.patch
new file mode 100644
index 0000000000000..ee219f323d7a5
--- /dev/null
+++ b/patches.marzen/0082-mmc-sdhi-add-OF-support-make-platform-data-optional.patch
@@ -0,0 +1,121 @@
+From a19323115f3cf3e2e7f0b56ce75752ed2e682bfb Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Tue, 1 May 2012 18:03:43 +0200
+Subject: mmc: sdhi: add OF support, make platform data optional
+
+Add primitive support for OF to the SDHI TMIO glue, which also makes it
+necessary to be able to run without platform data.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit c7bb4487a3474c03986758595fcae1cfb771b3b0)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mobile_sdhi.c | 35 +++++++++++++++++++++++------------
+ 1 file changed, 23 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index 1e7c5c4..a842939 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -21,6 +21,7 @@
+ #include <linux/kernel.h>
+ #include <linux/clk.h>
+ #include <linux/slab.h>
++#include <linux/mod_devicetable.h>
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/mmc/host.h>
+@@ -133,12 +134,14 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+ }
+
+ mmc_data = &priv->mmc_data;
+- p->pdata = mmc_data;
+
+- if (p->init) {
+- ret = p->init(pdev, &sdhi_ops);
+- if (ret)
+- goto einit;
++ if (p) {
++ p->pdata = mmc_data;
++ if (p->init) {
++ ret = p->init(pdev, &sdhi_ops);
++ if (ret)
++ goto einit;
++ }
+ }
+
+ snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id);
+@@ -149,10 +152,6 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+ goto eclkget;
+ }
+
+- if (p->set_pwr)
+- mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
+- if (p->get_cd)
+- mmc_data->get_cd = sh_mobile_sdhi_get_cd;
+ mmc_data->clk_enable = sh_mobile_sdhi_clk_enable;
+ mmc_data->clk_disable = sh_mobile_sdhi_clk_disable;
+ mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
+@@ -164,6 +163,10 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+ mmc_data->capabilities |= p->tmio_caps;
+ mmc_data->capabilities2 |= p->tmio_caps2;
+ mmc_data->cd_gpio = p->cd_gpio;
++ if (p->set_pwr)
++ mmc_data->set_pwr = sh_mobile_sdhi_set_pwr;
++ if (p->get_cd)
++ mmc_data->get_cd = sh_mobile_sdhi_get_cd;
+
+ if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) {
+ priv->param_tx.slave_id = p->dma_slave_tx;
+@@ -269,7 +272,7 @@ eirq_card_detect:
+ eprobe:
+ clk_put(priv->clk);
+ eclkget:
+- if (p->cleanup)
++ if (p && p->cleanup)
+ p->cleanup(pdev);
+ einit:
+ kfree(priv);
+@@ -284,7 +287,8 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
+ struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
+ int i = 0, irq;
+
+- p->pdata = NULL;
++ if (p)
++ p->pdata = NULL;
+
+ tmio_mmc_host_remove(host);
+
+@@ -297,7 +301,7 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
+
+ clk_put(priv->clk);
+
+- if (p->cleanup)
++ if (p && p->cleanup)
+ p->cleanup(pdev);
+
+ kfree(priv);
+@@ -312,11 +316,18 @@ static const struct dev_pm_ops tmio_mmc_dev_pm_ops = {
+ .runtime_resume = tmio_mmc_host_runtime_resume,
+ };
+
++static const struct of_device_id sh_mobile_sdhi_of_match[] = {
++ { .compatible = "renesas,shmobile-sdhi" },
++ { }
++};
++MODULE_DEVICE_TABLE(of, sh_mobile_sdhi_of_match);
++
+ static struct platform_driver sh_mobile_sdhi_driver = {
+ .driver = {
+ .name = "sh_mobile_sdhi",
+ .owner = THIS_MODULE,
+ .pm = &tmio_mmc_dev_pm_ops,
++ .of_match_table = sh_mobile_sdhi_of_match,
+ },
+ .probe = sh_mobile_sdhi_probe,
+ .remove = __devexit_p(sh_mobile_sdhi_remove),
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0083-mmc-core-use-a-more-generic-name-for-slot-function-t.patch b/patches.marzen/0083-mmc-core-use-a-more-generic-name-for-slot-function-t.patch
new file mode 100644
index 0000000000000..03ec82ddad882
--- /dev/null
+++ b/patches.marzen/0083-mmc-core-use-a-more-generic-name-for-slot-function-t.patch
@@ -0,0 +1,100 @@
+From 3383b414d84936e9695df242dbe081140e7b0fbd Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Tue, 1 May 2012 15:40:15 +0200
+Subject: mmc: core: use a more generic name for slot function types and fields
+
+struct mmc_host::hotplug is becoming a generic hook for slot functions.
+Rename it accordingly.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 27410ee7e391ce650d6d0242805f080599be7ad7)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/core/host.c | 2 ++
+ drivers/mmc/core/slot-gpio.c | 8 ++++----
+ include/linux/mmc/host.h | 17 ++++++++++++++---
+ 3 files changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
+index 91c84c7..b8c5290 100644
+--- a/drivers/mmc/core/host.c
++++ b/drivers/mmc/core/host.c
+@@ -327,6 +327,8 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
+
+ mmc_host_clk_init(host);
+
++ host->slot.cd_irq = -EINVAL;
++
+ spin_lock_init(&host->lock);
+ init_waitqueue_head(&host->wq);
+ INIT_DELAYED_WORK(&host->detect, mmc_rescan);
+diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
+index 9796710..468e5a0 100644
+--- a/drivers/mmc/core/slot-gpio.c
++++ b/drivers/mmc/core/slot-gpio.c
+@@ -56,8 +56,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
+ goto eirqreq;
+
+ ctx->cd_gpio = gpio;
+- host->hotplug.irq = irq;
+- host->hotplug.handler_priv = ctx;
++ host->slot.cd_irq = irq;
++ host->slot.handler_priv = ctx;
+
+ return 0;
+
+@@ -71,12 +71,12 @@ EXPORT_SYMBOL(mmc_gpio_request_cd);
+
+ void mmc_gpio_free_cd(struct mmc_host *host)
+ {
+- struct mmc_gpio *ctx = host->hotplug.handler_priv;
++ struct mmc_gpio *ctx = host->slot.handler_priv;
+
+ if (!ctx)
+ return;
+
+- free_irq(host->hotplug.irq, host);
++ free_irq(host->slot.cd_irq, host);
+ gpio_free(ctx->cd_gpio);
+ kfree(ctx);
+ }
+diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
+index 9deb725..90b6a38 100644
+--- a/include/linux/mmc/host.h
++++ b/include/linux/mmc/host.h
+@@ -150,8 +150,19 @@ struct mmc_async_req {
+ int (*err_check) (struct mmc_card *, struct mmc_async_req *);
+ };
+
+-struct mmc_hotplug {
+- unsigned int irq;
++/**
++ * struct mmc_slot - MMC slot functions
++ *
++ * @cd_irq: MMC/SD-card slot hotplug detection IRQ or -EINVAL
++ * @handler_priv: MMC/SD-card slot context
++ *
++ * Some MMC/SD host controllers implement slot-functions like card and
++ * write-protect detection natively. However, a large number of controllers
++ * leave these functions to the CPU. This struct provides a hook to attach
++ * such slot-function drivers.
++ */
++struct mmc_slot {
++ int cd_irq;
+ void *handler_priv;
+ };
+
+@@ -297,7 +308,7 @@ struct mmc_host {
+
+ struct delayed_work detect;
+ int detect_change; /* card detect flag */
+- struct mmc_hotplug hotplug;
++ struct mmc_slot slot;
+
+ const struct mmc_bus_ops *bus_ops; /* current bus driver */
+ unsigned int bus_refs; /* reference counter */
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0084-mmc-add-two-capability-flags-for-CD-and-WP-signal-po.patch b/patches.marzen/0084-mmc-add-two-capability-flags-for-CD-and-WP-signal-po.patch
new file mode 100644
index 0000000000000..b0886e59d8b99
--- /dev/null
+++ b/patches.marzen/0084-mmc-add-two-capability-flags-for-CD-and-WP-signal-po.patch
@@ -0,0 +1,33 @@
+From ecce3df848ddf973eae9260a50fdd16cbb860f3f Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Tue, 1 May 2012 15:49:52 +0200
+Subject: mmc: add two capability flags for CD and WP signal polarity
+
+To handle CD and WP SD/MMC slot pins we need generic flags to specify their
+polarity.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 5c08d7fae0815cd163a98e05c8d94fc0de77ff67)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/mmc/host.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
+index 90b6a38..c1a03ee 100644
+--- a/include/linux/mmc/host.h
++++ b/include/linux/mmc/host.h
+@@ -256,6 +256,8 @@ struct mmc_host {
+ #define MMC_CAP2_BROKEN_VOLTAGE (1 << 7) /* Use the broken voltage */
+ #define MMC_CAP2_DETECT_ON_ERR (1 << 8) /* On I/O err check card removal */
+ #define MMC_CAP2_HC_ERASE_SZ (1 << 9) /* High-capacity erase size */
++#define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10) /* Card-detect signal active high */
++#define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11) /* Write-protect signal active high */
+
+ mmc_pm_flag_t pm_caps; /* supported pm features */
+ unsigned int power_notify_type;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0085-mmc-add-CD-GPIO-polling-support-to-slot-functions.patch b/patches.marzen/0085-mmc-add-CD-GPIO-polling-support-to-slot-functions.patch
new file mode 100644
index 0000000000000..4005a0deed78c
--- /dev/null
+++ b/patches.marzen/0085-mmc-add-CD-GPIO-polling-support-to-slot-functions.patch
@@ -0,0 +1,141 @@
+From 2d3824e27d90f5cd81a034798596e8d6963c2b1f Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Tue, 1 May 2012 16:27:25 +0200
+Subject: mmc: add CD GPIO polling support to slot functions
+
+A simple extension of mmc slot functions add support for CD GPIO polling
+for cases where the GPIO cannot produce interrupts, or where this is not
+desired for some reason.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit befe4048d8d20483a62636e20f3dbffebf85a1c1)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/core/slot-gpio.c | 56 +++++++++++++++++++++++++++++++++----------
+ include/linux/mmc/slot-gpio.h | 2 ++
+ 2 files changed, 45 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
+index 468e5a0..92cba02 100644
+--- a/drivers/mmc/core/slot-gpio.c
++++ b/drivers/mmc/core/slot-gpio.c
+@@ -18,7 +18,7 @@
+ #include <linux/slab.h>
+
+ struct mmc_gpio {
+- unsigned int cd_gpio;
++ int cd_gpio;
+ char cd_label[0];
+ };
+
+@@ -29,6 +29,18 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
+ return IRQ_HANDLED;
+ }
+
++int mmc_gpio_get_cd(struct mmc_host *host)
++{
++ struct mmc_gpio *ctx = host->slot.handler_priv;
++
++ if (!ctx || !gpio_is_valid(ctx->cd_gpio))
++ return -ENOSYS;
++
++ return !gpio_get_value_cansleep(ctx->cd_gpio) ^
++ !!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH);
++}
++EXPORT_SYMBOL(mmc_gpio_get_cd);
++
+ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
+ {
+ size_t len = strlen(dev_name(host->parent)) + 4;
+@@ -36,9 +48,6 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
+ int irq = gpio_to_irq(gpio);
+ int ret;
+
+- if (irq < 0)
+- return irq;
+-
+ ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+@@ -49,20 +58,32 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
+ if (ret < 0)
+ goto egpioreq;
+
+- ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
++ /*
++ * Even if gpio_to_irq() returns a valid IRQ number, the platform might
++ * still prefer to poll, e.g., because that IRQ number is already used
++ * by another unit and cannot be shared.
++ */
++ if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL)
++ irq = -EINVAL;
++
++ if (irq >= 0) {
++ ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ ctx->cd_label, host);
+- if (ret < 0)
+- goto eirqreq;
++ if (ret < 0)
++ irq = ret;
++ }
+
+- ctx->cd_gpio = gpio;
+ host->slot.cd_irq = irq;
++
++ if (irq < 0)
++ host->caps |= MMC_CAP_NEEDS_POLL;
++
++ ctx->cd_gpio = gpio;
+ host->slot.handler_priv = ctx;
+
+ return 0;
+
+-eirqreq:
+- gpio_free(gpio);
+ egpioreq:
+ kfree(ctx);
+ return ret;
+@@ -72,12 +93,21 @@ EXPORT_SYMBOL(mmc_gpio_request_cd);
+ void mmc_gpio_free_cd(struct mmc_host *host)
+ {
+ struct mmc_gpio *ctx = host->slot.handler_priv;
++ int gpio;
+
+- if (!ctx)
++ if (!ctx || !gpio_is_valid(ctx->cd_gpio))
+ return;
+
+- free_irq(host->slot.cd_irq, host);
+- gpio_free(ctx->cd_gpio);
++ if (host->slot.cd_irq >= 0) {
++ free_irq(host->slot.cd_irq, host);
++ host->slot.cd_irq = -EINVAL;
++ }
++
++ gpio = ctx->cd_gpio;
++ ctx->cd_gpio = -EINVAL;
++
++ gpio_free(gpio);
++ host->slot.handler_priv = NULL;
+ kfree(ctx);
+ }
+ EXPORT_SYMBOL(mmc_gpio_free_cd);
+diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h
+index edfaa32..1a977d7 100644
+--- a/include/linux/mmc/slot-gpio.h
++++ b/include/linux/mmc/slot-gpio.h
+@@ -12,6 +12,8 @@
+ #define MMC_SLOT_GPIO_H
+
+ struct mmc_host;
++
++int mmc_gpio_get_cd(struct mmc_host *host);
+ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
+ void mmc_gpio_free_cd(struct mmc_host *host);
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0086-mmc-core-convert-slot-functions-to-managed-allocatio.patch b/patches.marzen/0086-mmc-core-convert-slot-functions-to-managed-allocatio.patch
new file mode 100644
index 0000000000000..f55688e0b7e7d
--- /dev/null
+++ b/patches.marzen/0086-mmc-core-convert-slot-functions-to-managed-allocatio.patch
@@ -0,0 +1,161 @@
+From 1acb00ed4e37416f9e71be4588be8fab3e03d1ee Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Tue, 1 May 2012 16:51:38 +0200
+Subject: mmc: core: convert slot functions to managed allocation
+
+This prepares for the addition of further slot functions.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit a7d1a1ebd8f5858a812ac3d5fbbc178b4959a63b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/core/host.c | 2 ++
+ drivers/mmc/core/slot-gpio.c | 51 +++++++++++++++++++++++++++++++++-----------
+ include/linux/mmc/host.h | 3 +++
+ 3 files changed, 43 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
+index b8c5290..74cf29a 100644
+--- a/drivers/mmc/core/host.c
++++ b/drivers/mmc/core/host.c
+@@ -32,6 +32,7 @@
+ static void mmc_host_classdev_release(struct device *dev)
+ {
+ struct mmc_host *host = cls_dev_to_mmc_host(dev);
++ mutex_destroy(&host->slot.lock);
+ kfree(host);
+ }
+
+@@ -327,6 +328,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
+
+ mmc_host_clk_init(host);
+
++ mutex_init(&host->slot.lock);
+ host->slot.cd_irq = -EINVAL;
+
+ spin_lock_init(&host->lock);
+diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
+index 92cba02..41689da 100644
+--- a/drivers/mmc/core/slot-gpio.c
++++ b/drivers/mmc/core/slot-gpio.c
+@@ -29,6 +29,34 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
+ return IRQ_HANDLED;
+ }
+
++static int mmc_gpio_alloc(struct mmc_host *host)
++{
++ size_t len = strlen(dev_name(host->parent)) + 4;
++ struct mmc_gpio *ctx;
++
++ mutex_lock(&host->slot.lock);
++
++ ctx = host->slot.handler_priv;
++ if (!ctx) {
++ /*
++ * devm_kzalloc() can be called after device_initialize(), even
++ * before device_add(), i.e., between mmc_alloc_host() and
++ * mmc_add_host()
++ */
++ ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + len,
++ GFP_KERNEL);
++ if (ctx) {
++ snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
++ ctx->cd_gpio = -EINVAL;
++ host->slot.handler_priv = ctx;
++ }
++ }
++
++ mutex_unlock(&host->slot.lock);
++
++ return ctx ? 0 : -ENOMEM;
++}
++
+ int mmc_gpio_get_cd(struct mmc_host *host)
+ {
+ struct mmc_gpio *ctx = host->slot.handler_priv;
+@@ -43,20 +71,24 @@ EXPORT_SYMBOL(mmc_gpio_get_cd);
+
+ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
+ {
+- size_t len = strlen(dev_name(host->parent)) + 4;
+ struct mmc_gpio *ctx;
+ int irq = gpio_to_irq(gpio);
+ int ret;
+
+- ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL);
+- if (!ctx)
+- return -ENOMEM;
++ ret = mmc_gpio_alloc(host);
++ if (ret < 0)
++ return ret;
+
+- snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
++ ctx = host->slot.handler_priv;
+
+ ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label);
+ if (ret < 0)
+- goto egpioreq;
++ /*
++ * don't bother freeing memory. It might still get used by other
++ * slot functions, in any case it will be freed, when the device
++ * is destroyed.
++ */
++ return ret;
+
+ /*
+ * Even if gpio_to_irq() returns a valid IRQ number, the platform might
+@@ -80,13 +112,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
+ host->caps |= MMC_CAP_NEEDS_POLL;
+
+ ctx->cd_gpio = gpio;
+- host->slot.handler_priv = ctx;
+
+ return 0;
+-
+-egpioreq:
+- kfree(ctx);
+- return ret;
+ }
+ EXPORT_SYMBOL(mmc_gpio_request_cd);
+
+@@ -107,7 +134,5 @@ void mmc_gpio_free_cd(struct mmc_host *host)
+ ctx->cd_gpio = -EINVAL;
+
+ gpio_free(gpio);
+- host->slot.handler_priv = NULL;
+- kfree(ctx);
+ }
+ EXPORT_SYMBOL(mmc_gpio_free_cd);
+diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
+index c1a03ee..65c64ee 100644
+--- a/include/linux/mmc/host.h
++++ b/include/linux/mmc/host.h
+@@ -11,6 +11,7 @@
+ #define LINUX_MMC_HOST_H
+
+ #include <linux/leds.h>
++#include <linux/mutex.h>
+ #include <linux/sched.h>
+ #include <linux/device.h>
+ #include <linux/fault-inject.h>
+@@ -154,6 +155,7 @@ struct mmc_async_req {
+ * struct mmc_slot - MMC slot functions
+ *
+ * @cd_irq: MMC/SD-card slot hotplug detection IRQ or -EINVAL
++ * @lock: protect the @handler_priv pointer
+ * @handler_priv: MMC/SD-card slot context
+ *
+ * Some MMC/SD host controllers implement slot-functions like card and
+@@ -163,6 +165,7 @@ struct mmc_async_req {
+ */
+ struct mmc_slot {
+ int cd_irq;
++ struct mutex lock;
+ void *handler_priv;
+ };
+
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0087-mmc-core-add-WP-pin-handler-to-slot-functions.patch b/patches.marzen/0087-mmc-core-add-WP-pin-handler-to-slot-functions.patch
new file mode 100644
index 0000000000000..dc21d563ab2e9
--- /dev/null
+++ b/patches.marzen/0087-mmc-core-add-WP-pin-handler-to-slot-functions.patch
@@ -0,0 +1,132 @@
+From e26593f54711c1135d3d1fd0994224e9dba0dee2 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Tue, 1 May 2012 16:59:38 +0200
+Subject: mmc: core: add WP pin handler to slot functions
+
+Card Write-Protect pin is often implemented, using a GPIO, which makes
+it simple to provide a generic handler for it.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 5aa7dad305594ea30d21e23b3036565042adf50c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/core/slot-gpio.c | 52 ++++++++++++++++++++++++++++++++++++++++++-
+ include/linux/mmc/slot-gpio.h | 4 ++++
+ 2 files changed, 55 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
+index 41689da..0582429 100644
+--- a/drivers/mmc/core/slot-gpio.c
++++ b/drivers/mmc/core/slot-gpio.c
+@@ -18,7 +18,9 @@
+ #include <linux/slab.h>
+
+ struct mmc_gpio {
++ int ro_gpio;
+ int cd_gpio;
++ char *ro_label;
+ char cd_label[0];
+ };
+
+@@ -43,11 +45,14 @@ static int mmc_gpio_alloc(struct mmc_host *host)
+ * before device_add(), i.e., between mmc_alloc_host() and
+ * mmc_add_host()
+ */
+- ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + len,
++ ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + 2 * len,
+ GFP_KERNEL);
+ if (ctx) {
++ ctx->ro_label = ctx->cd_label + len;
+ snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
++ snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent));
+ ctx->cd_gpio = -EINVAL;
++ ctx->ro_gpio = -EINVAL;
+ host->slot.handler_priv = ctx;
+ }
+ }
+@@ -57,6 +62,18 @@ static int mmc_gpio_alloc(struct mmc_host *host)
+ return ctx ? 0 : -ENOMEM;
+ }
+
++int mmc_gpio_get_ro(struct mmc_host *host)
++{
++ struct mmc_gpio *ctx = host->slot.handler_priv;
++
++ if (!ctx || !gpio_is_valid(ctx->ro_gpio))
++ return -ENOSYS;
++
++ return !gpio_get_value_cansleep(ctx->ro_gpio) ^
++ !!(host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH);
++}
++EXPORT_SYMBOL(mmc_gpio_get_ro);
++
+ int mmc_gpio_get_cd(struct mmc_host *host)
+ {
+ struct mmc_gpio *ctx = host->slot.handler_priv;
+@@ -69,6 +86,24 @@ int mmc_gpio_get_cd(struct mmc_host *host)
+ }
+ EXPORT_SYMBOL(mmc_gpio_get_cd);
+
++int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)
++{
++ struct mmc_gpio *ctx;
++ int ret;
++
++ if (!gpio_is_valid(gpio))
++ return -EINVAL;
++
++ ret = mmc_gpio_alloc(host);
++ if (ret < 0)
++ return ret;
++
++ ctx = host->slot.handler_priv;
++
++ return gpio_request_one(gpio, GPIOF_DIR_IN, ctx->ro_label);
++}
++EXPORT_SYMBOL(mmc_gpio_request_ro);
++
+ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
+ {
+ struct mmc_gpio *ctx;
+@@ -117,6 +152,21 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
+ }
+ EXPORT_SYMBOL(mmc_gpio_request_cd);
+
++void mmc_gpio_free_ro(struct mmc_host *host)
++{
++ struct mmc_gpio *ctx = host->slot.handler_priv;
++ int gpio;
++
++ if (!ctx || !gpio_is_valid(ctx->ro_gpio))
++ return;
++
++ gpio = ctx->ro_gpio;
++ ctx->ro_gpio = -EINVAL;
++
++ gpio_free(gpio);
++}
++EXPORT_SYMBOL(mmc_gpio_free_ro);
++
+ void mmc_gpio_free_cd(struct mmc_host *host)
+ {
+ struct mmc_gpio *ctx = host->slot.handler_priv;
+diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h
+index 1a977d7..7d88d27 100644
+--- a/include/linux/mmc/slot-gpio.h
++++ b/include/linux/mmc/slot-gpio.h
+@@ -13,6 +13,10 @@
+
+ struct mmc_host;
+
++int mmc_gpio_get_ro(struct mmc_host *host);
++int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio);
++void mmc_gpio_free_ro(struct mmc_host *host);
++
+ int mmc_gpio_get_cd(struct mmc_host *host);
+ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
+ void mmc_gpio_free_cd(struct mmc_host *host);
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0088-mmc-tmio-use-generic-GPIO-CD-and-WP-handlers.patch b/patches.marzen/0088-mmc-tmio-use-generic-GPIO-CD-and-WP-handlers.patch
new file mode 100644
index 0000000000000..6520920aace7a
--- /dev/null
+++ b/patches.marzen/0088-mmc-tmio-use-generic-GPIO-CD-and-WP-handlers.patch
@@ -0,0 +1,45 @@
+From faee1eb43fa5fa4ab009588d46a5e5b4da3be529 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Tue, 1 May 2012 17:11:56 +0200
+Subject: mmc: tmio: use generic GPIO CD and WP handlers
+
+The tmio-mmc driver is already using the generic GPIO CD handler in IRQ
+mode. This patch adds support for CD polling mode and also checks for
+availability of a WP GPIO.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 3071cafb7f6f9cbb52b1b7eb308c8b45cae0dcf8)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_pio.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index f8df021..0d8a9bb 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -875,6 +875,9 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc)
+ {
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+ struct tmio_mmc_data *pdata = host->pdata;
++ int ret = mmc_gpio_get_ro(mmc);
++ if (ret >= 0)
++ return ret;
+
+ return !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
+ (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
+@@ -884,6 +887,9 @@ static int tmio_mmc_get_cd(struct mmc_host *mmc)
+ {
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+ struct tmio_mmc_data *pdata = host->pdata;
++ int ret = mmc_gpio_get_cd(mmc);
++ if (ret >= 0)
++ return ret;
+
+ if (!pdata->get_cd)
+ return -ENOSYS;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0089-mmc-sh_mobile_sdhi-prepare-for-conversion-to-the-shd.patch b/patches.marzen/0089-mmc-sh_mobile_sdhi-prepare-for-conversion-to-the-shd.patch
new file mode 100644
index 0000000000000..3486d84ee7bd3
--- /dev/null
+++ b/patches.marzen/0089-mmc-sh_mobile_sdhi-prepare-for-conversion-to-the-shd.patch
@@ -0,0 +1,37 @@
+From e4f6cf57b801d98e400bc52f4c3eb372b7703feb Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 9 May 2012 17:09:16 +0200
+Subject: mmc: sh_mobile_sdhi: prepare for conversion to the shdma base library
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Cc: Chris Ball <cjb@laptop.org>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit c471270d7a4161a8f1794202ad8338c0ec55759e)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mobile_sdhi.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index a842939..0bdc146 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -169,10 +169,10 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+ mmc_data->get_cd = sh_mobile_sdhi_get_cd;
+
+ if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) {
+- priv->param_tx.slave_id = p->dma_slave_tx;
+- priv->param_rx.slave_id = p->dma_slave_rx;
+- priv->dma_priv.chan_priv_tx = &priv->param_tx;
+- priv->dma_priv.chan_priv_rx = &priv->param_rx;
++ priv->param_tx.shdma_slave.slave_id = p->dma_slave_tx;
++ priv->param_rx.shdma_slave.slave_id = p->dma_slave_rx;
++ priv->dma_priv.chan_priv_tx = &priv->param_tx.shdma_slave;
++ priv->dma_priv.chan_priv_rx = &priv->param_rx.shdma_slave;
+ priv->dma_priv.alignment_shift = 1; /* 2-byte alignment */
+ mmc_data->dma = &priv->dma_priv;
+ }
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0090-mmc-sh_mmcif-remove-unneeded-struct-sh_mmcif_dma-pre.patch b/patches.marzen/0090-mmc-sh_mmcif-remove-unneeded-struct-sh_mmcif_dma-pre.patch
new file mode 100644
index 0000000000000..bfc5b79456afc
--- /dev/null
+++ b/patches.marzen/0090-mmc-sh_mmcif-remove-unneeded-struct-sh_mmcif_dma-pre.patch
@@ -0,0 +1,94 @@
+From 52ffe4e5679653a9bb539a438d6521768fd70e25 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 9 May 2012 17:09:15 +0200
+Subject: mmc: sh_mmcif: remove unneeded struct sh_mmcif_dma, prepare to shdma
+ conversion
+
+Now that all users have been updated to use the embedded in struct
+sh_mmcif_plat_data DMA slave IDs, struct sh_mmcif_dma is no longer needed
+and can be removed. This also makes preparation to the shdma base library
+conversion easier.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Cc: Chris Ball <cjb@laptop.org>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit 916001fe33b7b4dc797f7b29ec8bc346c4369fa6)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 24 ++++++++++--------------
+ include/linux/mmc/sh_mmcif.h | 8 +-------
+ 2 files changed, 11 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index 724b35e..9e3b9b1 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -385,31 +385,27 @@ static void sh_mmcif_request_dma(struct sh_mmcif_host *host,
+ host->dma_active = false;
+
+ /* We can only either use DMA for both Tx and Rx or not use it at all */
+- if (pdata->dma) {
+- dev_warn(&host->pd->dev,
+- "Update your platform to use embedded DMA slave IDs\n");
+- tx = &pdata->dma->chan_priv_tx;
+- rx = &pdata->dma->chan_priv_rx;
+- } else {
+- tx = &host->dma_slave_tx;
+- tx->slave_id = pdata->slave_id_tx;
+- rx = &host->dma_slave_rx;
+- rx->slave_id = pdata->slave_id_rx;
+- }
+- if (tx->slave_id > 0 && rx->slave_id > 0) {
++ tx = &host->dma_slave_tx;
++ tx->shdma_slave.slave_id = pdata->slave_id_tx;
++ rx = &host->dma_slave_rx;
++ rx->shdma_slave.slave_id = pdata->slave_id_rx;
++
++ if (tx->shdma_slave.slave_id > 0 && rx->shdma_slave.slave_id > 0) {
+ dma_cap_mask_t mask;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+- host->chan_tx = dma_request_channel(mask, sh_mmcif_filter, tx);
++ host->chan_tx = dma_request_channel(mask, sh_mmcif_filter,
++ &tx->shdma_slave);
+ dev_dbg(&host->pd->dev, "%s: TX: got channel %p\n", __func__,
+ host->chan_tx);
+
+ if (!host->chan_tx)
+ return;
+
+- host->chan_rx = dma_request_channel(mask, sh_mmcif_filter, rx);
++ host->chan_rx = dma_request_channel(mask, sh_mmcif_filter,
++ &rx->shdma_slave);
+ dev_dbg(&host->pd->dev, "%s: RX: got channel %p\n", __func__,
+ host->chan_rx);
+
+diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h
+index 05f0e3d..c37956c 100644
+--- a/include/linux/mmc/sh_mmcif.h
++++ b/include/linux/mmc/sh_mmcif.h
+@@ -32,17 +32,11 @@
+ * 1111 : Peripheral clock (sup_pclk set '1')
+ */
+
+-struct sh_mmcif_dma {
+- struct sh_dmae_slave chan_priv_tx;
+- struct sh_dmae_slave chan_priv_rx;
+-};
+-
+ struct sh_mmcif_plat_data {
+ void (*set_pwr)(struct platform_device *pdev, int state);
+ void (*down_pwr)(struct platform_device *pdev);
+ int (*get_cd)(struct platform_device *pdef);
+- struct sh_mmcif_dma *dma; /* Deprecated. Instead */
+- unsigned int slave_id_tx; /* use embedded slave_id_[tr]x */
++ unsigned int slave_id_tx; /* embedded slave_id_[tr]x */
+ unsigned int slave_id_rx;
+ u8 sup_pclk; /* 1 :SH7757, 0: SH7724/SH7372 */
+ unsigned long caps;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0091-mmc-sh_mmcif-switch-to-the-new-DMA-channel-allocatio.patch b/patches.marzen/0091-mmc-sh_mmcif-switch-to-the-new-DMA-channel-allocatio.patch
new file mode 100644
index 0000000000000..02bbc7d068df1
--- /dev/null
+++ b/patches.marzen/0091-mmc-sh_mmcif-switch-to-the-new-DMA-channel-allocatio.patch
@@ -0,0 +1,138 @@
+From e528d448bb2c6e6b4c1ea80b809ffdc734806290 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 5 Jul 2012 12:29:43 +0200
+Subject: mmc: sh_mmcif: switch to the new DMA channel allocation and
+ configuration
+
+Using the "private" field from struct dma_chan is deprecated. The sh
+dmaengine driver now also supports the preferred DMA channel allocation
+and configuration method, using a standard filter function and a channel
+configuration operation. This patch updates sh_mmcif to use this new
+method.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Cc: Chris Ball <cjb@laptop.org>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit 0e79f9ae1610c15f5e5959c39d7c39071619de97)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 82 ++++++++++++++++++++++++++-------------------
+ 1 file changed, 47 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index 9e3b9b1..0f07d28 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -211,8 +211,6 @@ struct sh_mmcif_host {
+ struct mmc_host *mmc;
+ struct mmc_request *mrq;
+ struct platform_device *pd;
+- struct sh_dmae_slave dma_slave_tx;
+- struct sh_dmae_slave dma_slave_rx;
+ struct clk *hclk;
+ unsigned int clk;
+ int bus_width;
+@@ -371,52 +369,66 @@ static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host)
+ desc, cookie);
+ }
+
+-static bool sh_mmcif_filter(struct dma_chan *chan, void *arg)
+-{
+- dev_dbg(chan->device->dev, "%s: slave data %p\n", __func__, arg);
+- chan->private = arg;
+- return true;
+-}
+-
+ static void sh_mmcif_request_dma(struct sh_mmcif_host *host,
+ struct sh_mmcif_plat_data *pdata)
+ {
+- struct sh_dmae_slave *tx, *rx;
++ struct resource *res = platform_get_resource(host->pd, IORESOURCE_MEM, 0);
++ struct dma_slave_config cfg;
++ dma_cap_mask_t mask;
++ int ret;
++
+ host->dma_active = false;
+
++ if (pdata->slave_id_tx <= 0 || pdata->slave_id_rx <= 0)
++ return;
++
+ /* We can only either use DMA for both Tx and Rx or not use it at all */
+- tx = &host->dma_slave_tx;
+- tx->shdma_slave.slave_id = pdata->slave_id_tx;
+- rx = &host->dma_slave_rx;
+- rx->shdma_slave.slave_id = pdata->slave_id_rx;
++ dma_cap_zero(mask);
++ dma_cap_set(DMA_SLAVE, mask);
++
++ host->chan_tx = dma_request_channel(mask, shdma_chan_filter,
++ (void *)pdata->slave_id_tx);
++ dev_dbg(&host->pd->dev, "%s: TX: got channel %p\n", __func__,
++ host->chan_tx);
+
+- if (tx->shdma_slave.slave_id > 0 && rx->shdma_slave.slave_id > 0) {
+- dma_cap_mask_t mask;
++ if (!host->chan_tx)
++ return;
+
+- dma_cap_zero(mask);
+- dma_cap_set(DMA_SLAVE, mask);
++ cfg.slave_id = pdata->slave_id_tx;
++ cfg.direction = DMA_MEM_TO_DEV;
++ cfg.dst_addr = res->start + MMCIF_CE_DATA;
++ cfg.src_addr = 0;
++ ret = dmaengine_slave_config(host->chan_tx, &cfg);
++ if (ret < 0)
++ goto ecfgtx;
+
+- host->chan_tx = dma_request_channel(mask, sh_mmcif_filter,
+- &tx->shdma_slave);
+- dev_dbg(&host->pd->dev, "%s: TX: got channel %p\n", __func__,
+- host->chan_tx);
++ host->chan_rx = dma_request_channel(mask, shdma_chan_filter,
++ (void *)pdata->slave_id_rx);
++ dev_dbg(&host->pd->dev, "%s: RX: got channel %p\n", __func__,
++ host->chan_rx);
+
+- if (!host->chan_tx)
+- return;
++ if (!host->chan_rx)
++ goto erqrx;
+
+- host->chan_rx = dma_request_channel(mask, sh_mmcif_filter,
+- &rx->shdma_slave);
+- dev_dbg(&host->pd->dev, "%s: RX: got channel %p\n", __func__,
+- host->chan_rx);
++ cfg.slave_id = pdata->slave_id_rx;
++ cfg.direction = DMA_DEV_TO_MEM;
++ cfg.dst_addr = 0;
++ cfg.src_addr = res->start + MMCIF_CE_DATA;
++ ret = dmaengine_slave_config(host->chan_rx, &cfg);
++ if (ret < 0)
++ goto ecfgrx;
+
+- if (!host->chan_rx) {
+- dma_release_channel(host->chan_tx);
+- host->chan_tx = NULL;
+- return;
+- }
++ init_completion(&host->dma_complete);
+
+- init_completion(&host->dma_complete);
+- }
++ return;
++
++ecfgrx:
++ dma_release_channel(host->chan_rx);
++ host->chan_rx = NULL;
++erqrx:
++ecfgtx:
++ dma_release_channel(host->chan_tx);
++ host->chan_tx = NULL;
+ }
+
+ static void sh_mmcif_release_dma(struct sh_mmcif_host *host)
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0092-mmc-sh_mmcif-Support-MMC_SLEEP_AWAKE-command.patch b/patches.marzen/0092-mmc-sh_mmcif-Support-MMC_SLEEP_AWAKE-command.patch
new file mode 100644
index 0000000000000..ca047a2f6bca4
--- /dev/null
+++ b/patches.marzen/0092-mmc-sh_mmcif-Support-MMC_SLEEP_AWAKE-command.patch
@@ -0,0 +1,53 @@
+From a582cd28240bd5aca4462da1dacd8dd8e9ee0dbc Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Tue, 12 Jun 2012 22:56:09 +0200
+Subject: mmc: sh_mmcif: Support MMC_SLEEP_AWAKE command
+
+The MMC_SLEEP_AWAKE and SD_IO_SEND_OP_COND commands share the same
+opcode. SD_IO_SEND_OP_COND isn't supported by the SH MMCIF, but
+MMC_SLEEP_AWAKE is. Discriminate between the two commands using the
+command flags, and reject SD_IO_SEND_OP_COND only.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 7541ca98477862e2e9988c6c2ceadbdccefa9d77)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index 0f07d28..1eb23a7 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -900,21 +900,15 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
+
+ switch (mrq->cmd->opcode) {
+ /* MMCIF does not support SD/SDIO command */
+- case SD_IO_SEND_OP_COND:
++ case MMC_SLEEP_AWAKE: /* = SD_IO_SEND_OP_COND (5) */
++ case MMC_SEND_EXT_CSD: /* = SD_SEND_IF_COND (8) */
++ if ((mrq->cmd->flags & MMC_CMD_MASK) != MMC_CMD_BCR)
++ break;
+ case MMC_APP_CMD:
+ host->state = STATE_IDLE;
+ mrq->cmd->error = -ETIMEDOUT;
+ mmc_request_done(mmc, mrq);
+ return;
+- case MMC_SEND_EXT_CSD: /* = SD_SEND_IF_COND (8) */
+- if (!mrq->data) {
+- /* send_if_cond cmd (not support) */
+- host->state = STATE_IDLE;
+- mrq->cmd->error = -ETIMEDOUT;
+- mmc_request_done(mmc, mrq);
+- return;
+- }
+- break;
+ default:
+ break;
+ }
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0093-mmc-sh_mmcif-simplify-and-use-meaningful-label-names.patch b/patches.marzen/0093-mmc-sh_mmcif-simplify-and-use-meaningful-label-names.patch
new file mode 100644
index 0000000000000..e752b059a6ac6
--- /dev/null
+++ b/patches.marzen/0093-mmc-sh_mmcif-simplify-and-use-meaningful-label-names.patch
@@ -0,0 +1,126 @@
+From 31a4301b36511da303ad36da908f462f057f0e73 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 19 Apr 2012 16:15:52 +0200
+Subject: mmc: sh_mmcif: simplify and use meaningful label names in
+ error-handling
+
+A check for NULL platform data can be conveniently made in the very
+beginning of probing. Replace numbered error-handling labels in .probe()
+with meaningful names to make any future reorganisation simpler.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Reviewed-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit e1aae2eb3f7c446a2680a3a0ccd05aa50521b4e2)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 41 ++++++++++++++++++++---------------------
+ 1 file changed, 20 insertions(+), 21 deletions(-)
+
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -1253,11 +1253,16 @@ static int __devinit sh_mmcif_probe(stru
+ int ret = 0, irq[2];
+ struct mmc_host *mmc;
+ struct sh_mmcif_host *host;
+- struct sh_mmcif_plat_data *pd;
++ struct sh_mmcif_plat_data *pd = pdev->dev.platform_data;
+ struct resource *res;
+ void __iomem *reg;
+ char clk_name[8];
+
++ if (!pd) {
++ dev_err(&pdev->dev, "sh_mmcif plat data error.\n");
++ return -ENXIO;
++ }
++
+ irq[0] = platform_get_irq(pdev, 0);
+ irq[1] = platform_get_irq(pdev, 1);
+ if (irq[0] < 0 || irq[1] < 0) {
+@@ -1274,16 +1279,11 @@ static int __devinit sh_mmcif_probe(stru
+ dev_err(&pdev->dev, "ioremap error.\n");
+ return -ENOMEM;
+ }
+- pd = pdev->dev.platform_data;
+- if (!pd) {
+- dev_err(&pdev->dev, "sh_mmcif plat data error.\n");
+- ret = -ENXIO;
+- goto clean_up;
+- }
++
+ mmc = mmc_alloc_host(sizeof(struct sh_mmcif_host), &pdev->dev);
+ if (!mmc) {
+ ret = -ENOMEM;
+- goto clean_up;
++ goto ealloch;
+ }
+ host = mmc_priv(mmc);
+ host->mmc = mmc;
+@@ -1295,7 +1295,7 @@ static int __devinit sh_mmcif_probe(stru
+ if (IS_ERR(host->hclk)) {
+ dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
+ ret = PTR_ERR(host->hclk);
+- goto clean_up1;
++ goto eclkget;
+ }
+ clk_enable(host->hclk);
+ host->clk = clk_get_rate(host->hclk);
+@@ -1325,7 +1325,7 @@ static int __devinit sh_mmcif_probe(stru
+
+ ret = pm_runtime_resume(&pdev->dev);
+ if (ret < 0)
+- goto clean_up2;
++ goto eresume;
+
+ INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);
+
+@@ -1334,17 +1334,17 @@ static int __devinit sh_mmcif_probe(stru
+ ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n");
+- goto clean_up3;
++ goto ereqirq0;
+ }
+ ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
+- goto clean_up4;
++ goto ereqirq1;
+ }
+
+ ret = mmc_add_host(mmc);
+ if (ret < 0)
+- goto clean_up5;
++ goto emmcaddh;
+
+ dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
+
+@@ -1353,20 +1353,19 @@ static int __devinit sh_mmcif_probe(stru
+ sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff);
+ return ret;
+
+-clean_up5:
++emmcaddh:
+ free_irq(irq[1], host);
+-clean_up4:
++ereqirq1:
+ free_irq(irq[0], host);
+-clean_up3:
++ereqirq0:
+ pm_runtime_suspend(&pdev->dev);
+-clean_up2:
++eresume:
+ pm_runtime_disable(&pdev->dev);
+ clk_disable(host->hclk);
+-clean_up1:
++eclkget:
+ mmc_free_host(mmc);
+-clean_up:
+- if (reg)
+- iounmap(reg);
++ealloch:
++ iounmap(reg);
+ return ret;
+ }
+
diff --git a/patches.marzen/0094-mmc-sh_mmcif-fix-clock-management.patch b/patches.marzen/0094-mmc-sh_mmcif-fix-clock-management.patch
new file mode 100644
index 0000000000000..a0a25c610d71f
--- /dev/null
+++ b/patches.marzen/0094-mmc-sh_mmcif-fix-clock-management.patch
@@ -0,0 +1,160 @@
+From f504bc8e96b3633271ee5e623c35e026a6db62e7 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 19 Apr 2012 18:02:05 +0200
+Subject: mmc: sh_mmcif: fix clock management
+
+Regardless of whether the MMC bus clock is the same as the PM clock on
+this specific interface, it has to be managed separately. Its proper
+management should also include enabling and disabling of the clock,
+whenever the interface is becoming active or going idle respectively.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Reviewed-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit b289174ff70a591545a054d52ae081a75a73f085)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 46 ++++++++++++++++++++++----------------------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -950,6 +950,7 @@ static void sh_mmcif_set_ios(struct mmc_
+ }
+ if (host->power) {
+ pm_runtime_put(&host->pd->dev);
++ clk_disable(host->hclk);
+ host->power = false;
+ if (p->down_pwr && ios->power_mode == MMC_POWER_OFF)
+ p->down_pwr(host->pd);
+@@ -962,6 +963,7 @@ static void sh_mmcif_set_ios(struct mmc_
+ if (!host->power) {
+ if (p->set_pwr)
+ p->set_pwr(host->pd, ios->power_mode);
++ clk_enable(host->hclk);
+ pm_runtime_get_sync(&host->pd->dev);
+ host->power = true;
+ sh_mmcif_sync_reset(host);
+@@ -1290,22 +1292,11 @@ static int __devinit sh_mmcif_probe(stru
+ host->addr = reg;
+ host->timeout = 1000;
+
+- snprintf(clk_name, sizeof(clk_name), "mmc%d", pdev->id);
+- host->hclk = clk_get(&pdev->dev, clk_name);
+- if (IS_ERR(host->hclk)) {
+- dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
+- ret = PTR_ERR(host->hclk);
+- goto eclkget;
+- }
+- clk_enable(host->hclk);
+- host->clk = clk_get_rate(host->hclk);
+ host->pd = pdev;
+
+ spin_lock_init(&host->lock);
+
+ mmc->ops = &sh_mmcif_ops;
+- mmc->f_max = host->clk / 2;
+- mmc->f_min = host->clk / 512;
+ if (pd->ocr)
+ mmc->ocr_avail = pd->ocr;
+ mmc->caps = MMC_CAP_MMC_HIGHSPEED;
+@@ -1317,18 +1308,30 @@ static int __devinit sh_mmcif_probe(stru
+ mmc->max_blk_count = mmc->max_req_size / mmc->max_blk_size;
+ mmc->max_seg_size = mmc->max_req_size;
+
+- sh_mmcif_sync_reset(host);
+ platform_set_drvdata(pdev, host);
+
+ pm_runtime_enable(&pdev->dev);
+ host->power = false;
+
++ snprintf(clk_name, sizeof(clk_name), "mmc%d", pdev->id);
++ host->hclk = clk_get(&pdev->dev, clk_name);
++ if (IS_ERR(host->hclk)) {
++ ret = PTR_ERR(host->hclk);
++ dev_err(&pdev->dev, "cannot get clock \"%s\": %d\n", clk_name, ret);
++ goto eclkget;
++ }
++ clk_enable(host->hclk);
++ host->clk = clk_get_rate(host->hclk);
++ mmc->f_max = host->clk / 2;
++ mmc->f_min = host->clk / 512;
++
+ ret = pm_runtime_resume(&pdev->dev);
+ if (ret < 0)
+ goto eresume;
+
+ INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);
+
++ sh_mmcif_sync_reset(host);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
+
+ ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host);
+@@ -1342,6 +1345,7 @@ static int __devinit sh_mmcif_probe(stru
+ goto ereqirq1;
+ }
+
++ clk_disable(host->hclk);
+ ret = mmc_add_host(mmc);
+ if (ret < 0)
+ goto emmcaddh;
+@@ -1360,9 +1364,10 @@ ereqirq1:
+ ereqirq0:
+ pm_runtime_suspend(&pdev->dev);
+ eresume:
+- pm_runtime_disable(&pdev->dev);
+ clk_disable(host->hclk);
++ clk_put(host->hclk);
+ eclkget:
++ pm_runtime_disable(&pdev->dev);
+ mmc_free_host(mmc);
+ ealloch:
+ iounmap(reg);
+@@ -1375,6 +1380,7 @@ static int __devexit sh_mmcif_remove(str
+ int irq[2];
+
+ host->dying = true;
++ clk_enable(host->hclk);
+ pm_runtime_get_sync(&pdev->dev);
+
+ dev_pm_qos_hide_latency_limit(&pdev->dev);
+@@ -1400,9 +1406,9 @@ static int __devexit sh_mmcif_remove(str
+
+ platform_set_drvdata(pdev, NULL);
+
+- clk_disable(host->hclk);
+ mmc_free_host(host->mmc);
+ pm_runtime_put_sync(&pdev->dev);
++ clk_disable(host->hclk);
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+@@ -1411,24 +1417,18 @@ static int __devexit sh_mmcif_remove(str
+ #ifdef CONFIG_PM
+ static int sh_mmcif_suspend(struct device *dev)
+ {
+- struct platform_device *pdev = to_platform_device(dev);
+- struct sh_mmcif_host *host = platform_get_drvdata(pdev);
++ struct sh_mmcif_host *host = dev_get_drvdata(dev);
+ int ret = mmc_suspend_host(host->mmc);
+
+- if (!ret) {
++ if (!ret)
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
+- clk_disable(host->hclk);
+- }
+
+ return ret;
+ }
+
+ static int sh_mmcif_resume(struct device *dev)
+ {
+- struct platform_device *pdev = to_platform_device(dev);
+- struct sh_mmcif_host *host = platform_get_drvdata(pdev);
+-
+- clk_enable(host->hclk);
++ struct sh_mmcif_host *host = dev_get_drvdata(dev);
+
+ return mmc_resume_host(host->mmc);
+ }
diff --git a/patches.marzen/0095-mmc-sh_mmcif-re-read-the-clock-frequency-every-time-.patch b/patches.marzen/0095-mmc-sh_mmcif-re-read-the-clock-frequency-every-time-.patch
new file mode 100644
index 0000000000000..4752592f012ca
--- /dev/null
+++ b/patches.marzen/0095-mmc-sh_mmcif-re-read-the-clock-frequency-every-time-.patch
@@ -0,0 +1,73 @@
+From 417f01ebd88111d61e507af5d9cab347ffa41861 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 19 Apr 2012 18:02:50 +0200
+Subject: mmc: sh_mmcif: re-read the clock frequency every time it is turned on
+
+With aggressive clock gating the clock can be disabled during interface
+inactivity. During this time its frequency can be changed by another its
+user. Therefore when the interface is activated again and the clock is
+re-enabled, its frequency has to be re-read.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Reviewed-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit a6609267107ecc5598b79aa353036c1f57e7257e)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 23 ++++++++++++++++++-----
+ 1 file changed, 18 insertions(+), 5 deletions(-)
+
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -918,6 +918,19 @@ static void sh_mmcif_request(struct mmc_
+ sh_mmcif_start_cmd(host, mrq);
+ }
+
++static int sh_mmcif_clk_update(struct sh_mmcif_host *host)
++{
++ int ret = clk_enable(host->hclk);
++
++ if (!ret) {
++ host->clk = clk_get_rate(host->hclk);
++ host->mmc->f_max = host->clk / 2;
++ host->mmc->f_min = host->clk / 512;
++ }
++
++ return ret;
++}
++
+ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ {
+ struct sh_mmcif_host *host = mmc_priv(mmc);
+@@ -963,7 +976,7 @@ static void sh_mmcif_set_ios(struct mmc_
+ if (!host->power) {
+ if (p->set_pwr)
+ p->set_pwr(host->pd, ios->power_mode);
+- clk_enable(host->hclk);
++ sh_mmcif_clk_update(host);
+ pm_runtime_get_sync(&host->pd->dev);
+ host->power = true;
+ sh_mmcif_sync_reset(host);
+@@ -1320,10 +1333,9 @@ static int __devinit sh_mmcif_probe(stru
+ dev_err(&pdev->dev, "cannot get clock \"%s\": %d\n", clk_name, ret);
+ goto eclkget;
+ }
+- clk_enable(host->hclk);
+- host->clk = clk_get_rate(host->hclk);
+- mmc->f_max = host->clk / 2;
+- mmc->f_min = host->clk / 512;
++ ret = sh_mmcif_clk_update(host);
++ if (ret < 0)
++ goto eclkupdate;
+
+ ret = pm_runtime_resume(&pdev->dev);
+ if (ret < 0)
+@@ -1365,6 +1377,7 @@ ereqirq0:
+ pm_runtime_suspend(&pdev->dev);
+ eresume:
+ clk_disable(host->hclk);
++eclkupdate:
+ clk_put(host->hclk);
+ eclkget:
+ pm_runtime_disable(&pdev->dev);
diff --git a/patches.marzen/0096-mmc-sh_mmcif-remove-redundant-.down_pwr-callback.patch b/patches.marzen/0096-mmc-sh_mmcif-remove-redundant-.down_pwr-callback.patch
new file mode 100644
index 0000000000000..f30f7019bd8a8
--- /dev/null
+++ b/patches.marzen/0096-mmc-sh_mmcif-remove-redundant-.down_pwr-callback.patch
@@ -0,0 +1,39 @@
+From 57a9e156b943508dc6ee4ac85e43d90f0888985f Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Fri, 20 Apr 2012 09:01:05 +0200
+Subject: mmc: sh_mmcif: remove redundant .down_pwr() callback
+
+From the original version of sh_mmcif the .set_pwr() callback has only been
+used to turn the card's power on, and the .down_pwr() callback has been
+used to turn it off. .set_pwr() can be used for both these tasks, which is
+also how it is implemented by the only user of this API: the SH7724 ecovec
+board.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Reviewed-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit e2ee996eaad64c149cb7cfd344789c7e0c1577dc)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index 29d908a..10c5fcd 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -965,8 +965,8 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ pm_runtime_put(&host->pd->dev);
+ clk_disable(host->hclk);
+ host->power = false;
+- if (p->down_pwr && ios->power_mode == MMC_POWER_OFF)
+- p->down_pwr(host->pd);
++ if (p->set_pwr && ios->power_mode == MMC_POWER_OFF)
++ p->set_pwr(host->pd, 0);
+ }
+ host->state = STATE_IDLE;
+ return;
+--
+1.8.0.197.g5a90748
+
diff --git a/patches.marzen/0097-mmc-sh_mmcif-add-regulator-support.patch b/patches.marzen/0097-mmc-sh_mmcif-add-regulator-support.patch
new file mode 100644
index 0000000000000..ccdff8ee4ba1e
--- /dev/null
+++ b/patches.marzen/0097-mmc-sh_mmcif-add-regulator-support.patch
@@ -0,0 +1,108 @@
+From d573e549e130bfe6200b70a36ab44767943b52a2 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Fri, 20 Apr 2012 18:27:13 +0200
+Subject: mmc: sh_mmcif: add regulator support
+
+Add regulator support to the sh_mmcif driver, but also preserve the current
+power-callback.
+
+Also note, that the card power is not switched off during clock gating
+periods, hence there's no need to power it on every time the card is
+re-activated.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Reviwed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Reviewed-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 7d17baa05da6a2e64ee15011cdf4319bd3e0ff61)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 38 +++++++++++++++++++++++++++++++-------
+ 1 file changed, 31 insertions(+), 7 deletions(-)
+
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -931,10 +931,22 @@ static int sh_mmcif_clk_update(struct sh
+ return ret;
+ }
+
++static void sh_mmcif_set_power(struct sh_mmcif_host *host, struct mmc_ios *ios)
++{
++ struct sh_mmcif_plat_data *pd = host->pd->dev.platform_data;
++ struct mmc_host *mmc = host->mmc;
++
++ if (pd->set_pwr)
++ pd->set_pwr(host->pd, ios->power_mode != MMC_POWER_OFF);
++ if (!IS_ERR(mmc->supply.vmmc))
++ /* Errors ignored... */
++ mmc_regulator_set_ocr(mmc, mmc->supply.vmmc,
++ ios->power_mode ? ios->vdd : 0);
++}
++
+ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ {
+ struct sh_mmcif_host *host = mmc_priv(mmc);
+- struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+@@ -952,6 +964,7 @@ static void sh_mmcif_set_ios(struct mmc_
+ sh_mmcif_request_dma(host, host->pd->dev.platform_data);
+ host->card_present = true;
+ }
++ sh_mmcif_set_power(host, ios);
+ } else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) {
+ /* clock stop */
+ sh_mmcif_clock_control(host, 0);
+@@ -965,8 +978,8 @@ static void sh_mmcif_set_ios(struct mmc_
+ pm_runtime_put(&host->pd->dev);
+ clk_disable(host->hclk);
+ host->power = false;
+- if (p->set_pwr && ios->power_mode == MMC_POWER_OFF)
+- p->set_pwr(host->pd, 0);
++ if (ios->power_mode == MMC_POWER_OFF)
++ sh_mmcif_set_power(host, ios);
+ }
+ host->state = STATE_IDLE;
+ return;
+@@ -974,8 +987,6 @@ static void sh_mmcif_set_ios(struct mmc_
+
+ if (ios->clock) {
+ if (!host->power) {
+- if (p->set_pwr)
+- p->set_pwr(host->pd, ios->power_mode);
+ sh_mmcif_clk_update(host);
+ pm_runtime_get_sync(&host->pd->dev);
+ host->power = true;
+@@ -1263,6 +1274,19 @@ static void mmcif_timeout_work(struct wo
+ mmc_request_done(host->mmc, mrq);
+ }
+
++static void sh_mmcif_init_ocr(struct sh_mmcif_host *host)
++{
++ struct sh_mmcif_plat_data *pd = host->pd->dev.platform_data;
++ struct mmc_host *mmc = host->mmc;
++
++ mmc_regulator_get_supply(mmc);
++
++ if (!mmc->ocr_avail)
++ mmc->ocr_avail = pd->ocr;
++ else if (pd->ocr)
++ dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
++}
++
+ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
+ {
+ int ret = 0, irq[2];
+@@ -1310,8 +1334,8 @@ static int __devinit sh_mmcif_probe(stru
+ spin_lock_init(&host->lock);
+
+ mmc->ops = &sh_mmcif_ops;
+- if (pd->ocr)
+- mmc->ocr_avail = pd->ocr;
++ sh_mmcif_init_ocr(host);
++
+ mmc->caps = MMC_CAP_MMC_HIGHSPEED;
+ if (pd->caps)
+ mmc->caps |= pd->caps;
diff --git a/patches.marzen/0098-mmc-sh-mmcif-add-OF-support-make-platform-data-optio.patch b/patches.marzen/0098-mmc-sh-mmcif-add-OF-support-make-platform-data-optio.patch
new file mode 100644
index 0000000000000..6d3bd0133abf0
--- /dev/null
+++ b/patches.marzen/0098-mmc-sh-mmcif-add-OF-support-make-platform-data-optio.patch
@@ -0,0 +1,127 @@
+From 7feedc26deff116af14317bfba8356724b71a362 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Tue, 1 May 2012 18:18:16 +0200
+Subject: mmc: sh-mmcif: add OF support, make platform data optional
+
+Add primitive OF support to the sh-mmcif driver, which also makes it
+necessary to be able to run without platform data.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit bf68a812f06ca40bccfa2e792055141f2c3948c7)
+
+Conflicts:
+ drivers/mmc/host/sh_mmcif.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 29 ++++++++++++++++++++---------
+ 1 file changed, 20 insertions(+), 9 deletions(-)
+
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -54,6 +54,7 @@
+ #include <linux/mmc/mmc.h>
+ #include <linux/mmc/sdio.h>
+ #include <linux/mmc/sh_mmcif.h>
++#include <linux/mod_devicetable.h>
+ #include <linux/pagemap.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_qos.h>
+@@ -379,6 +380,9 @@ static void sh_mmcif_request_dma(struct
+
+ host->dma_active = false;
+
++ if (!pdata)
++ return;
++
+ if (pdata->slave_id_tx <= 0 || pdata->slave_id_rx <= 0)
+ return;
+
+@@ -452,13 +456,14 @@ static void sh_mmcif_release_dma(struct
+ static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
+ {
+ struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
++ bool sup_pclk = p ? p->sup_pclk : false;
+
+ sh_mmcif_bitclr(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE);
+ sh_mmcif_bitclr(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR);
+
+ if (!clk)
+ return;
+- if (p->sup_pclk && clk == host->clk)
++ if (sup_pclk && clk == host->clk)
+ sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK);
+ else
+ sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR &
+@@ -936,7 +941,7 @@ static void sh_mmcif_set_power(struct sh
+ struct sh_mmcif_plat_data *pd = host->pd->dev.platform_data;
+ struct mmc_host *mmc = host->mmc;
+
+- if (pd->set_pwr)
++ if (pd && pd->set_pwr)
+ pd->set_pwr(host->pd, ios->power_mode != MMC_POWER_OFF);
+ if (!IS_ERR(mmc->supply.vmmc))
+ /* Errors ignored... */
+@@ -1004,7 +1009,7 @@ static int sh_mmcif_get_cd(struct mmc_ho
+ struct sh_mmcif_host *host = mmc_priv(mmc);
+ struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
+
+- if (!p->get_cd)
++ if (!p || !p->get_cd)
+ return -ENOSYS;
+ else
+ return p->get_cd(host->pd);
+@@ -1281,6 +1286,9 @@ static void sh_mmcif_init_ocr(struct sh_
+
+ mmc_regulator_get_supply(mmc);
+
++ if (!pd)
++ return;
++
+ if (!mmc->ocr_avail)
+ mmc->ocr_avail = pd->ocr;
+ else if (pd->ocr)
+@@ -1297,11 +1305,6 @@ static int __devinit sh_mmcif_probe(stru
+ void __iomem *reg;
+ char clk_name[8];
+
+- if (!pd) {
+- dev_err(&pdev->dev, "sh_mmcif plat data error.\n");
+- return -ENXIO;
+- }
+-
+ irq[0] = platform_get_irq(pdev, 0);
+ irq[1] = platform_get_irq(pdev, 1);
+ if (irq[0] < 0 || irq[1] < 0) {
+@@ -1337,7 +1340,7 @@ static int __devinit sh_mmcif_probe(stru
+ sh_mmcif_init_ocr(host);
+
+ mmc->caps = MMC_CAP_MMC_HIGHSPEED;
+- if (pd->caps)
++ if (pd && pd->caps)
+ mmc->caps |= pd->caps;
+ mmc->max_segs = 32;
+ mmc->max_blk_size = 512;
+@@ -1474,6 +1477,12 @@ static int sh_mmcif_resume(struct device
+ #define sh_mmcif_resume NULL
+ #endif /* CONFIG_PM */
+
++static const struct of_device_id mmcif_of_match[] = {
++ { .compatible = "renesas,sh-mmcif" },
++ { }
++};
++MODULE_DEVICE_TABLE(of, mmcif_of_match);
++
+ static const struct dev_pm_ops sh_mmcif_dev_pm_ops = {
+ .suspend = sh_mmcif_suspend,
+ .resume = sh_mmcif_resume,
+@@ -1485,6 +1494,8 @@ static struct platform_driver sh_mmcif_d
+ .driver = {
+ .name = DRIVER_NAME,
+ .pm = &sh_mmcif_dev_pm_ops,
++ .owner = THIS_MODULE,
++ .of_match_table = mmcif_of_match,
+ },
+ };
+
diff --git a/patches.marzen/0099-mmc-sh_mmcif-support-generic-card-detection.patch b/patches.marzen/0099-mmc-sh_mmcif-support-generic-card-detection.patch
new file mode 100644
index 0000000000000..613690cff8889
--- /dev/null
+++ b/patches.marzen/0099-mmc-sh_mmcif-support-generic-card-detection.patch
@@ -0,0 +1,92 @@
+From 4156a922e2e32baccd17cb76ba388cecb1790299 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 14 Jun 2012 14:24:35 +0200
+Subject: mmc: sh_mmcif: support generic card-detection
+
+Extend the sh_mmcif driver to support GPIO card detection, provided by the
+slot function module. The original .get_cd() platform callback is also
+preserved for now.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit e480606ad43bb72fd82a9bd99cdcf21829a6e9c0)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 18 ++++++++++++++++++
+ include/linux/mmc/sh_mmcif.h | 2 ++
+ 2 files changed, 20 insertions(+)
+
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -54,6 +54,7 @@
+ #include <linux/mmc/mmc.h>
+ #include <linux/mmc/sdio.h>
+ #include <linux/mmc/sh_mmcif.h>
++#include <linux/mmc/slot-gpio.h>
+ #include <linux/mod_devicetable.h>
+ #include <linux/pagemap.h>
+ #include <linux/platform_device.h>
+@@ -1008,6 +1009,10 @@ static int sh_mmcif_get_cd(struct mmc_ho
+ {
+ struct sh_mmcif_host *host = mmc_priv(mmc);
+ struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
++ int ret = mmc_gpio_get_cd(mmc);
++
++ if (ret >= 0)
++ return ret;
+
+ if (!p || !p->get_cd)
+ return -ENOSYS;
+@@ -1384,6 +1389,12 @@ static int __devinit sh_mmcif_probe(stru
+ goto ereqirq1;
+ }
+
++ if (pd && pd->use_cd_gpio) {
++ ret = mmc_gpio_request_cd(mmc, pd->cd_gpio);
++ if (ret < 0)
++ goto erqcd;
++ }
++
+ clk_disable(host->hclk);
+ ret = mmc_add_host(mmc);
+ if (ret < 0)
+@@ -1397,6 +1408,9 @@ static int __devinit sh_mmcif_probe(stru
+ return ret;
+
+ emmcaddh:
++ if (pd && pd->use_cd_gpio)
++ mmc_gpio_free_cd(mmc);
++erqcd:
+ free_irq(irq[1], host);
+ ereqirq1:
+ free_irq(irq[0], host);
+@@ -1417,6 +1431,7 @@ ealloch:
+ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
+ {
+ struct sh_mmcif_host *host = platform_get_drvdata(pdev);
++ struct sh_mmcif_plat_data *pd = pdev->dev.platform_data;
+ int irq[2];
+
+ host->dying = true;
+@@ -1425,6 +1440,9 @@ static int __devexit sh_mmcif_remove(str
+
+ dev_pm_qos_hide_latency_limit(&pdev->dev);
+
++ if (pd && pd->use_cd_gpio)
++ mmc_gpio_free_cd(host->mmc);
++
+ mmc_remove_host(host->mmc);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
+
+--- a/include/linux/mmc/sh_mmcif.h
++++ b/include/linux/mmc/sh_mmcif.h
+@@ -38,6 +38,8 @@ struct sh_mmcif_plat_data {
+ int (*get_cd)(struct platform_device *pdef);
+ unsigned int slave_id_tx; /* embedded slave_id_[tr]x */
+ unsigned int slave_id_rx;
++ bool use_cd_gpio : 1;
++ unsigned int cd_gpio;
+ u8 sup_pclk; /* 1 :SH7757, 0: SH7724/SH7372 */
+ unsigned long caps;
+ u32 ocr;
diff --git a/series b/series
index d0618c18210e5..4f3b0d3a2439d 100644
--- a/series
+++ b/series
@@ -81,3 +81,211 @@ patches.pramfs/16-pramfs-ioctl-operations.patch
patches.pramfs/17-pramfs-makefile-and-kconfig.patch
+patches.marzen/0001-sh-clkfwk-Support-variable-size-accesses-for-MSTP-cl.patch
+patches.marzen/0002-sh-clkfwk-Support-variable-size-accesses-for-div4-di.patch
+patches.marzen/0003-sh-clkfwk-Move-to-common-clk_div_table-accessors-for.patch
+patches.marzen/0004-sh-clkfwk-Introduce-a-div_mask-for-variable-div-type.patch
+patches.marzen/0005-sh-clkfwk-Use-shared-sh_clk_div_recalc.patch
+patches.marzen/0006-sh-clkfwk-Use-shared-sh_clk_div_set_rate.patch
+patches.marzen/0007-sh-clkfwk-Use-shared-sh_clk_div_enable-disable.patch
+patches.marzen/0008-sh-clkfwk-Consolidate-div6-div4-clk_ops-definitions.patch
+patches.marzen/0009-sh-clkfwk-Consolidate-div-clk-registration-helper.patch
+patches.marzen/0010-irqdomain-Support-removal-of-IRQ-domains.patch
+patches.marzen/0011-irqdomain-Export-remaining-public-API-symbols.patch
+patches.marzen/0012-irqdomain-Make-irq_domain_simple_map-static.patch
+patches.marzen/0013-irqdomain-Kill-off-duplicate-definitions.patch
+patches.marzen/0014-irqdomain-trivial-pr_fmt-conversion.patch
+patches.marzen/0015-irqdomain-Document-size-parameter-of-irq_domain_add_.patch
+patches.marzen/0016-devicetree-add-helper-inline-for-retrieving-a-node-s.patch
+patches.marzen/0017-irqdomain-Simple-NUMA-awareness.patch
+patches.marzen/0018-irqdomain-Remove-unnecessary-test-for-IRQ_DOMAIN_MAP.patch
+patches.marzen/0019-irqdomain-Make-ops-map-hook-optional.patch
+patches.marzen/0020-irq_domain-Standardise-legacy-linear-domain-selectio.patch
+patches.marzen/0021-irq_domain-correct-a-minor-wrong-comment-for-linear-.patch
+patches.marzen/0022-irqdomain-Always-update-revmap-when-setting-up-a-vir.patch
+patches.marzen/0023-irqdomain-Split-disassociating-code-into-separate-fu.patch
+patches.marzen/0024-irqdomain-Support-for-static-IRQ-mapping-and-associa.patch
+patches.marzen/0025-irqdomain-Eliminate-dedicated-radix-lookup-functions.patch
+patches.marzen/0026-irqdomain-Fix-irq_create_direct_mapping-to-test-irq_.patch
+patches.marzen/0027-irqdomain-eliminate-slow-path-revmap-lookups.patch
+patches.marzen/0028-irqdomain-Improve-diagnostics-when-a-domain-mapping-.patch
+patches.marzen/0029-ARM-mach-shmobile-Introduce-INTC_IRQ_PINS_16H.patch
+patches.marzen/0030-sh-intc-Kill-off-special-reservation-interface.patch
+patches.marzen/0031-sh-intc-Allocate-subgroup-virq-backing-desc-directly.patch
+patches.marzen/0032-sh-intc-initial-irqdomain-support.patch
+patches.marzen/0033-sh-intc-Handle-domain-association-for-sparseirq-pre-.patch
+patches.marzen/0034-sh-intc-Fix-up-multi-evt-irq-association.patch
+patches.marzen/0035-ARM-mach-shmobile-Introduce-shmobile_setup_delay.patch
+patches.marzen/0036-ARM-mach-shmobile-Use-0x3400-as-INTCS-vector-offset.patch
+patches.marzen/0037-ARM-provide-a-late_initcall-hook-for-platform-initia.patch
+patches.marzen/0038-ARM-shmobile-use-machine-specific-hook-for-late-init.patch
+patches.marzen/0039-ARM-mach-shmobile-Use-preset_lpj-with-calibrate_dela.patch
+patches.marzen/0040-ARM-shmobile-r8a7740-add-MERAM-work-around.patch
+patches.marzen/0041-ARM-shmobile-add-common-extra-gpio-functions.patch
+patches.marzen/0042-ARM-mach-shmobile-add-fixed-voltage-regulators-to-ma.patch
+patches.marzen/0043-ARM-shmobile-marzen-fixup-smsc911x-id-for-regulator.patch
+patches.marzen/0044-ARM-shmobile-r8a7779-Route-all-interrupts-to-ARM.patch
+patches.marzen/0045-dmaengine-Fixup-dmaengine_prep_slave_single-to-be-ac.patch
+patches.marzen/0046-dma-dmaengine-add-slave-req-id-in-slave_config.patch
+patches.marzen/0047-dmaengine-Add-wrapper-for-device_tx_status-callback.patch
+patches.marzen/0048-dma-move-shdma-driver-to-an-own-directory.patch
+patches.marzen/0049-dmaengine-add-an-shdma-base-library.patch
+patches.marzen/0050-dma-shdma-prepare-for-conversion-to-the-shdma-base-l.patch
+patches.marzen/0051-ASoC-fsi-prepare-for-conversion-to-the-shdma-base-li.patch
+patches.marzen/0052-usb-renesas_usbhs-prepare-for-conversion-to-the-shdm.patch
+patches.marzen/0053-dma-shdma-convert-to-the-shdma-base-library.patch
+patches.marzen/0054-dmaengine-shdma-prepare-to-stop-using-struct-dma_cha.patch
+patches.marzen/0055-dmaengine-shdma-cosmetic-simplify-a-static-function.patch
+patches.marzen/0056-dma-sh-use-an-integer-slave-ID-to-improve-API-compat.patch
+patches.marzen/0057-dma-sh-provide-a-migration-path-for-slave-drivers-to.patch
+patches.marzen/0058-dmaengine-shdma-restore-partial-transfer-calculation.patch
+patches.marzen/0059-serial-sh-sci-modify-sci_break_ctl.patch
+patches.marzen/0060-serial-sh-sci-Update-break_ctl-handling-for-all-SCSP.patch
+patches.marzen/0061-serial-sh-sci-Fix-for-port-types-without-BRI-interru.patch
+patches.marzen/0062-serial-sh-sci-Fix-probe-error-paths.patch
+patches.marzen/0063-serial-sh-sci-Make-probe-fail-for-ports-that-exceed-.patch
+patches.marzen/0064-serial-sh-sci-prepare-for-conversion-to-the-shdma-ba.patch
+patches.marzen/0065-serial-sh-sci-fix-compilation-breakage-when-DMA-is-e.patch
+patches.marzen/0066-net-smsc911x-Repair-broken-failure-paths.patch
+patches.marzen/0067-smsc911x.c-encapsulate-enable-irq-calls.patch
+patches.marzen/0068-clocksource-sh_tmu-Convert-timer-lock-to-raw-spinloc.patch
+patches.marzen/0069-mmc-tmio-use-MMC-opcode-defines-instead-of-numbers.patch
+patches.marzen/0070-mmc-cd-gpio-pass-IRQF_ONESHOT-to-request_threaded_ir.patch
+patches.marzen/0071-mmc-extend-and-rename-cd-gpio-helpers-to-handle-more.patch
+patches.marzen/0072-mmc-tmio-Don-t-access-hardware-registers-after-stopp.patch
+patches.marzen/0073-mmc-tmio-don-t-needlessly-enable-interrupts-during-p.patch
+patches.marzen/0074-mmc-sdhi-implement-tmio-mmc-clock-enable-update-and-.patch
+patches.marzen/0075-mmc-tmio-add-callbacks-to-enable-update-and-disable-.patch
+patches.marzen/0076-mmc-sdhi-do-not-install-dummy-callbacks.patch
+patches.marzen/0077-mmc-add-a-function-to-get-regulators-supplying-card-.patch
+patches.marzen/0078-mmc-tmio-add-regulator-support.patch
+patches.marzen/0079-mmc-tmio-remove-a-duplicated-comment-line.patch
+patches.marzen/0080-mmc-tmio-support-caps2-flags.patch
+patches.marzen/0081-mmc-sh_mobile_sdhi-support-caps2-flags.patch
+patches.marzen/0082-mmc-sdhi-add-OF-support-make-platform-data-optional.patch
+patches.marzen/0083-mmc-core-use-a-more-generic-name-for-slot-function-t.patch
+patches.marzen/0084-mmc-add-two-capability-flags-for-CD-and-WP-signal-po.patch
+patches.marzen/0085-mmc-add-CD-GPIO-polling-support-to-slot-functions.patch
+patches.marzen/0086-mmc-core-convert-slot-functions-to-managed-allocatio.patch
+patches.marzen/0087-mmc-core-add-WP-pin-handler-to-slot-functions.patch
+patches.marzen/0088-mmc-tmio-use-generic-GPIO-CD-and-WP-handlers.patch
+patches.marzen/0089-mmc-sh_mobile_sdhi-prepare-for-conversion-to-the-shd.patch
+patches.marzen/0090-mmc-sh_mmcif-remove-unneeded-struct-sh_mmcif_dma-pre.patch
+patches.marzen/0091-mmc-sh_mmcif-switch-to-the-new-DMA-channel-allocatio.patch
+patches.marzen/0092-mmc-sh_mmcif-Support-MMC_SLEEP_AWAKE-command.patch
+patches.marzen/0093-mmc-sh_mmcif-simplify-and-use-meaningful-label-names.patch
+patches.marzen/0094-mmc-sh_mmcif-fix-clock-management.patch
+patches.marzen/0095-mmc-sh_mmcif-re-read-the-clock-frequency-every-time-.patch
+patches.marzen/0096-mmc-sh_mmcif-remove-redundant-.down_pwr-callback.patch
+patches.marzen/0097-mmc-sh_mmcif-add-regulator-support.patch
+patches.marzen/0098-mmc-sh-mmcif-add-OF-support-make-platform-data-optio.patch
+patches.marzen/0099-mmc-sh_mmcif-support-generic-card-detection.patch
+
+
+patches.armadillo800/0001-ARM-shmobile-add-common-DMAEngine-definitions.patch
+patches.armadillo800/0002-ARM-shmobile-soc-core-add-R-mobile-PM-domain-common-.patch
+patches.armadillo800/0003-media-V4L2-sh_mobile_ceu-manage-lower-8bit-bus.patch
+patches.armadillo800/0004-regulator-support-multiple-dummy-fixed-regulators.patch
+patches.armadillo800/0005-regulator-extend-the-fixed-dummy-voltage-regulator-t.patch
+patches.armadillo800/0006-Input-gpio_keys-remove-useless-reinitialization-of-p.patch
+patches.armadillo800/0007-Input-st1232-add-device-tree-support.patch
+patches.armadillo800/0008-Input-st1232-switch-to-using-SIMPLE_DEV_PM_OPS.patch
+patches.armadillo800/0009-net-sh_eth-add-support-R8A7740.patch
+patches.armadillo800/0010-net-sh_eth-fix-the-rxdesc-pointer-when-rx-descriptor.patch
+patches.armadillo800/0011-net-sh_eth-fix-the-condition-to-fix-the-cur_tx-dirty.patch
+patches.armadillo800/0012-net-sh-eth-Add-support-selecting-MII-function-for-SH.patch
+patches.armadillo800/0013-net-sh-eth-Check-return-value-of-sh_eth_reset-when-c.patch
+patches.armadillo800/0014-net-sh_eth-remove-unnecessary-function.patch
+patches.armadillo800/0015-net-sh_eth-remove-unnecessary-members-definitions.patch
+patches.armadillo800/0016-net-sh_eth-fix-up-the-buffer-pointers.patch
+patches.armadillo800/0017-net-sh_eth-add-support-for-set_ringparam-get_ringpar.patch
+patches.armadillo800/0018-net-sh_eth-Add-eth-support-for-R8A7779-device.patch
+patches.armadillo800/0019-ASoC-add-generic-simple-card-support.patch
+patches.armadillo800/0020-ASoC-sh-fsi-use-simple-card-instead-of-fsi-ak4642.patch
+patches.armadillo800/0021-ASoC-sh-fsi-use-simple-card-instead-of-fsi-hdmi.patch
+patches.armadillo800/0022-ASoC-sh-fsi-use-simple-card-instead-of-fsi-da7210.patch
+patches.armadillo800/0023-ASoC-sh-fsi-use-register-field-macro-name-on-IN-OUT_.patch
+patches.armadillo800/0024-ASoC-sh-fsi-add-fsi_version-and-removed-meaningless-.patch
+patches.armadillo800/0025-ASoC-sh-fsi-use-same-format-for-IN-OUT.patch
+patches.armadillo800/0026-ASoC-sh-fsi-call-fsi_hw_startup-shutdown-from-fsi_da.patch
+patches.armadillo800/0027-ASoC-sh-fsi-enable-chip-specific-data-transfer-mode.patch
+patches.armadillo800/0028-ASoC-fsi-bugfix-enable-master-clock-control-on-DMA-s.patch
+patches.armadillo800/0029-ASoC-fsi-bugfix-correct-dma-area.patch
+patches.armadillo800/0030-ASoC-fsi-bugfix-ensure-dma-is-terminated.patch
+patches.armadillo800/0031-ASoC-fsi-use-dmaengine-helper-functions.patch
+patches.armadillo800/0032-ASoC-fsi-use-PIO-handler-if-DMA-handler-was-invalid.patch
+#patches.armadillo800/0033-ASoC-fsi-prepare-for-conversion-to-the-shdma-base-li.patch
+patches.armadillo800/0034-fbdev-sh_mobile_hdmi-add-hdmi_bit_set-function.patch
+patches.armadillo800/0035-fbdev-sh_mobile_hdmi-add-interrupt-output-option.patch
+patches.armadillo800/0036-fbdev-sh_mobile_hdmi-32bit-register-access-support.patch
+patches.armadillo800/0037-fbdev-sh_mobile_hdmi-add-HDMI-Control-Register-suppo.patch
+patches.armadillo800/0038-fbdev-sh_mipi_dsi-fix-a-section-mismatch.patch
+patches.armadillo800/0039-fbdev-sh_mobile_lcdc-Constify-sh_mobile_lcdc_fix-str.patch
+patches.armadillo800/0040-fbdev-sh_mobile_lcdc-Rename-fb-operation-handlers-wi.patch
+patches.armadillo800/0041-fbdev-sh_mobile_lcdc-Implement-overlays-support.patch
+patches.armadillo800/0042-sh_mobile_meram-Rename-operations-to-cache_-alloc-fr.patch
+patches.armadillo800/0043-sh_mobile_meram-Use-direct-function-calls-for-the-pu.patch
+patches.armadillo800/0044-sh_mobile_meram-Add-direct-MERAM-allocation-API.patch
+patches.armadillo800/0045-fbdev-sh_mobile_lcdc-Destroy-mutex-at-remove-time.patch
+patches.armadillo800/0046-fbdev-sh_mobile_lcdc-Fix-line-pitch-computation.patch
+patches.armadillo800/0047-fbdev-sh_mobile_lcdc-Use-channel-configuration-to-in.patch
+patches.armadillo800/0048-fbdev-sh_mobile_lcdc-Support-horizontal-panning.patch
+patches.armadillo800/0049-fbdev-sh_mobile_lcdc-Fix-overlay-registers-update-du.patch
+patches.armadillo800/0050-fbdev-sh_mobile_lcdc-Fix-pan-offset-computation-in-Y.patch
+patches.armadillo800/0051-fbdev-sh_mobile_lcdc-Fix-vertical-panning-step.patch
+patches.armadillo800/0052-ARM-mach-shmobile-r8a7740-add-gpio_irq-support.patch
+patches.armadillo800/0053-ARM-mach-shmobile-r8a7740-cleanup-I2C-workaround-met.patch
+patches.armadillo800/0054-ARM-mach-shmobile-clock-r8a7740-add-FSI-clock.patch
+patches.armadillo800/0055-ARM-mach-shmobile-clock-r8a7740-add-USB-clock.patch
+patches.armadillo800/0056-ARM-mach-shmobile-clock-r8a7740-add-SDHI-clock.patch
+patches.armadillo800/0057-ARM-mach-shmobile-clock-r8a7740-add-MMCIF-clock.patch
+patches.armadillo800/0058-ARM-mach-shmobile-clock-r8a7740-use-followparent_rec.patch
+patches.armadillo800/0059-ARM-mach-shmobile-add-armadillo800eva-board-support.patch
+patches.armadillo800/0060-ARM-mach-shmobile-armadillo800eva-add-defconfig.patch
+patches.armadillo800/0061-ARM-mach-shmobile-armadillo800eva-add-support-LCDC0.patch
+patches.armadillo800/0062-ARM-mach-shmobile-armadillo800eva-add-support-gpio_k.patch
+patches.armadillo800/0063-ARM-mach-shmobile-armadillo800eva-add-support-sh_eth.patch
+patches.armadillo800/0064-ARM-mach-shmobile-armadillo800eva-add-support-ST1232.patch
+patches.armadillo800/0065-ARM-mach-shmobile-armadillo800eva-add-USB-function-s.patch
+patches.armadillo800/0066-ARM-mach-shmobile-armadillo800eva-add-SDHI0-support.patch
+patches.armadillo800/0067-ARM-mach-shmobile-armadillo800eva-add-SDHI1-support.patch
+patches.armadillo800/0068-ARM-mach-shmobile-armadillo800eva-add-MMCIF-support.patch
+patches.armadillo800/0069-ARM-mach-shmobile-r8a7740-reserve-DMA-memory-for-the.patch
+patches.armadillo800/0070-ARM-mach-shmobile-clock-r8a7740-add-sh-eth-clock.patch
+patches.armadillo800/0071-ARM-mach-shmobile-armadillo800eva-defconfig-update.patch
+patches.armadillo800/0072-ARM-mach-shmobile-Use-DT_MACHINE-for-armadillo-800-e.patch
+patches.armadillo800/0073-ARM-shmobile-r8a7740-add-HDMI-interrupt-support.patch
+patches.armadillo800/0074-ARM-shmobile-r8a7740-add-HDMI-clock-support.patch
+patches.armadillo800/0075-ARM-shmobile-r8a7740-add-HDMI-GPIO-support.patch
+patches.armadillo800/0076-ARM-shmobile-r8a7740-add-MERAM-work-around.patch
+patches.armadillo800/0077-ARM-shmobile-r8a7740-add-CEU-clock-support.patch
+patches.armadillo800/0078-ARM-shmobile-r8a7740-add-FSI-parent-clock-support.patch
+patches.armadillo800/0079-ARM-shmobile-r8a7740-add-FSI-B-for-HDMI-GPIO-support.patch
+patches.armadillo800/0080-ARM-shmobile-armadillo800eva-enable-HDMI.patch
+patches.armadillo800/0081-ARM-mach-shmobile-armadillo800eva-Use-late-init-mach.patch
+patches.armadillo800/0082-ARM-shmobile-armadillo800eva-enable-camera.patch
+patches.armadillo800/0083-ARM-shmobile-r8a7740-add-DMAEngine-support-for-FSI.patch
+patches.armadillo800/0084-ARM-shmobile-r8a7740-add-DMAEngine-support-for-SDHI.patch
+patches.armadillo800/0085-ARM-shmobile-r8a7740-add-DMAEngine-support-for-USB.patch
+patches.armadillo800/0086-ARM-shmobile-use-common-DMAEngine-definitions-on-r8a.patch
+patches.armadillo800/0087-ARM-shmobile-armadillo800eva-enable-FSI-WM8978-sound.patch
+patches.armadillo800/0088-ARM-shmobile-armadillo800eva-enable-FSI-HDMI-sound.patch
+patches.armadillo800/0089-ARM-shmobile-armadillo800eva-enable-DMAEngine-on-FSI.patch
+patches.armadillo800/0090-ARM-shmobile-armadillo800eva-enable-DMAEngine-on-SDH.patch
+patches.armadillo800/0091-ARM-shmobile-armadillo800eva-enable-DMAEngine-on-USB.patch
+patches.armadillo800/0092-ARM-shmobile-use-common-extra-gpio-functions-on-arma.patch
+patches.armadillo800/0093-ARM-mach-shmobile-add-fixed-voltage-regulators-to-ar.patch
+patches.armadillo800/0094-ARM-mach-shmobile-Convert-sh_clk_mstp32_register-to-.patch
+patches.armadillo800/0095-ARM-shmobile-r8a7740-fixup-MSEL1CR-7bit-control.patch
+patches.armadillo800/0096-ARM-shmobile-r8a7740-add-A4S-pm-domain-support.patch
+patches.armadillo800/0097-ARM-shmobile-r8a7740-add-A3SP-pm-domain-support.patch
+patches.armadillo800/0098-ARM-shmobile-r8a7740-add-A4LC-pm-domain-support.patch
+patches.armadillo800/0099-ARM-shmobile-armadillo800eva-USB-Func-enables-extern.patch
+patches.armadillo800/0100-ARM-shmobile-armadillo800eva-A4LC-domain-includes-LC.patch
+patches.armadillo800/0101-ARM-shmobile-armadillo800eva-A3SP-domain-includes-US.patch
+patches.armadillo800/0102-ARM-mach-shmobile-r8a7740-generic-board-support-via-.patch
+patches.armadillo800/0103-ARM-mach-shmobile-armadillo800eva-defconfig-Allow-us.patch
+patches.armadillo800/0104-ARM-mach-shmobile-armadillo800eva-Fix-GPIO-buttons-d.patch
+patches.armadillo800/0105-ARM-mach-shmobile-armadillo800eva-Enable-power-butto.patch
+patches.armadillo800/0106-ARM-shmobile-armadillo800eva-fixup-sound-card-detect.patch
+patches.armadillo800/0107-ARM-shmobile-armadillo800eva-enable-rw-rootfs-mount.patch