aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-06-07 16:32:41 +0900
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-06-07 16:32:41 +0900
commit43df169fe6887691f87935cdfae227f022cd7c1c (patch)
treeb1488627678a141695a36a9db04f6af06e1e288a
parentafe8135a605144e3795e2f0d4b18a2e341ed5c23 (diff)
downloadltsi-kernel-43df169fe6887691f87935cdfae227f022cd7c1c.tar.gz
add kzm9g patches
-rw-r--r--patches.kzm9g/0001-net-remove-mm.h-inclusion-from-netdevice.h.patch167
-rw-r--r--patches.kzm9g/0002-Include-linux-dma-mapping.h-in-linux-dmaengine.h.patch35
-rw-r--r--patches.kzm9g/0003-dmaengine-failure-to-get-a-specific-DMA-channel-is-n.patch53
-rw-r--r--patches.kzm9g/0004-Improve-slave-cyclic-DMA-engine-documentation.patch279
-rw-r--r--patches.kzm9g/0005-dmaengine-use-DEFINE_IDR-for-static-initialization.patch47
-rw-r--r--patches.kzm9g/0006-dmaengine-add-helper-function-for-slave_single.patch51
-rw-r--r--patches.kzm9g/0007-dmaengine-remove-struct-scatterlist-for-header.patch37
-rw-r--r--patches.kzm9g/0008-dmaengine-add-new-enum-dma_transfer_direction.patch83
-rw-r--r--patches.kzm9g/0009-linux-dmaengine.h-fix-implicit-use-of-bitmap.h-and-a.patch45
-rw-r--r--patches.kzm9g/0010-DMAEngine-Define-interleaved-transfer-request-api.patch192
-rw-r--r--patches.kzm9g/0011-dmaengine-add-DMA_TRANS_NONE-to-dma_transfer_directi.patch60
-rw-r--r--patches.kzm9g/0012-dmaengine-Add-flow-controller-information-to-dma_sla.patch59
-rw-r--r--patches.kzm9g/0013-dma-dmaengine-Distinguish-between-dmaengine-failed-t.patch49
-rw-r--r--patches.kzm9g/0014-dmaengine-add-private-header-file.patch87
-rw-r--r--patches.kzm9g/0015-dmaengine-dma_slave-introduce-inline-wrappers.patch79
-rw-r--r--patches.kzm9g/0016-ARM-Add-init_consistent_dma_size.patch195
-rw-r--r--patches.kzm9g/0017-mmc-add-a-card-hotplug-handler-context.patch55
-rw-r--r--patches.kzm9g/0018-mmc-add-a-generic-GPIO-card-detect-helper.patch144
-rw-r--r--patches.kzm9g/0019-mmc-simplify-mmc_cd_gpio_request-by-removing-two-par.patch71
-rw-r--r--patches.kzm9g/0020-mmc-Standardize-header-file-inclusion-checks.patch65
-rw-r--r--patches.kzm9g/0021-mmc-tmio-name-0xd8-as-CTL_DMA_ENABLE.patch48
-rw-r--r--patches.kzm9g/0022-mmc-tmio-Share-register-access-functions.patch130
-rw-r--r--patches.kzm9g/0023-mmc-sdhi-Add-write16_hook.patch149
-rw-r--r--patches.kzm9g/0024-mmc-tmio-Fix-race-condition-resulting-in-spurious-in.patch132
-rw-r--r--patches.kzm9g/0025-mmc-tmio-fix-recursive-spinlock-don-t-schedule-with-.patch167
-rw-r--r--patches.kzm9g/0026-mmc-tmio-maximize-power-saving.patch172
-rw-r--r--patches.kzm9g/0027-mmc-tmio-fix-a-recently-introduced-bug-in-DMA-code.patch34
-rw-r--r--patches.kzm9g/0028-mmc-tmio-fix-a-deadlock.patch85
-rw-r--r--patches.kzm9g/0029-net-remove-mm.h-inclusion-from-netdevice.h.patch109
-rw-r--r--patches.kzm9g/0030-MMC-TMIO-Fix-build-issue-related-to-struct-scatterli.patch32
-rw-r--r--patches.kzm9g/0031-mmc-tmio-eliminate-unused-variable-mmc-warning.patch45
-rw-r--r--patches.kzm9g/0032-mmc-sdhi-initialise-mmc_data-flags-before-use.patch39
-rw-r--r--patches.kzm9g/0033-mmc-tmio-Cache-interrupt-masks.patch131
-rw-r--r--patches.kzm9g/0034-mmc-tmio-Provide-separate-interrupt-handlers.patch215
-rw-r--r--patches.kzm9g/0035-mmc-sdhi-Allow-named-IRQs-to-use-specific-handlers.patch180
-rw-r--r--patches.kzm9g/0036-mmc-irq-Remove-IRQF_DISABLED.patch46
-rw-r--r--patches.kzm9g/0037-mmc-Add-module.h-to-drivers-mmc-users-assuming-impli.patch36
-rw-r--r--patches.kzm9g/0038-mmc-replace-printk-with-appropriate-display-macro.patch36
-rw-r--r--patches.kzm9g/0039-mmc-tmio-fix-clock-gating-on-platforms-with-a-.set_p.patch33
-rw-r--r--patches.kzm9g/0040-mmc-convert-drivers-mmc-host-to-use-module_platform_.patch103
-rw-r--r--patches.kzm9g/0041-mmc-remove-the-second-argument-of-k-un-map_atomic.patch46
-rw-r--r--patches.kzm9g/0042-mmc-tmio_mmc-Hotplug-code-regrouping.patch84
-rw-r--r--patches.kzm9g/0043-mmc-host-move-to-dma_transfer_direction.patch54
-rw-r--r--patches.kzm9g/0044-mmc-tmio_mmc-fix-card-eject-during-IO-with-DMA.patch111
-rw-r--r--patches.kzm9g/0045-mmc-tmio_mmc-do-not-enable-card-hotplug-interrupts-i.patch53
-rw-r--r--patches.kzm9g/0046-mmc-tmio-calculate-the-native-hotplug-condition-only.patch71
-rw-r--r--patches.kzm9g/0047-mmc-tmio_mmc-support-the-generic-MMC-GPIO-card-hotpl.patch255
-rw-r--r--patches.kzm9g/0048-mmc-sh_mobile_sdhi-pass-card-hotplug-GPIO-number-to-.patch55
-rw-r--r--patches.kzm9g/0049-mmc-tmio_mmc-power-status-flag-doesn-t-have-to-be-ex.patch101
-rw-r--r--patches.kzm9g/0050-mmc-tmio_mmc-remove-unused-sdio_irq_enabled-flag.patch54
-rw-r--r--patches.kzm9g/0051-mmc-sh_mobile_sdhi-do-not-manage-PM-clocks-manually.patch52
-rw-r--r--patches.kzm9g/0052-mmc-tmio-cosmetic-prettify-the-tmio_mmc_set_ios-func.patch63
-rw-r--r--patches.kzm9g/0053-mmc-sh_mobile_sdhi-add-a-callback-for-board-specific.patch74
-rw-r--r--patches.kzm9g/0054-mmc-sh_mobile_sdhi-support-modular-mmc-core-with-non.patch85
-rw-r--r--patches.kzm9g/0055-mmc-Standardize-header-file-inclusion-checks.patch61
-rw-r--r--patches.kzm9g/0056-mmc-sh_mmcif-maximize-power-saving.patch82
-rw-r--r--patches.kzm9g/0057-mmc-sh_mmcif-simplify-platform-data.patch89
-rw-r--r--patches.kzm9g/0058-mmc-Add-module.h-to-drivers-mmc-users-assuming-impli.patch52
-rw-r--r--patches.kzm9g/0059-mmc-host-move-to-dma_transfer_direction.patch54
-rw-r--r--patches.kzm9g/0060-mmc-sh_mmcif-fix-clock-gating-on-platforms-with-a-.d.patch34
-rw-r--r--patches.kzm9g/0061-mmc-sh_mmcif-simplify-clock-divisor-calculation.patch42
-rw-r--r--patches.kzm9g/0062-mmc-convert-drivers-mmc-host-to-use-module_platform_.patch79
-rw-r--r--patches.kzm9g/0063-mmc-sh_mmcif-process-error-interrupts-first.patch53
-rw-r--r--patches.kzm9g/0064-mmc-sh_mmcif-cosmetic-clean-up.patch211
-rw-r--r--patches.kzm9g/0065-mmc-sh_mmcif-process-requests-asynchronously.patch788
-rw-r--r--patches.kzm9g/0066-mmc-sh_mmcif-remove-now-superfluous-sh_mmcif_host-da.patch319
-rw-r--r--patches.kzm9g/0067-mmc-sh_mmcif-fix-MMC_GEN_CMD-setting.patch40
-rw-r--r--patches.kzm9g/0068-mmc-sh_mmcif-simplify-bitmask-macros.patch51
-rw-r--r--patches.kzm9g/0069-mmc-sh_mmcif-double-clock-speed.patch41
-rw-r--r--patches.kzm9g/0070-mmc-sh_mmcif-mmc-f_max-should-be-half-of-the-bus-clo.patch49
-rw-r--r--patches.kzm9g/0071-mmc-sh_mmcif-Simplify-calculation-of-mmc-f_min.patch44
-rw-r--r--patches.kzm9g/0072-ARM-mach-shmobile-clock-r8a7740-add-USB-clock.patch203
-rw-r--r--patches.kzm9g/0073-ALSA-workaround-change-the-timing-of-alsa_sound_last.patch38
-rw-r--r--patches.kzm9g/0074-ASoC-core-Optimise-and-refactor-pcm_new-to-pass-only.patch529
-rw-r--r--patches.kzm9g/0075-ASoC-core-Allow-components-to-probe-remove-in-sequen.patch249
-rw-r--r--patches.kzm9g/0076-ASoC-core-Separate-out-PCM-operations-into-new-file.patch1333
-rw-r--r--patches.kzm9g/0077-ASoC-core-PCM-mutex-per-rtd.patch203
-rw-r--r--patches.kzm9g/0078-ASoC-Allow-DAI-formats-to-be-specified-in-the-dai_li.patch148
-rw-r--r--patches.kzm9g/0079-ASoC-Hold-runtime-PM-references-to-components-of-act.patch78
-rw-r--r--patches.kzm9g/0080-ASoC-sh-fsi-tidyup-parameter-of-fsi_stream_push.patch64
-rw-r--r--patches.kzm9g/0081-ASoC-sh-fsi-add-fsi_set_master_clk.patch273
-rw-r--r--patches.kzm9g/0082-ASoC-sh-fsi-irq-control-moves-to-fsi_port_start-stop.patch74
-rw-r--r--patches.kzm9g/0083-ASoC-sh-fsi-tidyup-unclear-variable-naming.patch344
-rw-r--r--patches.kzm9g/0084-ASoC-sh-fsi-remove-pm_runtime-from-fsi_dai_set_fmt.patch160
-rw-r--r--patches.kzm9g/0085-ASoC-sh-fsi-make-sure-fsi_stream_push-pop-access-by-.patch62
-rw-r--r--patches.kzm9g/0086-ASoC-sh-fsi-remove-fsi_module_init-kill.patch106
-rw-r--r--patches.kzm9g/0087-ASoC-sh-fsi-cleanup-suspend-resume.patch202
-rw-r--r--patches.kzm9g/0088-ASoC-sh-fsi-add-fsi_hw_startup-shutdown.patch116
-rw-r--r--patches.kzm9g/0089-sound-irq-Remove-IRQF_DISABLED.patch43
-rw-r--r--patches.kzm9g/0090-ASoC-sh-use-correct-__iomem-annotations.patch66
-rw-r--r--patches.kzm9g/0091-sound-Add-module.h-to-the-previously-silent-sound-us.patch63
-rw-r--r--patches.kzm9g/0092-ASoC-fsi-fixup-compile-warning.patch50
-rw-r--r--patches.kzm9g/0093-ASoC-fsi-add-valid-data-position-control-support.patch62
-rw-r--r--patches.kzm9g/0094-ASoC-Constify-snd_soc_dai_ops-structs.patch169
-rw-r--r--patches.kzm9g/0095-ASoC-fsi-ak4642-modify-specification-method-of-FSI-a.patch272
-rw-r--r--patches.kzm9g/0096-ASoC-Convert-sh-directory-to-module_platform_driver.patch100
-rw-r--r--patches.kzm9g/0097-ASoC-Use-core-pm_runtime-callbacks-for-fsi.patch41
-rw-r--r--patches.kzm9g/0098-ASoC-sh-Add-.owner-to-struct-snd_soc_card.patch67
-rw-r--r--patches.kzm9g/0099-ASoC-fsi-Remove-unneeded-empty-runtime-PM-callbacks.patch47
-rw-r--r--patches.kzm9g/0100-ASoC-fsi-reduce-runtime-calculation-by-using-pre-set.patch81
-rw-r--r--patches.kzm9g/0101-ASoC-fsi-tidyup-fsi_stream_xx-functions-were-gathere.patch204
-rw-r--r--patches.kzm9g/0102-ASoC-fsi-data-push-pop-calculation-part-was-divided.patch159
-rw-r--r--patches.kzm9g/0103-ASoC-fsi-rename-fsi_dma_soft_xxx-to-fsi_pio_xxx.patch114
-rw-r--r--patches.kzm9g/0104-ASoC-fsi-tidyup-move-fsi_fifo_init-onto-fsi_hw_start.patch146
-rw-r--r--patches.kzm9g/0105-ASoC-fsi-remove-unnecessary-parameter-from-fsi_hw_sh.patch51
-rw-r--r--patches.kzm9g/0106-ASoC-fsi-rename-fsi_stream_push-pop-to-fsi_stream_in.patch57
-rw-r--r--patches.kzm9g/0107-ASoC-fsi-modify-fsi_pio_get_area-parameter-and-using.patch127
-rw-r--r--patches.kzm9g/0108-ASoC-fsi-re-define-fsi_is_play-and-fsi_stream_is_pla.patch70
-rw-r--r--patches.kzm9g/0109-ASoC-fsi-use-fsi_stream-in-fsi_get_current_fifo_samp.patch64
-rw-r--r--patches.kzm9g/0110-ASoC-fsi-add-fsi_stream_handler-and-PIO-handler.patch286
-rw-r--r--patches.kzm9g/0111-ASoC-fsi-tidyup-fsi_pio_xxx-are-gathered.patch152
-rw-r--r--patches.kzm9g/0112-ASoC-fsi-don-t-use-is_play-as-a-parameter-of-fsi-fun.patch291
-rw-r--r--patches.kzm9g/0113-ASoC-fsi-add-.start_stop-handler-to-fsi_stream_handl.patch129
-rw-r--r--patches.kzm9g/0114-ASoC-fsi-fsi_stream_is_working-care-substream-runtim.patch41
-rw-r--r--patches.kzm9g/0115-ASoC-fsi-PortA-B-information-was-controlled-by-sh_fs.patch285
-rw-r--r--patches.kzm9g/0116-ASoC-fsi-add-.init-.quit-handler-support.patch48
-rw-r--r--patches.kzm9g/0117-ASoC-fsi-fixup-fsi_pointer-calculation-method.patch42
-rw-r--r--patches.kzm9g/0118-ASoC-fsi-Add-DMAEngine-support.patch316
-rw-r--r--patches.kzm9g/0119-ASoC-fsi-update-for-dmaengine-prep_slave_sg-fallout.patch47
-rw-r--r--patches.kzm9g/0120-ASoC-add-generic-simple-card-support.patch241
-rw-r--r--patches.kzm9g/0121-ASoC-sh-fsi-select-simple-card-on-Kconfig.patch34
-rw-r--r--patches.kzm9g/0122-ASoC-ak4642-convert-to-soc-cache.patch162
-rw-r--r--patches.kzm9g/0123-ASoC-ak4642-ak4642-was-tested.patch32
-rw-r--r--patches.kzm9g/0124-ASoC-ak4642-add-ak4642_set_bias_level.patch88
-rw-r--r--patches.kzm9g/0125-ASoC-ak4642-add-DAPM-support-for-HeadPhone-Output.patch95
-rw-r--r--patches.kzm9g/0126-ASoC-ak4642-add-headphone-mute-switch-control.patch47
-rw-r--r--patches.kzm9g/0127-ASoC-ak4642-add-Line-out-support.patch61
-rw-r--r--patches.kzm9g/0128-ASoC-ak4642-add-ak4648-support.patch115
-rw-r--r--patches.kzm9g/0129-ASoC-Remove-driver-versioning-from-ak4642.patch41
-rw-r--r--patches.kzm9g/0130-ASoC-Convert-ak4642-to-devm_kzalloc.patch47
-rw-r--r--patches.kzm9g/0131-ASoC-ak4642-fixup-HeadPhone-L-R-dapm-settings.patch85
-rw-r--r--patches.kzm9g/0132-ARM-mach-shmobile-clock-r8a7740-add-SDHI-clock.patch54
-rw-r--r--patches.kzm9g/0133-ARM-mach-shmobile-clock-r8a7740-add-MMCIF-clock.patch45
-rw-r--r--patches.kzm9g/0134-ARM-mach-shmobile-r8a7740-reserve-DMA-memory-for-the.patch44
-rw-r--r--patches.kzm9g/0135-ARM-mach-shmobile-clock-r8a7740-add-FSI-clock.patch45
-rw-r--r--patches.kzm9g/0136-ARM-mach-shmobile-armadillo800eva-add-SDHI0-support.patch131
-rw-r--r--patches.kzm9g/0137-ARM-mach-shmobile-armadillo800eva-add-SDHI1-support.patch110
-rw-r--r--patches.kzm9g/0138-ARM-mach-shmobile-armadillo800eva-add-MMCIF-support.patch105
-rw-r--r--patches.kzm9g/0139-ARM-mach-shmobile-armadillo800eva-Add-FSI-WM8978-sup.patch181
-rw-r--r--patches.kzm9g/0140-ARM-mach-shmobile-Add-support-for-PINT-though-INTC-m.patch80
-rw-r--r--patches.kzm9g/0141-irq-Track-the-owner-of-irq-descriptor.patch260
-rw-r--r--patches.kzm9g/0142-irq-add-irq_domain-translation-infrastructure.patch400
-rw-r--r--patches.kzm9g/0143-dt-irq-add-irq_domain_generate_simple-helper.patch122
-rw-r--r--patches.kzm9g/0144-irq-Add-declaration-of-irq_domain_simple_ops-to-irqd.patch41
-rw-r--r--patches.kzm9g/0145-irq-Fix-check-for-already-initialized-irq_domain-in-.patch56
-rw-r--r--patches.kzm9g/0146-irq-support-domains-with-non-zero-hwirq-base.patch113
-rw-r--r--patches.kzm9g/0147-genirq-Add-support-for-per-cpu-dev_id-interrupts.patch769
-rw-r--r--patches.kzm9g/0148-ARM-introduce-handle_IRQ-not-to-dump-exception-stack.patch123
-rw-r--r--patches.kzm9g/0149-ARM-GIC-move-gic_chip_data-structure-declaration-to-.patch59
-rw-r--r--patches.kzm9g/0150-ARM-CPU-hotplug-fix-abuse-of-irqdesc-node.patch55
-rw-r--r--patches.kzm9g/0151-ARM-GIC-avoid-routing-interrupts-to-offline-CPUs.patch52
-rw-r--r--patches.kzm9g/0152-ARM-gic-Use-cpu-pm-notifiers-to-save-gic-state.patch268
-rw-r--r--patches.kzm9g/0153-ARM-7011-1-Add-ARM-cpu-topology-definition.patch351
-rw-r--r--patches.kzm9g/0154-ARM-7060-1-smp-populate-logical-CPU-mapping-during-b.patch74
-rw-r--r--patches.kzm9g/0155-ARM-gic-Allow-gic-arch-extensions-to-provide-irqchip.patch35
-rw-r--r--patches.kzm9g/0156-ARM-7061-1-gic-convert-logical-CPU-numbers-into-phys.patch67
-rw-r--r--patches.kzm9g/0157-ARM-7123-1-smp-Add-an-IPI-handler-callable-from-C-co.patch53
-rw-r--r--patches.kzm9g/0158-ARM-7124-1-smp-Add-a-localtimer-handler-callable-fro.patch53
-rw-r--r--patches.kzm9g/0159-ARM-gic-consolidate-PPI-handling.patch561
-rw-r--r--patches.kzm9g/0160-ARM-GIC-Add-global-gic_handle_irq-function.patch81
-rw-r--r--patches.kzm9g/0161-ARM-twd-register-clockevents-device-before-enabling-.patch41
-rw-r--r--patches.kzm9g/0162-ARM-EXYNOS4-set-the-affinity-of-mct1-interrupt-using.patch36
-rw-r--r--patches.kzm9g/0163-genirq-percpu-allow-interrupt-type-to-be-set-at-enab.patch75
-rw-r--r--patches.kzm9g/0164-ARM-gic-local-timers-use-the-request_percpu_irq-inte.patch508
-rw-r--r--patches.kzm9g/0165-ARM-gic-add-irq_domain-support.patch288
-rw-r--r--patches.kzm9g/0166-ARM-gic-add-OF-based-initialization.patch195
-rw-r--r--patches.kzm9g/0167-ARM-gic-fix-irq_alloc_descs-handling-for-sparse-irq.patch99
-rw-r--r--patches.kzm9g/0168-ARM-gic-use-module.h-instead-of-export.h.patch32
-rw-r--r--patches.kzm9g/0169-ARM-7176-1-cpu_pm-register-GIC-PM-notifier-only-once.patch44
-rw-r--r--patches.kzm9g/0170-ARM-7177-1-GIC-avoid-skipping-non-existent-PPIs-in-i.patch52
-rw-r--r--patches.kzm9g/0171-ARM-mach-shmobile-clock-sh73a0-tidyup-CKSCR-main-clo.patch32
-rw-r--r--patches.kzm9g/0172-ARM-mach-shmobile-sh73a0-PFC-pull-up-support-for-SDH.patch189
-rw-r--r--patches.kzm9g/0173-ARM-shmobile-convert-logical-CPU-numbers-to-physical.patch51
-rw-r--r--patches.kzm9g/0174-ARM-mach-shmobile-sh73a0-GPIO-IRQ-support.patch91
-rw-r--r--patches.kzm9g/0175-ARM-mach-shmobile-Use-common-INTC-IRQ-code-on-sh73a0.patch259
-rw-r--r--patches.kzm9g/0176-ARM-mach-shmobile-sh73a0-and-AG5EVM-PINT-support.patch174
-rw-r--r--patches.kzm9g/0177-ARM-mach-shmobile-Kota2-TPU-LED-platform-data.patch88
-rw-r--r--patches.kzm9g/0178-ARM-mach-shmobile-SH73A0-external-Ethernet-fix.patch38
-rw-r--r--patches.kzm9g/0179-sh-clkfwk-clock-sh73a0-all-div6_clks-use-SH_CLK_DIV6.patch233
-rw-r--r--patches.kzm9g/0180-arm-mach-shmobile-add-a-resource-name-for-shdma.patch62
-rw-r--r--patches.kzm9g/0181-ARM-mach-shmobile-sh73a0-PINT-IRQ-base-fix.patch39
-rw-r--r--patches.kzm9g/0182-ARM-mach-shmobile-sh73a0-IRQ-sparse-alloc-fix.patch44
-rw-r--r--patches.kzm9g/0183-ARM-mach-shmobile-clock-sh73a0-add-DSIxPHY-clock-sup.patch159
-rw-r--r--patches.kzm9g/0184-ARM-shmobile-remove-NR_IRQS.patch54
-rw-r--r--patches.kzm9g/0185-ARM-mach-shmobile-sh73a0-PSTR-32-bit-access-fix.patch34
-rw-r--r--patches.kzm9g/0186-ARM-mach-shmobile-sh73a0-sh_clk_ops-rename.patch77
-rw-r--r--patches.kzm9g/0187-ARM-mach-shmobile-sh73a0-map_io-and-init_early-updat.patch129
-rw-r--r--patches.kzm9g/0188-ARM-mach-shmobile-sh73a0-AG5EVM-and-Kota2-timer-rewo.patch95
-rw-r--r--patches.kzm9g/0189-ARM-mach-shmobile-sh73a0-add-MMC-data-pin-pull-up.patch130
-rw-r--r--patches.kzm9g/0190-ARM-Update-mach-types.patch640
-rw-r--r--patches.kzm9g/0191-ARM-mach-shmobile-add-KZM-A9-GT-board-support.patch126
-rw-r--r--patches.kzm9g/0192-ARM-mach-shmobile-kzm9g-add-defconfig.patch155
-rw-r--r--patches.kzm9g/0193-ARM-mach-shmobile-Invalidate-caches-when-booting-sec.patch97
-rw-r--r--patches.kzm9g/0194-ARM-mach-shmobile-kzm9g-enable-SMP-boot.patch92
-rw-r--r--patches.kzm9g/0195-ARM-mach-shmobile-kzm9g-add-LCDC-support.patch204
-rw-r--r--patches.kzm9g/0196-ARM-mach-shmobile-kzm9g-add-ST1232-Touchscreen-suppo.patch65
-rw-r--r--patches.kzm9g/0197-ARM-mach-shmobile-pfc-sh73a0-fixup-MSEL2CR-MSEL18-fo.patch44
-rw-r--r--patches.kzm9g/0198-ARM-mach-shmobile-sh73a0.h-add-GPIO_NR.patch38
-rw-r--r--patches.kzm9g/0199-ARM-mach-shmobile-kzm9g-correct-screen-direction.patch40
-rw-r--r--patches.kzm9g/0200-ARM-mach-shmobile-kzm9g-add-MMCIF-support.patch106
-rw-r--r--patches.kzm9g/0201-ARM-mach-shmobile-kzm9g-add-SDHI-support.patch110
-rw-r--r--patches.kzm9g/0202-ARM-mach-shmobile-kzm9g-add-PCF8757-gpio-key.patch140
-rw-r--r--patches.kzm9g/0203-ARM-mach-shmobile-kzm9g-defconfig-update.patch88
-rw-r--r--patches.kzm9g/0204-ARM-mach-shmobile-clock-sh73a0-add-FSI-clock.patch46
-rw-r--r--patches.kzm9g/0205-ARM-mach-shmobile-kzm9g-add-FSI-AK4648-support.patch162
-rw-r--r--series207
206 files changed, 26038 insertions, 0 deletions
diff --git a/patches.kzm9g/0001-net-remove-mm.h-inclusion-from-netdevice.h.patch b/patches.kzm9g/0001-net-remove-mm.h-inclusion-from-netdevice.h.patch
new file mode 100644
index 00000000000000..87178759729ae8
--- /dev/null
+++ b/patches.kzm9g/0001-net-remove-mm.h-inclusion-from-netdevice.h.patch
@@ -0,0 +1,167 @@
+From 49d759919c99a3cb5391a446f5541f606c65e3c1 Mon Sep 17 00:00:00 2001
+From: Alexey Dobriyan <adobriyan@gmail.com>
+Date: Thu, 16 Jun 2011 11:01:34 +0000
+Subject: net: remove mm.h inclusion from netdevice.h
+
+Remove linux/mm.h inclusion from netdevice.h -- it's unused (I've checked manually).
+
+To prevent mm.h inclusion via other channels also extract "enum dma_data_direction"
+definition into separate header. This tiny piece is what gluing netdevice.h with mm.h
+via "netdevice.h => dmaengine.h => dma-mapping.h => scatterlist.h => mm.h".
+Removal of mm.h from scatterlist.h was tried and was found not feasible
+on most archs, so the link was cutoff earlier.
+
+Hope people are OK with tiny include file.
+
+Note, that mm_types.h is still dragged in, but it is a separate story.
+
+Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit b7f080cfe223b3b7424872639d153695615a9255)
+
+Conflicts:
+
+ arch/arm/mach-davinci/board-mityomapl138.c
+ arch/arm/mach-davinci/dm646x.c
+ arch/arm/mach-davinci/pm.c
+ arch/arm/mach-imx/dma-v1.c
+ arch/arm/mach-imx/mach-mx31_3ds.c
+ arch/arm/mach-iop13xx/setup.c
+ arch/arm/mach-mxs/devices/platform-auart.c
+ arch/arm/mach-mxs/devices/platform-dma.c
+ arch/arm/mach-mxs/devices/platform-fec.c
+ arch/arm/plat-mxc/devices/platform-fec.c
+ arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c
+ arch/arm/plat-mxc/devices/platform-imx-fb.c
+ arch/arm/plat-mxc/devices/platform-ipu-core.c
+ arch/arm/plat-mxc/devices/platform-mxc-ehci.c
+ arch/arm/plat-mxc/devices/platform-mxc-mmc.c
+ arch/arm/plat-nomadik/include/plat/ste_dma40.h
+ arch/x86/kernel/tboot.c
+ crypto/async_tx/raid6test.c
+ drivers/dma/coh901318.c
+ drivers/dma/dmatest.c
+ drivers/dma/ipu/ipu_idmac.c
+ drivers/dma/ste_dma40.c
+ drivers/media/dvb/mantis/mantis_ca.c
+ drivers/media/dvb/mantis/mantis_evm.c
+ drivers/media/dvb/mantis/mantis_hif.c
+ drivers/media/dvb/mantis/mantis_ioc.c
+ drivers/media/dvb/mantis/mantis_pcmcia.c
+ drivers/media/dvb/mantis/mantis_uart.c
+ drivers/media/dvb/mantis/mantis_vp1034.c
+ drivers/mmc/host/tmio_mmc_dma.c
+ drivers/mtd/nand/atmel_nand.c
+ drivers/net/arm/ks8695net.c
+ drivers/net/bnx2x/bnx2x.h
+ drivers/net/can/janz-ican3.c
+ drivers/net/can/softing/softing_fw.c
+ drivers/net/can/softing/softing_main.c
+ drivers/net/ethoc.c
+ drivers/net/fec_mpc52xx.c
+ drivers/net/greth.c
+ drivers/net/irda/pxaficp_ir.c
+ drivers/net/ks8851_mll.c
+ drivers/net/sgiseeq.c
+ drivers/net/stmmac/dwmac1000_core.c
+ drivers/net/stmmac/dwmac1000_dma.c
+ drivers/net/stmmac/dwmac100_core.c
+ drivers/net/stmmac/dwmac100_dma.c
+ drivers/net/stmmac/stmmac_ethtool.c
+ drivers/net/stmmac/stmmac_mdio.c
+ drivers/net/usb/cdc-phonet.c
+ drivers/net/vxge/vxge-config.h
+ drivers/net/wireless/ath/ath5k/base.c
+ drivers/net/wireless/ath/ath9k/beacon.c
+ drivers/net/wireless/ath/ath9k/init.c
+ drivers/net/wireless/ath/ath9k/recv.c
+ drivers/net/wireless/ath/ath9k/xmit.c
+ drivers/staging/pohmelfs/crypto.c
+ drivers/tty/serial/ifx6x60.c
+ drivers/usb/gadget/f_phonet.c
+ include/crypto/if_alg.h
+ include/linux/netdevice.h
+ net/sched/sch_netem.c
+ security/apparmor/lib.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/dma/dmaengine.c | 1 +
+ include/linux/dma-direction.h | 13 +++++++++++++
+ include/linux/dma-mapping.h | 10 +---------
+ include/linux/dmaengine.h | 4 +++-
+ 4 files changed, 18 insertions(+), 10 deletions(-)
+ create mode 100644 include/linux/dma-direction.h
+
+diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
+index 8bcb15f..48694c3 100644
+--- a/drivers/dma/dmaengine.c
++++ b/drivers/dma/dmaengine.c
+@@ -45,6 +45,7 @@
+ * See Documentation/dmaengine.txt for more details
+ */
+
++#include <linux/dma-mapping.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/mm.h>
+diff --git a/include/linux/dma-direction.h b/include/linux/dma-direction.h
+new file mode 100644
+index 0000000..95b6a82
+--- /dev/null
++++ b/include/linux/dma-direction.h
+@@ -0,0 +1,13 @@
++#ifndef _LINUX_DMA_DIRECTION_H
++#define _LINUX_DMA_DIRECTION_H
++/*
++ * These definitions mirror those in pci.h, so they can be used
++ * interchangeably with their PCI_ counterparts.
++ */
++enum dma_data_direction {
++ DMA_BIDIRECTIONAL = 0,
++ DMA_TO_DEVICE = 1,
++ DMA_FROM_DEVICE = 2,
++ DMA_NONE = 3,
++};
++#endif
+diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
+index ba8319a..1a167c4 100644
+--- a/include/linux/dma-mapping.h
++++ b/include/linux/dma-mapping.h
+@@ -4,17 +4,9 @@
+ #include <linux/device.h>
+ #include <linux/err.h>
+ #include <linux/dma-attrs.h>
++#include <linux/dma-direction.h>
+ #include <linux/scatterlist.h>
+
+-/* These definitions mirror those in pci.h, so they can be used
+- * interchangeably with their PCI_ counterparts */
+-enum dma_data_direction {
+- DMA_BIDIRECTIONAL = 0,
+- DMA_TO_DEVICE = 1,
+- DMA_FROM_DEVICE = 2,
+- DMA_NONE = 3,
+-};
+-
+ struct dma_map_ops {
+ void* (*alloc_coherent)(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp);
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index eee7add..8fbf40e 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -23,7 +23,9 @@
+
+ #include <linux/device.h>
+ #include <linux/uio.h>
+-#include <linux/dma-mapping.h>
++#include <linux/dma-direction.h>
++
++struct scatterlist;
+
+ /**
+ * typedef dma_cookie_t - an opaque DMA cookie
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0002-Include-linux-dma-mapping.h-in-linux-dmaengine.h.patch b/patches.kzm9g/0002-Include-linux-dma-mapping.h-in-linux-dmaengine.h.patch
new file mode 100644
index 00000000000000..049d91e5123c18
--- /dev/null
+++ b/patches.kzm9g/0002-Include-linux-dma-mapping.h-in-linux-dmaengine.h.patch
@@ -0,0 +1,35 @@
+From 0056ad033559371f0ce04d68fffc30c92fb551e8 Mon Sep 17 00:00:00 2001
+From: Simon Horman <horms@verge.net.au>
+Date: Fri, 17 Feb 2012 16:16:28 +0900
+Subject: Include linux/dma-mapping.h in linux/dmaengine.h
+
+This reverses the effect of b7f080cfe223b3b7424872639d153695615a9255 (net:
+remove mm.h inclusion from netdevice.h) while leaving almost all of the
+code changes in place, in particular the creation of linux/dma-diretion.h
+which is a dependency of subsequent patches that will be backported.
+
+The motivation for this it to unbreak multiple drivers.
+This patch cam be reverted if backports to all relevant drivers
+are made.
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/dmaengine.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index 8fbf40e..8bf1032 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -23,7 +23,7 @@
+
+ #include <linux/device.h>
+ #include <linux/uio.h>
+-#include <linux/dma-direction.h>
++#include <linux/dma-mapping.h>
+
+ struct scatterlist;
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0003-dmaengine-failure-to-get-a-specific-DMA-channel-is-n.patch b/patches.kzm9g/0003-dmaengine-failure-to-get-a-specific-DMA-channel-is-n.patch
new file mode 100644
index 00000000000000..a57dbe97cab20a
--- /dev/null
+++ b/patches.kzm9g/0003-dmaengine-failure-to-get-a-specific-DMA-channel-is-n.patch
@@ -0,0 +1,53 @@
+From d607a7087661613a9c1e4a45ae548570061bc6b8 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Mon, 20 Jun 2011 17:02:47 +0200
+Subject: dmaengine: failure to get a specific DMA channel is not critical
+
+There exist systems with multiple DMA controllers with different
+capabilities. For example, on some sh-mobile / rmobile systems there are
+DMA controllers, whose channels can be configured to be used with
+SD- and MMC-host controllers, serial ports etc. Besides there are also
+DMA controllers, that can only be used for one special function, e.g.,
+for USB. In such cases the DMA client filter function can just choose
+to specify to the DMA driver, which channel it needs. Then the
+.device_alloc_chan_resources() method of the DMA driver will check,
+whether it can provide that dunction. If not, it will fail and the loop
+in __dma_request_channel() will continue to the next DMA device, until
+it finds a suitable one. This works fine with just one minor glitch:
+the kernel logs error messages like
+
+dmaengine: failed to get <channel name>: (-<error code>)
+
+after each such non-critical failure. This patch lowers priority of
+this message to the debug level.
+
+Reported-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Tested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+(cherry picked from commit a03a202e95fdaa3ff52ccfc2594ec531e5917816)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/dma/dmaengine.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
+index 48694c3..26374b2 100644
+--- a/drivers/dma/dmaengine.c
++++ b/drivers/dma/dmaengine.c
+@@ -510,8 +510,8 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v
+ dma_chan_name(chan));
+ list_del_rcu(&device->global_node);
+ } else if (err)
+- pr_err("dmaengine: failed to get %s: (%d)\n",
+- dma_chan_name(chan), err);
++ pr_debug("dmaengine: failed to get %s: (%d)\n",
++ dma_chan_name(chan), err);
+ else
+ break;
+ if (--device->privatecnt == 0)
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0004-Improve-slave-cyclic-DMA-engine-documentation.patch b/patches.kzm9g/0004-Improve-slave-cyclic-DMA-engine-documentation.patch
new file mode 100644
index 00000000000000..66ba26c33f5787
--- /dev/null
+++ b/patches.kzm9g/0004-Improve-slave-cyclic-DMA-engine-documentation.patch
@@ -0,0 +1,279 @@
+From 8c0defafbf160e399767547d7b08b19fba273026 Mon Sep 17 00:00:00 2001
+From: Russell King - ARM Linux <linux@arm.linux.org.uk>
+Date: Tue, 26 Jul 2011 14:25:10 +0100
+Subject: Improve slave/cyclic DMA engine documentation
+
+Improve the documentation for the slave and cyclic DMA engine support
+reformatting it for easier reading, adding further APIs, splitting it
+into five steps, and including references to the documentation in
+dmaengine.h.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+[Fixed the index title to reflect new changes]
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+(cherry picked from commit 5a42fb93e6a33224774786691027ef2d9795c245)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ Documentation/dmaengine.txt | 234 +++++++++++++++++++++++++++++++-------------
+ 1 file changed, 164 insertions(+), 70 deletions(-)
+
+diff --git a/Documentation/dmaengine.txt b/Documentation/dmaengine.txt
+index 5a0cb1e..94b7e0f 100644
+--- a/Documentation/dmaengine.txt
++++ b/Documentation/dmaengine.txt
+@@ -10,87 +10,181 @@ NOTE: For DMA Engine usage in async_tx please see:
+ Below is a guide to device driver writers on how to use the Slave-DMA API of the
+ DMA Engine. This is applicable only for slave DMA usage only.
+
+-The slave DMA usage consists of following steps
++The slave DMA usage consists of following steps:
+ 1. Allocate a DMA slave channel
+ 2. Set slave and controller specific parameters
+ 3. Get a descriptor for transaction
+-4. Submit the transaction and wait for callback notification
++4. Submit the transaction
++5. Issue pending requests and wait for callback notification
+
+ 1. Allocate a DMA slave channel
+-Channel allocation is slightly different in the slave DMA context, client
+-drivers typically need a channel from a particular DMA controller only and even
+-in some cases a specific channel is desired. To request a channel
+-dma_request_channel() API is used.
+-
+-Interface:
+-struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
+- dma_filter_fn filter_fn,
+- void *filter_param);
+-where dma_filter_fn is defined as:
+-typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param);
+-
+-When the optional 'filter_fn' parameter is set to NULL dma_request_channel
+-simply returns the first channel that satisfies the capability mask. Otherwise,
+-when the mask parameter is insufficient for specifying the necessary channel,
+-the filter_fn routine can be used to disposition the available channels in the
+-system. The filter_fn routine is called once for each free channel in the
+-system. Upon seeing a suitable channel filter_fn returns DMA_ACK which flags
+-that channel to be the return value from dma_request_channel. A channel
+-allocated via this interface is exclusive to the caller, until
+-dma_release_channel() is called.
++
++ Channel allocation is slightly different in the slave DMA context,
++ client drivers typically need a channel from a particular DMA
++ controller only and even in some cases a specific channel is desired.
++ To request a channel dma_request_channel() API is used.
++
++ Interface:
++ struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
++ dma_filter_fn filter_fn,
++ void *filter_param);
++ where dma_filter_fn is defined as:
++ typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param);
++
++ The 'filter_fn' parameter is optional, but highly recommended for
++ slave and cyclic channels as they typically need to obtain a specific
++ DMA channel.
++
++ When the optional 'filter_fn' parameter is NULL, dma_request_channel()
++ simply returns the first channel that satisfies the capability mask.
++
++ Otherwise, the 'filter_fn' routine will be called once for each free
++ channel which has a capability in 'mask'. 'filter_fn' is expected to
++ return 'true' when the desired DMA channel is found.
++
++ A channel allocated via this interface is exclusive to the caller,
++ until dma_release_channel() is called.
+
+ 2. Set slave and controller specific parameters
+-Next step is always to pass some specific information to the DMA driver. Most of
+-the generic information which a slave DMA can use is in struct dma_slave_config.
+-It allows the clients to specify DMA direction, DMA addresses, bus widths, DMA
+-burst lengths etc. If some DMA controllers have more parameters to be sent then
+-they should try to embed struct dma_slave_config in their controller specific
+-structure. That gives flexibility to client to pass more parameters, if
+-required.
+-
+-Interface:
+-int dmaengine_slave_config(struct dma_chan *chan,
+- struct dma_slave_config *config)
++
++ Next step is always to pass some specific information to the DMA
++ driver. Most of the generic information which a slave DMA can use
++ is in struct dma_slave_config. This allows the clients to specify
++ DMA direction, DMA addresses, bus widths, DMA burst lengths etc
++ for the peripheral.
++
++ If some DMA controllers have more parameters to be sent then they
++ should try to embed struct dma_slave_config in their controller
++ specific structure. That gives flexibility to client to pass more
++ parameters, if required.
++
++ Interface:
++ int dmaengine_slave_config(struct dma_chan *chan,
++ struct dma_slave_config *config)
++
++ Please see the dma_slave_config structure definition in dmaengine.h
++ for a detailed explaination of the struct members. Please note
++ that the 'direction' member will be going away as it duplicates the
++ direction given in the prepare call.
+
+ 3. Get a descriptor for transaction
+-For slave usage the various modes of slave transfers supported by the
+-DMA-engine are:
+-slave_sg - DMA a list of scatter gather buffers from/to a peripheral
+-dma_cyclic - Perform a cyclic DMA operation from/to a peripheral till the
++
++ For slave usage the various modes of slave transfers supported by the
++ DMA-engine are:
++
++ slave_sg - DMA a list of scatter gather buffers from/to a peripheral
++ dma_cyclic - Perform a cyclic DMA operation from/to a peripheral till the
+ operation is explicitly stopped.
+-The non NULL return of this transfer API represents a "descriptor" for the given
+-transaction.
+-
+-Interface:
+-struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_sg)(
+- struct dma_chan *chan,
+- struct scatterlist *dst_sg, unsigned int dst_nents,
+- struct scatterlist *src_sg, unsigned int src_nents,
++
++ A non-NULL return of this transfer API represents a "descriptor" for
++ the given transaction.
++
++ Interface:
++ struct dma_async_tx_descriptor *(*chan->device->device_prep_slave_sg)(
++ struct dma_chan *chan, struct scatterlist *sgl,
++ unsigned int sg_len, enum dma_data_direction direction,
+ unsigned long flags);
+-struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_cyclic)(
++
++ struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_cyclic)(
+ struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
+ size_t period_len, enum dma_data_direction direction);
+
+-4. Submit the transaction and wait for callback notification
+-To schedule the transaction to be scheduled by dma device, the "descriptor"
+-returned in above (3) needs to be submitted.
+-To tell the dma driver that a transaction is ready to be serviced, the
+-descriptor->submit() callback needs to be invoked. This chains the descriptor to
+-the pending queue.
+-The transactions in the pending queue can be activated by calling the
+-issue_pending API. If channel is idle then the first transaction in queue is
+-started and subsequent ones queued up.
+-On completion of the DMA operation the next in queue is submitted and a tasklet
+-triggered. The tasklet would then call the client driver completion callback
+-routine for notification, if set.
+-Interface:
+-void dma_async_issue_pending(struct dma_chan *chan);
+-
+-==============================================================================
+-
+-Additional usage notes for dma driver writers
+-1/ Although DMA engine specifies that completion callback routines cannot submit
+-any new operations, but typically for slave DMA subsequent transaction may not
+-be available for submit prior to callback routine being called. This requirement
+-is not a requirement for DMA-slave devices. But they should take care to drop
+-the spin-lock they might be holding before calling the callback routine
++ The peripheral driver is expected to have mapped the scatterlist for
++ the DMA operation prior to calling device_prep_slave_sg, and must
++ keep the scatterlist mapped until the DMA operation has completed.
++ The scatterlist must be mapped using the DMA struct device. So,
++ normal setup should look like this:
++
++ nr_sg = dma_map_sg(chan->device->dev, sgl, sg_len);
++ if (nr_sg == 0)
++ /* error */
++
++ desc = chan->device->device_prep_slave_sg(chan, sgl, nr_sg,
++ direction, flags);
++
++ Once a descriptor has been obtained, the callback information can be
++ added and the descriptor must then be submitted. Some DMA engine
++ drivers may hold a spinlock between a successful preparation and
++ submission so it is important that these two operations are closely
++ paired.
++
++ Note:
++ Although the async_tx API specifies that completion callback
++ routines cannot submit any new operations, this is not the
++ case for slave/cyclic DMA.
++
++ For slave DMA, the subsequent transaction may not be available
++ for submission prior to callback function being invoked, so
++ slave DMA callbacks are permitted to prepare and submit a new
++ transaction.
++
++ For cyclic DMA, a callback function may wish to terminate the
++ DMA via dmaengine_terminate_all().
++
++ Therefore, it is important that DMA engine drivers drop any
++ locks before calling the callback function which may cause a
++ deadlock.
++
++ Note that callbacks will always be invoked from the DMA
++ engines tasklet, never from interrupt context.
++
++4. Submit the transaction
++
++ Once the descriptor has been prepared and the callback information
++ added, it must be placed on the DMA engine drivers pending queue.
++
++ Interface:
++ dma_cookie_t dmaengine_submit(struct dma_async_tx_descriptor *desc)
++
++ This returns a cookie can be used to check the progress of DMA engine
++ activity via other DMA engine calls not covered in this document.
++
++ dmaengine_submit() will not start the DMA operation, it merely adds
++ it to the pending queue. For this, see step 5, dma_async_issue_pending.
++
++5. Issue pending DMA requests and wait for callback notification
++
++ The transactions in the pending queue can be activated by calling the
++ issue_pending API. If channel is idle then the first transaction in
++ queue is started and subsequent ones queued up.
++
++ On completion of each DMA operation, the next in queue is started and
++ a tasklet triggered. The tasklet will then call the client driver
++ completion callback routine for notification, if set.
++
++ Interface:
++ void dma_async_issue_pending(struct dma_chan *chan);
++
++Further APIs:
++
++1. int dmaengine_terminate_all(struct dma_chan *chan)
++
++ This causes all activity for the DMA channel to be stopped, and may
++ discard data in the DMA FIFO which hasn't been fully transferred.
++ No callback functions will be called for any incomplete transfers.
++
++2. int dmaengine_pause(struct dma_chan *chan)
++
++ This pauses activity on the DMA channel without data loss.
++
++3. int dmaengine_resume(struct dma_chan *chan)
++
++ Resume a previously paused DMA channel. It is invalid to resume a
++ channel which is not currently paused.
++
++4. enum dma_status dma_async_is_tx_complete(struct dma_chan *chan,
++ dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used)
++
++ This can be used to check the status of the channel. Please see
++ the documentation in include/linux/dmaengine.h for a more complete
++ description of this API.
++
++ This can be used in conjunction with dma_async_is_complete() and
++ the cookie returned from 'descriptor->submit()' to check for
++ completion of a specific DMA transaction.
++
++ Note:
++ Not all DMA engine drivers can return reliable information for
++ a running DMA channel. It is recommended that DMA engine users
++ pause or stop (via dmaengine_terminate_all) the channel before
++ using this API.
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0005-dmaengine-use-DEFINE_IDR-for-static-initialization.patch b/patches.kzm9g/0005-dmaengine-use-DEFINE_IDR-for-static-initialization.patch
new file mode 100644
index 00000000000000..d954e2422daa19
--- /dev/null
+++ b/patches.kzm9g/0005-dmaengine-use-DEFINE_IDR-for-static-initialization.patch
@@ -0,0 +1,47 @@
+From b30e6b9e041ba92ec2ce074eff1e7094e047f036 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@gmail.com>
+Date: Wed, 20 Jul 2011 11:32:28 +0800
+Subject: dmaengine: use DEFINE_IDR for static initialization
+
+We could use DEFINE_IDR for statically allocated idr
+that allow us to save a few lines of code.
+
+And also remove unneeded mutex_init() for dma_list_mutex, as
+dma_list_mutex is initialized automatically by DEFINE_MUTEX().
+
+Signed-off-by: Axel Lin <axel.lin@gmail.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+(cherry picked from commit 21ef4b8b7a7d59a995bf44382de38c95587767d4)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/dma/dmaengine.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
+index 26374b2..b48967b 100644
+--- a/drivers/dma/dmaengine.c
++++ b/drivers/dma/dmaengine.c
+@@ -62,9 +62,9 @@
+ #include <linux/slab.h>
+
+ static DEFINE_MUTEX(dma_list_mutex);
++static DEFINE_IDR(dma_idr);
+ static LIST_HEAD(dma_device_list);
+ static long dmaengine_ref_count;
+-static struct idr dma_idr;
+
+ /* --- sysfs implementation --- */
+
+@@ -1050,8 +1050,6 @@ EXPORT_SYMBOL_GPL(dma_run_dependencies);
+
+ static int __init dma_bus_init(void)
+ {
+- idr_init(&dma_idr);
+- mutex_init(&dma_list_mutex);
+ return class_register(&dma_devclass);
+ }
+ arch_initcall(dma_bus_init);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0006-dmaengine-add-helper-function-for-slave_single.patch b/patches.kzm9g/0006-dmaengine-add-helper-function-for-slave_single.patch
new file mode 100644
index 00000000000000..f16c73a718e7dc
--- /dev/null
+++ b/patches.kzm9g/0006-dmaengine-add-helper-function-for-slave_single.patch
@@ -0,0 +1,51 @@
+From 1259f8b41cee5c445fd905087ec351f3e3f6524d Mon Sep 17 00:00:00 2001
+From: Vinod Koul <vinod.koul@intel.com>
+Date: Mon, 25 Jul 2011 19:57:52 +0530
+Subject: dmaengine: add helper function for slave_single
+
+For clients which require a single slave transfer and dont want to be bothered
+about the scatterlist api, this helper gives simple API for this transfer and
+creates single scatterlist for DMA API
+
+Idea from Russell King
+
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+(cherry picked from commit 90b44f8ffdf6c66d190ee71b330009bf7f11a208)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/dmaengine.h | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index 8bf1032..2ae9e01 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -24,6 +24,7 @@
+ #include <linux/device.h>
+ #include <linux/uio.h>
+ #include <linux/dma-mapping.h>
++#include <linux/scatterlist.h>
+
+ struct scatterlist;
+
+@@ -519,6 +520,16 @@ static inline int dmaengine_slave_config(struct dma_chan *chan,
+ (unsigned long)config);
+ }
+
++static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single(
++ struct dma_chan *chan, void *buf, size_t len,
++ enum dma_data_direction dir, unsigned long flags)
++{
++ struct scatterlist sg;
++ sg_init_one(&sg, buf, len);
++
++ return chan->device->device_prep_slave_sg(chan, &sg, 1, dir, flags);
++}
++
+ static inline int dmaengine_terminate_all(struct dma_chan *chan)
+ {
+ return dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0007-dmaengine-remove-struct-scatterlist-for-header.patch b/patches.kzm9g/0007-dmaengine-remove-struct-scatterlist-for-header.patch
new file mode 100644
index 00000000000000..90fd360233b3bf
--- /dev/null
+++ b/patches.kzm9g/0007-dmaengine-remove-struct-scatterlist-for-header.patch
@@ -0,0 +1,37 @@
+From d8000e0bf432de5c7bb8454e660c6d6d75f7df0c Mon Sep 17 00:00:00 2001
+From: Vinod Koul <vinod.koul@intel.com>
+Date: Tue, 9 Aug 2011 10:08:10 +0530
+Subject: dmaengine: remove struct scatterlist for header
+
+Commit 90b44f8 introduces dmaengine_prep_slave_single API which adds
+scatterlist.h in dmaengine.h, so defining struct scatterlist is not required
+
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+Acked-by: Dan Williams <dan.j.williams@intel.com>
+(cherry picked from commit a16e470caa173d323ef68dcac98c899b95fa4f84)
+
+Conflicts:
+
+ include/linux/dmaengine.h
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/dmaengine.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index 2ae9e01..0d079a4 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -26,8 +26,6 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/scatterlist.h>
+
+-struct scatterlist;
+-
+ /**
+ * typedef dma_cookie_t - an opaque DMA cookie
+ *
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0008-dmaengine-add-new-enum-dma_transfer_direction.patch b/patches.kzm9g/0008-dmaengine-add-new-enum-dma_transfer_direction.patch
new file mode 100644
index 00000000000000..24bd2ec0feaa0f
--- /dev/null
+++ b/patches.kzm9g/0008-dmaengine-add-new-enum-dma_transfer_direction.patch
@@ -0,0 +1,83 @@
+From f506f696ecb0ca3f9f34ea0bffbece7ed2c79342 Mon Sep 17 00:00:00 2001
+From: Vinod Koul <vinod.koul@linux.intel.com>
+Date: Thu, 13 Oct 2011 15:15:27 +0530
+Subject: dmaengine: add new enum dma_transfer_direction
+
+This new enum removes usage of dma_data_direction for dma direction. The new
+enum cleans tells the DMA direction and mode
+This further paves way for merging the dmaengine _prep operations and also for
+interleaved dma
+
+Suggested-by: Jassi Brar <jaswinder.singh@linaro.org>
+Reviewed-by: Barry Song <Baohua.Song@csr.com>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit 49920bc66984a512f4bcc7735a61642cd0e4d6f2)
+
+Conflicts:
+
+ include/linux/dmaengine.h
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/dmaengine.h | 21 +++++++++++++++++----
+ 1 file changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index 0d079a4..7a51acb 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -75,6 +75,19 @@ enum dma_transaction_type {
+ /* last transaction type for creation of the capabilities mask */
+ #define DMA_TX_TYPE_END (DMA_CYCLIC + 1)
+
++/**
++ * enum dma_transfer_direction - dma transfer mode and direction indicator
++ * @DMA_MEM_TO_MEM: Async/Memcpy mode
++ * @DMA_MEM_TO_DEV: Slave mode & From Memory to Device
++ * @DMA_DEV_TO_MEM: Slave mode & From Device to Memory
++ * @DMA_DEV_TO_DEV: Slave mode & From Device to Device
++ */
++enum dma_transfer_direction {
++ DMA_MEM_TO_MEM,
++ DMA_MEM_TO_DEV,
++ DMA_DEV_TO_MEM,
++ DMA_DEV_TO_DEV,
++};
+
+ /**
+ * enum dma_ctrl_flags - DMA flags to augment operation preparation,
+@@ -267,7 +280,7 @@ enum dma_slave_buswidth {
+ * struct, if applicable.
+ */
+ struct dma_slave_config {
+- enum dma_data_direction direction;
++ enum dma_transfer_direction direction;
+ dma_addr_t src_addr;
+ dma_addr_t dst_addr;
+ enum dma_slave_buswidth src_addr_width;
+@@ -490,11 +503,11 @@ struct dma_device {
+
+ struct dma_async_tx_descriptor *(*device_prep_slave_sg)(
+ struct dma_chan *chan, struct scatterlist *sgl,
+- unsigned int sg_len, enum dma_data_direction direction,
++ unsigned int sg_len, enum dma_transfer_direction direction,
+ unsigned long flags);
+ struct dma_async_tx_descriptor *(*device_prep_dma_cyclic)(
+ struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
+- size_t period_len, enum dma_data_direction direction);
++ size_t period_len, enum dma_transfer_direction direction);
+ int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+ unsigned long arg);
+
+@@ -520,7 +533,7 @@ 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,
+- enum dma_data_direction dir, unsigned long flags)
++ enum dma_transfer_direction dir, unsigned long flags)
+ {
+ struct scatterlist sg;
+ sg_init_one(&sg, buf, len);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0009-linux-dmaengine.h-fix-implicit-use-of-bitmap.h-and-a.patch b/patches.kzm9g/0009-linux-dmaengine.h-fix-implicit-use-of-bitmap.h-and-a.patch
new file mode 100644
index 00000000000000..7845d6bbf189ba
--- /dev/null
+++ b/patches.kzm9g/0009-linux-dmaengine.h-fix-implicit-use-of-bitmap.h-and-a.patch
@@ -0,0 +1,45 @@
+From 7f472b5f26b7ca5024aa78e636ecce48c03c3dc2 Mon Sep 17 00:00:00 2001
+From: Paul Gortmaker <paul.gortmaker@windriver.com>
+Date: Fri, 29 Jul 2011 16:55:11 +1000
+Subject: linux/dmaengine.h: fix implicit use of bitmap.h and asm/page.h
+
+The implicit presence of module.h and all its sub-includes was
+masking these implicit header usages:
+
+include/linux/dmaengine.h:684: warning: 'struct page' declared inside parameter list
+include/linux/dmaengine.h:684: warning: its scope is only this definition or declaration, which is probably not what you want
+include/linux/dmaengine.h:687: warning: 'struct page' declared inside parameter list
+include/linux/dmaengine.h:736:2: error: implicit declaration of function 'bitmap_zero'
+
+With input from Stephen Rothwell <sfr@canb.auug.org.au>
+
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+(cherry picked from commit a8efa9d6bf00fbe9597dd3352dc062a998bf9b15)
+
+Conflicts:
+
+ include/linux/dmaengine.h
+
+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 7a51acb..79d6881 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -25,6 +25,10 @@
+ #include <linux/uio.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/scatterlist.h>
++#include <linux/bitmap.h>
++#include <asm/page.h>
++
++struct scatterlist;
+
+ /**
+ * typedef dma_cookie_t - an opaque DMA cookie
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0010-DMAEngine-Define-interleaved-transfer-request-api.patch b/patches.kzm9g/0010-DMAEngine-Define-interleaved-transfer-request-api.patch
new file mode 100644
index 00000000000000..53cc2f6ec6fba3
--- /dev/null
+++ b/patches.kzm9g/0010-DMAEngine-Define-interleaved-transfer-request-api.patch
@@ -0,0 +1,192 @@
+From c6e7f820f97455f1f4320f3a9a925ee9e3a9c0c1 Mon Sep 17 00:00:00 2001
+From: Jassi Brar <jaswinder.singh@linaro.org>
+Date: Thu, 13 Oct 2011 12:33:30 +0530
+Subject: DMAEngine: Define interleaved transfer request api
+
+Define a new api that could be used for doing fancy data transfers
+like interleaved to contiguous copy and vice-versa.
+Traditional SG_list based transfers tend to be very inefficient in
+such cases as where the interleave and chunk are only a few bytes,
+which call for a very condensed api to convey pattern of the transfer.
+This api supports all 4 variants of scatter-gather and contiguous transfer.
+
+Of course, neither can this api help transfers that don't lend to DMA by
+nature, i.e, scattered tiny read/writes with no periodic pattern.
+
+Also since now we support SLAVE channels that might not provide
+device_prep_slave_sg callback but device_prep_interleaved_dma,
+remove the BUG_ON check.
+
+Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
+Acked-by: Barry Song <Baohua.Song@csr.com>
+[renamed dmaxfer_template to dma_interleaved_template
+ did fixup after the enum dma_transfer_merge]
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit b14dab792dee3245b628e046d80a7fad5573fea6)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ Documentation/dmaengine.txt | 8 +++++
+ drivers/dma/dmaengine.c | 4 +--
+ include/linux/dmaengine.h | 78 +++++++++++++++++++++++++++++++++++++++++++--
+ 3 files changed, 85 insertions(+), 5 deletions(-)
+
+diff --git a/Documentation/dmaengine.txt b/Documentation/dmaengine.txt
+index 94b7e0f..bbe6cb3 100644
+--- a/Documentation/dmaengine.txt
++++ b/Documentation/dmaengine.txt
+@@ -75,6 +75,10 @@ The slave DMA usage consists of following steps:
+ slave_sg - DMA a list of scatter gather buffers from/to a peripheral
+ dma_cyclic - Perform a cyclic DMA operation from/to a peripheral till the
+ operation is explicitly stopped.
++ interleaved_dma - This is common to Slave as well as M2M clients. For slave
++ address of devices' fifo could be already known to the driver.
++ Various types of operations could be expressed by setting
++ appropriate values to the 'dma_interleaved_template' members.
+
+ A non-NULL return of this transfer API represents a "descriptor" for
+ the given transaction.
+@@ -89,6 +93,10 @@ The slave DMA usage consists of following steps:
+ struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
+ size_t period_len, enum dma_data_direction direction);
+
++ struct dma_async_tx_descriptor *(*device_prep_interleaved_dma)(
++ struct dma_chan *chan, struct dma_interleaved_template *xt,
++ unsigned long flags);
++
+ The peripheral driver is expected to have mapped the scatterlist for
+ the DMA operation prior to calling device_prep_slave_sg, and must
+ keep the scatterlist mapped until the DMA operation has completed.
+diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
+index b48967b..a6c6051 100644
+--- a/drivers/dma/dmaengine.c
++++ b/drivers/dma/dmaengine.c
+@@ -693,12 +693,12 @@ int dma_async_device_register(struct dma_device *device)
+ !device->device_prep_dma_interrupt);
+ BUG_ON(dma_has_cap(DMA_SG, device->cap_mask) &&
+ !device->device_prep_dma_sg);
+- BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) &&
+- !device->device_prep_slave_sg);
+ BUG_ON(dma_has_cap(DMA_CYCLIC, device->cap_mask) &&
+ !device->device_prep_dma_cyclic);
+ BUG_ON(dma_has_cap(DMA_SLAVE, device->cap_mask) &&
+ !device->device_control);
++ BUG_ON(dma_has_cap(DMA_INTERLEAVE, device->cap_mask) &&
++ !device->device_prep_interleaved_dma);
+
+ BUG_ON(!device->device_alloc_chan_resources);
+ BUG_ON(!device->device_free_chan_resources);
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index 79d6881..3489430 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -74,10 +74,10 @@ enum dma_transaction_type {
+ DMA_ASYNC_TX,
+ DMA_SLAVE,
+ DMA_CYCLIC,
+-};
+-
++ DMA_INTERLEAVE,
+ /* last transaction type for creation of the capabilities mask */
+-#define DMA_TX_TYPE_END (DMA_CYCLIC + 1)
++ DMA_TX_TYPE_END,
++};
+
+ /**
+ * enum dma_transfer_direction - dma transfer mode and direction indicator
+@@ -94,6 +94,74 @@ enum dma_transfer_direction {
+ };
+
+ /**
++ * Interleaved Transfer Request
++ * ----------------------------
++ * A chunk is collection of contiguous bytes to be transfered.
++ * The gap(in bytes) between two chunks is called inter-chunk-gap(ICG).
++ * ICGs may or maynot change between chunks.
++ * A FRAME is the smallest series of contiguous {chunk,icg} pairs,
++ * that when repeated an integral number of times, specifies the transfer.
++ * A transfer template is specification of a Frame, the number of times
++ * it is to be repeated and other per-transfer attributes.
++ *
++ * Practically, a client driver would have ready a template for each
++ * type of transfer it is going to need during its lifetime and
++ * set only 'src_start' and 'dst_start' before submitting the requests.
++ *
++ *
++ * | Frame-1 | Frame-2 | ~ | Frame-'numf' |
++ * |====....==.===...=...|====....==.===...=...| ~ |====....==.===...=...|
++ *
++ * == Chunk size
++ * ... ICG
++ */
++
++/**
++ * struct data_chunk - Element of scatter-gather list that makes a frame.
++ * @size: Number of bytes to read from source.
++ * size_dst := fn(op, size_src), so doesn't mean much for destination.
++ * @icg: Number of bytes to jump after last src/dst address of this
++ * chunk and before first src/dst address for next chunk.
++ * Ignored for dst(assumed 0), if dst_inc is true and dst_sgl is false.
++ * Ignored for src(assumed 0), if src_inc is true and src_sgl is false.
++ */
++struct data_chunk {
++ size_t size;
++ size_t icg;
++};
++
++/**
++ * struct dma_interleaved_template - Template to convey DMAC the transfer pattern
++ * and attributes.
++ * @src_start: Bus address of source for the first chunk.
++ * @dst_start: Bus address of destination for the first chunk.
++ * @dir: Specifies the type of Source and Destination.
++ * @src_inc: If the source address increments after reading from it.
++ * @dst_inc: If the destination address increments after writing to it.
++ * @src_sgl: If the 'icg' of sgl[] applies to Source (scattered read).
++ * Otherwise, source is read contiguously (icg ignored).
++ * Ignored if src_inc is false.
++ * @dst_sgl: If the 'icg' of sgl[] applies to Destination (scattered write).
++ * Otherwise, destination is filled contiguously (icg ignored).
++ * Ignored if dst_inc is false.
++ * @numf: Number of frames in this template.
++ * @frame_size: Number of chunks in a frame i.e, size of sgl[].
++ * @sgl: Array of {chunk,icg} pairs that make up a frame.
++ */
++struct dma_interleaved_template {
++ dma_addr_t src_start;
++ dma_addr_t dst_start;
++ enum dma_transfer_direction dir;
++ bool src_inc;
++ bool dst_inc;
++ bool src_sgl;
++ bool dst_sgl;
++ size_t numf;
++ size_t frame_size;
++ struct data_chunk sgl[0];
++};
++
++/**
+ * enum dma_ctrl_flags - DMA flags to augment operation preparation,
+ * control completion, and communicate status.
+ * @DMA_PREP_INTERRUPT - trigger an interrupt (callback) upon completion of
+@@ -448,6 +516,7 @@ struct dma_tx_state {
+ * @device_prep_dma_cyclic: prepare a cyclic dma operation suitable for audio.
+ * The function takes a buffer of size buf_len. The callback function will
+ * be called after period_len bytes have been transferred.
++ * @device_prep_interleaved_dma: Transfer expression in a generic way.
+ * @device_control: manipulate all pending operations on a channel, returns
+ * zero or error code
+ * @device_tx_status: poll for transaction completion, the optional
+@@ -512,6 +581,9 @@ struct dma_device {
+ struct dma_async_tx_descriptor *(*device_prep_dma_cyclic)(
+ struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
+ size_t period_len, enum dma_transfer_direction direction);
++ struct dma_async_tx_descriptor *(*device_prep_interleaved_dma)(
++ struct dma_chan *chan, struct dma_interleaved_template *xt,
++ unsigned long flags);
+ int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+ unsigned long arg);
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0011-dmaengine-add-DMA_TRANS_NONE-to-dma_transfer_directi.patch b/patches.kzm9g/0011-dmaengine-add-DMA_TRANS_NONE-to-dma_transfer_directi.patch
new file mode 100644
index 00000000000000..b3bc13296a62a5
--- /dev/null
+++ b/patches.kzm9g/0011-dmaengine-add-DMA_TRANS_NONE-to-dma_transfer_directi.patch
@@ -0,0 +1,60 @@
+From d063219e6c8f9f5ec4f6b03c874f0e77d4ffc686 Mon Sep 17 00:00:00 2001
+From: Shawn Guo <shawn.guo@linaro.org>
+Date: Tue, 13 Dec 2011 23:48:03 +0800
+Subject: dmaengine: add DMA_TRANS_NONE to dma_transfer_direction
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Before dma_transfer_direction was introduced to replace
+dma_data_direction, some dmaengine device uses DMA_NONE of
+dma_data_direction for some talk with its client drivers.
+The mxs-dma and its clients mxs-mmc and gpmi-nand are such case.
+
+This patch adds DMA_TRANS_NONE to dma_transfer_direction and
+migrate the DMA_NONE use in mxs-dma to it.
+
+It also fixes the compile warning below.
+
+CC drivers/dma/mxs-dma.o
+drivers/dma/mxs-dma.c: In function ‘mxs_dma_prep_slave_sg’:
+drivers/dma/mxs-dma.c:420:16: warning: comparison between ‘enum dma_transfer_direction’ and ‘enum dma_data_direction’
+
+Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit 62268ce9170c5466332c046ff6ddafcb67751502)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/dma/mxs-dma.c | 2 +-
+ include/linux/dmaengine.h | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
+index 88aad4f..428903d 100644
+--- a/drivers/dma/mxs-dma.c
++++ b/drivers/dma/mxs-dma.c
+@@ -412,7 +412,7 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
+ idx = 0;
+ }
+
+- if (direction == DMA_NONE) {
++ if (direction == DMA_TRANS_NONE) {
+ ccw = &mxs_chan->ccw[idx++];
+ pio = (u32 *) sgl;
+
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index 3489430..18e71fd 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -91,6 +91,7 @@ enum dma_transfer_direction {
+ DMA_MEM_TO_DEV,
+ DMA_DEV_TO_MEM,
+ DMA_DEV_TO_DEV,
++ DMA_TRANS_NONE,
+ };
+
+ /**
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0012-dmaengine-Add-flow-controller-information-to-dma_sla.patch b/patches.kzm9g/0012-dmaengine-Add-flow-controller-information-to-dma_sla.patch
new file mode 100644
index 00000000000000..11538f96799a0c
--- /dev/null
+++ b/patches.kzm9g/0012-dmaengine-Add-flow-controller-information-to-dma_sla.patch
@@ -0,0 +1,59 @@
+From f7b36b70b02e3a82938758b9975c41dbe6aa331d Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@st.com>
+Date: Wed, 1 Feb 2012 16:12:18 +0530
+Subject: dmaengine: Add flow controller information to dma_slave_config
+
+Flow controller is programmable for few controllers and there are few
+intelligent peripherals like, Synopsys JPEG controller, that needs to be a flow
+controller of DMA transfers on dest side.
+
+For this, currently two drivers, pl08x and dw_dmac, support flow controller to
+be passed from platform to these drivers.
+
+Perhaps, this should be a part of struct dma_slave_config. This patch adds
+another field device_fc to this structure. User drivers must pass this as true
+if they want to be flow controller of certain transfers.
+
+Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
+Acked-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit dcc043dc0c60046cf6b75ca04a462314cf64e2ba)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/dmaengine.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index 18e71fd..b8b4a84 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -26,6 +26,7 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/scatterlist.h>
+ #include <linux/bitmap.h>
++#include <linux/types.h>
+ #include <asm/page.h>
+
+ struct scatterlist;
+@@ -334,6 +335,9 @@ enum dma_slave_buswidth {
+ * may or may not be applicable on memory sources.
+ * @dst_maxburst: same as src_maxburst but for destination target
+ * mutatis mutandis.
++ * @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.
+ *
+ * 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.
+@@ -360,6 +364,7 @@ struct dma_slave_config {
+ enum dma_slave_buswidth dst_addr_width;
+ u32 src_maxburst;
+ u32 dst_maxburst;
++ bool device_fc;
+ };
+
+ static inline const char *dma_chan_name(struct dma_chan *chan)
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0013-dma-dmaengine-Distinguish-between-dmaengine-failed-t.patch b/patches.kzm9g/0013-dma-dmaengine-Distinguish-between-dmaengine-failed-t.patch
new file mode 100644
index 00000000000000..25327e73ecd196
--- /dev/null
+++ b/patches.kzm9g/0013-dma-dmaengine-Distinguish-between-dmaengine-failed-t.patch
@@ -0,0 +1,49 @@
+From 081cbf58313406bddf98861bb72e9d97a9343e83 Mon Sep 17 00:00:00 2001
+From: Fabio Estevam <festevam@gmail.com>
+Date: Tue, 21 Feb 2012 12:51:59 -0200
+Subject: dma: dmaengine: Distinguish between 'dmaengine: failed to get'
+ messages
+
+The message "dmaengine: failed to get" can come from two possible locations within dmaengine.c.
+
+In order to distinguish between them, replace "dmaengine" with __func__ string so that the
+source function of the error message can be easily identified.
+
+Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit d8b53489d4c80490a70327fce6657816e33fafb3)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/dma/dmaengine.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
+index a6c6051..767bcc3 100644
+--- a/drivers/dma/dmaengine.c
++++ b/drivers/dma/dmaengine.c
+@@ -510,8 +510,8 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v
+ dma_chan_name(chan));
+ list_del_rcu(&device->global_node);
+ } else if (err)
+- pr_debug("dmaengine: failed to get %s: (%d)\n",
+- dma_chan_name(chan), err);
++ pr_debug("%s: failed to get %s: (%d)\n",
++ __func__, dma_chan_name(chan), err);
+ else
+ break;
+ if (--device->privatecnt == 0)
+@@ -564,8 +564,8 @@ void dmaengine_get(void)
+ list_del_rcu(&device->global_node);
+ break;
+ } else if (err)
+- pr_err("dmaengine: failed to get %s: (%d)\n",
+- dma_chan_name(chan), err);
++ pr_err("%s: failed to get %s: (%d)\n",
++ __func__, dma_chan_name(chan), err);
+ }
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0014-dmaengine-add-private-header-file.patch b/patches.kzm9g/0014-dmaengine-add-private-header-file.patch
new file mode 100644
index 00000000000000..805892068e3e12
--- /dev/null
+++ b/patches.kzm9g/0014-dmaengine-add-private-header-file.patch
@@ -0,0 +1,87 @@
+From 49799aa5029a873211dda26d311c29fac21e9d58 Mon Sep 17 00:00:00 2001
+From: Russell King - ARM Linux <linux@arm.linux.org.uk>
+Date: Tue, 6 Mar 2012 22:34:26 +0000
+Subject: dmaengine: add private header file
+
+Add a local private header file to contain definitions and declarations
+which should only be used by DMA engine drivers.
+
+We also fix linux/dmaengine.h to use LINUX_DMAENGINE_H to guard against
+multiple inclusion.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Tested-by: Linus Walleij <linus.walleij@linaro.org>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
+[imx-sdma.c & mxs-dma.c]
+Tested-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit d2ebfb335b0426deb1a4fb14e4e926d81ecd8235)
+
+Conflicts:
+
+ drivers/dma/amba-pl08x.c
+ drivers/dma/at_hdmac.c
+ drivers/dma/coh901318.c
+ drivers/dma/dw_dmac.c
+ drivers/dma/ep93xx_dma.c
+ drivers/dma/fsldma.c
+ drivers/dma/imx-dma.c
+ drivers/dma/imx-sdma.c
+ drivers/dma/intel_mid_dma.c
+ drivers/dma/ioat/dma.c
+ drivers/dma/ioat/dma_v2.c
+ drivers/dma/iop-adma.c
+ drivers/dma/ipu/ipu_idmac.c
+ drivers/dma/mpc512x_dma.c
+ drivers/dma/mv_xor.c
+ drivers/dma/mxs-dma.c
+ drivers/dma/pch_dma.c
+ drivers/dma/pl330.c
+ drivers/dma/ppc4xx/adma.c
+ drivers/dma/shdma.c
+ drivers/dma/ste_dma40.c
+ drivers/dma/timb_dma.c
+ drivers/dma/txx9dmac.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/dma/dmaengine.h | 10 ++++++++++
+ include/linux/dmaengine.h | 4 ++--
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/dma/dmaengine.h
+
+diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h
+new file mode 100644
+index 0000000..968570d
+--- /dev/null
++++ b/drivers/dma/dmaengine.h
+@@ -0,0 +1,10 @@
++/*
++ * The contents of this file are private to DMA engine drivers, and is not
++ * part of the API to be used by DMA engine users.
++ */
++#ifndef DMAENGINE_H
++#define DMAENGINE_H
++
++#include <linux/dmaengine.h>
++
++#endif
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index b8b4a84..56628b2 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -18,8 +18,8 @@
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+-#ifndef DMAENGINE_H
+-#define DMAENGINE_H
++#ifndef LINUX_DMAENGINE_H
++#define LINUX_DMAENGINE_H
+
+ #include <linux/device.h>
+ #include <linux/uio.h>
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0015-dmaengine-dma_slave-introduce-inline-wrappers.patch b/patches.kzm9g/0015-dmaengine-dma_slave-introduce-inline-wrappers.patch
new file mode 100644
index 00000000000000..9acba60907eb7b
--- /dev/null
+++ b/patches.kzm9g/0015-dmaengine-dma_slave-introduce-inline-wrappers.patch
@@ -0,0 +1,79 @@
+From 5a5c8a21c23c048134232d2daf8dc275c26c244d Mon Sep 17 00:00:00 2001
+From: Alexandre Bounine <alexandre.bounine@idt.com>
+Date: Thu, 8 Mar 2012 16:11:18 -0500
+Subject: dmaengine/dma_slave: introduce inline wrappers
+
+Add inline wrappers for device_prep_slave_sg() and device_prep_dma_cyclic()
+interfaces to hide new parameter from current users of affected interfaces.
+Convert current users to use new wrappers instead of direct calls.
+Suggested by Russell King [https://lkml.org/lkml/2012/2/3/269].
+
+Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit 16052827d98fbc13c31ebad560af4bd53e2b4dd5)
+
+Conflicts:
+
+ arch/arm/plat-samsung/dma-ops.c
+ arch/arm/plat-nomadik/include/plat/ste_dma40.h
+ drivers/media/video/mx3_camera.c
+ drivers/media/video/timblogiw.c
+ drivers/mmc/host/atmel-mci.c
+ drivers/mmc/host/mmci.c
+ drivers/mmc/host/mxcmmc.c
+ drivers/mmc/host/mxs-mmc.c
+ drivers/mmc/host/sh_mmcif.c
+ drivers/mmc/host/tmio_mmc_dma.c
+ drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+ drivers/usb/musb/ux500_dma.c
+ drivers/net/ethernet/micrel/ks8842.c
+ drivers/spi/spi-dw-mid.c
+ drivers/spi/spi-ep93xx.c
+ drivers/spi/spi-pl022.c
+ drivers/spi/spi-topcliff-pch.c
+ drivers/tty/serial/amba-pl011.c
+ drivers/tty/serial/pch_uart.c
+ drivers/tty/serial/sh-sci.c
+ drivers/usb/renesas_usbhs/fifo.c
+ drivers/video/mx3fb.c
+ sound/soc/ep93xx/ep93xx-pcm.c
+ sound/soc/imx/imx-pcm-dma-mx2.c
+ sound/soc/mxs/mxs-pcm.c
+ sound/soc/sh/siu_pcm.c
+ sound/soc/txx9/txx9aclc.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/dmaengine.h | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
+index 56628b2..ee123d2 100644
+--- a/include/linux/dmaengine.h
++++ b/include/linux/dmaengine.h
+@@ -623,6 +623,22 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single(
+ return chan->device->device_prep_slave_sg(chan, &sg, 1, dir, flags);
+ }
+
++static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_sg(
++ struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len,
++ enum dma_transfer_direction dir, unsigned long flags)
++{
++ return chan->device->device_prep_slave_sg(chan, sgl, sg_len,
++ dir, flags);
++}
++
++static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_cyclic(
++ struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
++ size_t period_len, enum dma_transfer_direction dir)
++{
++ return chan->device->device_prep_dma_cyclic(chan, buf_addr, buf_len,
++ period_len, dir);
++}
++
+ static inline int dmaengine_terminate_all(struct dma_chan *chan)
+ {
+ return dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0016-ARM-Add-init_consistent_dma_size.patch b/patches.kzm9g/0016-ARM-Add-init_consistent_dma_size.patch
new file mode 100644
index 00000000000000..2679fb0230eaa4
--- /dev/null
+++ b/patches.kzm9g/0016-ARM-Add-init_consistent_dma_size.patch
@@ -0,0 +1,195 @@
+From 2690e41103fa44c11e9e435bb58121de3cf16350 Mon Sep 17 00:00:00 2001
+From: Jon Medhurst <tixy@yxit.co.uk>
+Date: Tue, 2 Aug 2011 17:28:27 +0100
+Subject: ARM: Add init_consistent_dma_size()
+
+This function can be called during boot to increase the size of the consistent
+DMA region above it's default value of 2MB. It must be called before the memory
+allocator is initialised, i.e. before any core_initcall.
+
+Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
+Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
+(cherry picked from commit 99d1717dd7fecf2b10195b0d864323b952b4eba0)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/include/asm/dma-mapping.h | 7 ++++++
+ arch/arm/include/asm/memory.h | 9 -------
+ arch/arm/mm/dma-mapping.c | 49 +++++++++++++++++++++++++++++---------
+ arch/arm/mm/init.c | 9 -------
+ 4 files changed, 45 insertions(+), 29 deletions(-)
+
+diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
+index 4fff837..5f974f2 100644
+--- a/arch/arm/include/asm/dma-mapping.h
++++ b/arch/arm/include/asm/dma-mapping.h
+@@ -236,6 +236,13 @@ extern void *dma_alloc_writecombine(struct device *, size_t, dma_addr_t *,
+ int dma_mmap_writecombine(struct device *, struct vm_area_struct *,
+ void *, dma_addr_t, size_t);
+
++/*
++ * This can be called during boot to increase the size of the consistent
++ * DMA region above it's default value of 2MB. It must be called before the
++ * memory allocator is initialised, i.e. before any core_initcall.
++ */
++extern void __init init_consistent_dma_size(unsigned long size);
++
+
+ #ifdef CONFIG_DMABOUNCE
+ /*
+diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
+index af44a8f..0b0aaa4 100644
+--- a/arch/arm/include/asm/memory.h
++++ b/arch/arm/include/asm/memory.h
+@@ -77,16 +77,7 @@
+ */
+ #define IOREMAP_MAX_ORDER 24
+
+-/*
+- * Size of DMA-consistent memory region. Must be multiple of 2M,
+- * between 2MB and 14MB inclusive.
+- */
+-#ifndef CONSISTENT_DMA_SIZE
+-#define CONSISTENT_DMA_SIZE SZ_2M
+-#endif
+-
+ #define CONSISTENT_END (0xffe00000UL)
+-#define CONSISTENT_BASE (CONSISTENT_END - CONSISTENT_DMA_SIZE)
+
+ #else /* CONFIG_MMU */
+
+diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
+index f96d2c7..c6e2c9f 100644
+--- a/arch/arm/mm/dma-mapping.c
++++ b/arch/arm/mm/dma-mapping.c
+@@ -18,12 +18,14 @@
+ #include <linux/device.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/highmem.h>
++#include <linux/slab.h>
+
+ #include <asm/memory.h>
+ #include <asm/highmem.h>
+ #include <asm/cacheflush.h>
+ #include <asm/tlbflush.h>
+ #include <asm/sizes.h>
++#include <asm/mach/arch.h>
+
+ static u64 get_coherent_dma_mask(struct device *dev)
+ {
+@@ -115,26 +117,41 @@ static void __dma_free_buffer(struct page *page, size_t size)
+ }
+
+ #ifdef CONFIG_MMU
+-/* Sanity check size */
+-#if (CONSISTENT_DMA_SIZE % SZ_2M)
+-#error "CONSISTENT_DMA_SIZE must be multiple of 2MiB"
+-#endif
+
+-#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
+-#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
+-#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
++
++#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - consistent_base) >> PAGE_SHIFT)
++#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - consistent_base) >> PGDIR_SHIFT)
+
+ /*
+ * These are the page tables (2MB each) covering uncached, DMA consistent allocations
+ */
+-static pte_t *consistent_pte[NUM_CONSISTENT_PTES];
++static pte_t **consistent_pte;
++
++#ifdef CONSISTENT_DMA_SIZE
++#define DEFAULT_CONSISTENT_DMA_SIZE CONSISTENT_DMA_SIZE
++#else
++#define DEFAULT_CONSISTENT_DMA_SIZE SZ_2M
++#endif
++
++unsigned long consistent_base = CONSISTENT_END - DEFAULT_CONSISTENT_DMA_SIZE;
++
++void __init init_consistent_dma_size(unsigned long size)
++{
++ unsigned long base = CONSISTENT_END - ALIGN(size, SZ_2M);
++
++ BUG_ON(consistent_pte); /* Check we're called before DMA region init */
++ BUG_ON(base < VMALLOC_END);
++
++ /* Grow region to accommodate specified size */
++ if (base < consistent_base)
++ consistent_base = base;
++}
+
+ #include "vmregion.h"
+
+ static struct arm_vmregion_head consistent_head = {
+ .vm_lock = __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock),
+ .vm_list = LIST_HEAD_INIT(consistent_head.vm_list),
+- .vm_start = CONSISTENT_BASE,
+ .vm_end = CONSISTENT_END,
+ };
+
+@@ -153,7 +170,17 @@ static int __init consistent_init(void)
+ pmd_t *pmd;
+ pte_t *pte;
+ int i = 0;
+- u32 base = CONSISTENT_BASE;
++ unsigned long base = consistent_base;
++ unsigned long num_ptes = (CONSISTENT_END - base) >> PGDIR_SHIFT;
++
++ consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL);
++ if (!consistent_pte) {
++ pr_err("%s: no memory\n", __func__);
++ return -ENOMEM;
++ }
++
++ pr_debug("DMA memory: 0x%08lx - 0x%08lx:\n", base, CONSISTENT_END);
++ consistent_head.vm_start = base;
+
+ do {
+ pgd = pgd_offset(&init_mm, base);
+@@ -196,7 +223,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
+ size_t align;
+ int bit;
+
+- if (!consistent_pte[0]) {
++ if (!consistent_pte) {
+ printk(KERN_ERR "%s: not initialised\n", __func__);
+ dump_stack();
+ return NULL;
+diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
+index e038b49..db04a3e5 100644
+--- a/arch/arm/mm/init.c
++++ b/arch/arm/mm/init.c
+@@ -638,9 +638,6 @@ void __init mem_init(void)
+ " ITCM : 0x%08lx - 0x%08lx (%4ld kB)\n"
+ #endif
+ " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
+-#ifdef CONFIG_MMU
+- " DMA : 0x%08lx - 0x%08lx (%4ld MB)\n"
+-#endif
+ " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
+ " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n"
+ #ifdef CONFIG_HIGHMEM
+@@ -659,9 +656,6 @@ void __init mem_init(void)
+ MLK(ITCM_OFFSET, (unsigned long) itcm_end),
+ #endif
+ MLK(FIXADDR_START, FIXADDR_TOP),
+-#ifdef CONFIG_MMU
+- MLM(CONSISTENT_BASE, CONSISTENT_END),
+-#endif
+ MLM(VMALLOC_START, VMALLOC_END),
+ MLM(PAGE_OFFSET, (unsigned long)high_memory),
+ #ifdef CONFIG_HIGHMEM
+@@ -684,9 +678,6 @@ void __init mem_init(void)
+ * be detected at build time already.
+ */
+ #ifdef CONFIG_MMU
+- BUILD_BUG_ON(VMALLOC_END > CONSISTENT_BASE);
+- BUG_ON(VMALLOC_END > CONSISTENT_BASE);
+-
+ BUILD_BUG_ON(TASK_SIZE > MODULES_VADDR);
+ BUG_ON(TASK_SIZE > MODULES_VADDR);
+ #endif
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0017-mmc-add-a-card-hotplug-handler-context.patch b/patches.kzm9g/0017-mmc-add-a-card-hotplug-handler-context.patch
new file mode 100644
index 00000000000000..6b31c7b051fa93
--- /dev/null
+++ b/patches.kzm9g/0017-mmc-add-a-card-hotplug-handler-context.patch
@@ -0,0 +1,55 @@
+From 6ce12292dadb9a6064862a23cbda3ba144de06ff Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Sun, 25 Dec 2011 20:40:03 -0500
+Subject: mmc: add a card hotplug handler context
+
+SD/MMC controllers provide different card insertion and removal detection
+methods. On some of them the controller itself issues an interrupt, on
+others polling is used, on yet others auxiliary means are used for this
+purpose, e.g., a GPIO IRQ. Further, on some systems one of those methods
+can be chosen at driver probing time and configured in software. E.g., on
+some systems the SD/MMC controller card hot-plug detection pin can be
+configured either as a respective controller functions, or an IRQ-capable
+GPIO. To support such flexible configurations a card hot-plug context
+is added by this patch.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit b67e198073b2d2f16572f5fa77553fec14775f69)
+
+Conflicts:
+
+ include/linux/mmc/host.h
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/mmc/host.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
+index 1ee4424..786bd1f 100644
+--- a/include/linux/mmc/host.h
++++ b/include/linux/mmc/host.h
+@@ -144,6 +144,11 @@ struct mmc_host_ops {
+ struct mmc_card;
+ struct device;
+
++struct mmc_hotplug {
++ unsigned int irq;
++ void *handler_priv;
++};
++
+ struct mmc_host {
+ struct device *parent;
+ struct device class_dev;
+@@ -261,6 +266,7 @@ struct mmc_host {
+ int claim_cnt; /* "claim" nesting count */
+
+ struct delayed_work detect;
++ struct mmc_hotplug hotplug;
+
+ const struct mmc_bus_ops *bus_ops; /* current bus driver */
+ unsigned int bus_refs; /* reference counter */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0018-mmc-add-a-generic-GPIO-card-detect-helper.patch b/patches.kzm9g/0018-mmc-add-a-generic-GPIO-card-detect-helper.patch
new file mode 100644
index 00000000000000..e5901c4a52bbd5
--- /dev/null
+++ b/patches.kzm9g/0018-mmc-add-a-generic-GPIO-card-detect-helper.patch
@@ -0,0 +1,144 @@
+From e9d1edae3f34367442cab71753a0d1e55cbc439b Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Sun, 25 Dec 2011 21:36:02 +0100
+Subject: mmc: add a generic GPIO card-detect helper
+
+This patch adds a primitive helper to support card hotplug detection on
+platforms, where a GPIO, capable of producing interrupts, is used for
+detection of card-insertion and -removal events.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 349ab52446772a359bc7e7699cae3880d48fa5c9)
+
+Conflicts:
+
+ drivers/mmc/core/Makefile
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/core/Makefile | 1 +
+ drivers/mmc/core/cd-gpio.c | 74 +++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/mmc/cd-gpio.h | 19 ++++++++++++
+ 3 files changed, 94 insertions(+)
+ create mode 100644 drivers/mmc/core/cd-gpio.c
+ create mode 100644 include/linux/mmc/cd-gpio.h
+
+diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
+index 6395019..274b67c 100644
+--- a/drivers/mmc/core/Makefile
++++ b/drivers/mmc/core/Makefile
+@@ -9,4 +9,5 @@ mmc_core-y := core.o bus.o host.o \
+ sdio_cis.o sdio_io.o sdio_irq.o \
+ quirks.o
+
++mmc_core-$(CONFIG_GPIOLIB) += cd-gpio.o
+ mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
+diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c
+new file mode 100644
+index 0000000..082202a
+--- /dev/null
++++ b/drivers/mmc/core/cd-gpio.c
+@@ -0,0 +1,74 @@
++/*
++ * Generic GPIO card-detect helper
++ *
++ * Copyright (C) 2011, 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.
++ */
++
++#include <linux/err.h>
++#include <linux/gpio.h>
++#include <linux/interrupt.h>
++#include <linux/jiffies.h>
++#include <linux/mmc/host.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++
++struct mmc_cd_gpio {
++ unsigned int gpio;
++ char label[0];
++};
++
++static irqreturn_t mmc_cd_gpio_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,
++ unsigned int irq, unsigned long flags)
++{
++ size_t len = strlen(dev_name(host->parent)) + 4;
++ struct mmc_cd_gpio *cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL);
++ int ret;
++
++ if (!cd)
++ return -ENOMEM;
++
++ snprintf(cd->label, len, "%s cd", dev_name(host->parent));
++
++ ret = gpio_request_one(gpio, GPIOF_DIR_IN, cd->label);
++ if (ret < 0)
++ goto egpioreq;
++
++ ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt,
++ flags, cd->label, host);
++ if (ret < 0)
++ goto eirqreq;
++
++ cd->gpio = gpio;
++ host->hotplug.irq = irq;
++ host->hotplug.handler_priv = cd;
++
++ return 0;
++
++eirqreq:
++ gpio_free(gpio);
++egpioreq:
++ kfree(cd);
++ return ret;
++}
++EXPORT_SYMBOL(mmc_cd_gpio_request);
++
++void mmc_cd_gpio_free(struct mmc_host *host)
++{
++ struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
++
++ free_irq(host->hotplug.irq, host);
++ gpio_free(cd->gpio);
++ kfree(cd);
++}
++EXPORT_SYMBOL(mmc_cd_gpio_free);
+diff --git a/include/linux/mmc/cd-gpio.h b/include/linux/mmc/cd-gpio.h
+new file mode 100644
+index 0000000..a8e4697
+--- /dev/null
++++ b/include/linux/mmc/cd-gpio.h
+@@ -0,0 +1,19 @@
++/*
++ * Generic GPIO card-detect helper header
++ *
++ * Copyright (C) 2011, 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 MMC_CD_GPIO_H
++#define MMC_CD_GPIO_H
++
++struct mmc_host;
++int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio,
++ unsigned int irq, unsigned long flags);
++void mmc_cd_gpio_free(struct mmc_host *host);
++
++#endif
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0019-mmc-simplify-mmc_cd_gpio_request-by-removing-two-par.patch b/patches.kzm9g/0019-mmc-simplify-mmc_cd_gpio_request-by-removing-two-par.patch
new file mode 100644
index 00000000000000..8c85d61ce13f2c
--- /dev/null
+++ b/patches.kzm9g/0019-mmc-simplify-mmc_cd_gpio_request-by-removing-two-par.patch
@@ -0,0 +1,71 @@
+From 6859f92c44996d7337c5d3a1dbfbbb43af00a3c4 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 9 Feb 2012 22:57:07 +0100
+Subject: mmc: simplify mmc_cd_gpio_request() by removing two parameters
+
+Calculate the IRQ number, using gpio_to_irq() and use fixed flags: trigger
+on both edges. This makes two out of four arguments of the
+mmc_cd_gpio_request() function redundant.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit c9b0546a59293cabf54c85e1218da595af3274ff)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/core/cd-gpio.c | 13 +++++++++----
+ include/linux/mmc/cd-gpio.h | 3 +--
+ 2 files changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c
+index 082202a..29de31e 100644
+--- a/drivers/mmc/core/cd-gpio.c
++++ b/drivers/mmc/core/cd-gpio.c
+@@ -28,13 +28,17 @@ static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id)
+ return IRQ_HANDLED;
+ }
+
+-int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio,
+- unsigned int irq, unsigned long flags)
++int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio)
+ {
+ size_t len = strlen(dev_name(host->parent)) + 4;
+- struct mmc_cd_gpio *cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL);
++ struct mmc_cd_gpio *cd;
++ int irq = gpio_to_irq(gpio);
+ int ret;
+
++ if (irq < 0)
++ return irq;
++
++ cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL);
+ if (!cd)
+ return -ENOMEM;
+
+@@ -45,7 +49,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,
+- flags, cd->label, host);
++ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++ cd->label, host);
+ if (ret < 0)
+ goto eirqreq;
+
+diff --git a/include/linux/mmc/cd-gpio.h b/include/linux/mmc/cd-gpio.h
+index a8e4697..cefaba0 100644
+--- a/include/linux/mmc/cd-gpio.h
++++ b/include/linux/mmc/cd-gpio.h
+@@ -12,8 +12,7 @@
+ #define MMC_CD_GPIO_H
+
+ struct mmc_host;
+-int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio,
+- unsigned int irq, unsigned long flags);
++int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio);
+ void mmc_cd_gpio_free(struct mmc_host *host);
+
+ #endif
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0020-mmc-Standardize-header-file-inclusion-checks.patch b/patches.kzm9g/0020-mmc-Standardize-header-file-inclusion-checks.patch
new file mode 100644
index 00000000000000..560a4ac361d4b7
--- /dev/null
+++ b/patches.kzm9g/0020-mmc-Standardize-header-file-inclusion-checks.patch
@@ -0,0 +1,65 @@
+From 062b1cec7113d11cddbead31195d74707b9c5bb8 Mon Sep 17 00:00:00 2001
+From: "Robert P. J. Day" <rpjday@crashcourse.ca>
+Date: Fri, 27 May 2011 16:04:03 -0400
+Subject: mmc: Standardize header file inclusion checks.
+
+Standardize the checks for multiple MMC header file inclusion,
+including adding comments to terminating #endif's, and fixing
+one incorrect comment.
+
+Signed-off-by: Robert P. J. Day <rpjday@crashcourse.ca>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 100e918610b7487fa18db97b3879cd8d1fdd5974)
+
+Cherry-picked changes for:
+ include/linux/mmc/sh_mobile_sdhi.h
+ include/linux/mmc/tmio.h
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/mmc/sh_mobile_sdhi.h | 6 +++---
+ include/linux/mmc/tmio.h | 6 +++---
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
+index faf32b6..bd50b36 100644
+--- a/include/linux/mmc/sh_mobile_sdhi.h
++++ b/include/linux/mmc/sh_mobile_sdhi.h
+@@ -1,5 +1,5 @@
+-#ifndef __SH_MOBILE_SDHI_H__
+-#define __SH_MOBILE_SDHI_H__
++#ifndef LINUX_MMC_SH_MOBILE_SDHI_H
++#define LINUX_MMC_SH_MOBILE_SDHI_H
+
+ #include <linux/types.h>
+
+@@ -17,4 +17,4 @@ struct sh_mobile_sdhi_info {
+ int (*get_cd)(struct platform_device *pdev);
+ };
+
+-#endif /* __SH_MOBILE_SDHI_H__ */
++#endif /* LINUX_MMC_SH_MOBILE_SDHI_H */
+diff --git a/include/linux/mmc/tmio.h b/include/linux/mmc/tmio.h
+index 19490b9..551490f 100644
+--- a/include/linux/mmc/tmio.h
++++ b/include/linux/mmc/tmio.h
+@@ -12,8 +12,8 @@
+ *
+ * TC6393XB TC6391XB TC6387XB T7L66XB ASIC3
+ */
+-#ifndef _LINUX_MMC_TMIO_H_
+-#define _LINUX_MMC_TMIO_H_
++#ifndef LINUX_MMC_TMIO_H
++#define LINUX_MMC_TMIO_H
+
+ #define CTL_SD_CMD 0x00
+ #define CTL_ARG_REG 0x04
+@@ -60,4 +60,4 @@
+
+ #define TMIO_BBS 512 /* Boot block size */
+
+-#endif /* _LINUX_MMC_TMIO_H_ */
++#endif /* LINUX_MMC_TMIO_H */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0021-mmc-tmio-name-0xd8-as-CTL_DMA_ENABLE.patch b/patches.kzm9g/0021-mmc-tmio-name-0xd8-as-CTL_DMA_ENABLE.patch
new file mode 100644
index 00000000000000..f218a6469806da
--- /dev/null
+++ b/patches.kzm9g/0021-mmc-tmio-name-0xd8-as-CTL_DMA_ENABLE.patch
@@ -0,0 +1,48 @@
+From 92448997a8190180d93ffc4e48be91a99fca2c41 Mon Sep 17 00:00:00 2001
+From: Simon Horman <horms@verge.net.au>
+Date: Tue, 21 Jun 2011 08:00:08 +0900
+Subject: mmc: tmio: name 0xd8 as CTL_DMA_ENABLE
+
+This reflects at least the current usage of this register
+and I think it improves the readability of the code ever so slightly.
+
+Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Cc: Magnus Damm <magnus.damm@gmail.com>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 95c7348d948dc4832434ddfaeba804ac14732f02)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_dma.c | 2 +-
+ include/linux/mmc/tmio.h | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c
+index 25f1ad6..9c4da66 100644
+--- a/drivers/mmc/host/tmio_mmc_dma.c
++++ b/drivers/mmc/host/tmio_mmc_dma.c
+@@ -26,7 +26,7 @@ static void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
+ {
+ #if defined(CONFIG_SUPERH) || defined(CONFIG_ARCH_SHMOBILE)
+ /* Switch DMA mode on or off - SuperH specific? */
+- writew(enable ? 2 : 0, host->ctl + (0xd8 << host->bus_shift));
++ writew(enable ? 2 : 0, host->ctl + (CTL_DMA_ENABLE << host->bus_shift));
+ #endif
+ }
+
+diff --git a/include/linux/mmc/tmio.h b/include/linux/mmc/tmio.h
+index 551490f..3ae3776 100644
+--- a/include/linux/mmc/tmio.h
++++ b/include/linux/mmc/tmio.h
+@@ -30,6 +30,7 @@
+ #define CTL_TRANSACTION_CTL 0x34
+ #define CTL_SDIO_STATUS 0x36
+ #define CTL_SDIO_IRQ_MASK 0x38
++#define CTL_DMA_ENABLE 0xd8
+ #define CTL_RESET_SD 0xe0
+ #define CTL_SDIO_REGS 0x100
+ #define CTL_CLK_AND_WAIT_CTL 0x138
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0022-mmc-tmio-Share-register-access-functions.patch b/patches.kzm9g/0022-mmc-tmio-Share-register-access-functions.patch
new file mode 100644
index 00000000000000..05bfa4654dee85
--- /dev/null
+++ b/patches.kzm9g/0022-mmc-tmio-Share-register-access-functions.patch
@@ -0,0 +1,130 @@
+From 92d89dd2b2076ea2d981596de7753ce0ded0fb17 Mon Sep 17 00:00:00 2001
+From: Simon Horman <horms@verge.net.au>
+Date: Tue, 21 Jun 2011 08:00:09 +0900
+Subject: mmc: tmio: Share register access functions
+
+Move register access functions into a shared header.
+Use sd_ctrl_write16 in tmio_mmc_dma.c:tmio_mmc_enable_dma().
+
+Other than avoiding (trivial) open-coding, the motivation for
+this is to allow platform-hooks in access functions to
+be applied across all applicable accesses.
+
+Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Cc: Magnus Damm <magnus.damm@gmail.com>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit a11862d3389d4304211eed0758f510d5e573f93c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc.h | 35 +++++++++++++++++++++++++++++++++++
+ drivers/mmc/host/tmio_mmc_dma.c | 2 +-
+ drivers/mmc/host/tmio_mmc_pio.c | 34 ----------------------------------
+ 3 files changed, 36 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index 8260bc2..0c22df0 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -134,4 +134,39 @@ int tmio_mmc_host_resume(struct device *dev);
+ int tmio_mmc_host_runtime_suspend(struct device *dev);
+ int tmio_mmc_host_runtime_resume(struct device *dev);
+
++static inline u16 sd_ctrl_read16(struct tmio_mmc_host *host, int addr)
++{
++ return readw(host->ctl + (addr << host->bus_shift));
++}
++
++static inline void sd_ctrl_read16_rep(struct tmio_mmc_host *host, int addr,
++ u16 *buf, int count)
++{
++ readsw(host->ctl + (addr << host->bus_shift), buf, count);
++}
++
++static inline u32 sd_ctrl_read32(struct tmio_mmc_host *host, int addr)
++{
++ return readw(host->ctl + (addr << host->bus_shift)) |
++ readw(host->ctl + ((addr + 2) << host->bus_shift)) << 16;
++}
++
++static inline void sd_ctrl_write16(struct tmio_mmc_host *host, int addr, u16 val)
++{
++ writew(val, host->ctl + (addr << host->bus_shift));
++}
++
++static inline void sd_ctrl_write16_rep(struct tmio_mmc_host *host, int addr,
++ u16 *buf, int count)
++{
++ writesw(host->ctl + (addr << host->bus_shift), buf, count);
++}
++
++static inline void sd_ctrl_write32(struct tmio_mmc_host *host, int addr, u32 val)
++{
++ writew(val, host->ctl + (addr << host->bus_shift));
++ writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift));
++}
++
++
+ #endif
+diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c
+index 9c4da66..f24a029 100644
+--- a/drivers/mmc/host/tmio_mmc_dma.c
++++ b/drivers/mmc/host/tmio_mmc_dma.c
+@@ -26,7 +26,7 @@ static void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
+ {
+ #if defined(CONFIG_SUPERH) || defined(CONFIG_ARCH_SHMOBILE)
+ /* Switch DMA mode on or off - SuperH specific? */
+- writew(enable ? 2 : 0, host->ctl + (CTL_DMA_ENABLE << host->bus_shift));
++ sd_ctrl_write16(host, enable ? 2 : 0, CTL_DMA_ENABLE);
+ #endif
+ }
+
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index 0b09e82..4d17807 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -46,40 +46,6 @@
+
+ #include "tmio_mmc.h"
+
+-static u16 sd_ctrl_read16(struct tmio_mmc_host *host, int addr)
+-{
+- return readw(host->ctl + (addr << host->bus_shift));
+-}
+-
+-static void sd_ctrl_read16_rep(struct tmio_mmc_host *host, int addr,
+- u16 *buf, int count)
+-{
+- readsw(host->ctl + (addr << host->bus_shift), buf, count);
+-}
+-
+-static u32 sd_ctrl_read32(struct tmio_mmc_host *host, int addr)
+-{
+- return readw(host->ctl + (addr << host->bus_shift)) |
+- readw(host->ctl + ((addr + 2) << host->bus_shift)) << 16;
+-}
+-
+-static void sd_ctrl_write16(struct tmio_mmc_host *host, int addr, u16 val)
+-{
+- writew(val, host->ctl + (addr << host->bus_shift));
+-}
+-
+-static void sd_ctrl_write16_rep(struct tmio_mmc_host *host, int addr,
+- u16 *buf, int count)
+-{
+- writesw(host->ctl + (addr << host->bus_shift), buf, count);
+-}
+-
+-static void sd_ctrl_write32(struct tmio_mmc_host *host, int addr, u32 val)
+-{
+- writew(val, host->ctl + (addr << host->bus_shift));
+- writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift));
+-}
+-
+ void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
+ {
+ u32 mask = sd_ctrl_read32(host, CTL_IRQ_MASK) & ~(i & TMIO_MASK_IRQ);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0023-mmc-sdhi-Add-write16_hook.patch b/patches.kzm9g/0023-mmc-sdhi-Add-write16_hook.patch
new file mode 100644
index 00000000000000..ae80b0eede9db1
--- /dev/null
+++ b/patches.kzm9g/0023-mmc-sdhi-Add-write16_hook.patch
@@ -0,0 +1,149 @@
+From 337f49667f11fbdb1bcd1ca51816c812de84123f Mon Sep 17 00:00:00 2001
+From: Simon Horman <horms@verge.net.au>
+Date: Tue, 21 Jun 2011 08:00:10 +0900
+Subject: mmc: sdhi: Add write16_hook
+
+Some controllers require waiting for the bus to become idle
+before writing to some registers. I have implemented this
+by adding a hook to sd_ctrl_write16() and implementing
+a hook for SDHI which waits for the bus to become idle.
+
+Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Cc: Magnus Damm <magnus.damm@gmail.com>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 973ed3af1a570612771ed10dec6506c757767668)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mobile_sdhi.c | 36 ++++++++++++++++++++++++++++++++++++
+ drivers/mmc/host/tmio_mmc.h | 5 +++++
+ include/linux/mfd/tmio.h | 8 ++++++++
+ include/linux/mmc/tmio.h | 1 +
+ 4 files changed, 50 insertions(+)
+
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index ce500f0..774f643 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -26,6 +26,7 @@
+ #include <linux/mmc/sh_mobile_sdhi.h>
+ #include <linux/mfd/tmio.h>
+ #include <linux/sh_dma.h>
++#include <linux/delay.h>
+
+ #include "tmio_mmc.h"
+
+@@ -55,6 +56,39 @@ static int sh_mobile_sdhi_get_cd(struct platform_device *pdev)
+ return -ENOSYS;
+ }
+
++static int sh_mobile_sdhi_wait_idle(struct tmio_mmc_host *host)
++{
++ int timeout = 1000;
++
++ while (--timeout && !(sd_ctrl_read16(host, CTL_STATUS2) & (1 << 13)))
++ udelay(1);
++
++ if (!timeout) {
++ dev_warn(host->pdata->dev, "timeout waiting for SD bus idle\n");
++ return -EBUSY;
++ }
++
++ return 0;
++}
++
++static int sh_mobile_sdhi_write16_hook(struct tmio_mmc_host *host, int addr)
++{
++ switch (addr)
++ {
++ case CTL_SD_CMD:
++ case CTL_STOP_INTERNAL_ACTION:
++ case CTL_XFER_BLK_COUNT:
++ case CTL_SD_CARD_CLK_CTL:
++ case CTL_SD_XFER_LEN:
++ case CTL_SD_MEM_CARD_OPT:
++ case CTL_TRANSACTION_CTL:
++ case CTL_DMA_ENABLE:
++ return sh_mobile_sdhi_wait_idle(host);
++ }
++
++ return 0;
++}
++
+ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+ {
+ struct sh_mobile_sdhi *priv;
+@@ -86,6 +120,8 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+ 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;
++ if (mmc_data->flags & TMIO_MMC_HAS_IDLE_WAIT)
++ mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
+ mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
+ if (p) {
+ mmc_data->flags = p->tmio_flags;
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index 0c22df0..211ef6e 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -153,6 +153,11 @@ static inline u32 sd_ctrl_read32(struct tmio_mmc_host *host, int addr)
+
+ static inline void sd_ctrl_write16(struct tmio_mmc_host *host, int addr, u16 val)
+ {
++ /* If there is a hook and it returns non-zero then there
++ * is an error and the write should be skipped
++ */
++ if (host->pdata->write16_hook && host->pdata->write16_hook(host, addr))
++ return;
+ writew(val, host->ctl + (addr << host->bus_shift));
+ }
+
+diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
+index 5a90266..0dc9804 100644
+--- a/include/linux/mfd/tmio.h
++++ b/include/linux/mfd/tmio.h
+@@ -68,6 +68,11 @@
+ * controller and report the event to the driver.
+ */
+ #define TMIO_MMC_HAS_COLD_CD (1 << 3)
++/*
++ * Some controllers require waiting for the SD bus to become
++ * idle before writing to some registers.
++ */
++#define TMIO_MMC_HAS_IDLE_WAIT (1 << 4)
+
+ int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base);
+ int tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base);
+@@ -80,6 +85,8 @@ struct tmio_mmc_dma {
+ int alignment_shift;
+ };
+
++struct tmio_mmc_host;
++
+ /*
+ * data for the MMC controller
+ */
+@@ -94,6 +101,7 @@ struct tmio_mmc_data {
+ void (*set_pwr)(struct platform_device *host, int state);
+ 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);
+ };
+
+ static inline void tmio_mmc_cd_wakeup(struct tmio_mmc_data *pdata)
+diff --git a/include/linux/mmc/tmio.h b/include/linux/mmc/tmio.h
+index 3ae3776..a1c1f32 100644
+--- a/include/linux/mmc/tmio.h
++++ b/include/linux/mmc/tmio.h
+@@ -21,6 +21,7 @@
+ #define CTL_XFER_BLK_COUNT 0xa
+ #define CTL_RESPONSE 0x0c
+ #define CTL_STATUS 0x1c
++#define CTL_STATUS2 0x1e
+ #define CTL_IRQ_MASK 0x20
+ #define CTL_SD_CARD_CLK_CTL 0x24
+ #define CTL_SD_XFER_LEN 0x26
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0024-mmc-tmio-Fix-race-condition-resulting-in-spurious-in.patch b/patches.kzm9g/0024-mmc-tmio-Fix-race-condition-resulting-in-spurious-in.patch
new file mode 100644
index 00000000000000..3a2ce6eed2ab07
--- /dev/null
+++ b/patches.kzm9g/0024-mmc-tmio-Fix-race-condition-resulting-in-spurious-in.patch
@@ -0,0 +1,132 @@
+From 95c27915c3f1955092a6cc2e5900a58aa2dfc7c0 Mon Sep 17 00:00:00 2001
+From: Paul Parsons <lost.distance@yahoo.com>
+Date: Sun, 15 May 2011 13:24:41 +0000
+Subject: mmc: tmio: Fix race condition resulting in spurious interrupts
+
+There is a race condition in the tmio_mmc_irq() interrupt handler,
+caused by the presence of a while loop, which results in warnings of
+spurious interrupts. This was found on an HP iPAQ hx4700 whose HTC
+ASIC3 reportedly incorporates the Toshiba TC6380AF controller.
+
+Towards the end of a multiple read (CMD18) operation the handler clears
+the final RXRDY status bit in the first loop iteration, sees the DATAEND
+status bit at the bottom of the loop, and so clears the DATAEND status
+bit in the second loop iteration. However the DATAEND interrupt is still
+queued in the system somewhere and can't be delivered until the handler
+has returned. This second interrupt is then reported as spurious in the
+next call to the handler. Likewise for single read (CMD17) operations.
+And something similar occurs for multiple write (CMD25) and single write
+(CMD24) operations, where CMDRESPEND and TXRQ status bits are cleared in
+a single call.
+
+In these cases the interrupt handler clears two separate interrupts when
+it should only clear the one interrupt for which it was invoked. The fix
+is to remove the while loop.
+
+Signed-off-by: Paul Parsons <lost.distance@yahoo.com>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit e312eb1e66e4357000e4e7438849d5a5fd738219)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_pio.c | 76 +++++++++++++++++------------------------
+ 1 file changed, 32 insertions(+), 44 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index 4d17807..f7dd3b1 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -569,58 +569,46 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
+ pr_debug_status(status);
+ pr_debug_status(ireg);
+
+- if (!ireg) {
+- tmio_mmc_disable_mmc_irqs(host, status & ~irq_mask);
+-
+- pr_warning("tmio_mmc: Spurious irq, disabling! "
+- "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg);
+- pr_debug_status(status);
+-
++ /* Card insert / remove attempts */
++ if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
++ tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT |
++ TMIO_STAT_CARD_REMOVE);
++ mmc_detect_change(host->mmc, msecs_to_jiffies(100));
+ goto out;
+ }
+
+- while (ireg) {
+- /* Card insert / remove attempts */
+- if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
+- tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT |
+- TMIO_STAT_CARD_REMOVE);
+- mmc_detect_change(host->mmc, msecs_to_jiffies(100));
+- }
+-
+- /* CRC and other errors */
+-/* if (ireg & TMIO_STAT_ERR_IRQ)
+- * handled |= tmio_error_irq(host, irq, stat);
++ /* CRC and other errors */
++/* if (ireg & TMIO_STAT_ERR_IRQ)
++ * handled |= tmio_error_irq(host, irq, stat);
+ */
+
+- /* Command completion */
+- if (ireg & (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT)) {
+- tmio_mmc_ack_mmc_irqs(host,
+- TMIO_STAT_CMDRESPEND |
+- TMIO_STAT_CMDTIMEOUT);
+- tmio_mmc_cmd_irq(host, status);
+- }
+-
+- /* Data transfer */
+- if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) {
+- tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ);
+- tmio_mmc_pio_irq(host);
+- }
+-
+- /* Data transfer completion */
+- if (ireg & TMIO_STAT_DATAEND) {
+- tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_DATAEND);
+- tmio_mmc_data_irq(host);
+- }
++ /* Command completion */
++ if (ireg & (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT)) {
++ tmio_mmc_ack_mmc_irqs(host,
++ TMIO_STAT_CMDRESPEND |
++ TMIO_STAT_CMDTIMEOUT);
++ tmio_mmc_cmd_irq(host, status);
++ goto out;
++ }
+
+- /* Check status - keep going until we've handled it all */
+- status = sd_ctrl_read32(host, CTL_STATUS);
+- irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK);
+- ireg = status & TMIO_MASK_IRQ & ~irq_mask;
++ /* Data transfer */
++ if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) {
++ tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ);
++ tmio_mmc_pio_irq(host);
++ goto out;
++ }
+
+- pr_debug("Status at end of loop: %08x\n", status);
+- pr_debug_status(status);
++ /* Data transfer completion */
++ if (ireg & TMIO_STAT_DATAEND) {
++ tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_DATAEND);
++ tmio_mmc_data_irq(host);
++ goto out;
+ }
+- pr_debug("MMC IRQ end\n");
++
++ pr_warning("tmio_mmc: Spurious irq, disabling! "
++ "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg);
++ pr_debug_status(status);
++ tmio_mmc_disable_mmc_irqs(host, status & ~irq_mask);
+
+ out:
+ return IRQ_HANDLED;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0025-mmc-tmio-fix-recursive-spinlock-don-t-schedule-with-.patch b/patches.kzm9g/0025-mmc-tmio-fix-recursive-spinlock-don-t-schedule-with-.patch
new file mode 100644
index 00000000000000..30f595ec588b1b
--- /dev/null
+++ b/patches.kzm9g/0025-mmc-tmio-fix-recursive-spinlock-don-t-schedule-with-.patch
@@ -0,0 +1,167 @@
+From ea988b80417af51f72b175c2ec36c82b41b08b5d Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 14 Jul 2011 12:12:38 +0200
+Subject: mmc: tmio: fix recursive spinlock, don't schedule with interrupts
+ disabled
+
+Calling mmc_request_done() under a spinlock with interrupts disabled
+leads to a recursive spin-lock on request retry path and to
+scheduling in atomic context. This patch fixes both these problems
+by moving mmc_request_done() to the scheduler workqueue.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit b9269fdd4f61aa4d185c982b0f84a3e7b7ccb4d2)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc.h | 6 +++++-
+ drivers/mmc/host/tmio_mmc_pio.c | 35 +++++++++++++++++++++++++++++------
+ 2 files changed, 34 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index 211ef6e..f0d7c43 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -18,6 +18,7 @@
+
+ #include <linux/highmem.h>
+ #include <linux/mmc/tmio.h>
++#include <linux/mutex.h>
+ #include <linux/pagemap.h>
+ #include <linux/spinlock.h>
+
+@@ -73,8 +74,11 @@ struct tmio_mmc_host {
+
+ /* Track lost interrupts */
+ struct delayed_work delayed_reset_work;
+- spinlock_t lock;
++ struct work_struct done;
++
++ spinlock_t lock; /* protect host private data */
+ unsigned long last_req_ts;
++ struct mutex ios_lock; /* protect set_ios() context */
+ };
+
+ int tmio_mmc_host_probe(struct tmio_mmc_host **host,
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index f7dd3b1..a2f76ad 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -250,10 +250,16 @@ static void tmio_mmc_reset_work(struct work_struct *work)
+ /* called with host->lock held, interrupts disabled */
+ static void tmio_mmc_finish_request(struct tmio_mmc_host *host)
+ {
+- struct mmc_request *mrq = host->mrq;
++ struct mmc_request *mrq;
++ unsigned long flags;
+
+- if (!mrq)
++ spin_lock_irqsave(&host->lock, flags);
++
++ mrq = host->mrq;
++ if (IS_ERR_OR_NULL(mrq)) {
++ spin_unlock_irqrestore(&host->lock, flags);
+ return;
++ }
+
+ host->cmd = NULL;
+ host->data = NULL;
+@@ -262,11 +268,18 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host)
+ cancel_delayed_work(&host->delayed_reset_work);
+
+ host->mrq = NULL;
++ spin_unlock_irqrestore(&host->lock, flags);
+
+- /* FIXME: mmc_request_done() can schedule! */
+ mmc_request_done(host->mmc, mrq);
+ }
+
++static void tmio_mmc_done_work(struct work_struct *work)
++{
++ struct tmio_mmc_host *host = container_of(work, struct tmio_mmc_host,
++ done);
++ tmio_mmc_finish_request(host);
++}
++
+ /* These are the bitmasks the tmio chip requires to implement the MMC response
+ * types. Note that R1 and R6 are the same in this scheme. */
+ #define APP_CMD 0x0040
+@@ -433,7 +446,7 @@ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host)
+ BUG();
+ }
+
+- tmio_mmc_finish_request(host);
++ schedule_work(&host->done);
+ }
+
+ static void tmio_mmc_data_irq(struct tmio_mmc_host *host)
+@@ -523,7 +536,7 @@ static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host,
+ tasklet_schedule(&host->dma_issue);
+ }
+ } else {
+- tmio_mmc_finish_request(host);
++ schedule_work(&host->done);
+ }
+
+ out:
+@@ -573,7 +586,8 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
+ if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
+ tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT |
+ TMIO_STAT_CARD_REMOVE);
+- mmc_detect_change(host->mmc, msecs_to_jiffies(100));
++ if (!work_pending(&host->mmc->detect.work))
++ mmc_detect_change(host->mmc, msecs_to_jiffies(100));
+ goto out;
+ }
+
+@@ -703,6 +717,8 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ struct tmio_mmc_data *pdata = host->pdata;
+ unsigned long flags;
+
++ mutex_lock(&host->ios_lock);
++
+ spin_lock_irqsave(&host->lock, flags);
+ if (host->mrq) {
+ if (IS_ERR(host->mrq)) {
+@@ -718,6 +734,8 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ host->mrq->cmd->opcode, host->last_req_ts, jiffies);
+ }
+ spin_unlock_irqrestore(&host->lock, flags);
++
++ mutex_unlock(&host->ios_lock);
+ return;
+ }
+
+@@ -771,6 +789,8 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ current->comm, task_pid_nr(current),
+ ios->clock, ios->power_mode);
+ host->mrq = NULL;
++
++ mutex_unlock(&host->ios_lock);
+ }
+
+ static int tmio_mmc_get_ro(struct mmc_host *mmc)
+@@ -867,9 +887,11 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ tmio_mmc_enable_sdio_irq(mmc, 0);
+
+ spin_lock_init(&_host->lock);
++ mutex_init(&_host->ios_lock);
+
+ /* Init delayed work for request timeouts */
+ INIT_DELAYED_WORK(&_host->delayed_reset_work, tmio_mmc_reset_work);
++ INIT_WORK(&_host->done, tmio_mmc_done_work);
+
+ /* See if we also get DMA */
+ tmio_mmc_request_dma(_host, pdata);
+@@ -917,6 +939,7 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
+ pm_runtime_get_sync(&pdev->dev);
+
+ mmc_remove_host(host->mmc);
++ cancel_work_sync(&host->done);
+ cancel_delayed_work_sync(&host->delayed_reset_work);
+ tmio_mmc_release_dma(host);
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0026-mmc-tmio-maximize-power-saving.patch b/patches.kzm9g/0026-mmc-tmio-maximize-power-saving.patch
new file mode 100644
index 00000000000000..5e9aaa562be870
--- /dev/null
+++ b/patches.kzm9g/0026-mmc-tmio-maximize-power-saving.patch
@@ -0,0 +1,172 @@
+From b3250d284d1eafa128d1955c4142697d9227e9e6 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 14 Jul 2011 12:16:59 +0200
+Subject: mmc: tmio: maximize power saving
+
+This patch uses runtime PM to allow the system to power down the MMC
+controller, when the MMC closk is switched off.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 71d111cd34ee119c93d056ad9e84dc0e82367f82)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc.h | 2 ++
+ drivers/mmc/host/tmio_mmc_pio.c | 64 ++++++++++++++++++++++++-----------------
+ 2 files changed, 39 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index f0d7c43..ba0d8e6 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -53,6 +53,8 @@ struct tmio_mmc_host {
+ void (*set_clk_div)(struct platform_device *host, int state);
+
+ int pm_error;
++ /* recognise system-wide suspend in runtime PM methods */
++ bool pm_global;
+
+ /* pio related stuff */
+ struct scatterlist *sg_ptr;
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index a2f76ad..221ffb7 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -546,6 +546,7 @@ out:
+ irqreturn_t tmio_mmc_irq(int irq, void *devid)
+ {
+ struct tmio_mmc_host *host = devid;
++ struct mmc_host *mmc = host->mmc;
+ struct tmio_mmc_data *pdata = host->pdata;
+ unsigned int ireg, irq_mask, status;
+ unsigned int sdio_ireg, sdio_irq_mask, sdio_status;
+@@ -567,13 +568,13 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
+ if (sdio_ireg && !host->sdio_irq_enabled) {
+ pr_warning("tmio_mmc: Spurious SDIO IRQ, disabling! 0x%04x 0x%04x 0x%04x\n",
+ sdio_status, sdio_irq_mask, sdio_ireg);
+- tmio_mmc_enable_sdio_irq(host->mmc, 0);
++ tmio_mmc_enable_sdio_irq(mmc, 0);
+ goto out;
+ }
+
+- if (host->mmc->caps & MMC_CAP_SDIO_IRQ &&
++ if (mmc->caps & MMC_CAP_SDIO_IRQ &&
+ sdio_ireg & TMIO_SDIO_STAT_IOIRQ)
+- mmc_signal_sdio_irq(host->mmc);
++ mmc_signal_sdio_irq(mmc);
+
+ if (sdio_ireg)
+ goto out;
+@@ -586,7 +587,9 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
+ if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
+ tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT |
+ TMIO_STAT_CARD_REMOVE);
+- if (!work_pending(&host->mmc->detect.work))
++ if ((((ireg & TMIO_STAT_CARD_REMOVE) && mmc->card) ||
++ ((ireg & TMIO_STAT_CARD_INSERT) && !mmc->card)) &&
++ !work_pending(&mmc->detect.work))
+ mmc_detect_change(host->mmc, msecs_to_jiffies(100));
+ goto out;
+ }
+@@ -743,33 +746,30 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+
+ spin_unlock_irqrestore(&host->lock, flags);
+
+- if (ios->clock)
+- tmio_mmc_set_clock(host, ios->clock);
+-
+- /* Power sequence - OFF -> UP -> ON */
+- if (ios->power_mode == MMC_POWER_UP) {
+- if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) && !pdata->power) {
++ /*
++ * pdata->power == false only if COLD_CD is available, otherwise only
++ * in short time intervals during probing or resuming
++ */
++ if (ios->power_mode == MMC_POWER_ON && ios->clock) {
++ if (!pdata->power) {
+ pm_runtime_get_sync(&host->pdev->dev);
+ pdata->power = true;
+ }
++ tmio_mmc_set_clock(host, ios->clock);
+ /* power up SD bus */
+ if (host->set_pwr)
+ host->set_pwr(host->pdev, 1);
+- } else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) {
+- /* power down SD bus */
+- if (ios->power_mode == MMC_POWER_OFF) {
+- if (host->set_pwr)
+- host->set_pwr(host->pdev, 0);
+- if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) &&
+- pdata->power) {
+- pdata->power = false;
+- pm_runtime_put(&host->pdev->dev);
+- }
+- }
+- tmio_mmc_clk_stop(host);
+- } else {
+ /* start bus clock */
+ tmio_mmc_clk_start(host);
++ } else if (ios->power_mode != MMC_POWER_UP) {
++ if (host->set_pwr)
++ host->set_pwr(host->pdev, 0);
++ if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) &&
++ pdata->power) {
++ pdata->power = false;
++ pm_runtime_put(&host->pdev->dev);
++ }
++ tmio_mmc_clk_stop(host);
+ }
+
+ switch (ios->bus_width) {
+@@ -897,8 +897,10 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ tmio_mmc_request_dma(_host, pdata);
+
+ /* We have to keep the device powered for its card detection to work */
+- if (!(pdata->flags & TMIO_MMC_HAS_COLD_CD))
++ if (!(pdata->flags & TMIO_MMC_HAS_COLD_CD)) {
++ pdata->power = true;
+ pm_runtime_get_noresume(&pdev->dev);
++ }
+
+ mmc_add_host(mmc);
+
+@@ -975,11 +977,16 @@ int tmio_mmc_host_resume(struct device *dev)
+ /* The MMC core will perform the complete set up */
+ host->pdata->power = false;
+
++ host->pm_global = true;
+ if (!host->pm_error)
+ pm_runtime_get_sync(dev);
+
+- tmio_mmc_reset(mmc_priv(mmc));
+- tmio_mmc_request_dma(host, host->pdata);
++ if (host->pm_global) {
++ /* Runtime PM resume callback didn't run */
++ tmio_mmc_reset(host);
++ tmio_mmc_request_dma(host, host->pdata);
++ host->pm_global = false;
++ }
+
+ return mmc_resume_host(mmc);
+ }
+@@ -1000,12 +1007,15 @@ int tmio_mmc_host_runtime_resume(struct device *dev)
+ struct tmio_mmc_data *pdata = host->pdata;
+
+ tmio_mmc_reset(host);
++ tmio_mmc_request_dma(host, host->pdata);
+
+ if (pdata->power) {
+ /* Only entered after a card-insert interrupt */
+- tmio_mmc_set_ios(mmc, &mmc->ios);
++ if (!mmc->card)
++ tmio_mmc_set_ios(mmc, &mmc->ios);
+ mmc_detect_change(mmc, msecs_to_jiffies(100));
+ }
++ host->pm_global = false;
+
+ return 0;
+ }
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0027-mmc-tmio-fix-a-recently-introduced-bug-in-DMA-code.patch b/patches.kzm9g/0027-mmc-tmio-fix-a-recently-introduced-bug-in-DMA-code.patch
new file mode 100644
index 00000000000000..283da7f0c71e0e
--- /dev/null
+++ b/patches.kzm9g/0027-mmc-tmio-fix-a-recently-introduced-bug-in-DMA-code.patch
@@ -0,0 +1,34 @@
+From c87079bc67dfd1e0aac3f5acf682085f6b65d266 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 14 Jul 2011 18:39:06 +0200
+Subject: mmc: tmio: fix a recently introduced bug in DMA code
+
+A recent commit "mmc: tmio: Share register access functions" has swapped
+arguments of a macro and broken DMA with TMIO MMC. This patch fixes the
+arguments back.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 332bdb506f800d177f6657247347a253dd5b5be8)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_dma.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c
+index f24a029..7e86662 100644
+--- a/drivers/mmc/host/tmio_mmc_dma.c
++++ b/drivers/mmc/host/tmio_mmc_dma.c
+@@ -26,7 +26,7 @@ static void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
+ {
+ #if defined(CONFIG_SUPERH) || defined(CONFIG_ARCH_SHMOBILE)
+ /* Switch DMA mode on or off - SuperH specific? */
+- sd_ctrl_write16(host, enable ? 2 : 0, CTL_DMA_ENABLE);
++ sd_ctrl_write16(host, CTL_DMA_ENABLE, enable ? 2 : 0);
+ #endif
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0028-mmc-tmio-fix-a-deadlock.patch b/patches.kzm9g/0028-mmc-tmio-fix-a-deadlock.patch
new file mode 100644
index 00000000000000..2b82b73c9d48c4
--- /dev/null
+++ b/patches.kzm9g/0028-mmc-tmio-fix-a-deadlock.patch
@@ -0,0 +1,85 @@
+From 3d74cc1d62a8973298e5f559517f1f9cc362cfe4 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 14 Jul 2011 18:39:10 +0200
+Subject: mmc: tmio: fix a deadlock
+
+Currently the tmio-mmc driver contains a recursive runtime PM method
+invocation, which leads to a deadlock on a mutex. Avoid it by taking
+care not to request DMA too early.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 162f43e31c5a376ec16336e5d0ac973373d54c89)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc.h | 5 +++++
+ drivers/mmc/host/tmio_mmc_dma.c | 5 ++++-
+ drivers/mmc/host/tmio_mmc_pio.c | 4 ++--
+ 3 files changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index ba0d8e6..087d880 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -109,6 +109,7 @@ static inline void tmio_mmc_kunmap_atomic(struct scatterlist *sg,
+
+ #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
+ void tmio_mmc_start_dma(struct tmio_mmc_host *host, struct mmc_data *data);
++void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable);
+ void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata);
+ void tmio_mmc_release_dma(struct tmio_mmc_host *host);
+ #else
+@@ -117,6 +118,10 @@ static inline void tmio_mmc_start_dma(struct tmio_mmc_host *host,
+ {
+ }
+
++static inline void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
++{
++}
++
+ static inline void tmio_mmc_request_dma(struct tmio_mmc_host *host,
+ struct tmio_mmc_data *pdata)
+ {
+diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c
+index 7e86662..2aa616d 100644
+--- a/drivers/mmc/host/tmio_mmc_dma.c
++++ b/drivers/mmc/host/tmio_mmc_dma.c
+@@ -22,8 +22,11 @@
+
+ #define TMIO_MMC_MIN_DMA_LEN 8
+
+-static void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
++void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
+ {
++ if (!host->chan_tx || !host->chan_rx)
++ return;
++
+ #if defined(CONFIG_SUPERH) || defined(CONFIG_ARCH_SHMOBILE)
+ /* Switch DMA mode on or off - SuperH specific? */
+ sd_ctrl_write16(host, CTL_DMA_ENABLE, enable ? 2 : 0);
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index 221ffb7..1f16357 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -984,7 +984,7 @@ int tmio_mmc_host_resume(struct device *dev)
+ if (host->pm_global) {
+ /* Runtime PM resume callback didn't run */
+ tmio_mmc_reset(host);
+- tmio_mmc_request_dma(host, host->pdata);
++ tmio_mmc_enable_dma(host, true);
+ host->pm_global = false;
+ }
+
+@@ -1007,7 +1007,7 @@ int tmio_mmc_host_runtime_resume(struct device *dev)
+ struct tmio_mmc_data *pdata = host->pdata;
+
+ tmio_mmc_reset(host);
+- tmio_mmc_request_dma(host, host->pdata);
++ tmio_mmc_enable_dma(host, true);
+
+ if (pdata->power) {
+ /* Only entered after a card-insert interrupt */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0029-net-remove-mm.h-inclusion-from-netdevice.h.patch b/patches.kzm9g/0029-net-remove-mm.h-inclusion-from-netdevice.h.patch
new file mode 100644
index 00000000000000..66dc4806ea641d
--- /dev/null
+++ b/patches.kzm9g/0029-net-remove-mm.h-inclusion-from-netdevice.h.patch
@@ -0,0 +1,109 @@
+From f079e5f73032b58caef775a101a141f45fed0915 Mon Sep 17 00:00:00 2001
+From: Alexey Dobriyan <adobriyan@gmail.com>
+Date: Thu, 16 Jun 2011 11:01:34 +0000
+Subject: net: remove mm.h inclusion from netdevice.h
+
+Remove linux/mm.h inclusion from netdevice.h -- it's unused (I've checked manually).
+
+To prevent mm.h inclusion via other channels also extract "enum dma_data_direction"
+definition into separate header. This tiny piece is what gluing netdevice.h with mm.h
+via "netdevice.h => dmaengine.h => dma-mapping.h => scatterlist.h => mm.h".
+Removal of mm.h from scatterlist.h was tried and was found not feasible
+on most archs, so the link was cutoff earlier.
+
+Hope people are OK with tiny include file.
+
+Note, that mm_types.h is still dragged in, but it is a separate story.
+
+Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+(cherry picked from commit b7f080cfe223b3b7424872639d153695615a9255)
+
+Conflicts:
+
+ arch/arm/mach-davinci/board-mityomapl138.c
+ arch/arm/mach-davinci/dm646x.c
+ arch/arm/mach-davinci/pm.c
+ arch/arm/mach-imx/dma-v1.c
+ arch/arm/mach-imx/mach-mx31_3ds.c
+ arch/arm/mach-iop13xx/setup.c
+ arch/arm/mach-mxs/devices/platform-auart.c
+ arch/arm/mach-mxs/devices/platform-dma.c
+ arch/arm/mach-mxs/devices/platform-fec.c
+ arch/arm/plat-mxc/devices/platform-fec.c
+ arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c
+ arch/arm/plat-mxc/devices/platform-imx-fb.c
+ arch/arm/plat-mxc/devices/platform-ipu-core.c
+ arch/arm/plat-mxc/devices/platform-mxc-ehci.c
+ arch/arm/plat-mxc/devices/platform-mxc-mmc.c
+ arch/arm/plat-nomadik/include/plat/ste_dma40.h
+ arch/x86/kernel/tboot.c
+ crypto/async_tx/raid6test.c
+ drivers/dma/coh901318.c
+ drivers/dma/dmaengine.c
+ drivers/dma/dmatest.c
+ drivers/dma/ipu/ipu_idmac.c
+ drivers/dma/ste_dma40.c
+ drivers/media/dvb/mantis/mantis_ca.c
+ drivers/media/dvb/mantis/mantis_evm.c
+ drivers/media/dvb/mantis/mantis_hif.c
+ drivers/media/dvb/mantis/mantis_ioc.c
+ drivers/media/dvb/mantis/mantis_pcmcia.c
+ drivers/media/dvb/mantis/mantis_uart.c
+ drivers/media/dvb/mantis/mantis_vp1034.c
+ drivers/mtd/nand/atmel_nand.c
+ drivers/net/arm/ks8695net.c
+ drivers/net/bnx2x/bnx2x.h
+ drivers/net/can/janz-ican3.c
+ drivers/net/can/softing/softing_fw.c
+ drivers/net/can/softing/softing_main.c
+ drivers/net/ethoc.c
+ drivers/net/fec_mpc52xx.c
+ drivers/net/greth.c
+ drivers/net/irda/pxaficp_ir.c
+ drivers/net/ks8851_mll.c
+ drivers/net/sgiseeq.c
+ drivers/net/stmmac/dwmac1000_core.c
+ drivers/net/stmmac/dwmac1000_dma.c
+ drivers/net/stmmac/dwmac100_core.c
+ drivers/net/stmmac/dwmac100_dma.c
+ drivers/net/stmmac/stmmac_ethtool.c
+ drivers/net/stmmac/stmmac_mdio.c
+ drivers/net/usb/cdc-phonet.c
+ drivers/net/vxge/vxge-config.h
+ drivers/net/wireless/ath/ath5k/base.c
+ drivers/net/wireless/ath/ath9k/beacon.c
+ drivers/net/wireless/ath/ath9k/init.c
+ drivers/net/wireless/ath/ath9k/recv.c
+ drivers/net/wireless/ath/ath9k/xmit.c
+ drivers/staging/pohmelfs/crypto.c
+ drivers/tty/serial/ifx6x60.c
+ drivers/usb/gadget/f_phonet.c
+ include/crypto/if_alg.h
+ include/linux/dma-direction.h
+ include/linux/dma-mapping.h
+ include/linux/dmaengine.h
+ include/linux/netdevice.h
+ net/sched/sch_netem.c
+ security/apparmor/lib.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_dma.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c
+index 2aa616d..86f259c 100644
+--- a/drivers/mmc/host/tmio_mmc_dma.c
++++ b/drivers/mmc/host/tmio_mmc_dma.c
+@@ -11,6 +11,7 @@
+ */
+
+ #include <linux/device.h>
++#include <linux/dma-mapping.h>
+ #include <linux/dmaengine.h>
+ #include <linux/mfd/tmio.h>
+ #include <linux/mmc/host.h>
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0030-MMC-TMIO-Fix-build-issue-related-to-struct-scatterli.patch b/patches.kzm9g/0030-MMC-TMIO-Fix-build-issue-related-to-struct-scatterli.patch
new file mode 100644
index 00000000000000..8d59531622e57f
--- /dev/null
+++ b/patches.kzm9g/0030-MMC-TMIO-Fix-build-issue-related-to-struct-scatterli.patch
@@ -0,0 +1,32 @@
+From 5f95cc2e38f83f6ce91e1312e078cbcc5ee839b1 Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rjw@sisk.pl>
+Date: Tue, 26 Jul 2011 20:50:23 +0200
+Subject: MMC / TMIO: Fix build issue related to struct scatterlist
+
+Fix build issue caused by undefined struct scatterlist in
+drivers/mmc/host/tmio_mmc.c.
+
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+(cherry picked from commit 6c0cbef6662aa685c6a47a18039b9d4f1d5abcb1)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index 087d880..eeaf643 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -21,6 +21,7 @@
+ #include <linux/mutex.h>
+ #include <linux/pagemap.h>
+ #include <linux/spinlock.h>
++#include <linux/scatterlist.h>
+
+ /* Definitions for values the CTRL_SDIO_STATUS register can take. */
+ #define TMIO_SDIO_STAT_IOIRQ 0x0001
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0031-mmc-tmio-eliminate-unused-variable-mmc-warning.patch b/patches.kzm9g/0031-mmc-tmio-eliminate-unused-variable-mmc-warning.patch
new file mode 100644
index 00000000000000..554251e6533874
--- /dev/null
+++ b/patches.kzm9g/0031-mmc-tmio-eliminate-unused-variable-mmc-warning.patch
@@ -0,0 +1,45 @@
+From 37284ff5509343e2d777637a23487da3335c2f31 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@gmail.com>
+Date: Wed, 3 Aug 2011 14:48:58 +0800
+Subject: mmc: tmio: eliminate unused variable 'mmc' warning
+
+Fix below compile warning:
+ CC drivers/mmc/host/tmio_mmc.o
+drivers/mmc/host/tmio_mmc.c: In function 'tmio_mmc_suspend':
+drivers/mmc/host/tmio_mmc.c:30: warning: unused variable 'mmc'
+drivers/mmc/host/tmio_mmc.c: In function 'tmio_mmc_resume':
+drivers/mmc/host/tmio_mmc.c:45: warning: unused variable 'mmc'
+
+Signed-off-by: Axel Lin <axel.lin@gmail.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 4906baf080623b4971bdeeac0a9fec5b8885d3ac)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
+index 8d185de..44a9668 100644
+--- a/drivers/mmc/host/tmio_mmc.c
++++ b/drivers/mmc/host/tmio_mmc.c
+@@ -27,7 +27,6 @@
+ static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state)
+ {
+ const struct mfd_cell *cell = mfd_get_cell(dev);
+- struct mmc_host *mmc = platform_get_drvdata(dev);
+ int ret;
+
+ ret = tmio_mmc_host_suspend(&dev->dev);
+@@ -42,7 +41,6 @@ static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state)
+ static int tmio_mmc_resume(struct platform_device *dev)
+ {
+ const struct mfd_cell *cell = mfd_get_cell(dev);
+- struct mmc_host *mmc = platform_get_drvdata(dev);
+ int ret = 0;
+
+ /* Tell the MFD core we are ready to be enabled */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0032-mmc-sdhi-initialise-mmc_data-flags-before-use.patch b/patches.kzm9g/0032-mmc-sdhi-initialise-mmc_data-flags-before-use.patch
new file mode 100644
index 00000000000000..c88dadd8462f77
--- /dev/null
+++ b/patches.kzm9g/0032-mmc-sdhi-initialise-mmc_data-flags-before-use.patch
@@ -0,0 +1,39 @@
+From bf87a92d768043390903be036df2292b6775bdb5 Mon Sep 17 00:00:00 2001
+From: Simon Horman <horms@verge.net.au>
+Date: Fri, 19 Aug 2011 10:07:07 +0900
+Subject: mmc: sdhi: initialise mmc_data->flags before use
+
+This corrects a logic error that I introduced in
+"mmc: sdhi: Add write16_hook"
+
+Reported-by: Magnus Damm <magnus.damm@gmail.com>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit b91df1593e361109f1fe665ce17c5e87ca60582b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mobile_sdhi.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index 774f643..0c4a672 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -120,11 +120,11 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+ 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;
+- if (mmc_data->flags & TMIO_MMC_HAS_IDLE_WAIT)
+- mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
+ mmc_data->capabilities = MMC_CAP_MMC_HIGHSPEED;
+ if (p) {
+ mmc_data->flags = p->tmio_flags;
++ if (mmc_data->flags & TMIO_MMC_HAS_IDLE_WAIT)
++ mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
+ mmc_data->ocr_mask = p->tmio_ocr_mask;
+ mmc_data->capabilities |= p->tmio_caps;
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0033-mmc-tmio-Cache-interrupt-masks.patch b/patches.kzm9g/0033-mmc-tmio-Cache-interrupt-masks.patch
new file mode 100644
index 00000000000000..7f23958328ab13
--- /dev/null
+++ b/patches.kzm9g/0033-mmc-tmio-Cache-interrupt-masks.patch
@@ -0,0 +1,131 @@
+From 841db3ade6dadb8573cbe50fa35238f7d0bbe637 Mon Sep 17 00:00:00 2001
+From: Simon Horman <horms@verge.net.au>
+Date: Thu, 25 Aug 2011 10:27:25 +0900
+Subject: mmc: tmio: Cache interrupt masks
+
+This avoids the need to look up the masks each time an interrupt is handled.
+As suggested by Guennadi.
+
+Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Acked-by: Magnus Damm <magnus.damm@gmail.com>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 54680fe7f6ad0fb0c52e330484e2cf1609587862)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc.h | 4 ++++
+ drivers/mmc/host/tmio_mmc_pio.c | 34 ++++++++++++++++++----------------
+ 2 files changed, 22 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index eeaf643..1cf8db5 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -79,6 +79,10 @@ struct tmio_mmc_host {
+ struct delayed_work delayed_reset_work;
+ struct work_struct done;
+
++ /* Cache IRQ mask */
++ u32 sdcard_irq_mask;
++ u32 sdio_irq_mask;
++
+ spinlock_t lock; /* protect host private data */
+ unsigned long last_req_ts;
+ struct mutex ios_lock; /* protect set_ios() context */
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index 1f16357..f0c7830 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -48,14 +48,14 @@
+
+ void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
+ {
+- u32 mask = sd_ctrl_read32(host, CTL_IRQ_MASK) & ~(i & TMIO_MASK_IRQ);
+- sd_ctrl_write32(host, CTL_IRQ_MASK, mask);
++ host->sdcard_irq_mask &= ~(i & TMIO_MASK_IRQ);
++ sd_ctrl_write32(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
+ }
+
+ void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
+ {
+- u32 mask = sd_ctrl_read32(host, CTL_IRQ_MASK) | (i & TMIO_MASK_IRQ);
+- sd_ctrl_write32(host, CTL_IRQ_MASK, mask);
++ host->sdcard_irq_mask |= (i & TMIO_MASK_IRQ);
++ sd_ctrl_write32(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
+ }
+
+ static void tmio_mmc_ack_mmc_irqs(struct tmio_mmc_host *host, u32 i)
+@@ -127,11 +127,13 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+
+ if (enable) {
+ host->sdio_irq_enabled = 1;
++ host->sdio_irq_mask = TMIO_SDIO_MASK_ALL &
++ ~TMIO_SDIO_STAT_IOIRQ;
+ sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
+- sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK,
+- (TMIO_SDIO_MASK_ALL & ~TMIO_SDIO_STAT_IOIRQ));
++ sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
+ } else {
+- sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, TMIO_SDIO_MASK_ALL);
++ host->sdio_irq_mask = TMIO_SDIO_MASK_ALL;
++ sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
+ sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000);
+ host->sdio_irq_enabled = 0;
+ }
+@@ -548,26 +550,25 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
+ struct tmio_mmc_host *host = devid;
+ struct mmc_host *mmc = host->mmc;
+ struct tmio_mmc_data *pdata = host->pdata;
+- unsigned int ireg, irq_mask, status;
+- unsigned int sdio_ireg, sdio_irq_mask, sdio_status;
++ unsigned int ireg, status;
++ unsigned int sdio_ireg, sdio_status;
+
+ pr_debug("MMC IRQ begin\n");
+
+ status = sd_ctrl_read32(host, CTL_STATUS);
+- irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK);
+- ireg = status & TMIO_MASK_IRQ & ~irq_mask;
++ ireg = status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask;
+
+ sdio_ireg = 0;
+ if (!ireg && pdata->flags & TMIO_MMC_SDIO_IRQ) {
+ sdio_status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
+- sdio_irq_mask = sd_ctrl_read16(host, CTL_SDIO_IRQ_MASK);
+- sdio_ireg = sdio_status & TMIO_SDIO_MASK_ALL & ~sdio_irq_mask;
++ sdio_ireg = sdio_status & TMIO_SDIO_MASK_ALL &
++ ~host->sdio_irq_mask;
+
+ sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status & ~TMIO_SDIO_MASK_ALL);
+
+ if (sdio_ireg && !host->sdio_irq_enabled) {
+ pr_warning("tmio_mmc: Spurious SDIO IRQ, disabling! 0x%04x 0x%04x 0x%04x\n",
+- sdio_status, sdio_irq_mask, sdio_ireg);
++ sdio_status, host->sdio_irq_mask, sdio_ireg);
+ tmio_mmc_enable_sdio_irq(mmc, 0);
+ goto out;
+ }
+@@ -623,9 +624,9 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
+ }
+
+ pr_warning("tmio_mmc: Spurious irq, disabling! "
+- "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg);
++ "0x%08x 0x%08x 0x%08x\n", status, host->sdcard_irq_mask, ireg);
+ pr_debug_status(status);
+- tmio_mmc_disable_mmc_irqs(host, status & ~irq_mask);
++ tmio_mmc_disable_mmc_irqs(host, status & ~host->sdcard_irq_mask);
+
+ out:
+ return IRQ_HANDLED;
+@@ -882,6 +883,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ tmio_mmc_clk_stop(_host);
+ tmio_mmc_reset(_host);
+
++ _host->sdcard_irq_mask = sd_ctrl_read32(_host, CTL_IRQ_MASK);
+ tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);
+ if (pdata->flags & TMIO_MMC_SDIO_IRQ)
+ tmio_mmc_enable_sdio_irq(mmc, 0);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0034-mmc-tmio-Provide-separate-interrupt-handlers.patch b/patches.kzm9g/0034-mmc-tmio-Provide-separate-interrupt-handlers.patch
new file mode 100644
index 00000000000000..a36ee79a77255d
--- /dev/null
+++ b/patches.kzm9g/0034-mmc-tmio-Provide-separate-interrupt-handlers.patch
@@ -0,0 +1,215 @@
+From 82db957f7a037e60d56f38437d5d0e8517cfd3f9 Mon Sep 17 00:00:00 2001
+From: Simon Horman <horms@verge.net.au>
+Date: Thu, 25 Aug 2011 10:27:26 +0900
+Subject: mmc: tmio: Provide separate interrupt handlers
+
+Provide separate interrupt handlers which may be used by platforms where
+SDHI has three interrupt sources.
+
+This patch also removes the commented-out handling of CRC and other errors.
+
+Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Acked-by: Magnus Damm <magnus.damm@gmail.com>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 7729c7a232a95360fa17ffe8beb1adb621bc0ba0)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc.h | 3 +
+ drivers/mmc/host/tmio_mmc_pio.c | 131 +++++++++++++++++++++++++---------------
+ 2 files changed, 86 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index 1cf8db5..3020f98 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -97,6 +97,9 @@ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host);
+ void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
+ void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
+ irqreturn_t tmio_mmc_irq(int irq, void *devid);
++irqreturn_t tmio_mmc_sdcard_irq(int irq, void *devid);
++irqreturn_t tmio_mmc_card_detect_irq(int irq, void *devid);
++irqreturn_t tmio_mmc_sdio_irq(int irq, void *devid);
+
+ static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg,
+ unsigned long *flags)
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index f0c7830..6275e3d 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -545,44 +545,20 @@ out:
+ spin_unlock(&host->lock);
+ }
+
+-irqreturn_t tmio_mmc_irq(int irq, void *devid)
++static void tmio_mmc_card_irq_status(struct tmio_mmc_host *host,
++ int *ireg, int *status)
+ {
+- struct tmio_mmc_host *host = devid;
+- struct mmc_host *mmc = host->mmc;
+- struct tmio_mmc_data *pdata = host->pdata;
+- unsigned int ireg, status;
+- unsigned int sdio_ireg, sdio_status;
+-
+- pr_debug("MMC IRQ begin\n");
+-
+- status = sd_ctrl_read32(host, CTL_STATUS);
+- ireg = status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask;
++ *status = sd_ctrl_read32(host, CTL_STATUS);
++ *ireg = *status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask;
+
+- sdio_ireg = 0;
+- if (!ireg && pdata->flags & TMIO_MMC_SDIO_IRQ) {
+- sdio_status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
+- sdio_ireg = sdio_status & TMIO_SDIO_MASK_ALL &
+- ~host->sdio_irq_mask;
+-
+- sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status & ~TMIO_SDIO_MASK_ALL);
+-
+- if (sdio_ireg && !host->sdio_irq_enabled) {
+- pr_warning("tmio_mmc: Spurious SDIO IRQ, disabling! 0x%04x 0x%04x 0x%04x\n",
+- sdio_status, host->sdio_irq_mask, sdio_ireg);
+- tmio_mmc_enable_sdio_irq(mmc, 0);
+- goto out;
+- }
+-
+- if (mmc->caps & MMC_CAP_SDIO_IRQ &&
+- sdio_ireg & TMIO_SDIO_STAT_IOIRQ)
+- mmc_signal_sdio_irq(mmc);
+-
+- if (sdio_ireg)
+- goto out;
+- }
++ pr_debug_status(*status);
++ pr_debug_status(*ireg);
++}
+
+- pr_debug_status(status);
+- pr_debug_status(ireg);
++static bool __tmio_mmc_card_detect_irq(struct tmio_mmc_host *host,
++ int ireg, int status)
++{
++ struct mmc_host *mmc = host->mmc;
+
+ /* Card insert / remove attempts */
+ if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
+@@ -592,43 +568,102 @@ irqreturn_t tmio_mmc_irq(int irq, void *devid)
+ ((ireg & TMIO_STAT_CARD_INSERT) && !mmc->card)) &&
+ !work_pending(&mmc->detect.work))
+ mmc_detect_change(host->mmc, msecs_to_jiffies(100));
+- goto out;
++ return true;
+ }
+
+- /* CRC and other errors */
+-/* if (ireg & TMIO_STAT_ERR_IRQ)
+- * handled |= tmio_error_irq(host, irq, stat);
+- */
++ return false;
++}
++
++irqreturn_t tmio_mmc_card_detect_irq(int irq, void *devid)
++{
++ unsigned int ireg, status;
++ struct tmio_mmc_host *host = devid;
+
++ tmio_mmc_card_irq_status(host, &ireg, &status);
++ __tmio_mmc_card_detect_irq(host, ireg, status);
++
++ return IRQ_HANDLED;
++}
++EXPORT_SYMBOL(tmio_mmc_card_detect_irq);
++
++static bool __tmio_mmc_sdcard_irq(struct tmio_mmc_host *host,
++ int ireg, int status)
++{
+ /* Command completion */
+ if (ireg & (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT)) {
+ tmio_mmc_ack_mmc_irqs(host,
+ TMIO_STAT_CMDRESPEND |
+ TMIO_STAT_CMDTIMEOUT);
+ tmio_mmc_cmd_irq(host, status);
+- goto out;
++ return true;
+ }
+
+ /* Data transfer */
+ if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) {
+ tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ);
+ tmio_mmc_pio_irq(host);
+- goto out;
++ return true;
+ }
+
+ /* Data transfer completion */
+ if (ireg & TMIO_STAT_DATAEND) {
+ tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_DATAEND);
+ tmio_mmc_data_irq(host);
+- goto out;
++ return true;
+ }
+
+- pr_warning("tmio_mmc: Spurious irq, disabling! "
+- "0x%08x 0x%08x 0x%08x\n", status, host->sdcard_irq_mask, ireg);
+- pr_debug_status(status);
+- tmio_mmc_disable_mmc_irqs(host, status & ~host->sdcard_irq_mask);
++ return false;
++}
++
++irqreturn_t tmio_mmc_sdcard_irq(int irq, void *devid)
++{
++ unsigned int ireg, status;
++ struct tmio_mmc_host *host = devid;
++
++ tmio_mmc_card_irq_status(host, &ireg, &status);
++ __tmio_mmc_sdcard_irq(host, ireg, status);
++
++ return IRQ_HANDLED;
++}
++EXPORT_SYMBOL(tmio_mmc_sdcard_irq);
++
++irqreturn_t tmio_mmc_sdio_irq(int irq, void *devid)
++{
++ struct tmio_mmc_host *host = devid;
++ struct mmc_host *mmc = host->mmc;
++ struct tmio_mmc_data *pdata = host->pdata;
++ unsigned int ireg, status;
++
++ if (!(pdata->flags & TMIO_MMC_SDIO_IRQ))
++ return IRQ_HANDLED;
++
++ status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
++ ireg = status & TMIO_SDIO_MASK_ALL & ~host->sdcard_irq_mask;
++
++ sd_ctrl_write16(host, CTL_SDIO_STATUS, status & ~TMIO_SDIO_MASK_ALL);
++
++ if (mmc->caps & MMC_CAP_SDIO_IRQ && ireg & TMIO_SDIO_STAT_IOIRQ)
++ mmc_signal_sdio_irq(mmc);
++
++ return IRQ_HANDLED;
++}
++EXPORT_SYMBOL(tmio_mmc_sdio_irq);
++
++irqreturn_t tmio_mmc_irq(int irq, void *devid)
++{
++ struct tmio_mmc_host *host = devid;
++ unsigned int ireg, status;
++
++ pr_debug("MMC IRQ begin\n");
++
++ tmio_mmc_card_irq_status(host, &ireg, &status);
++ if (__tmio_mmc_card_detect_irq(host, ireg, status))
++ return IRQ_HANDLED;
++ if (__tmio_mmc_sdcard_irq(host, ireg, status))
++ return IRQ_HANDLED;
++
++ tmio_mmc_sdio_irq(irq, devid);
+
+-out:
+ return IRQ_HANDLED;
+ }
+ EXPORT_SYMBOL(tmio_mmc_irq);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0035-mmc-sdhi-Allow-named-IRQs-to-use-specific-handlers.patch b/patches.kzm9g/0035-mmc-sdhi-Allow-named-IRQs-to-use-specific-handlers.patch
new file mode 100644
index 00000000000000..44d188ce33d7ea
--- /dev/null
+++ b/patches.kzm9g/0035-mmc-sdhi-Allow-named-IRQs-to-use-specific-handlers.patch
@@ -0,0 +1,180 @@
+From 0f69bae0394ca010c38bb88a66b8a9a480f5f3ea Mon Sep 17 00:00:00 2001
+From: Simon Horman <horms@verge.net.au>
+Date: Fri, 26 Aug 2011 10:42:39 +0200
+Subject: mmc: sdhi: Allow named IRQs to use specific handlers
+
+Allow named IRQs to use corresponding specific handlers. If named IRQs are
+used, at least an "sdcard" IRQ has to be specified by the platform. If
+names are not used, an arbitrary number of IRQs can be provided by the
+platform, in which case the generic ISR will be used for each of them.
+
+Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Acked-by: Magnus Damm <magnus.damm@gmail.com>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+[g.liakhovetski@gmx.de: style and typo corrections, platform data check]
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit d5098cb63b3f13da2a2b230b3566ac7b5dfa4f28)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mobile_sdhi.c | 98 ++++++++++++++++++++++++++++----------
+ include/linux/mmc/sh_mobile_sdhi.h | 4 ++
+ 2 files changed, 77 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index 0c4a672..75bffc4 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -96,7 +96,8 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+ struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
+ struct tmio_mmc_host *host;
+ char clk_name[8];
+- int i, irq, ret;
++ int irq, ret, i = 0;
++ bool multiplexed_isr = true;
+
+ priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
+ if (priv == NULL) {
+@@ -153,27 +154,60 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+ if (ret < 0)
+ goto eprobe;
+
+- for (i = 0; i < 3; i++) {
+- irq = platform_get_irq(pdev, i);
+- if (irq < 0) {
+- if (i) {
+- continue;
+- } else {
+- ret = irq;
+- goto eirq;
+- }
+- }
+- ret = request_irq(irq, tmio_mmc_irq, 0,
++ /*
++ * Allow one or more specific (named) ISRs or
++ * one or more multiplexed (un-named) ISRs.
++ */
++
++ irq = platform_get_irq_byname(pdev, SH_MOBILE_SDHI_IRQ_CARD_DETECT);
++ if (irq >= 0) {
++ multiplexed_isr = false;
++ ret = request_irq(irq, tmio_mmc_card_detect_irq, 0,
++ dev_name(&pdev->dev), host);
++ if (ret)
++ goto eirq_card_detect;
++ }
++
++ irq = platform_get_irq_byname(pdev, SH_MOBILE_SDHI_IRQ_SDIO);
++ if (irq >= 0) {
++ multiplexed_isr = false;
++ ret = request_irq(irq, tmio_mmc_sdio_irq, 0,
++ dev_name(&pdev->dev), host);
++ if (ret)
++ goto eirq_sdio;
++ }
++
++ irq = platform_get_irq_byname(pdev, SH_MOBILE_SDHI_IRQ_SDCARD);
++ if (irq >= 0) {
++ multiplexed_isr = false;
++ ret = request_irq(irq, tmio_mmc_sdcard_irq, 0,
+ dev_name(&pdev->dev), host);
+- if (ret) {
+- while (i--) {
+- irq = platform_get_irq(pdev, i);
+- if (irq >= 0)
+- free_irq(irq, host);
+- }
+- goto eirq;
++ if (ret)
++ goto eirq_sdcard;
++ } else if (!multiplexed_isr) {
++ dev_err(&pdev->dev,
++ "Principal SD-card IRQ is missing among named interrupts\n");
++ ret = irq;
++ goto eirq_sdcard;
++ }
++
++ if (multiplexed_isr) {
++ while (1) {
++ irq = platform_get_irq(pdev, i);
++ if (irq < 0)
++ break;
++ i++;
++ ret = request_irq(irq, tmio_mmc_irq, 0,
++ dev_name(&pdev->dev), host);
++ if (ret)
++ goto eirq_multiplexed;
+ }
++
++ /* There must be at least one IRQ source */
++ if (!i)
++ goto eirq_multiplexed;
+ }
++
+ dev_info(&pdev->dev, "%s base at 0x%08lx clock rate %u MHz\n",
+ mmc_hostname(host->mmc), (unsigned long)
+ (platform_get_resource(pdev,IORESOURCE_MEM, 0)->start),
+@@ -181,7 +215,20 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+
+ return ret;
+
+-eirq:
++eirq_multiplexed:
++ while (i--) {
++ irq = platform_get_irq(pdev, i);
++ free_irq(irq, host);
++ }
++eirq_sdcard:
++ irq = platform_get_irq_byname(pdev, SH_MOBILE_SDHI_IRQ_SDIO);
++ if (irq >= 0)
++ free_irq(irq, host);
++eirq_sdio:
++ irq = platform_get_irq_byname(pdev, SH_MOBILE_SDHI_IRQ_CARD_DETECT);
++ if (irq >= 0)
++ free_irq(irq, host);
++eirq_card_detect:
+ tmio_mmc_host_remove(host);
+ eprobe:
+ clk_disable(priv->clk);
+@@ -197,16 +244,17 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+ struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
+ struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
+- int i, irq;
++ int i = 0, irq;
+
+ p->pdata = NULL;
+
+ tmio_mmc_host_remove(host);
+
+- for (i = 0; i < 3; i++) {
+- irq = platform_get_irq(pdev, i);
+- if (irq >= 0)
+- free_irq(irq, host);
++ while (1) {
++ irq = platform_get_irq(pdev, i++);
++ if (irq < 0)
++ break;
++ free_irq(irq, host);
+ }
+
+ clk_disable(priv->clk);
+diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
+index bd50b36..71b8054 100644
+--- a/include/linux/mmc/sh_mobile_sdhi.h
++++ b/include/linux/mmc/sh_mobile_sdhi.h
+@@ -6,6 +6,10 @@
+ struct platform_device;
+ struct tmio_mmc_data;
+
++#define SH_MOBILE_SDHI_IRQ_CARD_DETECT "card_detect"
++#define SH_MOBILE_SDHI_IRQ_SDCARD "sdcard"
++#define SH_MOBILE_SDHI_IRQ_SDIO "sdio"
++
+ struct sh_mobile_sdhi_info {
+ int dma_slave_tx;
+ int dma_slave_rx;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0036-mmc-irq-Remove-IRQF_DISABLED.patch b/patches.kzm9g/0036-mmc-irq-Remove-IRQF_DISABLED.patch
new file mode 100644
index 00000000000000..be5d23aac991d4
--- /dev/null
+++ b/patches.kzm9g/0036-mmc-irq-Remove-IRQF_DISABLED.patch
@@ -0,0 +1,46 @@
+From 659def1c9d9094e00aef310907f2859663a850c8 Mon Sep 17 00:00:00 2001
+From: Yong Zhang <yong.zhang0@gmail.com>
+Date: Thu, 22 Sep 2011 16:59:04 +0800
+Subject: mmc: irq: Remove IRQF_DISABLED
+
+Since commit [e58aa3d2: genirq: Run irq handlers with interrupts
+disabled], we run all interrupt handlers with interrupts disabled
+and we even check and yell when an interrupt handler returns with
+interrupts enabled (see commit [b738a50a: genirq: Warn when handler
+enables interrupts]).
+
+So now this flag is a NOOP and can be removed.
+
+Signed-off-by: Yong Zhang <yong.zhang0@gmail.com>
+Acked-by: Kishore Kadiyala <kishore.kadiyala@ti.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit d9618e9f1a057efdfc52514d6cd7af56e9bddc17)
+
+Conflicts:
+
+ drivers/mmc/host/omap_hsmmc.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
+index 44a9668..a4ea102 100644
+--- a/drivers/mmc/host/tmio_mmc.c
++++ b/drivers/mmc/host/tmio_mmc.c
+@@ -88,8 +88,8 @@ static int __devinit tmio_mmc_probe(struct platform_device *pdev)
+ if (ret)
+ goto cell_disable;
+
+- ret = request_irq(irq, tmio_mmc_irq, IRQF_DISABLED |
+- IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), host);
++ ret = request_irq(irq, tmio_mmc_irq, IRQF_TRIGGER_FALLING,
++ dev_name(&pdev->dev), host);
+ if (ret)
+ goto host_remove;
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0037-mmc-Add-module.h-to-drivers-mmc-users-assuming-impli.patch b/patches.kzm9g/0037-mmc-Add-module.h-to-drivers-mmc-users-assuming-impli.patch
new file mode 100644
index 00000000000000..b3cae7b2e76dd6
--- /dev/null
+++ b/patches.kzm9g/0037-mmc-Add-module.h-to-drivers-mmc-users-assuming-impli.patch
@@ -0,0 +1,36 @@
+From b19f896d27c56c6fdf613e245c7cd8963cac5c05 Mon Sep 17 00:00:00 2001
+From: Paul Gortmaker <paul.gortmaker@windriver.com>
+Date: Sun, 3 Jul 2011 15:15:51 -0400
+Subject: mmc: Add module.h to drivers/mmc users assuming implicit presence.
+
+We are cleaning up the implicit presence of module.h; these guys are
+some of the people who just assume it will be there. Call it out
+explitly for those that really need it.
+
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 88b47679746b81534002bcba42da97ab82b5d12a)
+
+Cherry picked changes for:
+ drivers/mmc/host/sh_mobile_sdhi.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mobile_sdhi.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index 75bffc4..41ae646 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/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/mmc/host.h>
+ #include <linux/mmc/sh_mobile_sdhi.h>
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0038-mmc-replace-printk-with-appropriate-display-macro.patch b/patches.kzm9g/0038-mmc-replace-printk-with-appropriate-display-macro.patch
new file mode 100644
index 00000000000000..d31b0098cfaeeb
--- /dev/null
+++ b/patches.kzm9g/0038-mmc-replace-printk-with-appropriate-display-macro.patch
@@ -0,0 +1,36 @@
+From f1b038d466d3385553728a07eb252ea400847af6 Mon Sep 17 00:00:00 2001
+From: Girish K S <girish.shivananjappa@linaro.org>
+Date: Tue, 11 Oct 2011 11:44:09 +0530
+Subject: mmc: replace printk with appropriate display macro
+
+All the files using printk function for displaying kernel messages
+in the mmc driver have been replaced with corresponding macro.
+
+Signed-off-by: Girish K S <girish.shivananjappa@linaro.org>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit a3c76eb9d4a1e68a69dd880cf0bcb8a52418b993)
+
+Cherry-picked changes for:
+ drivers/mmc/host/tmio_mmc_pio.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_pio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index 6275e3d..d85a60c 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -92,7 +92,7 @@ static int tmio_mmc_next_sg(struct tmio_mmc_host *host)
+ static void pr_debug_status(u32 status)
+ {
+ int i = 0;
+- printk(KERN_DEBUG "status: %08x = ", status);
++ pr_debug("status: %08x = ", status);
+ STATUS_TO_TEXT(CARD_REMOVE, status, i);
+ STATUS_TO_TEXT(CARD_INSERT, status, i);
+ STATUS_TO_TEXT(SIGSTATE, status, i);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0039-mmc-tmio-fix-clock-gating-on-platforms-with-a-.set_p.patch b/patches.kzm9g/0039-mmc-tmio-fix-clock-gating-on-platforms-with-a-.set_p.patch
new file mode 100644
index 00000000000000..e0f1bf06d3a7e8
--- /dev/null
+++ b/patches.kzm9g/0039-mmc-tmio-fix-clock-gating-on-platforms-with-a-.set_p.patch
@@ -0,0 +1,33 @@
+From 998c2d6fab4e0ed0eb6f8bc58f9fdeb2f9ee9620 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 16 Nov 2011 10:11:45 +0100
+Subject: mmc: tmio: fix clock gating on platforms with a .set_pwr() method
+
+Do not power down the card in .set_ios(), unless MMC_POWER_OFF is
+requested. This fixes the SDHI functionality on ecovec.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit f6b8b52c68f6109db4be02b55660258ff503fc3b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_pio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index d85a60c..4208b39 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -798,7 +798,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ /* start bus clock */
+ tmio_mmc_clk_start(host);
+ } else if (ios->power_mode != MMC_POWER_UP) {
+- if (host->set_pwr)
++ if (host->set_pwr && ios->power_mode == MMC_POWER_OFF)
+ host->set_pwr(host->pdev, 0);
+ if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) &&
+ pdata->power) {
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0040-mmc-convert-drivers-mmc-host-to-use-module_platform_.patch b/patches.kzm9g/0040-mmc-convert-drivers-mmc-host-to-use-module_platform_.patch
new file mode 100644
index 00000000000000..51127b5b8c05e1
--- /dev/null
+++ b/patches.kzm9g/0040-mmc-convert-drivers-mmc-host-to-use-module_platform_.patch
@@ -0,0 +1,103 @@
+From 9fd478fb4b61077bb435702bcb65e79de681e1c6 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@gmail.com>
+Date: Sat, 26 Nov 2011 12:55:43 +0800
+Subject: mmc: convert drivers/mmc/host/* to use module_platform_driver()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch converts the drivers in drivers/mmc/host/* to use the
+module_platform_driver() macro which makes the code smaller and a bit
+simpler.
+
+Signed-off-by: Axel Lin <axel.lin@gmail.com>
+Acked-by: "Michał Mirosław" <mirq-linux@rere.qmqm.pl>
+Acked-by: David Brown <davidb@codeaurora.org>
+Acked-by: Viresh Kumar <viresh.kumar@st.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
+Acked-by: Wolfram Sang <w.sang@pengutronix.de>
+Acked-by: Anton Vorontsov <cbouatmailru@gmail.com>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry-picked from commit d1f81a64a4250bdd776978be06ae2b8e13ec7471)
+
+Conflicts:
+
+ drivers/mmc/host/bfin_sdh.c
+ drivers/mmc/host/cb710-mmc.c
+ drivers/mmc/host/jz4740_mmc.c
+ drivers/mmc/host/msm_sdcc.c
+ drivers/mmc/host/mxcmmc.c
+ drivers/mmc/host/mxs-mmc.c
+ drivers/mmc/host/pxamci.c
+ drivers/mmc/host/s3cmci.c
+ drivers/mmc/host/sdhci-cns3xxx.c
+ drivers/mmc/host/sdhci-dove.c
+ drivers/mmc/host/sdhci-esdhc-imx.c
+ drivers/mmc/host/sdhci-of-esdhc.c
+ drivers/mmc/host/sdhci-of-hlwd.c
+ drivers/mmc/host/sdhci-pxav2.c
+ drivers/mmc/host/sdhci-pxav3.c
+ drivers/mmc/host/sdhci-s3c.c
+ drivers/mmc/host/sdhci-spear.c
+ drivers/mmc/host/sdhci-tegra.c
+ drivers/mmc/host/sh_mmcif.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mobile_sdhi.c | 13 +------------
+ drivers/mmc/host/tmio_mmc.c | 14 +-------------
+ 2 files changed, 2 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index 41ae646..58da3c4 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -282,18 +282,7 @@ static struct platform_driver sh_mobile_sdhi_driver = {
+ .remove = __devexit_p(sh_mobile_sdhi_remove),
+ };
+
+-static int __init sh_mobile_sdhi_init(void)
+-{
+- return platform_driver_register(&sh_mobile_sdhi_driver);
+-}
+-
+-static void __exit sh_mobile_sdhi_exit(void)
+-{
+- platform_driver_unregister(&sh_mobile_sdhi_driver);
+-}
+-
+-module_init(sh_mobile_sdhi_init);
+-module_exit(sh_mobile_sdhi_exit);
++module_platform_driver(sh_mobile_sdhi_driver);
+
+ MODULE_DESCRIPTION("SuperH Mobile SDHI driver");
+ MODULE_AUTHOR("Magnus Damm");
+diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
+index a4ea102..113ce6c 100644
+--- a/drivers/mmc/host/tmio_mmc.c
++++ b/drivers/mmc/host/tmio_mmc.c
+@@ -138,19 +138,7 @@ static struct platform_driver tmio_mmc_driver = {
+ .resume = tmio_mmc_resume,
+ };
+
+-
+-static int __init tmio_mmc_init(void)
+-{
+- return platform_driver_register(&tmio_mmc_driver);
+-}
+-
+-static void __exit tmio_mmc_exit(void)
+-{
+- platform_driver_unregister(&tmio_mmc_driver);
+-}
+-
+-module_init(tmio_mmc_init);
+-module_exit(tmio_mmc_exit);
++module_platform_driver(tmio_mmc_driver);
+
+ MODULE_DESCRIPTION("Toshiba TMIO SD/MMC driver");
+ MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0041-mmc-remove-the-second-argument-of-k-un-map_atomic.patch b/patches.kzm9g/0041-mmc-remove-the-second-argument-of-k-un-map_atomic.patch
new file mode 100644
index 00000000000000..9ac5f48f863ccc
--- /dev/null
+++ b/patches.kzm9g/0041-mmc-remove-the-second-argument-of-k-un-map_atomic.patch
@@ -0,0 +1,46 @@
+From 5a1454200daaf7e2ed0ec2ad17e960240af1f9ee Mon Sep 17 00:00:00 2001
+From: Cong Wang <amwang@redhat.com>
+Date: Sun, 27 Nov 2011 13:27:00 +0800
+Subject: mmc: remove the second argument of k[un]map_atomic()
+
+Signed-off-by: Cong Wang <amwang@redhat.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 482fce997e143a8d5429406fe066d31aa76ef70a)
+
+Conflicts:
+
+ drivers/mmc/host/at91_mci.c
+ drivers/mmc/host/msm_sdcc.c
+ drivers/mmc/host/sdhci.c
+ drivers/mmc/host/tifm_sd.c
+ drivers/mmc/host/tmio_mmc.h
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index 3020f98..a95e6d9 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -105,13 +105,13 @@ static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg,
+ unsigned long *flags)
+ {
+ local_irq_save(*flags);
+- return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
++ return kmap_atomic(sg_page(sg)) + sg->offset;
+ }
+
+ static inline void tmio_mmc_kunmap_atomic(struct scatterlist *sg,
+ unsigned long *flags, void *virt)
+ {
+- kunmap_atomic(virt - sg->offset, KM_BIO_SRC_IRQ);
++ kunmap_atomic(virt - sg->offset);
+ local_irq_restore(*flags);
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0042-mmc-tmio_mmc-Hotplug-code-regrouping.patch b/patches.kzm9g/0042-mmc-tmio_mmc-Hotplug-code-regrouping.patch
new file mode 100644
index 00000000000000..9c567795f38f3a
--- /dev/null
+++ b/patches.kzm9g/0042-mmc-tmio_mmc-Hotplug-code-regrouping.patch
@@ -0,0 +1,84 @@
+From 4ca7e51f2818d592650cabed935acd9f094ca26a Mon Sep 17 00:00:00 2001
+From: Bastian Hecht <hechtb@googlemail.com>
+Date: Fri, 23 Dec 2011 23:03:13 +0100
+Subject: mmc: tmio_mmc: Hotplug code regrouping
+
+This patch regroups the code slightly, adds documentation and allows
+the rtpm counter of MMC_CAP_NEEDS_POLL devices to reach 0 again.
+
+Signed-off-by: Bastian Hecht <hechtb@gmail.com>
+[g.liakhovetski@gmx.de: restore pm_runtime_get_noresume()]
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit cbb18b309d3d6b6661f931279697eac77b6591c9)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_pio.c | 30 +++++++++++++++++++++---------
+ 1 file changed, 21 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index 4208b39..abad01b 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -800,8 +800,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ } 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 ((pdata->flags & TMIO_MMC_HAS_COLD_CD) &&
+- pdata->power) {
++ if (pdata->power) {
+ pdata->power = false;
+ pm_runtime_put(&host->pdev->dev);
+ }
+@@ -915,6 +914,23 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ if (ret < 0)
+ goto pm_disable;
+
++ /*
++ * There are 4 different scenarios for the card detection:
++ * 1) an external gpio irq handles the cd (best for power savings)
++ * 2) internal sdhi irq handles the cd
++ * 3) a worker thread polls the sdhi - indicated by MMC_CAP_NEEDS_POLL
++ * 4) the medium is non-removable - indicated by MMC_CAP_NONREMOVABLE
++ *
++ * While we increment the rtpm 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
++ * powered on during runtime for the card detection to work.
++ */
++ if (!(pdata->flags & TMIO_MMC_HAS_COLD_CD
++ || mmc->caps & MMC_CAP_NEEDS_POLL
++ || mmc->caps & MMC_CAP_NONREMOVABLE))
++ pm_runtime_get_noresume(&pdev->dev);
++
+ tmio_mmc_clk_stop(_host);
+ tmio_mmc_reset(_host);
+
+@@ -933,12 +949,6 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ /* See if we also get DMA */
+ tmio_mmc_request_dma(_host, pdata);
+
+- /* We have to keep the device powered for its card detection to work */
+- if (!(pdata->flags & TMIO_MMC_HAS_COLD_CD)) {
+- pdata->power = true;
+- pm_runtime_get_noresume(&pdev->dev);
+- }
+-
+ mmc_add_host(mmc);
+
+ /* Unmask the IRQs we want to know about */
+@@ -974,7 +984,9 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
+ * the controller, the runtime PM is suspended and pdata->power == false,
+ * so, our .runtime_resume() will not try to detect a card in the slot.
+ */
+- if (host->pdata->flags & TMIO_MMC_HAS_COLD_CD)
++ if (host->pdata->flags & TMIO_MMC_HAS_COLD_CD
++ || host->mmc->caps & MMC_CAP_NEEDS_POLL
++ || host->mmc->caps & MMC_CAP_NONREMOVABLE)
+ pm_runtime_get_sync(&pdev->dev);
+
+ mmc_remove_host(host->mmc);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0043-mmc-host-move-to-dma_transfer_direction.patch b/patches.kzm9g/0043-mmc-host-move-to-dma_transfer_direction.patch
new file mode 100644
index 00000000000000..e0e100e94f4d61
--- /dev/null
+++ b/patches.kzm9g/0043-mmc-host-move-to-dma_transfer_direction.patch
@@ -0,0 +1,54 @@
+From aa9a805a43f06d6cf99be9a4ef28701aa8ec1314 Mon Sep 17 00:00:00 2001
+From: Vinod Koul <vinod.koul@linux.intel.com>
+Date: Fri, 14 Oct 2011 10:45:11 +0530
+Subject: mmc-host: move to dma_transfer_direction
+
+fixup usage of dma direction by introducing dma_transfer_direction,
+this patch moves mmc drivers to use new enum
+
+Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
+Cc: Chris Ball <cjb@laptop.org>
+Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry picked from commit 05f5799cbe5c9e2c03f604b3de5783cf4d726227)
+
+Conflicts:
+
+ drivers/mmc/host/atmel-mci.c
+ drivers/mmc/host/mmci.c
+ drivers/mmc/host/mxcmmc.c
+ drivers/mmc/host/mxs-mmc.c
+ drivers/mmc/host/sh_mmcif.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_dma.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c
+index 86f259c..7a6e6cc 100644
+--- a/drivers/mmc/host/tmio_mmc_dma.c
++++ b/drivers/mmc/host/tmio_mmc_dma.c
+@@ -77,7 +77,7 @@ static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
+ ret = dma_map_sg(chan->device->dev, sg, host->sg_len, DMA_FROM_DEVICE);
+ if (ret > 0)
+ desc = chan->device->device_prep_slave_sg(chan, sg, ret,
+- DMA_FROM_DEVICE, DMA_CTRL_ACK);
++ DMA_DEV_TO_MEM, DMA_CTRL_ACK);
+
+ if (desc) {
+ cookie = dmaengine_submit(desc);
+@@ -158,7 +158,7 @@ static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
+ ret = dma_map_sg(chan->device->dev, sg, host->sg_len, DMA_TO_DEVICE);
+ if (ret > 0)
+ desc = chan->device->device_prep_slave_sg(chan, sg, ret,
+- DMA_TO_DEVICE, DMA_CTRL_ACK);
++ DMA_MEM_TO_DEV, DMA_CTRL_ACK);
+
+ if (desc) {
+ cookie = dmaengine_submit(desc);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0044-mmc-tmio_mmc-fix-card-eject-during-IO-with-DMA.patch b/patches.kzm9g/0044-mmc-tmio_mmc-fix-card-eject-during-IO-with-DMA.patch
new file mode 100644
index 00000000000000..5f23faae47bc97
--- /dev/null
+++ b/patches.kzm9g/0044-mmc-tmio_mmc-fix-card-eject-during-IO-with-DMA.patch
@@ -0,0 +1,111 @@
+From 471b39df4319e8f35fe4ab3d91c859c391385bdd Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Fri, 6 Jan 2012 13:06:51 +0100
+Subject: mmc: tmio_mmc: fix card eject during IO with DMA
+
+When DMA is in use and the card is ejected during IO, DMA transfers have to
+be terminated, otherwise the dmaengine driver fails to operate properly,
+when the card is re-inserted.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit e3de2be7368d2983bd7f7ddb6e9cf5ea32363128)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc.h | 7 ++++++-
+ drivers/mmc/host/tmio_mmc_dma.c | 12 ++++++++++++
+ drivers/mmc/host/tmio_mmc_pio.c | 6 +++++-
+ 3 files changed, 23 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index a95e6d9..f96c536 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -20,8 +20,8 @@
+ #include <linux/mmc/tmio.h>
+ #include <linux/mutex.h>
+ #include <linux/pagemap.h>
+-#include <linux/spinlock.h>
+ #include <linux/scatterlist.h>
++#include <linux/spinlock.h>
+
+ /* Definitions for values the CTRL_SDIO_STATUS register can take. */
+ #define TMIO_SDIO_STAT_IOIRQ 0x0001
+@@ -120,6 +120,7 @@ void tmio_mmc_start_dma(struct tmio_mmc_host *host, struct mmc_data *data);
+ void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable);
+ void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata);
+ void tmio_mmc_release_dma(struct tmio_mmc_host *host);
++void tmio_mmc_abort_dma(struct tmio_mmc_host *host);
+ #else
+ static inline void tmio_mmc_start_dma(struct tmio_mmc_host *host,
+ struct mmc_data *data)
+@@ -140,6 +141,10 @@ static inline void tmio_mmc_request_dma(struct tmio_mmc_host *host,
+ static inline void tmio_mmc_release_dma(struct tmio_mmc_host *host)
+ {
+ }
++
++static inline void tmio_mmc_abort_dma(struct tmio_mmc_host *host)
++{
++}
+ #endif
+
+ #ifdef CONFIG_PM
+diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c
+index 7a6e6cc..8253ec1 100644
+--- a/drivers/mmc/host/tmio_mmc_dma.c
++++ b/drivers/mmc/host/tmio_mmc_dma.c
+@@ -34,6 +34,18 @@ void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
+ #endif
+ }
+
++void tmio_mmc_abort_dma(struct tmio_mmc_host *host)
++{
++ tmio_mmc_enable_dma(host, false);
++
++ if (host->chan_rx)
++ dmaengine_terminate_all(host->chan_rx);
++ if (host->chan_tx)
++ dmaengine_terminate_all(host->chan_tx);
++
++ tmio_mmc_enable_dma(host, true);
++}
++
+ static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
+ {
+ struct scatterlist *sg = host->sg_ptr, *sg_tmp;
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index abad01b..5f9ad74 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -41,8 +41,8 @@
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/scatterlist.h>
+-#include <linux/workqueue.h>
+ #include <linux/spinlock.h>
++#include <linux/workqueue.h>
+
+ #include "tmio_mmc.h"
+
+@@ -246,6 +246,7 @@ static void tmio_mmc_reset_work(struct work_struct *work)
+ /* Ready for new calls */
+ host->mrq = NULL;
+
++ tmio_mmc_abort_dma(host);
+ mmc_request_done(host->mmc, mrq);
+ }
+
+@@ -272,6 +273,9 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host)
+ host->mrq = NULL;
+ spin_unlock_irqrestore(&host->lock, flags);
+
++ if (mrq->cmd->error || (mrq->data && mrq->data->error))
++ tmio_mmc_abort_dma(host);
++
+ mmc_request_done(host->mmc, mrq);
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0045-mmc-tmio_mmc-do-not-enable-card-hotplug-interrupts-i.patch b/patches.kzm9g/0045-mmc-tmio_mmc-do-not-enable-card-hotplug-interrupts-i.patch
new file mode 100644
index 00000000000000..fbf34ec4499e10
--- /dev/null
+++ b/patches.kzm9g/0045-mmc-tmio_mmc-do-not-enable-card-hotplug-interrupts-i.patch
@@ -0,0 +1,53 @@
+From aa83922dbd8c0d4e16cbc28fae2d59a6d709ed07 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 22 Feb 2012 13:16:09 +0100
+Subject: mmc: tmio_mmc: do not enable card hotplug interrupts, if unused
+
+If TMIO MMC is used in polling mode, or the card is non-removable, or
+card-detection is performed, using an external interrupt, there is no
+need to enable controller native card hotplug interrupts.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit e23cd53c799694d0dc1d6a66370201ad9c181bae)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_pio.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index 5f9ad74..f013347 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -303,6 +303,7 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command
+ {
+ struct mmc_data *data = host->data;
+ int c = cmd->opcode;
++ u32 irq_mask = TMIO_MASK_CMD;
+
+ /* Command 12 is handled by hardware */
+ if (cmd->opcode == 12 && !cmd->arg) {
+@@ -338,7 +339,9 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command
+ c |= TRANSFER_READ;
+ }
+
+- tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_CMD);
++ if (!host->native_hotplug)
++ irq_mask &= ~(TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT);
++ tmio_mmc_enable_mmc_irqs(host, irq_mask);
+
+ /* Fire off the command */
+ sd_ctrl_write32(host, CTL_ARG_REG, cmd->arg);
+@@ -960,6 +963,8 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ 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);
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0046-mmc-tmio-calculate-the-native-hotplug-condition-only.patch b/patches.kzm9g/0046-mmc-tmio-calculate-the-native-hotplug-condition-only.patch
new file mode 100644
index 00000000000000..f2e1b51a51d4d0
--- /dev/null
+++ b/patches.kzm9g/0046-mmc-tmio-calculate-the-native-hotplug-condition-only.patch
@@ -0,0 +1,71 @@
+From ca17c6399644d13094702101c3a3960445a465dd Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 9 Feb 2012 22:57:08 +0100
+Subject: mmc: tmio: calculate the native hotplug condition only once
+
+The condition, whether we have to use the native TMIO card hotplug
+detection interrupt, is rather complex, it is better to only calculate it
+once and store in the private data.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 2b1ac5c2caccbfd43bd616321cbbe21eb33c7879)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc.h | 1 +
+ drivers/mmc/host/tmio_mmc_pio.c | 12 ++++++------
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index f96c536..8531d8d 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -86,6 +86,7 @@ struct tmio_mmc_host {
+ spinlock_t lock; /* protect host private data */
+ unsigned long last_req_ts;
+ struct mutex ios_lock; /* protect set_ios() context */
++ bool native_hotplug;
+ };
+
+ int tmio_mmc_host_probe(struct tmio_mmc_host **host,
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index f013347..0a111f4 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -915,6 +915,10 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ else
+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+
++ _host->native_hotplug = !(pdata->flags & TMIO_MMC_HAS_COLD_CD ||
++ mmc->caps & MMC_CAP_NEEDS_POLL ||
++ mmc->caps & MMC_CAP_NONREMOVABLE);
++
+ pdata->power = false;
+ pm_runtime_enable(&pdev->dev);
+ ret = pm_runtime_resume(&pdev->dev);
+@@ -933,9 +937,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ * additionally ensure that in case 2) the tmio mmc hardware stays
+ * powered on during runtime for the card detection to work.
+ */
+- if (!(pdata->flags & TMIO_MMC_HAS_COLD_CD
+- || mmc->caps & MMC_CAP_NEEDS_POLL
+- || mmc->caps & MMC_CAP_NONREMOVABLE))
++ if (_host->native_hotplug)
+ pm_runtime_get_noresume(&pdev->dev);
+
+ tmio_mmc_clk_stop(_host);
+@@ -993,9 +995,7 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
+ * the controller, the runtime PM is suspended and pdata->power == false,
+ * so, our .runtime_resume() will not try to detect a card in the slot.
+ */
+- if (host->pdata->flags & TMIO_MMC_HAS_COLD_CD
+- || host->mmc->caps & MMC_CAP_NEEDS_POLL
+- || host->mmc->caps & MMC_CAP_NONREMOVABLE)
++ if (!host->native_hotplug)
+ pm_runtime_get_sync(&pdev->dev);
+
+ mmc_remove_host(host->mmc);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0047-mmc-tmio_mmc-support-the-generic-MMC-GPIO-card-hotpl.patch b/patches.kzm9g/0047-mmc-tmio_mmc-support-the-generic-MMC-GPIO-card-hotpl.patch
new file mode 100644
index 00000000000000..5d839b0bb05098
--- /dev/null
+++ b/patches.kzm9g/0047-mmc-tmio_mmc-support-the-generic-MMC-GPIO-card-hotpl.patch
@@ -0,0 +1,255 @@
+From 8605d396d99e7c52ec9a8b5f67835735ce9fa7c2 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 9 Feb 2012 22:57:09 +0100
+Subject: mmc: tmio_mmc: support the generic MMC GPIO card hotplug helper
+
+If the platform specifies the TMIO_MMC_HAS_COLD_CD flag, use the generic
+MMC GPIO card hotplug helper.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit c8be24c2afd3ed2445bbf8f542af35a9787fc0e8)
+
+Conflicts:
+
+ drivers/mmc/host/tmio_mmc_pio.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc.h | 4 ---
+ drivers/mmc/host/tmio_mmc_pio.c | 67 ++++++++++++++++++-----------------------
+ include/linux/mfd/tmio.h | 25 +++++++++++----
+ 3 files changed, 49 insertions(+), 47 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index 8531d8d..ede2f4e5 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -53,10 +53,6 @@ struct tmio_mmc_host {
+ void (*set_pwr)(struct platform_device *host, int state);
+ void (*set_clk_div)(struct platform_device *host, int state);
+
+- int pm_error;
+- /* recognise system-wide suspend in runtime PM methods */
+- bool pm_global;
+-
+ /* pio related stuff */
+ struct scatterlist *sg_ptr;
+ struct scatterlist *sg_orig;
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index 0a111f4..ce5f126 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -34,6 +34,7 @@
+ #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/tmio.h>
+ #include <linux/module.h>
+@@ -790,8 +791,10 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ /*
+- * pdata->power == false only if COLD_CD is available, otherwise only
+- * in short time intervals during probing or resuming
++ * pdata->power toggles between false and true in both cases - either
++ * or not the controller can be runtime-suspended during inactivity.
++ * But if the controller has to be kept on, the runtime-pm usage_count
++ * is kept positive, so no suspending actually takes place.
+ */
+ if (ios->power_mode == MMC_POWER_ON && ios->clock) {
+ if (!pdata->power) {
+@@ -915,7 +918,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ else
+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+- _host->native_hotplug = !(pdata->flags & TMIO_MMC_HAS_COLD_CD ||
++ _host->native_hotplug = !(pdata->flags & TMIO_MMC_USE_GPIO_CD ||
+ mmc->caps & MMC_CAP_NEEDS_POLL ||
+ mmc->caps & MMC_CAP_NONREMOVABLE);
+
+@@ -932,8 +935,9 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ * 3) a worker thread polls the sdhi - indicated by MMC_CAP_NEEDS_POLL
+ * 4) the medium is non-removable - indicated by MMC_CAP_NONREMOVABLE
+ *
+- * While we increment the rtpm counter for all scenarios when the mmc
+- * core activates us by calling an appropriate set_ios(), we must
++ * 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.
+ */
+@@ -970,6 +974,14 @@ 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);
++ if (ret < 0) {
++ tmio_mmc_host_remove(_host);
++ return ret;
++ }
++ }
++
+ *host = _host;
+
+ return 0;
+@@ -987,14 +999,16 @@ EXPORT_SYMBOL(tmio_mmc_host_probe);
+ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
+ {
+ struct platform_device *pdev = host->pdev;
++ struct tmio_mmc_data *pdata = host->pdata;
++ struct mmc_host *mmc = host->mmc;
++
++ if (pdata->flags & TMIO_MMC_USE_GPIO_CD)
++ /*
++ * 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);
+
+- /*
+- * We don't have to manipulate pdata->power here: if there is a card in
+- * the slot, the runtime PM is active and our .runtime_resume() will not
+- * be run. If there is no card in the slot and the platform can suspend
+- * the controller, the runtime PM is suspended and pdata->power == false,
+- * so, our .runtime_resume() will not try to detect a card in the slot.
+- */
+ if (!host->native_hotplug)
+ pm_runtime_get_sync(&pdev->dev);
+
+@@ -1007,7 +1021,7 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
+ pm_runtime_disable(&pdev->dev);
+
+ iounmap(host->ctl);
+- mmc_free_host(host->mmc);
++ mmc_free_host(mmc);
+ }
+ EXPORT_SYMBOL(tmio_mmc_host_remove);
+
+@@ -1021,8 +1035,6 @@ int tmio_mmc_host_suspend(struct device *dev)
+ if (!ret)
+ tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL);
+
+- host->pm_error = pm_runtime_put_sync(dev);
+-
+ return ret;
+ }
+ EXPORT_SYMBOL(tmio_mmc_host_suspend);
+@@ -1032,20 +1044,10 @@ int tmio_mmc_host_resume(struct device *dev)
+ struct mmc_host *mmc = dev_get_drvdata(dev);
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+
+- /* The MMC core will perform the complete set up */
+- host->pdata->power = false;
+-
+- host->pm_global = true;
+- if (!host->pm_error)
+- pm_runtime_get_sync(dev);
+-
+- if (host->pm_global) {
+- /* Runtime PM resume callback didn't run */
+- tmio_mmc_reset(host);
+- tmio_mmc_enable_dma(host, true);
+- host->pm_global = false;
+- }
++ tmio_mmc_reset(host);
++ tmio_mmc_enable_dma(host, true);
+
++ /* The MMC core will perform the complete set up */
+ return mmc_resume_host(mmc);
+ }
+ EXPORT_SYMBOL(tmio_mmc_host_resume);
+@@ -1062,19 +1064,10 @@ int tmio_mmc_host_runtime_resume(struct device *dev)
+ {
+ struct mmc_host *mmc = dev_get_drvdata(dev);
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+- struct tmio_mmc_data *pdata = host->pdata;
+
+ tmio_mmc_reset(host);
+ tmio_mmc_enable_dma(host, true);
+
+- if (pdata->power) {
+- /* Only entered after a card-insert interrupt */
+- if (!mmc->card)
+- tmio_mmc_set_ios(mmc, &mmc->ios);
+- mmc_detect_change(mmc, msecs_to_jiffies(100));
+- }
+- host->pm_global = false;
+-
+ return 0;
+ }
+ EXPORT_SYMBOL(tmio_mmc_host_runtime_resume);
+diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
+index 0dc9804..5a197de 100644
+--- a/include/linux/mfd/tmio.h
++++ b/include/linux/mfd/tmio.h
+@@ -1,8 +1,10 @@
+ #ifndef MFD_TMIO_H
+ #define MFD_TMIO_H
+
++#include <linux/device.h>
+ #include <linux/fb.h>
+ #include <linux/io.h>
++#include <linux/jiffies.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+
+@@ -64,8 +66,8 @@
+ #define TMIO_MMC_SDIO_IRQ (1 << 2)
+ /*
+ * Some platforms can detect card insertion events with controller powered
+- * down, in which case they have to call tmio_mmc_cd_wakeup() to power up the
+- * controller and report the event to the driver.
++ * down, using a GPIO IRQ, in which case they have to fill in cd_irq, cd_gpio,
++ * and cd_flags fields of struct tmio_mmc_data.
+ */
+ #define TMIO_MMC_HAS_COLD_CD (1 << 3)
+ /*
+@@ -73,6 +75,12 @@
+ * idle before writing to some registers.
+ */
+ #define TMIO_MMC_HAS_IDLE_WAIT (1 << 4)
++/*
++ * A GPIO is used for card hotplug detection. We need an extra flag for this,
++ * because 0 is a valid GPIO number too, and requiring users to specify
++ * cd_gpio < 0 to disable GPIO hotplug would break backwards compatibility.
++ */
++#define TMIO_MMC_USE_GPIO_CD (1 << 5)
+
+ int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base);
+ int tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base);
+@@ -98,18 +106,23 @@ struct tmio_mmc_data {
+ struct tmio_mmc_dma *dma;
+ struct device *dev;
+ bool power;
++ unsigned int cd_gpio;
+ void (*set_pwr)(struct platform_device *host, int state);
+ 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);
+ };
+
++/*
++ * This function is deprecated and will be removed soon. Please, convert your
++ * platform to use drivers/mmc/core/cd-gpio.c
++ */
++#include <linux/mmc/host.h>
+ static inline void tmio_mmc_cd_wakeup(struct tmio_mmc_data *pdata)
+ {
+- if (pdata && !pdata->power) {
+- pdata->power = true;
+- pm_runtime_get(pdata->dev);
+- }
++ if (pdata)
++ mmc_detect_change(dev_get_drvdata(pdata->dev),
++ msecs_to_jiffies(100));
+ }
+
+ /*
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0048-mmc-sh_mobile_sdhi-pass-card-hotplug-GPIO-number-to-.patch b/patches.kzm9g/0048-mmc-sh_mobile_sdhi-pass-card-hotplug-GPIO-number-to-.patch
new file mode 100644
index 00000000000000..48b733b7c362b7
--- /dev/null
+++ b/patches.kzm9g/0048-mmc-sh_mobile_sdhi-pass-card-hotplug-GPIO-number-to-.patch
@@ -0,0 +1,55 @@
+From 4c75a4614497dab36aeb8a5a033ae5da1cb18a98 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 9 Feb 2012 22:57:10 +0100
+Subject: mmc: sh_mobile_sdhi: pass card hotplug GPIO number to TMIO MMC
+
+To use TMIO MMC driver ability to interface to the generic MMC GPIO card
+hotplug detection helper, the SDHI driver has to pass the GPIO number
+from its own platform data.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 58126c878b4a4f658015e383614bafb6331e46d3)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mobile_sdhi.c | 3 ++-
+ include/linux/mmc/sh_mobile_sdhi.h | 1 +
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index 58da3c4..cb279b4 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -129,6 +129,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->cd_gpio = p->cd_gpio;
+
+ if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) {
+ priv->param_tx.slave_id = p->dma_slave_tx;
+@@ -211,7 +212,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+
+ dev_info(&pdev->dev, "%s base at 0x%08lx clock rate %u MHz\n",
+ mmc_hostname(host->mmc), (unsigned long)
+- (platform_get_resource(pdev,IORESOURCE_MEM, 0)->start),
++ (platform_get_resource(pdev, IORESOURCE_MEM, 0)->start),
+ mmc_data->hclk / 1000000);
+
+ return ret;
+diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
+index 71b8054..082a736 100644
+--- a/include/linux/mmc/sh_mobile_sdhi.h
++++ b/include/linux/mmc/sh_mobile_sdhi.h
+@@ -16,6 +16,7 @@ struct sh_mobile_sdhi_info {
+ unsigned long tmio_flags;
+ unsigned long tmio_caps;
+ u32 tmio_ocr_mask; /* available MMC voltages */
++ unsigned int cd_gpio;
+ struct tmio_mmc_data *pdata;
+ void (*set_pwr)(struct platform_device *pdev, int state);
+ int (*get_cd)(struct platform_device *pdev);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0049-mmc-tmio_mmc-power-status-flag-doesn-t-have-to-be-ex.patch b/patches.kzm9g/0049-mmc-tmio_mmc-power-status-flag-doesn-t-have-to-be-ex.patch
new file mode 100644
index 00000000000000..c11b9bb76837a2
--- /dev/null
+++ b/patches.kzm9g/0049-mmc-tmio_mmc-power-status-flag-doesn-t-have-to-be-ex.patch
@@ -0,0 +1,101 @@
+From 9c90215e8425dad06659dcb19f69b7c62d5de92a Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 9 Feb 2012 22:57:13 +0100
+Subject: mmc: tmio_mmc: power status flag doesn't have to be exposed in
+ platform data
+
+The controller power status flag does not have to be accessed from the
+hot-plug detection code any more, it can now be removed from the platform
+data and put in the controller private struct.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit c391e1b9ebfe31514fa95a0cdd30c2cbc9652c89)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc.h | 3 +++
+ drivers/mmc/host/tmio_mmc_pio.c | 13 ++++++-------
+ include/linux/mfd/tmio.h | 1 -
+ 3 files changed, 9 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index ede2f4e5..edfcfd7 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -49,6 +49,9 @@ struct tmio_mmc_host {
+ struct mmc_host *mmc;
+ unsigned int sdio_irq_enabled;
+
++ /* Controller power state */
++ bool power;
++
+ /* Callbacks for clock / power control */
+ void (*set_pwr)(struct platform_device *host, int state);
+ void (*set_clk_div)(struct platform_device *host, int state);
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index ce5f126..4a2829c 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -761,7 +761,6 @@ fail:
+ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ {
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+- struct tmio_mmc_data *pdata = host->pdata;
+ unsigned long flags;
+
+ mutex_lock(&host->ios_lock);
+@@ -791,15 +790,15 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ /*
+- * pdata->power toggles between false and true in both cases - either
++ * host->power toggles between false and true in both cases - either
+ * or not the controller can be runtime-suspended during inactivity.
+ * But if the controller has to be kept on, the runtime-pm usage_count
+ * is kept positive, so no suspending actually takes place.
+ */
+ if (ios->power_mode == MMC_POWER_ON && ios->clock) {
+- if (!pdata->power) {
++ if (!host->power) {
+ pm_runtime_get_sync(&host->pdev->dev);
+- pdata->power = true;
++ host->power = true;
+ }
+ tmio_mmc_set_clock(host, ios->clock);
+ /* power up SD bus */
+@@ -810,8 +809,8 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ } 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 (pdata->power) {
+- pdata->power = false;
++ if (host->power) {
++ host->power = false;
+ pm_runtime_put(&host->pdev->dev);
+ }
+ tmio_mmc_clk_stop(host);
+@@ -922,7 +921,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ mmc->caps & MMC_CAP_NEEDS_POLL ||
+ mmc->caps & MMC_CAP_NONREMOVABLE);
+
+- pdata->power = false;
++ _host->power = false;
+ pm_runtime_enable(&pdev->dev);
+ ret = pm_runtime_resume(&pdev->dev);
+ if (ret < 0)
+diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
+index 5a197de..f5171db 100644
+--- a/include/linux/mfd/tmio.h
++++ b/include/linux/mfd/tmio.h
+@@ -105,7 +105,6 @@ struct tmio_mmc_data {
+ u32 ocr_mask; /* available voltages */
+ struct tmio_mmc_dma *dma;
+ struct device *dev;
+- bool power;
+ unsigned int cd_gpio;
+ void (*set_pwr)(struct platform_device *host, int state);
+ void (*set_clk_div)(struct platform_device *host, int state);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0050-mmc-tmio_mmc-remove-unused-sdio_irq_enabled-flag.patch b/patches.kzm9g/0050-mmc-tmio_mmc-remove-unused-sdio_irq_enabled-flag.patch
new file mode 100644
index 00000000000000..0e15dcedde89cd
--- /dev/null
+++ b/patches.kzm9g/0050-mmc-tmio_mmc-remove-unused-sdio_irq_enabled-flag.patch
@@ -0,0 +1,54 @@
+From a863686f8649014af31553e5d294fb6fc34a0406 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 9 Feb 2012 22:57:14 +0100
+Subject: mmc: tmio_mmc: remove unused sdio_irq_enabled flag
+
+The sdio_irq_enabled member of struct tmio_mmc_host is a left-over from the
+previously removed SDIO IRQ workaround. It is no longer needed and can now
+be removed too.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 5bd99c375e141b8dd12e18c45617158f98920e57)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc.h | 1 -
+ drivers/mmc/host/tmio_mmc_pio.c | 2 --
+ 2 files changed, 3 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+index edfcfd7..d857f5c 100644
+--- a/drivers/mmc/host/tmio_mmc.h
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -47,7 +47,6 @@ struct tmio_mmc_host {
+ struct mmc_request *mrq;
+ struct mmc_data *data;
+ struct mmc_host *mmc;
+- unsigned int sdio_irq_enabled;
+
+ /* Controller power state */
+ bool power;
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index 4a2829c..97110ba 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -127,7 +127,6 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+
+ if (enable) {
+- host->sdio_irq_enabled = 1;
+ host->sdio_irq_mask = TMIO_SDIO_MASK_ALL &
+ ~TMIO_SDIO_STAT_IOIRQ;
+ sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
+@@ -136,7 +135,6 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+ host->sdio_irq_mask = TMIO_SDIO_MASK_ALL;
+ sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask);
+ sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000);
+- host->sdio_irq_enabled = 0;
+ }
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0051-mmc-sh_mobile_sdhi-do-not-manage-PM-clocks-manually.patch b/patches.kzm9g/0051-mmc-sh_mobile_sdhi-do-not-manage-PM-clocks-manually.patch
new file mode 100644
index 00000000000000..3d6c1a941d4438
--- /dev/null
+++ b/patches.kzm9g/0051-mmc-sh_mobile_sdhi-do-not-manage-PM-clocks-manually.patch
@@ -0,0 +1,52 @@
+From 3305f89b5921cc5a8174d1fa302be7ff8fd7085b Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 9 Feb 2012 22:57:15 +0100
+Subject: mmc: sh_mobile_sdhi: do not manage PM clocks manually
+
+On sh-mobile platforms the MMC clock frequency for the TMIO MMC unit is
+obtained from the same clock, as the one, that runtime power-manages the
+controller. The SDHI glue code has to access that clock directly,
+bypassing the runtime PM framework, to get its frequency, but it
+shouldn't enable or disable it.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 996bc8aebd2cd5b6d4c5d85085f171fa2447f364)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mobile_sdhi.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index cb279b4..f91c3aa 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -117,8 +117,6 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+ goto eclkget;
+ }
+
+- clk_enable(priv->clk);
+-
+ 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;
+@@ -233,7 +231,6 @@ eirq_sdio:
+ eirq_card_detect:
+ tmio_mmc_host_remove(host);
+ eprobe:
+- clk_disable(priv->clk);
+ clk_put(priv->clk);
+ eclkget:
+ kfree(priv);
+@@ -259,7 +256,6 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
+ free_irq(irq, host);
+ }
+
+- clk_disable(priv->clk);
+ clk_put(priv->clk);
+ kfree(priv);
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0052-mmc-tmio-cosmetic-prettify-the-tmio_mmc_set_ios-func.patch b/patches.kzm9g/0052-mmc-tmio-cosmetic-prettify-the-tmio_mmc_set_ios-func.patch
new file mode 100644
index 00000000000000..f4c6d66f0d0095
--- /dev/null
+++ b/patches.kzm9g/0052-mmc-tmio-cosmetic-prettify-the-tmio_mmc_set_ios-func.patch
@@ -0,0 +1,63 @@
+From 62da637655deae3561b0ba9fd230afa6e15cc221 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 9 Feb 2012 22:57:16 +0100
+Subject: mmc: tmio: cosmetic: prettify the tmio_mmc_set_ios() function
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 4932bd64a2bb4e80b79efb20c4736ac3b30ba7fe)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/tmio_mmc_pio.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
+index 97110ba..2500163 100644
+--- a/drivers/mmc/host/tmio_mmc_pio.c
++++ b/drivers/mmc/host/tmio_mmc_pio.c
+@@ -759,6 +759,7 @@ fail:
+ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ {
+ struct tmio_mmc_host *host = mmc_priv(mmc);
++ struct device *dev = &host->pdev->dev;
+ unsigned long flags;
+
+ mutex_lock(&host->ios_lock);
+@@ -766,13 +767,13 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ spin_lock_irqsave(&host->lock, flags);
+ if (host->mrq) {
+ if (IS_ERR(host->mrq)) {
+- dev_dbg(&host->pdev->dev,
++ dev_dbg(dev,
+ "%s.%d: concurrent .set_ios(), clk %u, mode %u\n",
+ current->comm, task_pid_nr(current),
+ ios->clock, ios->power_mode);
+ host->mrq = ERR_PTR(-EINTR);
+ } else {
+- dev_dbg(&host->pdev->dev,
++ dev_dbg(dev,
+ "%s.%d: CMD%u active since %lu, now %lu!\n",
+ current->comm, task_pid_nr(current),
+ host->mrq->cmd->opcode, host->last_req_ts, jiffies);
+@@ -795,7 +796,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) {
+- pm_runtime_get_sync(&host->pdev->dev);
++ pm_runtime_get_sync(dev);
+ host->power = true;
+ }
+ tmio_mmc_set_clock(host, ios->clock);
+@@ -809,7 +810,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ host->set_pwr(host->pdev, 0);
+ if (host->power) {
+ host->power = false;
+- pm_runtime_put(&host->pdev->dev);
++ pm_runtime_put(dev);
+ }
+ tmio_mmc_clk_stop(host);
+ }
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0053-mmc-sh_mobile_sdhi-add-a-callback-for-board-specific.patch b/patches.kzm9g/0053-mmc-sh_mobile_sdhi-add-a-callback-for-board-specific.patch
new file mode 100644
index 00000000000000..58860876e860ab
--- /dev/null
+++ b/patches.kzm9g/0053-mmc-sh_mobile_sdhi-add-a-callback-for-board-specific.patch
@@ -0,0 +1,74 @@
+From 0a98733a6514780187f2f435f3057949932d531b Mon Sep 17 00:00:00 2001
+From: Bastian Hecht <hechtb@googlemail.com>
+Date: Fri, 16 Mar 2012 12:19:29 -0400
+Subject: mmc: sh_mobile_sdhi: add a callback for board specific init code
+
+Some boards need a preliminary setup stage to prepare the sdhi
+controller.
+
+Signed-off-by: Bastian Hecht <hechtb@gmail.com>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit e82b4ac94e5c43fad51b975aed058858ceda1f0f)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mobile_sdhi.c | 13 +++++++++++++
+ include/linux/mmc/sh_mobile_sdhi.h | 4 ++++
+ 2 files changed, 17 insertions(+)
+
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index f91c3aa..07ff3fe 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -109,6 +109,12 @@ 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);
++ if (ret)
++ goto einit;
++ }
++
+ snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id);
+ priv->clk = clk_get(&pdev->dev, clk_name);
+ if (IS_ERR(priv->clk)) {
+@@ -233,6 +239,9 @@ eirq_card_detect:
+ eprobe:
+ clk_put(priv->clk);
+ eclkget:
++ if (p->cleanup)
++ p->cleanup(pdev);
++einit:
+ kfree(priv);
+ return ret;
+ }
+@@ -257,6 +266,10 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
+ }
+
+ clk_put(priv->clk);
++
++ if (p->cleanup)
++ p->cleanup(pdev);
++
+ kfree(priv);
+
+ return 0;
+diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
+index 082a736..686b85b 100644
+--- a/include/linux/mmc/sh_mobile_sdhi.h
++++ b/include/linux/mmc/sh_mobile_sdhi.h
+@@ -20,6 +20,10 @@ struct sh_mobile_sdhi_info {
+ struct tmio_mmc_data *pdata;
+ void (*set_pwr)(struct platform_device *pdev, int state);
+ int (*get_cd)(struct platform_device *pdev);
++
++ /* callbacks for board specific setup code */
++ int (*init)(struct platform_device *pdev);
++ void (*cleanup)(struct platform_device *pdev);
+ };
+
+ #endif /* LINUX_MMC_SH_MOBILE_SDHI_H */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0054-mmc-sh_mobile_sdhi-support-modular-mmc-core-with-non.patch b/patches.kzm9g/0054-mmc-sh_mobile_sdhi-support-modular-mmc-core-with-non.patch
new file mode 100644
index 00000000000000..bbffae5a0f631f
--- /dev/null
+++ b/patches.kzm9g/0054-mmc-sh_mobile_sdhi-support-modular-mmc-core-with-non.patch
@@ -0,0 +1,85 @@
+From 0107e6bd1c3993bcd3cefb7406bff5976921bced Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Fri, 9 Mar 2012 10:16:00 +0100
+Subject: mmc: sh_mobile_sdhi: support modular mmc-core with non-standard
+ hotplug
+
+Currently if a platform wants to implement a non-standard card-detection
+method, it would need to call tmio_mmc_cd_wakeup(), which is an inline
+function, calling mmc_detect_change(). For this the platform would have
+to link mmc_core statically into the kernel, losing the ability to build
+it as a module. This patch adds a callback to the sh_mobile_sdhi driver,
+which eliminates this dependency.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Acked-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 7f524217439cc17da74523582c303cced432713e)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mobile_sdhi.c | 11 ++++++++++-
+ include/linux/mmc/sh_mobile_sdhi.h | 11 ++++++++++-
+ 2 files changed, 20 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
+index 07ff3fe..934b68e 100644
+--- a/drivers/mmc/host/sh_mobile_sdhi.c
++++ b/drivers/mmc/host/sh_mobile_sdhi.c
+@@ -90,6 +90,15 @@ static int sh_mobile_sdhi_write16_hook(struct tmio_mmc_host *host, int addr)
+ return 0;
+ }
+
++static void sh_mobile_sdhi_cd_wakeup(const struct platform_device *pdev)
++{
++ mmc_detect_change(dev_get_drvdata(&pdev->dev), msecs_to_jiffies(100));
++}
++
++static const struct sh_mobile_sdhi_ops sdhi_ops = {
++ .cd_wakeup = sh_mobile_sdhi_cd_wakeup,
++};
++
+ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+ {
+ struct sh_mobile_sdhi *priv;
+@@ -110,7 +119,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
+ p->pdata = mmc_data;
+
+ if (p->init) {
+- ret = p->init(pdev);
++ ret = p->init(pdev, &sdhi_ops);
+ if (ret)
+ goto einit;
+ }
+diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
+index 686b85b..e94e620 100644
+--- a/include/linux/mmc/sh_mobile_sdhi.h
++++ b/include/linux/mmc/sh_mobile_sdhi.h
+@@ -10,6 +10,14 @@ struct tmio_mmc_data;
+ #define SH_MOBILE_SDHI_IRQ_SDCARD "sdcard"
+ #define SH_MOBILE_SDHI_IRQ_SDIO "sdio"
+
++/**
++ * struct sh_mobile_sdhi_ops - SDHI driver callbacks
++ * @cd_wakeup: trigger a card-detection run
++ */
++struct sh_mobile_sdhi_ops {
++ void (*cd_wakeup)(const struct platform_device *pdev);
++};
++
+ struct sh_mobile_sdhi_info {
+ int dma_slave_tx;
+ int dma_slave_rx;
+@@ -22,7 +30,8 @@ struct sh_mobile_sdhi_info {
+ int (*get_cd)(struct platform_device *pdev);
+
+ /* callbacks for board specific setup code */
+- int (*init)(struct platform_device *pdev);
++ int (*init)(struct platform_device *pdev,
++ const struct sh_mobile_sdhi_ops *ops);
+ void (*cleanup)(struct platform_device *pdev);
+ };
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0055-mmc-Standardize-header-file-inclusion-checks.patch b/patches.kzm9g/0055-mmc-Standardize-header-file-inclusion-checks.patch
new file mode 100644
index 00000000000000..2ba0ecbdc76767
--- /dev/null
+++ b/patches.kzm9g/0055-mmc-Standardize-header-file-inclusion-checks.patch
@@ -0,0 +1,61 @@
+From 905868b59a760b3df8ce9ae406534a8299e0a0e2 Mon Sep 17 00:00:00 2001
+From: "Robert P. J. Day" <rpjday@crashcourse.ca>
+Date: Fri, 27 May 2011 16:04:03 -0400
+Subject: mmc: Standardize header file inclusion checks.
+
+Standardize the checks for multiple MMC header file inclusion,
+including adding comments to terminating #endif's, and fixing
+one incorrect comment.
+
+Signed-off-by: Robert P. J. Day <rpjday@crashcourse.ca>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 100e918610b7487fa18db97b3879cd8d1fdd5974)
+
+Conflicts:
+
+ include/linux/mmc/boot.h
+ include/linux/mmc/card.h
+ include/linux/mmc/core.h
+ include/linux/mmc/dw_mmc.h
+ include/linux/mmc/host.h
+ include/linux/mmc/ioctl.h
+ include/linux/mmc/mmc.h
+ include/linux/mmc/pm.h
+ include/linux/mmc/sd.h
+ include/linux/mmc/sdhci-spear.h
+ include/linux/mmc/sdhci.h
+ include/linux/mmc/sdio.h
+ include/linux/mmc/sdio_func.h
+ include/linux/mmc/sdio_ids.h
+ include/linux/mmc/sh_mobile_sdhi.h
+ include/linux/mmc/tmio.h
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/mmc/sh_mmcif.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h
+index 9eb9b4b..0222cd8 100644
+--- a/include/linux/mmc/sh_mmcif.h
++++ b/include/linux/mmc/sh_mmcif.h
+@@ -11,8 +11,8 @@
+ *
+ */
+
+-#ifndef __SH_MMCIF_H__
+-#define __SH_MMCIF_H__
++#ifndef LINUX_MMC_SH_MMCIF_H
++#define LINUX_MMC_SH_MMCIF_H
+
+ #include <linux/io.h>
+ #include <linux/platform_device.h>
+@@ -220,4 +220,4 @@ static inline void sh_mmcif_boot_init(void __iomem *base)
+ sh_mmcif_boot_cmd(base, 0x03400040, 0x00010000);
+ }
+
+-#endif /* __SH_MMCIF_H__ */
++#endif /* LINUX_MMC_SH_MMCIF_H */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0056-mmc-sh_mmcif-maximize-power-saving.patch b/patches.kzm9g/0056-mmc-sh_mmcif-maximize-power-saving.patch
new file mode 100644
index 00000000000000..28e6383a2bf9f9
--- /dev/null
+++ b/patches.kzm9g/0056-mmc-sh_mmcif-maximize-power-saving.patch
@@ -0,0 +1,82 @@
+From 896e44c328f1ab6c44097333ba1db7ae3a08ff5d Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Thu, 26 May 2011 15:33:30 +0200
+Subject: mmc: sh_mmcif: maximize power saving
+
+This patch uses runtime PM to allow the system to power down the MMC
+controller, when the MMC closk is switched off.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit c9b0cef23f8d2a16c97623d25d6e8f8e93a56e4b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 27 ++++++++++++++++++---------
+ 1 file changed, 18 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index 14f8edb..557886b 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -175,6 +175,7 @@ struct sh_mmcif_host {
+ enum mmcif_state state;
+ spinlock_t lock;
+ bool power;
++ bool card_present;
+
+ /* DMA support */
+ struct dma_chan *chan_rx;
+@@ -877,23 +878,23 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ if (ios->power_mode == MMC_POWER_UP) {
+- if (p->set_pwr)
+- p->set_pwr(host->pd, ios->power_mode);
+- if (!host->power) {
++ if (!host->card_present) {
+ /* See if we also get DMA */
+ sh_mmcif_request_dma(host, host->pd->dev.platform_data);
+- pm_runtime_get_sync(&host->pd->dev);
+- host->power = true;
++ host->card_present = true;
+ }
+ } else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) {
+ /* clock stop */
+ sh_mmcif_clock_control(host, 0);
+ if (ios->power_mode == MMC_POWER_OFF) {
+- if (host->power) {
+- pm_runtime_put(&host->pd->dev);
++ if (host->card_present) {
+ sh_mmcif_release_dma(host);
+- host->power = false;
++ host->card_present = false;
+ }
++ }
++ if (host->power) {
++ pm_runtime_put(&host->pd->dev);
++ host->power = false;
+ if (p->down_pwr)
+ p->down_pwr(host->pd);
+ }
+@@ -901,8 +902,16 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ return;
+ }
+
+- if (ios->clock)
++ if (ios->clock) {
++ if (!host->power) {
++ if (p->set_pwr)
++ p->set_pwr(host->pd, ios->power_mode);
++ pm_runtime_get_sync(&host->pd->dev);
++ host->power = true;
++ sh_mmcif_sync_reset(host);
++ }
+ sh_mmcif_clock_control(host, ios->clock);
++ }
+
+ host->bus_width = ios->bus_width;
+ host->state = STATE_IDLE;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0057-mmc-sh_mmcif-simplify-platform-data.patch b/patches.kzm9g/0057-mmc-sh_mmcif-simplify-platform-data.patch
new file mode 100644
index 00000000000000..3197c322c9b371
--- /dev/null
+++ b/patches.kzm9g/0057-mmc-sh_mmcif-simplify-platform-data.patch
@@ -0,0 +1,89 @@
+From e269a3b04e790e2b0c18d19a64358706363f9ace Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Tue, 30 Aug 2011 18:26:39 +0200
+Subject: mmc: sh_mmcif: simplify platform data
+
+Provide platforms with a simplified way to specify MMCIF DMA slave IDs in
+a way, similar to SDHI and other sh_dma clients.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 714c4a6e3a0f730834ec8a8bc83b2a6da33f54dc)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 20 ++++++++++++++++----
+ include/linux/mmc/sh_mmcif.h | 4 +++-
+ 2 files changed, 19 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index 557886b..bd91c94 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -165,6 +165,8 @@ struct sh_mmcif_host {
+ struct mmc_host *mmc;
+ struct mmc_data *data;
+ 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;
+@@ -323,25 +325,35 @@ static bool sh_mmcif_filter(struct dma_chan *chan, void *arg)
+ static void sh_mmcif_request_dma(struct sh_mmcif_host *host,
+ struct sh_mmcif_plat_data *pdata)
+ {
++ struct sh_dmae_slave *tx, *rx;
+ 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) {
+ 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,
+- &pdata->dma->chan_priv_tx);
++ host->chan_tx = dma_request_channel(mask, sh_mmcif_filter, tx);
+ 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,
+- &pdata->dma->chan_priv_rx);
++ host->chan_rx = dma_request_channel(mask, sh_mmcif_filter, rx);
+ 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 0222cd8..04ff452 100644
+--- a/include/linux/mmc/sh_mmcif.h
++++ b/include/linux/mmc/sh_mmcif.h
+@@ -41,7 +41,9 @@ 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;
++ struct sh_mmcif_dma *dma; /* Deprecated. Instead */
++ unsigned int slave_id_tx; /* use embedded slave_id_[tr]x */
++ unsigned int slave_id_rx;
+ u8 sup_pclk; /* 1 :SH7757, 0: SH7724/SH7372 */
+ unsigned long caps;
+ u32 ocr;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0058-mmc-Add-module.h-to-drivers-mmc-users-assuming-impli.patch b/patches.kzm9g/0058-mmc-Add-module.h-to-drivers-mmc-users-assuming-impli.patch
new file mode 100644
index 00000000000000..6555f45617df5d
--- /dev/null
+++ b/patches.kzm9g/0058-mmc-Add-module.h-to-drivers-mmc-users-assuming-impli.patch
@@ -0,0 +1,52 @@
+From c53d4419269e916098238ef2bbd15ee2e9381cf0 Mon Sep 17 00:00:00 2001
+From: Paul Gortmaker <paul.gortmaker@windriver.com>
+Date: Sun, 3 Jul 2011 15:15:51 -0400
+Subject: mmc: Add module.h to drivers/mmc users assuming implicit presence.
+
+We are cleaning up the implicit presence of module.h; these guys are
+some of the people who just assume it will be there. Call it out
+explitly for those that really need it.
+
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 88b47679746b81534002bcba42da97ab82b5d12a)
+
+Conflicts:
+
+ drivers/mmc/card/mmc_test.c
+ drivers/mmc/host/mmc_spi.c
+ drivers/mmc/host/mxs-mmc.c
+ drivers/mmc/host/sdhci-of-esdhc.c
+ drivers/mmc/host/sdhci-of-hlwd.c
+ drivers/mmc/host/sdhci-pci.c
+ drivers/mmc/host/sdhci-pltfm.c
+ drivers/mmc/host/sdhci-pxav2.c
+ drivers/mmc/host/sdhci-pxav3.c
+ drivers/mmc/host/sdhci-spear.c
+ drivers/mmc/host/sdhci-tegra.c
+ drivers/mmc/host/sdhci.c
+ drivers/mmc/host/sdricoh_cs.c
+ drivers/mmc/host/sh_mobile_sdhi.c
+ drivers/mmc/host/tifm_sd.c
+ drivers/mmc/host/via-sdmmc.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index bd91c94..369366c 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -31,6 +31,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/spinlock.h>
++#include <linux/module.h>
+
+ #define DRIVER_NAME "sh_mmcif"
+ #define DRIVER_VERSION "2010-04-28"
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0059-mmc-host-move-to-dma_transfer_direction.patch b/patches.kzm9g/0059-mmc-host-move-to-dma_transfer_direction.patch
new file mode 100644
index 00000000000000..a9168363038e0e
--- /dev/null
+++ b/patches.kzm9g/0059-mmc-host-move-to-dma_transfer_direction.patch
@@ -0,0 +1,54 @@
+From 36af543e2ebf0c4fd2201cf4aa7bd652c2a78809 Mon Sep 17 00:00:00 2001
+From: Vinod Koul <vinod.koul@linux.intel.com>
+Date: Fri, 14 Oct 2011 10:45:11 +0530
+Subject: mmc-host: move to dma_transfer_direction
+
+fixup usage of dma direction by introducing dma_transfer_direction,
+this patch moves mmc drivers to use new enum
+
+Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
+Cc: Chris Ball <cjb@laptop.org>
+Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
+(cherry-picked from commit 05f5799cbe5c9e2c03f604b3de5783cf4d726227)
+
+Conflicts:
+
+ drivers/mmc/host/atmel-mci.c
+ drivers/mmc/host/mmci.c
+ drivers/mmc/host/mxcmmc.c
+ drivers/mmc/host/mxs-mmc.c
+ drivers/mmc/host/tmio_mmc_dma.c
+
+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 369366c..1c0c10b 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -233,7 +233,7 @@ static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host)
+ if (ret > 0) {
+ host->dma_active = true;
+ desc = chan->device->device_prep_slave_sg(chan, sg, ret,
+- DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
++ DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ }
+
+ if (desc) {
+@@ -281,7 +281,7 @@ static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host)
+ if (ret > 0) {
+ host->dma_active = true;
+ desc = chan->device->device_prep_slave_sg(chan, sg, ret,
+- DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
++ DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ }
+
+ if (desc) {
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0060-mmc-sh_mmcif-fix-clock-gating-on-platforms-with-a-.d.patch b/patches.kzm9g/0060-mmc-sh_mmcif-fix-clock-gating-on-platforms-with-a-.d.patch
new file mode 100644
index 00000000000000..aaa15101e62b63
--- /dev/null
+++ b/patches.kzm9g/0060-mmc-sh_mmcif-fix-clock-gating-on-platforms-with-a-.d.patch
@@ -0,0 +1,34 @@
+From 9349a2c3b6de8530004a628228b5b72e646decbd Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 16 Nov 2011 10:10:41 +0100
+Subject: mmc: sh_mmcif: fix clock gating on platforms with a .down_pwr()
+ method
+
+Do not power down the card in .set_ios(), unless MMC_POWER_OFF is
+requested. This fixes the MMCIF interface functionality on ecovec boards.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit f6bc41fb08cbd6943df358437e0af90c91a3caa3)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index 1c0c10b..b758b21 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -908,7 +908,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ if (host->power) {
+ pm_runtime_put(&host->pd->dev);
+ host->power = false;
+- if (p->down_pwr)
++ if (p->down_pwr && ios->power_mode == MMC_POWER_OFF)
+ p->down_pwr(host->pd);
+ }
+ host->state = STATE_IDLE;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0061-mmc-sh_mmcif-simplify-clock-divisor-calculation.patch b/patches.kzm9g/0061-mmc-sh_mmcif-simplify-clock-divisor-calculation.patch
new file mode 100644
index 00000000000000..07c17d299f77db
--- /dev/null
+++ b/patches.kzm9g/0061-mmc-sh_mmcif-simplify-clock-divisor-calculation.patch
@@ -0,0 +1,42 @@
+From ac5156aad3d50ae4acfe30f57e74c0677b5cc3a7 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 23 Nov 2011 15:52:30 +0100
+Subject: mmc: sh_mmcif: simplify clock divisor calculation
+
+Replace ilog2(__rounddown_pow_of_two(x)) with the equivalent but much
+simpler fls(x) - 1.
+
+Reported-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 86df174585de79a460e3515ec413ea1f5a0bcf68)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index b758b21..86edbad 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -16,6 +16,7 @@
+ *
+ */
+
++#include <linux/bitops.h>
+ #include <linux/clk.h>
+ #include <linux/completion.h>
+ #include <linux/delay.h>
+@@ -399,7 +400,7 @@ static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
+ sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK);
+ else
+ sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR &
+- (ilog2(__rounddown_pow_of_two(host->clk / clk)) << 16));
++ ((fls(host->clk / clk) - 1) << 16));
+
+ sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE);
+ }
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0062-mmc-convert-drivers-mmc-host-to-use-module_platform_.patch b/patches.kzm9g/0062-mmc-convert-drivers-mmc-host-to-use-module_platform_.patch
new file mode 100644
index 00000000000000..3c15bd131c035b
--- /dev/null
+++ b/patches.kzm9g/0062-mmc-convert-drivers-mmc-host-to-use-module_platform_.patch
@@ -0,0 +1,79 @@
+From 44f21f022edbdf0032b9f6d2e197d7e042c14d04 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@gmail.com>
+Date: Sat, 26 Nov 2011 12:55:43 +0800
+Subject: mmc: convert drivers/mmc/host/* to use module_platform_driver()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch converts the drivers in drivers/mmc/host/* to use the
+module_platform_driver() macro which makes the code smaller and a bit
+simpler.
+
+Signed-off-by: Axel Lin <axel.lin@gmail.com>
+Acked-by: "Michał Mirosław" <mirq-linux@rere.qmqm.pl>
+Acked-by: David Brown <davidb@codeaurora.org>
+Acked-by: Viresh Kumar <viresh.kumar@st.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
+Acked-by: Wolfram Sang <w.sang@pengutronix.de>
+Acked-by: Anton Vorontsov <cbouatmailru@gmail.com>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit d1f81a64a4250bdd776978be06ae2b8e13ec7471)
+
+Conflicts:
+
+ drivers/mmc/host/bfin_sdh.c
+ drivers/mmc/host/cb710-mmc.c
+ drivers/mmc/host/jz4740_mmc.c
+ drivers/mmc/host/msm_sdcc.c
+ drivers/mmc/host/mxcmmc.c
+ drivers/mmc/host/mxs-mmc.c
+ drivers/mmc/host/pxamci.c
+ drivers/mmc/host/s3cmci.c
+ drivers/mmc/host/sdhci-cns3xxx.c
+ drivers/mmc/host/sdhci-dove.c
+ drivers/mmc/host/sdhci-esdhc-imx.c
+ drivers/mmc/host/sdhci-of-esdhc.c
+ drivers/mmc/host/sdhci-of-hlwd.c
+ drivers/mmc/host/sdhci-pxav2.c
+ drivers/mmc/host/sdhci-pxav3.c
+ drivers/mmc/host/sdhci-s3c.c
+ drivers/mmc/host/sdhci-spear.c
+ drivers/mmc/host/sdhci-tegra.c
+ drivers/mmc/host/sh_mobile_sdhi.c
+ drivers/mmc/host/tmio_mmc.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 14 +-------------
+ 1 file changed, 1 insertion(+), 13 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index 86edbad..fd0fd11 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -1207,19 +1207,7 @@ static struct platform_driver sh_mmcif_driver = {
+ },
+ };
+
+-static int __init sh_mmcif_init(void)
+-{
+- return platform_driver_register(&sh_mmcif_driver);
+-}
+-
+-static void __exit sh_mmcif_exit(void)
+-{
+- platform_driver_unregister(&sh_mmcif_driver);
+-}
+-
+-module_init(sh_mmcif_init);
+-module_exit(sh_mmcif_exit);
+-
++module_platform_driver(sh_mmcif_driver);
+
+ MODULE_DESCRIPTION("SuperH on-chip MMC/eMMC interface driver");
+ MODULE_LICENSE("GPL");
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0063-mmc-sh_mmcif-process-error-interrupts-first.patch b/patches.kzm9g/0063-mmc-sh_mmcif-process-error-interrupts-first.patch
new file mode 100644
index 00000000000000..67e7f70ae2b098
--- /dev/null
+++ b/patches.kzm9g/0063-mmc-sh_mmcif-process-error-interrupts-first.patch
@@ -0,0 +1,53 @@
+From 5e6bf4faa8039a5bc1dba4d380a116a7e4d9a7e4 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 14 Dec 2011 19:31:51 +0100
+Subject: mmc: sh_mmcif: process error interrupts first
+
+If an interrupt is coming with both error and data completion status bits
+set, it has to be handled as an error interrupt, for which error interrupts
+have to be processed first. The current version of the driver on the
+contrary doesn't recognise such interrupts as an error event, which leads
+to data corruption and breaks the error recovery.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 8a8284a98c1a58f5aa3eebce7971f81bcdb29d98)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index fd0fd11..e9ba52e 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -961,7 +961,12 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
+
+ state = sh_mmcif_readl(host->addr, MMCIF_CE_INT);
+
+- if (state & INT_RBSYE) {
++ if (state & INT_ERR_STS) {
++ /* error interrupts - process first */
++ sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
++ sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
++ err = 1;
++ } else if (state & INT_RBSYE) {
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT,
+ ~(INT_RBSYE | INT_CRSPE));
+ sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MRBSYE);
+@@ -989,11 +994,6 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT,
+ ~(INT_CMD12RBE | INT_CMD12CRE));
+ sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE);
+- } else if (state & INT_ERR_STS) {
+- /* err interrupts */
+- sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
+- sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
+- err = 1;
+ } else {
+ dev_dbg(&host->pd->dev, "Unsupported interrupt: 0x%x\n", state);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0064-mmc-sh_mmcif-cosmetic-clean-up.patch b/patches.kzm9g/0064-mmc-sh_mmcif-cosmetic-clean-up.patch
new file mode 100644
index 00000000000000..5b4215a8f80813
--- /dev/null
+++ b/patches.kzm9g/0064-mmc-sh_mmcif-cosmetic-clean-up.patch
@@ -0,0 +1,211 @@
+From 364bbb124f5f7023aa0999c8382c3cfb38629615 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Wed, 14 Dec 2011 19:31:52 +0100
+Subject: mmc: sh_mmcif: cosmetic clean up
+
+This patch doesn't introduce any functional changes, it only simplifies
+some code fragments, removes superfluous parameters, fixes typos.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit ee4b88879f23badd54f5557852745fa28a1570f6)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 79 +++++++++++++++++++--------------------------
+ 1 file changed, 34 insertions(+), 45 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index e9ba52e..1408ded 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -124,6 +124,11 @@
+ #define MASK_MRBSYTO (1 << 1)
+ #define MASK_MRSPTO (1 << 0)
+
++#define MASK_START_CMD (MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR | \
++ MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR | \
++ MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | \
++ MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO)
++
+ /* CE_HOST_STS1 */
+ #define STS1_CMDSEQ (1 << 31)
+
+@@ -176,8 +181,8 @@ struct sh_mmcif_host {
+ long timeout;
+ void __iomem *addr;
+ struct completion intr_wait;
++ spinlock_t lock; /* protect sh_mmcif_host::state */
+ enum mmcif_state state;
+- spinlock_t lock;
+ bool power;
+ bool card_present;
+
+@@ -422,7 +427,7 @@ static void sh_mmcif_sync_reset(struct sh_mmcif_host *host)
+ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
+ {
+ u32 state1, state2;
+- int ret, timeout = 10000000;
++ int ret, timeout;
+
+ host->sd_error = false;
+
+@@ -434,31 +439,30 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
+ if (state1 & STS1_CMDSEQ) {
+ sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK);
+ sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, ~CMD_CTRL_BREAK);
+- while (1) {
+- timeout--;
+- if (timeout < 0) {
+- dev_err(&host->pd->dev,
+- "Forceed end of command sequence timeout err\n");
+- return -EIO;
+- }
++ for (timeout = 10000000; timeout; timeout--) {
+ if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1)
+- & STS1_CMDSEQ))
++ & STS1_CMDSEQ))
+ break;
+ mdelay(1);
+ }
++ if (!timeout) {
++ dev_err(&host->pd->dev,
++ "Forced end of command sequence timeout err\n");
++ return -EIO;
++ }
+ sh_mmcif_sync_reset(host);
+ dev_dbg(&host->pd->dev, "Forced end of command sequence\n");
+ return -EIO;
+ }
+
+ if (state2 & STS2_CRC_ERR) {
+- dev_dbg(&host->pd->dev, ": Happened CRC error\n");
++ dev_dbg(&host->pd->dev, ": CRC error\n");
+ ret = -EIO;
+ } else if (state2 & STS2_TIMEOUT_ERR) {
+- dev_dbg(&host->pd->dev, ": Happened Timeout error\n");
++ dev_dbg(&host->pd->dev, ": Timeout\n");
+ ret = -ETIMEDOUT;
+ } else {
+- dev_dbg(&host->pd->dev, ": Happened End/Index error\n");
++ dev_dbg(&host->pd->dev, ": End/Index error\n");
+ ret = -EIO;
+ }
+ return ret;
+@@ -681,55 +685,44 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
+ static int sh_mmcif_data_trans(struct sh_mmcif_host *host,
+ struct mmc_request *mrq, u32 opc)
+ {
+- int ret;
+-
+ switch (opc) {
+ case MMC_READ_MULTIPLE_BLOCK:
+- ret = sh_mmcif_multi_read(host, mrq);
+- break;
++ return sh_mmcif_multi_read(host, mrq);
+ case MMC_WRITE_MULTIPLE_BLOCK:
+- ret = sh_mmcif_multi_write(host, mrq);
+- break;
++ return sh_mmcif_multi_write(host, mrq);
+ case MMC_WRITE_BLOCK:
+- ret = sh_mmcif_single_write(host, mrq);
+- break;
++ return sh_mmcif_single_write(host, mrq);
+ case MMC_READ_SINGLE_BLOCK:
+ case MMC_SEND_EXT_CSD:
+- ret = sh_mmcif_single_read(host, mrq);
+- break;
++ return sh_mmcif_single_read(host, mrq);
+ default:
+ dev_err(&host->pd->dev, "UNSUPPORTED CMD = d'%08d\n", opc);
+- ret = -EINVAL;
+- break;
++ return -EINVAL;
+ }
+- return ret;
+ }
+
+ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
+- struct mmc_request *mrq, struct mmc_command *cmd)
++ struct mmc_request *mrq)
+ {
++ struct mmc_command *cmd = mrq->cmd;
+ long time;
+- int ret = 0, mask = 0;
+- u32 opc = cmd->opcode;
++ int ret = 0;
++ u32 mask, opc = cmd->opcode;
+
+ switch (opc) {
+- /* respons busy check */
++ /* response busy check */
+ case MMC_SWITCH:
+ case MMC_STOP_TRANSMISSION:
+ case MMC_SET_WRITE_PROT:
+ case MMC_CLR_WRITE_PROT:
+ case MMC_ERASE:
+ case MMC_GEN_CMD:
+- mask = MASK_MRBSYE;
++ mask = MASK_START_CMD | MASK_MRBSYE;
+ break;
+ default:
+- mask = MASK_MCRSPE;
++ mask = MASK_START_CMD | MASK_MCRSPE;
+ break;
+ }
+- mask |= MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR |
+- MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR |
+- MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO |
+- MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO;
+
+ if (host->data) {
+ sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0);
+@@ -797,8 +790,9 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
+ }
+
+ static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
+- struct mmc_request *mrq, struct mmc_command *cmd)
++ struct mmc_request *mrq)
+ {
++ struct mmc_command *cmd = mrq->stop;
+ long time;
+
+ if (mrq->cmd->opcode == MMC_READ_MULTIPLE_BLOCK)
+@@ -867,11 +861,11 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
+ sh_mmcif_start_dma_tx(host);
+ }
+ }
+- sh_mmcif_start_cmd(host, mrq, mrq->cmd);
++ sh_mmcif_start_cmd(host, mrq);
+ host->data = NULL;
+
+ if (!mrq->cmd->error && mrq->stop)
+- sh_mmcif_stop_cmd(host, mrq, mrq->stop);
++ sh_mmcif_stop_cmd(host, mrq);
+ host->state = STATE_IDLE;
+ mmc_request_done(mmc, mrq);
+ }
+@@ -948,11 +942,6 @@ static struct mmc_host_ops sh_mmcif_ops = {
+ .get_cd = sh_mmcif_get_cd,
+ };
+
+-static void sh_mmcif_detect(struct mmc_host *mmc)
+-{
+- mmc_detect_change(mmc, 0);
+-}
+-
+ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
+ {
+ struct sh_mmcif_host *host = dev_id;
+@@ -1114,7 +1103,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
+ goto clean_up3;
+ }
+
+- sh_mmcif_detect(host->mmc);
++ mmc_detect_change(host->mmc, 0);
+
+ dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION);
+ dev_dbg(&pdev->dev, "chip ver H'%04x\n",
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0065-mmc-sh_mmcif-process-requests-asynchronously.patch b/patches.kzm9g/0065-mmc-sh_mmcif-process-requests-asynchronously.patch
new file mode 100644
index 00000000000000..ac2e137efa91b1
--- /dev/null
+++ b/patches.kzm9g/0065-mmc-sh_mmcif-process-requests-asynchronously.patch
@@ -0,0 +1,788 @@
+From 24a541a85df9dd327db05d3ebb3058d256ac90a6 Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Sun, 25 Dec 2011 21:07:52 +0100
+Subject: mmc: sh_mmcif: process requests asynchronously
+
+This patch converts the sh_mmcif MMC host driver to process requests
+asynchronously instead of waiting in its .request() method for completion.
+This is achieved by using threaded IRQs.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit f985da17f4d368896fb30d94531e4ffaa18e68d8)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 588 +++++++++++++++++++++++++++++++-------------
+ 1 file changed, 416 insertions(+), 172 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index 1408ded..5d0ade7 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -16,6 +16,32 @@
+ *
+ */
+
++/*
++ * The MMCIF driver is now processing MMC requests asynchronously, according
++ * to the Linux MMC API requirement.
++ *
++ * The MMCIF driver processes MMC requests in up to 3 stages: command, optional
++ * data, and optional stop. To achieve asynchronous processing each of these
++ * stages is split into two halves: a top and a bottom half. The top half
++ * initialises the hardware, installs a timeout handler to handle completion
++ * timeouts, and returns. In case of the command stage this immediately returns
++ * control to the caller, leaving all further processing to run asynchronously.
++ * All further request processing is performed by the bottom halves.
++ *
++ * The bottom half further consists of a "hard" IRQ handler, an IRQ handler
++ * thread, a DMA completion callback, if DMA is used, a timeout work, and
++ * request- and stage-specific handler methods.
++ *
++ * Each bottom half run begins with either a hardware interrupt, a DMA callback
++ * invocation, or a timeout work run. In case of an error or a successful
++ * processing completion, the MMC core is informed and the request processing is
++ * finished. In case processing has to continue, i.e., if data has to be read
++ * from or written to the card, or if a stop command has to be sent, the next
++ * top half is called, which performs the necessary hardware handling and
++ * reschedules the timeout work. This returns the driver state machine into the
++ * bottom half waiting state.
++ */
++
+ #include <linux/bitops.h>
+ #include <linux/clk.h>
+ #include <linux/completion.h>
+@@ -168,9 +194,22 @@ enum mmcif_state {
+ STATE_IOS,
+ };
+
++enum mmcif_wait_for {
++ MMCIF_WAIT_FOR_REQUEST,
++ MMCIF_WAIT_FOR_CMD,
++ MMCIF_WAIT_FOR_MREAD,
++ MMCIF_WAIT_FOR_MWRITE,
++ MMCIF_WAIT_FOR_READ,
++ MMCIF_WAIT_FOR_WRITE,
++ MMCIF_WAIT_FOR_READ_END,
++ MMCIF_WAIT_FOR_WRITE_END,
++ MMCIF_WAIT_FOR_STOP,
++};
++
+ struct sh_mmcif_host {
+ struct mmc_host *mmc;
+ struct mmc_data *data;
++ struct mmc_request *mrq;
+ struct platform_device *pd;
+ struct sh_dmae_slave dma_slave_tx;
+ struct sh_dmae_slave dma_slave_rx;
+@@ -178,11 +217,17 @@ struct sh_mmcif_host {
+ unsigned int clk;
+ int bus_width;
+ bool sd_error;
++ bool dying;
+ long timeout;
+ void __iomem *addr;
+- struct completion intr_wait;
++ u32 *pio_ptr;
+ spinlock_t lock; /* protect sh_mmcif_host::state */
+ enum mmcif_state state;
++ enum mmcif_wait_for wait_for;
++ struct delayed_work timeout_work;
++ size_t blocksize;
++ int sg_idx;
++ int sg_blkidx;
+ bool power;
+ bool card_present;
+
+@@ -468,125 +513,183 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
+ return ret;
+ }
+
+-static int sh_mmcif_single_read(struct sh_mmcif_host *host,
+- struct mmc_request *mrq)
++static bool sh_mmcif_next_block(struct sh_mmcif_host *host, u32 *p)
+ {
+- struct mmc_data *data = mrq->data;
+- long time;
+- u32 blocksize, i, *p = sg_virt(data->sg);
++ struct mmc_data *data = host->mrq->data;
++
++ host->sg_blkidx += host->blocksize;
++
++ /* data->sg->length must be a multiple of host->blocksize? */
++ BUG_ON(host->sg_blkidx > data->sg->length);
++
++ if (host->sg_blkidx == data->sg->length) {
++ host->sg_blkidx = 0;
++ if (++host->sg_idx < data->sg_len)
++ host->pio_ptr = sg_virt(++data->sg);
++ } else {
++ host->pio_ptr = p;
++ }
++
++ if (host->sg_idx == data->sg_len)
++ return false;
++
++ return true;
++}
++
++static void sh_mmcif_single_read(struct sh_mmcif_host *host,
++ struct mmc_request *mrq)
++{
++ host->blocksize = (sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) &
++ BLOCK_SIZE_MASK) + 3;
++
++ host->wait_for = MMCIF_WAIT_FOR_READ;
++ schedule_delayed_work(&host->timeout_work, host->timeout);
+
+ /* buf read enable */
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
+- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+- host->timeout);
+- if (time <= 0 || host->sd_error)
+- return sh_mmcif_error_manage(host);
+-
+- blocksize = (BLOCK_SIZE_MASK &
+- sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3;
+- for (i = 0; i < blocksize / 4; i++)
++}
++
++static bool sh_mmcif_read_block(struct sh_mmcif_host *host)
++{
++ struct mmc_data *data = host->mrq->data;
++ u32 *p = sg_virt(data->sg);
++ int i;
++
++ if (host->sd_error) {
++ data->error = sh_mmcif_error_manage(host);
++ return false;
++ }
++
++ for (i = 0; i < host->blocksize / 4; i++)
+ *p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA);
+
+ /* buffer read end */
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE);
+- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+- host->timeout);
+- if (time <= 0 || host->sd_error)
+- return sh_mmcif_error_manage(host);
++ host->wait_for = MMCIF_WAIT_FOR_READ_END;
+
+- return 0;
++ return true;
+ }
+
+-static int sh_mmcif_multi_read(struct sh_mmcif_host *host,
+- struct mmc_request *mrq)
++static void sh_mmcif_multi_read(struct sh_mmcif_host *host,
++ struct mmc_request *mrq)
+ {
+ struct mmc_data *data = mrq->data;
+- long time;
+- u32 blocksize, i, j, sec, *p;
+-
+- blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr,
+- MMCIF_CE_BLOCK_SET);
+- for (j = 0; j < data->sg_len; j++) {
+- p = sg_virt(data->sg);
+- for (sec = 0; sec < data->sg->length / blocksize; sec++) {
+- sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
+- /* buf read enable */
+- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+- host->timeout);
+-
+- if (time <= 0 || host->sd_error)
+- return sh_mmcif_error_manage(host);
+-
+- for (i = 0; i < blocksize / 4; i++)
+- *p++ = sh_mmcif_readl(host->addr,
+- MMCIF_CE_DATA);
+- }
+- if (j < data->sg_len - 1)
+- data->sg++;
++
++ if (!data->sg_len || !data->sg->length)
++ return;
++
++ host->blocksize = sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) &
++ BLOCK_SIZE_MASK;
++
++ host->wait_for = MMCIF_WAIT_FOR_MREAD;
++ host->sg_idx = 0;
++ host->sg_blkidx = 0;
++ host->pio_ptr = sg_virt(data->sg);
++ schedule_delayed_work(&host->timeout_work, host->timeout);
++ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
++}
++
++static bool sh_mmcif_mread_block(struct sh_mmcif_host *host)
++{
++ struct mmc_data *data = host->mrq->data;
++ u32 *p = host->pio_ptr;
++ int i;
++
++ if (host->sd_error) {
++ data->error = sh_mmcif_error_manage(host);
++ return false;
+ }
+- return 0;
++
++ BUG_ON(!data->sg->length);
++
++ for (i = 0; i < host->blocksize / 4; i++)
++ *p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA);
++
++ if (!sh_mmcif_next_block(host, p))
++ return false;
++
++ schedule_delayed_work(&host->timeout_work, host->timeout);
++ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
++
++ return true;
+ }
+
+-static int sh_mmcif_single_write(struct sh_mmcif_host *host,
++static void sh_mmcif_single_write(struct sh_mmcif_host *host,
+ struct mmc_request *mrq)
+ {
+- struct mmc_data *data = mrq->data;
+- long time;
+- u32 blocksize, i, *p = sg_virt(data->sg);
++ host->blocksize = (sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) &
++ BLOCK_SIZE_MASK) + 3;
+
+- sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
++ host->wait_for = MMCIF_WAIT_FOR_WRITE;
++ schedule_delayed_work(&host->timeout_work, host->timeout);
+
+ /* buf write enable */
+- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+- host->timeout);
+- if (time <= 0 || host->sd_error)
+- return sh_mmcif_error_manage(host);
+-
+- blocksize = (BLOCK_SIZE_MASK &
+- sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3;
+- for (i = 0; i < blocksize / 4; i++)
++ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
++}
++
++static bool sh_mmcif_write_block(struct sh_mmcif_host *host)
++{
++ struct mmc_data *data = host->mrq->data;
++ u32 *p = sg_virt(data->sg);
++ int i;
++
++ if (host->sd_error) {
++ data->error = sh_mmcif_error_manage(host);
++ return false;
++ }
++
++ for (i = 0; i < host->blocksize / 4; i++)
+ sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++);
+
+ /* buffer write end */
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE);
++ host->wait_for = MMCIF_WAIT_FOR_WRITE_END;
+
+- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+- host->timeout);
+- if (time <= 0 || host->sd_error)
+- return sh_mmcif_error_manage(host);
+-
+- return 0;
++ return true;
+ }
+
+-static int sh_mmcif_multi_write(struct sh_mmcif_host *host,
+- struct mmc_request *mrq)
++static void sh_mmcif_multi_write(struct sh_mmcif_host *host,
++ struct mmc_request *mrq)
+ {
+ struct mmc_data *data = mrq->data;
+- long time;
+- u32 i, sec, j, blocksize, *p;
+
+- blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr,
+- MMCIF_CE_BLOCK_SET);
++ if (!data->sg_len || !data->sg->length)
++ return;
+
+- for (j = 0; j < data->sg_len; j++) {
+- p = sg_virt(data->sg);
+- for (sec = 0; sec < data->sg->length / blocksize; sec++) {
+- sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
+- /* buf write enable*/
+- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+- host->timeout);
++ host->blocksize = sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) &
++ BLOCK_SIZE_MASK;
+
+- if (time <= 0 || host->sd_error)
+- return sh_mmcif_error_manage(host);
++ host->wait_for = MMCIF_WAIT_FOR_MWRITE;
++ host->sg_idx = 0;
++ host->sg_blkidx = 0;
++ host->pio_ptr = sg_virt(data->sg);
++ schedule_delayed_work(&host->timeout_work, host->timeout);
++ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
++}
+
+- for (i = 0; i < blocksize / 4; i++)
+- sh_mmcif_writel(host->addr,
+- MMCIF_CE_DATA, *p++);
+- }
+- if (j < data->sg_len - 1)
+- data->sg++;
++static bool sh_mmcif_mwrite_block(struct sh_mmcif_host *host)
++{
++ struct mmc_data *data = host->mrq->data;
++ u32 *p = host->pio_ptr;
++ int i;
++
++ if (host->sd_error) {
++ data->error = sh_mmcif_error_manage(host);
++ return false;
+ }
+- return 0;
++
++ BUG_ON(!data->sg->length);
++
++ for (i = 0; i < host->blocksize / 4; i++)
++ sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++);
++
++ if (!sh_mmcif_next_block(host, p))
++ return false;
++
++ schedule_delayed_work(&host->timeout_work, host->timeout);
++ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
++
++ return true;
+ }
+
+ static void sh_mmcif_get_response(struct sh_mmcif_host *host,
+@@ -683,18 +786,22 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
+ }
+
+ static int sh_mmcif_data_trans(struct sh_mmcif_host *host,
+- struct mmc_request *mrq, u32 opc)
++ struct mmc_request *mrq, u32 opc)
+ {
+ switch (opc) {
+ case MMC_READ_MULTIPLE_BLOCK:
+- return sh_mmcif_multi_read(host, mrq);
++ sh_mmcif_multi_read(host, mrq);
++ return 0;
+ case MMC_WRITE_MULTIPLE_BLOCK:
+- return sh_mmcif_multi_write(host, mrq);
++ sh_mmcif_multi_write(host, mrq);
++ return 0;
+ case MMC_WRITE_BLOCK:
+- return sh_mmcif_single_write(host, mrq);
++ sh_mmcif_single_write(host, mrq);
++ return 0;
+ case MMC_READ_SINGLE_BLOCK:
+ case MMC_SEND_EXT_CSD:
+- return sh_mmcif_single_read(host, mrq);
++ sh_mmcif_single_read(host, mrq);
++ return 0;
+ default:
+ dev_err(&host->pd->dev, "UNSUPPORTED CMD = d'%08d\n", opc);
+ return -EINVAL;
+@@ -705,9 +812,8 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
+ struct mmc_request *mrq)
+ {
+ struct mmc_command *cmd = mrq->cmd;
+- long time;
+- int ret = 0;
+- u32 mask, opc = cmd->opcode;
++ u32 opc = cmd->opcode;
++ u32 mask;
+
+ switch (opc) {
+ /* response busy check */
+@@ -738,62 +844,14 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
+ /* set cmd */
+ sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc);
+
+- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+- host->timeout);
+- if (time <= 0) {
+- cmd->error = sh_mmcif_error_manage(host);
+- return;
+- }
+- if (host->sd_error) {
+- switch (cmd->opcode) {
+- case MMC_ALL_SEND_CID:
+- case MMC_SELECT_CARD:
+- case MMC_APP_CMD:
+- cmd->error = -ETIMEDOUT;
+- break;
+- default:
+- dev_dbg(&host->pd->dev, "Cmd(d'%d) err\n",
+- cmd->opcode);
+- cmd->error = sh_mmcif_error_manage(host);
+- break;
+- }
+- host->sd_error = false;
+- return;
+- }
+- if (!(cmd->flags & MMC_RSP_PRESENT)) {
+- cmd->error = 0;
+- return;
+- }
+- sh_mmcif_get_response(host, cmd);
+- if (host->data) {
+- if (!host->dma_active) {
+- ret = sh_mmcif_data_trans(host, mrq, cmd->opcode);
+- } else {
+- long time =
+- wait_for_completion_interruptible_timeout(&host->dma_complete,
+- host->timeout);
+- if (!time)
+- ret = -ETIMEDOUT;
+- else if (time < 0)
+- ret = time;
+- sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC,
+- BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
+- host->dma_active = false;
+- }
+- if (ret < 0)
+- mrq->data->bytes_xfered = 0;
+- else
+- mrq->data->bytes_xfered =
+- mrq->data->blocks * mrq->data->blksz;
+- }
+- cmd->error = ret;
++ host->wait_for = MMCIF_WAIT_FOR_CMD;
++ schedule_delayed_work(&host->timeout_work, host->timeout);
+ }
+
+ static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
+ struct mmc_request *mrq)
+ {
+ struct mmc_command *cmd = mrq->stop;
+- long time;
+
+ if (mrq->cmd->opcode == MMC_READ_MULTIPLE_BLOCK)
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE);
+@@ -805,14 +863,8 @@ static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
+ return;
+ }
+
+- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
+- host->timeout);
+- if (time <= 0 || host->sd_error) {
+- cmd->error = sh_mmcif_error_manage(host);
+- return;
+- }
+- sh_mmcif_get_cmd12response(host, cmd);
+- cmd->error = 0;
++ host->wait_for = MMCIF_WAIT_FOR_STOP;
++ schedule_delayed_work(&host->timeout_work, host->timeout);
+ }
+
+ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
+@@ -851,23 +903,11 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
+ default:
+ break;
+ }
++
++ host->mrq = mrq;
+ host->data = mrq->data;
+- if (mrq->data) {
+- if (mrq->data->flags & MMC_DATA_READ) {
+- if (host->chan_rx)
+- sh_mmcif_start_dma_rx(host);
+- } else {
+- if (host->chan_tx)
+- sh_mmcif_start_dma_tx(host);
+- }
+- }
+- sh_mmcif_start_cmd(host, mrq);
+- host->data = NULL;
+
+- if (!mrq->cmd->error && mrq->stop)
+- sh_mmcif_stop_cmd(host, mrq);
+- host->state = STATE_IDLE;
+- mmc_request_done(mmc, mrq);
++ sh_mmcif_start_cmd(host, mrq);
+ }
+
+ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+@@ -942,6 +982,157 @@ static struct mmc_host_ops sh_mmcif_ops = {
+ .get_cd = sh_mmcif_get_cd,
+ };
+
++static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host)
++{
++ struct mmc_command *cmd = host->mrq->cmd;
++ long time;
++
++ if (host->sd_error) {
++ switch (cmd->opcode) {
++ case MMC_ALL_SEND_CID:
++ case MMC_SELECT_CARD:
++ case MMC_APP_CMD:
++ cmd->error = -ETIMEDOUT;
++ host->sd_error = false;
++ break;
++ default:
++ cmd->error = sh_mmcif_error_manage(host);
++ dev_dbg(&host->pd->dev, "Cmd(d'%d) error %d\n",
++ cmd->opcode, cmd->error);
++ break;
++ }
++ return false;
++ }
++ if (!(cmd->flags & MMC_RSP_PRESENT)) {
++ cmd->error = 0;
++ return false;
++ }
++
++ sh_mmcif_get_response(host, cmd);
++
++ if (!host->data)
++ return false;
++
++ if (host->mrq->data->flags & MMC_DATA_READ) {
++ if (host->chan_rx)
++ sh_mmcif_start_dma_rx(host);
++ } else {
++ if (host->chan_tx)
++ sh_mmcif_start_dma_tx(host);
++ }
++
++ if (!host->dma_active) {
++ host->data->error = sh_mmcif_data_trans(host, host->mrq, cmd->opcode);
++ if (!host->data->error)
++ return true;
++ return false;
++ }
++
++ /* Running in the IRQ thread, can sleep */
++ time = wait_for_completion_interruptible_timeout(&host->dma_complete,
++ host->timeout);
++ if (host->sd_error) {
++ dev_err(host->mmc->parent,
++ "Error IRQ while waiting for DMA completion!\n");
++ /* Woken up by an error IRQ: abort DMA */
++ if (host->data->flags & MMC_DATA_READ)
++ dmaengine_terminate_all(host->chan_rx);
++ else
++ dmaengine_terminate_all(host->chan_tx);
++ host->data->error = sh_mmcif_error_manage(host);
++ } else if (!time) {
++ host->data->error = -ETIMEDOUT;
++ } else if (time < 0) {
++ host->data->error = time;
++ }
++ sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC,
++ BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
++ host->dma_active = false;
++
++ if (host->data->error)
++ host->data->bytes_xfered = 0;
++
++ return false;
++}
++
++static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
++{
++ struct sh_mmcif_host *host = dev_id;
++ struct mmc_request *mrq = host->mrq;
++
++ cancel_delayed_work_sync(&host->timeout_work);
++
++ /*
++ * All handlers return true, if processing continues, and false, if the
++ * request has to be completed - successfully or not
++ */
++ switch (host->wait_for) {
++ case MMCIF_WAIT_FOR_REQUEST:
++ /* We're too late, the timeout has already kicked in */
++ return IRQ_HANDLED;
++ case MMCIF_WAIT_FOR_CMD:
++ if (sh_mmcif_end_cmd(host))
++ /* Wait for data */
++ return IRQ_HANDLED;
++ break;
++ case MMCIF_WAIT_FOR_MREAD:
++ if (sh_mmcif_mread_block(host))
++ /* Wait for more data */
++ return IRQ_HANDLED;
++ break;
++ case MMCIF_WAIT_FOR_READ:
++ if (sh_mmcif_read_block(host))
++ /* Wait for data end */
++ return IRQ_HANDLED;
++ break;
++ case MMCIF_WAIT_FOR_MWRITE:
++ if (sh_mmcif_mwrite_block(host))
++ /* Wait data to write */
++ return IRQ_HANDLED;
++ break;
++ case MMCIF_WAIT_FOR_WRITE:
++ if (sh_mmcif_write_block(host))
++ /* Wait for data end */
++ return IRQ_HANDLED;
++ break;
++ case MMCIF_WAIT_FOR_STOP:
++ if (host->sd_error) {
++ mrq->stop->error = sh_mmcif_error_manage(host);
++ break;
++ }
++ sh_mmcif_get_cmd12response(host, mrq->stop);
++ mrq->stop->error = 0;
++ break;
++ case MMCIF_WAIT_FOR_READ_END:
++ case MMCIF_WAIT_FOR_WRITE_END:
++ if (host->sd_error)
++ mrq->data->error = sh_mmcif_error_manage(host);
++ break;
++ default:
++ BUG();
++ }
++
++ if (host->wait_for != MMCIF_WAIT_FOR_STOP) {
++ host->data = NULL;
++
++ if (!mrq->cmd->error && mrq->data && !mrq->data->error)
++ mrq->data->bytes_xfered =
++ mrq->data->blocks * mrq->data->blksz;
++
++ if (mrq->stop && !mrq->cmd->error && (!mrq->data || !mrq->data->error)) {
++ sh_mmcif_stop_cmd(host, mrq);
++ if (!mrq->stop->error)
++ return IRQ_HANDLED;
++ }
++ }
++
++ host->wait_for = MMCIF_WAIT_FOR_REQUEST;
++ host->state = STATE_IDLE;
++ mmc_request_done(host->mmc, mrq);
++
++ return IRQ_HANDLED;
++}
++
+ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
+ {
+ struct sh_mmcif_host *host = dev_id;
+@@ -993,14 +1184,58 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
+ host->sd_error = true;
+ dev_dbg(&host->pd->dev, "int err state = %08x\n", state);
+ }
+- if (state & ~(INT_CMD12RBE | INT_CMD12CRE))
+- complete(&host->intr_wait);
+- else
++ if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) {
++ if (!host->dma_active)
++ return IRQ_WAKE_THREAD;
++ else if (host->sd_error)
++ mmcif_dma_complete(host);
++ } else {
+ dev_dbg(&host->pd->dev, "Unexpected IRQ 0x%x\n", state);
++ }
+
+ return IRQ_HANDLED;
+ }
+
++static void mmcif_timeout_work(struct work_struct *work)
++{
++ struct delayed_work *d = container_of(work, struct delayed_work, work);
++ struct sh_mmcif_host *host = container_of(d, struct sh_mmcif_host, timeout_work);
++ struct mmc_request *mrq = host->mrq;
++
++ if (host->dying)
++ /* Don't run after mmc_remove_host() */
++ return;
++
++ /*
++ * Handle races with cancel_delayed_work(), unless
++ * cancel_delayed_work_sync() is used
++ */
++ switch (host->wait_for) {
++ case MMCIF_WAIT_FOR_CMD:
++ mrq->cmd->error = sh_mmcif_error_manage(host);
++ break;
++ case MMCIF_WAIT_FOR_STOP:
++ mrq->stop->error = sh_mmcif_error_manage(host);
++ break;
++ case MMCIF_WAIT_FOR_MREAD:
++ case MMCIF_WAIT_FOR_MWRITE:
++ case MMCIF_WAIT_FOR_READ:
++ case MMCIF_WAIT_FOR_WRITE:
++ case MMCIF_WAIT_FOR_READ_END:
++ case MMCIF_WAIT_FOR_WRITE_END:
++ host->data->error = sh_mmcif_error_manage(host);
++ break;
++ default:
++ BUG();
++ }
++
++ host->state = STATE_IDLE;
++ host->wait_for = MMCIF_WAIT_FOR_REQUEST;
++ host->data = NULL;
++ host->mrq = NULL;
++ mmc_request_done(host->mmc, mrq);
++}
++
+ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
+ {
+ int ret = 0, irq[2];
+@@ -1054,7 +1289,6 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
+ host->clk = clk_get_rate(host->hclk);
+ host->pd = pdev;
+
+- init_completion(&host->intr_wait);
+ spin_lock_init(&host->lock);
+
+ mmc->ops = &sh_mmcif_ops;
+@@ -1091,18 +1325,20 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
+
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
+
+- ret = request_irq(irq[0], sh_mmcif_intr, 0, "sh_mmc:error", host);
++ 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;
+ }
+- ret = request_irq(irq[1], sh_mmcif_intr, 0, "sh_mmc:int", host);
++ ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host);
+ if (ret) {
+ free_irq(irq[0], host);
+ dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
+ goto clean_up3;
+ }
+
++ INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);
++
+ mmc_detect_change(host->mmc, 0);
+
+ dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION);
+@@ -1129,11 +1365,19 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
+ struct sh_mmcif_host *host = platform_get_drvdata(pdev);
+ int irq[2];
+
++ host->dying = true;
+ pm_runtime_get_sync(&pdev->dev);
+
+ mmc_remove_host(host->mmc);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
+
++ /*
++ * FIXME: cancel_delayed_work(_sync)() and free_irq() race with the
++ * mmc_remove_host() call above. But swapping order doesn't help either
++ * (a query on the linux-mmc mailing list didn't bring any replies).
++ */
++ cancel_delayed_work_sync(&host->timeout_work);
++
+ if (host->addr)
+ iounmap(host->addr);
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0066-mmc-sh_mmcif-remove-now-superfluous-sh_mmcif_host-da.patch b/patches.kzm9g/0066-mmc-sh_mmcif-remove-now-superfluous-sh_mmcif_host-da.patch
new file mode 100644
index 00000000000000..36257241a0c463
--- /dev/null
+++ b/patches.kzm9g/0066-mmc-sh_mmcif-remove-now-superfluous-sh_mmcif_host-da.patch
@@ -0,0 +1,319 @@
+From 2f2db71dd4017c3fec347a00c6e8b2a9ac8df42d Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Mon, 26 Dec 2011 12:52:13 -0500
+Subject: mmc: sh_mmcif: remove now superfluous sh_mmcif_host::data member
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 699834045f1ec30156dd51c362a6840e737baaba)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 94 ++++++++++++++++++++++++---------------------
+ 1 file changed, 50 insertions(+), 44 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index 5d0ade7..f5d8b53 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -208,7 +208,6 @@ enum mmcif_wait_for {
+
+ struct sh_mmcif_host {
+ struct mmc_host *mmc;
+- struct mmc_data *data;
+ struct mmc_request *mrq;
+ struct platform_device *pd;
+ struct sh_dmae_slave dma_slave_tx;
+@@ -253,19 +252,21 @@ static inline void sh_mmcif_bitclr(struct sh_mmcif_host *host,
+ static void mmcif_dma_complete(void *arg)
+ {
+ struct sh_mmcif_host *host = arg;
++ struct mmc_data *data = host->mrq->data;
++
+ dev_dbg(&host->pd->dev, "Command completed\n");
+
+- if (WARN(!host->data, "%s: NULL data in DMA completion!\n",
++ if (WARN(!data, "%s: NULL data in DMA completion!\n",
+ dev_name(&host->pd->dev)))
+ return;
+
+- if (host->data->flags & MMC_DATA_READ)
++ if (data->flags & MMC_DATA_READ)
+ dma_unmap_sg(host->chan_rx->device->dev,
+- host->data->sg, host->data->sg_len,
++ data->sg, data->sg_len,
+ DMA_FROM_DEVICE);
+ else
+ dma_unmap_sg(host->chan_tx->device->dev,
+- host->data->sg, host->data->sg_len,
++ data->sg, data->sg_len,
+ DMA_TO_DEVICE);
+
+ complete(&host->dma_complete);
+@@ -273,13 +274,14 @@ static void mmcif_dma_complete(void *arg)
+
+ static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host)
+ {
+- struct scatterlist *sg = host->data->sg;
++ struct mmc_data *data = host->mrq->data;
++ struct scatterlist *sg = data->sg;
+ struct dma_async_tx_descriptor *desc = NULL;
+ struct dma_chan *chan = host->chan_rx;
+ dma_cookie_t cookie = -EINVAL;
+ int ret;
+
+- ret = dma_map_sg(chan->device->dev, sg, host->data->sg_len,
++ ret = dma_map_sg(chan->device->dev, sg, data->sg_len,
+ DMA_FROM_DEVICE);
+ if (ret > 0) {
+ host->dma_active = true;
+@@ -295,7 +297,7 @@ static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host)
+ dma_async_issue_pending(chan);
+ }
+ dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n",
+- __func__, host->data->sg_len, ret, cookie);
++ __func__, data->sg_len, ret, cookie);
+
+ if (!desc) {
+ /* DMA failed, fall back to PIO */
+@@ -316,18 +318,19 @@ static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host)
+ }
+
+ dev_dbg(&host->pd->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__,
+- desc, cookie, host->data->sg_len);
++ desc, cookie, data->sg_len);
+ }
+
+ static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host)
+ {
+- struct scatterlist *sg = host->data->sg;
++ struct mmc_data *data = host->mrq->data;
++ struct scatterlist *sg = data->sg;
+ struct dma_async_tx_descriptor *desc = NULL;
+ struct dma_chan *chan = host->chan_tx;
+ dma_cookie_t cookie = -EINVAL;
+ int ret;
+
+- ret = dma_map_sg(chan->device->dev, sg, host->data->sg_len,
++ ret = dma_map_sg(chan->device->dev, sg, data->sg_len,
+ DMA_TO_DEVICE);
+ if (ret > 0) {
+ host->dma_active = true;
+@@ -343,7 +346,7 @@ static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host)
+ dma_async_issue_pending(chan);
+ }
+ dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n",
+- __func__, host->data->sg_len, ret, cookie);
++ __func__, data->sg_len, ret, cookie);
+
+ if (!desc) {
+ /* DMA failed, fall back to PIO */
+@@ -711,8 +714,11 @@ static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host,
+ }
+
+ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
+- struct mmc_request *mrq, struct mmc_command *cmd, u32 opc)
++ struct mmc_request *mrq)
+ {
++ struct mmc_data *data = mrq->data;
++ struct mmc_command *cmd = mrq->cmd;
++ u32 opc = cmd->opcode;
+ u32 tmp = 0;
+
+ /* Response Type check */
+@@ -744,7 +750,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
+ break;
+ }
+ /* WDAT / DATW */
+- if (host->data) {
++ if (data) {
+ tmp |= CMD_SET_WDAT;
+ switch (host->bus_width) {
+ case MMC_BUS_WIDTH_1:
+@@ -768,7 +774,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
+ if (opc == MMC_READ_MULTIPLE_BLOCK || opc == MMC_WRITE_MULTIPLE_BLOCK) {
+ tmp |= CMD_SET_CMLTE | CMD_SET_CMD12EN;
+ sh_mmcif_bitset(host, MMCIF_CE_BLOCK_SET,
+- mrq->data->blocks << 16);
++ data->blocks << 16);
+ }
+ /* RIDXC[1:0] check bits */
+ if (opc == MMC_SEND_OP_COND || opc == MMC_ALL_SEND_CID ||
+@@ -782,7 +788,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
+ opc == MMC_SEND_CSD || opc == MMC_SEND_CID)
+ tmp |= CMD_SET_CRC7C_INTERNAL;
+
+- return opc = ((opc << 24) | tmp);
++ return (opc << 24) | tmp;
+ }
+
+ static int sh_mmcif_data_trans(struct sh_mmcif_host *host,
+@@ -830,12 +836,12 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
+ break;
+ }
+
+- if (host->data) {
++ if (mrq->data) {
+ sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0);
+ sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET,
+ mrq->data->blksz);
+ }
+- opc = sh_mmcif_set_cmd(host, mrq, cmd, opc);
++ opc = sh_mmcif_set_cmd(host, mrq);
+
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT, 0xD80430C0);
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask);
+@@ -851,15 +857,16 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
+ static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
+ struct mmc_request *mrq)
+ {
+- struct mmc_command *cmd = mrq->stop;
+-
+- if (mrq->cmd->opcode == MMC_READ_MULTIPLE_BLOCK)
++ switch (mrq->cmd->opcode) {
++ case MMC_READ_MULTIPLE_BLOCK:
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE);
+- else if (mrq->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK)
++ break;
++ case MMC_WRITE_MULTIPLE_BLOCK:
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE);
+- else {
++ break;
++ default:
+ dev_err(&host->pd->dev, "unsupported stop cmd\n");
+- cmd->error = sh_mmcif_error_manage(host);
++ mrq->stop->error = sh_mmcif_error_manage(host);
+ return;
+ }
+
+@@ -905,7 +912,6 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
+ }
+
+ host->mrq = mrq;
+- host->data = mrq->data;
+
+ sh_mmcif_start_cmd(host, mrq);
+ }
+@@ -985,6 +991,7 @@ static struct mmc_host_ops sh_mmcif_ops = {
+ static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host)
+ {
+ struct mmc_command *cmd = host->mrq->cmd;
++ struct mmc_data *data = host->mrq->data;
+ long time;
+
+ if (host->sd_error) {
+@@ -1010,10 +1017,10 @@ static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host)
+
+ sh_mmcif_get_response(host, cmd);
+
+- if (!host->data)
++ if (!data)
+ return false;
+
+- if (host->mrq->data->flags & MMC_DATA_READ) {
++ if (data->flags & MMC_DATA_READ) {
+ if (host->chan_rx)
+ sh_mmcif_start_dma_rx(host);
+ } else {
+@@ -1022,8 +1029,8 @@ static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host)
+ }
+
+ if (!host->dma_active) {
+- host->data->error = sh_mmcif_data_trans(host, host->mrq, cmd->opcode);
+- if (!host->data->error)
++ data->error = sh_mmcif_data_trans(host, host->mrq, cmd->opcode);
++ if (!data->error)
+ return true;
+ return false;
+ }
+@@ -1035,22 +1042,22 @@ static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host)
+ dev_err(host->mmc->parent,
+ "Error IRQ while waiting for DMA completion!\n");
+ /* Woken up by an error IRQ: abort DMA */
+- if (host->data->flags & MMC_DATA_READ)
++ if (data->flags & MMC_DATA_READ)
+ dmaengine_terminate_all(host->chan_rx);
+ else
+ dmaengine_terminate_all(host->chan_tx);
+- host->data->error = sh_mmcif_error_manage(host);
++ data->error = sh_mmcif_error_manage(host);
+ } else if (!time) {
+- host->data->error = -ETIMEDOUT;
++ data->error = -ETIMEDOUT;
+ } else if (time < 0) {
+- host->data->error = time;
++ data->error = time;
+ }
+ sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC,
+ BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
+ host->dma_active = false;
+
+- if (host->data->error)
+- host->data->bytes_xfered = 0;
++ if (data->error)
++ data->bytes_xfered = 0;
+
+ return false;
+ }
+@@ -1059,6 +1066,7 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
+ {
+ struct sh_mmcif_host *host = dev_id;
+ struct mmc_request *mrq = host->mrq;
++ struct mmc_data *data = mrq->data;
+
+ cancel_delayed_work_sync(&host->timeout_work);
+
+@@ -1106,20 +1114,18 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
+ case MMCIF_WAIT_FOR_READ_END:
+ case MMCIF_WAIT_FOR_WRITE_END:
+ if (host->sd_error)
+- mrq->data->error = sh_mmcif_error_manage(host);
++ data->error = sh_mmcif_error_manage(host);
+ break;
+ default:
+ BUG();
+ }
+
+ if (host->wait_for != MMCIF_WAIT_FOR_STOP) {
+- host->data = NULL;
++ if (!mrq->cmd->error && data && !data->error)
++ data->bytes_xfered =
++ data->blocks * data->blksz;
+
+- if (!mrq->cmd->error && mrq->data && !mrq->data->error)
+- mrq->data->bytes_xfered =
+- mrq->data->blocks * mrq->data->blksz;
+-
+- if (mrq->stop && !mrq->cmd->error && (!mrq->data || !mrq->data->error)) {
++ if (mrq->stop && !mrq->cmd->error && (!data || !data->error)) {
+ sh_mmcif_stop_cmd(host, mrq);
+ if (!mrq->stop->error)
+ return IRQ_HANDLED;
+@@ -1128,6 +1134,7 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
+
+ host->wait_for = MMCIF_WAIT_FOR_REQUEST;
+ host->state = STATE_IDLE;
++ host->mrq = NULL;
+ mmc_request_done(host->mmc, mrq);
+
+ return IRQ_HANDLED;
+@@ -1223,7 +1230,7 @@ static void mmcif_timeout_work(struct work_struct *work)
+ case MMCIF_WAIT_FOR_WRITE:
+ case MMCIF_WAIT_FOR_READ_END:
+ case MMCIF_WAIT_FOR_WRITE_END:
+- host->data->error = sh_mmcif_error_manage(host);
++ mrq->data->error = sh_mmcif_error_manage(host);
+ break;
+ default:
+ BUG();
+@@ -1231,7 +1238,6 @@ static void mmcif_timeout_work(struct work_struct *work)
+
+ host->state = STATE_IDLE;
+ host->wait_for = MMCIF_WAIT_FOR_REQUEST;
+- host->data = NULL;
+ host->mrq = NULL;
+ mmc_request_done(host->mmc, mrq);
+ }
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0067-mmc-sh_mmcif-fix-MMC_GEN_CMD-setting.patch b/patches.kzm9g/0067-mmc-sh_mmcif-fix-MMC_GEN_CMD-setting.patch
new file mode 100644
index 00000000000000..c7f20da2927c71
--- /dev/null
+++ b/patches.kzm9g/0067-mmc-sh_mmcif-fix-MMC_GEN_CMD-setting.patch
@@ -0,0 +1,40 @@
+From 34adc0ba61f82e5f33cb9d17893051afaac12a7a Mon Sep 17 00:00:00 2001
+From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com>
+Date: Wed, 7 Mar 2012 17:37:10 +0900
+Subject: mmc: sh_mmcif: fix MMC_GEN_CMD setting
+
+The MMC_GEN_CMD (CMD56) doesn't need to check busy signal.
+So, the patch fixes the setting.
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 183f796b5f701f8ab530ab232e4c27aef527bd76)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index f5d8b53..f91ae31 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -745,7 +745,6 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
+ case MMC_SET_WRITE_PROT:
+ case MMC_CLR_WRITE_PROT:
+ case MMC_ERASE:
+- case MMC_GEN_CMD:
+ tmp |= CMD_SET_RBSY;
+ break;
+ }
+@@ -828,7 +827,6 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
+ case MMC_SET_WRITE_PROT:
+ case MMC_CLR_WRITE_PROT:
+ case MMC_ERASE:
+- case MMC_GEN_CMD:
+ mask = MASK_START_CMD | MASK_MRBSYE;
+ break;
+ default:
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0068-mmc-sh_mmcif-simplify-bitmask-macros.patch b/patches.kzm9g/0068-mmc-sh_mmcif-simplify-bitmask-macros.patch
new file mode 100644
index 00000000000000..ea61e07929d1e0
--- /dev/null
+++ b/patches.kzm9g/0068-mmc-sh_mmcif-simplify-bitmask-macros.patch
@@ -0,0 +1,51 @@
+From 75e468534fc26dc5eea595dee43f1a6ae0231ddc Mon Sep 17 00:00:00 2001
+From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Date: Fri, 16 Mar 2012 12:49:04 +0100
+Subject: mmc: sh_mmcif: simplify bitmask macros
+
+Purely cosmetic readability improvement, no functional change.
+
+Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 135111cc5595c6a24dd826d503e2d2bae92da1c4)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/mmc/sh_mmcif.h | 21 +++++++++------------
+ 1 file changed, 9 insertions(+), 12 deletions(-)
+
+diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h
+index 04ff452..05f0e3d 100644
+--- a/include/linux/mmc/sh_mmcif.h
++++ b/include/linux/mmc/sh_mmcif.h
+@@ -77,18 +77,15 @@ struct sh_mmcif_plat_data {
+
+ /* CE_CLK_CTRL */
+ #define CLK_ENABLE (1 << 24) /* 1: output mmc clock */
+-#define CLK_CLEAR ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16))
+-#define CLK_SUP_PCLK ((1 << 19) | (1 << 18) | (1 << 17) | (1 << 16))
+-#define CLKDIV_4 (1<<16) /* mmc clock frequency.
+- * n: bus clock/(2^(n+1)) */
+-#define CLKDIV_256 (7<<16) /* mmc clock frequency. (see above) */
+-#define SRSPTO_256 ((1 << 13) | (0 << 12)) /* resp timeout */
+-#define SRBSYTO_29 ((1 << 11) | (1 << 10) | \
+- (1 << 9) | (1 << 8)) /* resp busy timeout */
+-#define SRWDTO_29 ((1 << 7) | (1 << 6) | \
+- (1 << 5) | (1 << 4)) /* read/write timeout */
+-#define SCCSTO_29 ((1 << 3) | (1 << 2) | \
+- (1 << 1) | (1 << 0)) /* ccs timeout */
++#define CLK_CLEAR (0xf << 16)
++#define CLK_SUP_PCLK (0xf << 16)
++#define CLKDIV_4 (1 << 16) /* mmc clock frequency.
++ * n: bus clock/(2^(n+1)) */
++#define CLKDIV_256 (7 << 16) /* mmc clock frequency. (see above) */
++#define SRSPTO_256 (2 << 12) /* resp timeout */
++#define SRBSYTO_29 (0xf << 8) /* resp busy timeout */
++#define SRWDTO_29 (0xf << 4) /* read/write timeout */
++#define SCCSTO_29 (0xf << 0) /* ccs timeout */
+
+ /* CE_VERSION */
+ #define SOFT_RST_ON (1 << 31)
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0069-mmc-sh_mmcif-double-clock-speed.patch b/patches.kzm9g/0069-mmc-sh_mmcif-double-clock-speed.patch
new file mode 100644
index 00000000000000..921cf8c2925c74
--- /dev/null
+++ b/patches.kzm9g/0069-mmc-sh_mmcif-double-clock-speed.patch
@@ -0,0 +1,41 @@
+From 7d7d0268cfe4401bd5a571771542032700670266 Mon Sep 17 00:00:00 2001
+From: Simon Horman <horms@verge.net.au>
+Date: Wed, 28 Mar 2012 18:01:09 +0900
+Subject: mmc: sh_mmcif: double clock speed
+
+Correct an off-by one error when calculating the clock divisor in cases
+where the host clock is a power of two of the target clock. Previously the
+divisor was one greater than the correct value in these cases leading to
+the clock being set at half the desired speed.
+
+Thanks to Guennadi Liakhovetski for working with me on the logic for this
+change.
+
+Tested-by: Cao Minh Hiep <hiepcm@gmail.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit f93882570496aa02ba8a47bfaf81cce43046b978)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index f91ae31..6288046 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -453,7 +453,8 @@ static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
+ sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK);
+ else
+ sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR &
+- ((fls(host->clk / clk) - 1) << 16));
++ ((fls(DIV_ROUND_UP(host->clk,
++ clk) - 1) - 1) << 16));
+
+ sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE);
+ }
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0070-mmc-sh_mmcif-mmc-f_max-should-be-half-of-the-bus-clo.patch b/patches.kzm9g/0070-mmc-sh_mmcif-mmc-f_max-should-be-half-of-the-bus-clo.patch
new file mode 100644
index 00000000000000..49db503a2580cb
--- /dev/null
+++ b/patches.kzm9g/0070-mmc-sh_mmcif-mmc-f_max-should-be-half-of-the-bus-clo.patch
@@ -0,0 +1,49 @@
+From f75a73e27d80a451ca2d71defb9a19412eda150b Mon Sep 17 00:00:00 2001
+From: Simon Horman <horms@verge.net.au>
+Date: Wed, 28 Mar 2012 18:01:10 +0900
+Subject: mmc: sh_mmcif: mmc->f_max should be half of the bus clock
+
+mmc->f_max should be half of the bus clock.
+And now that mmc->f_max is not equal to the bus clock the
+latter should be used directly to calculate mmc->f_min.
+
+Cc: Magnus Damm <magnus.damm@gmail.com>
+Tested-by: Cao Minh Hiep <hiepcm@gmail.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit 930f152cc9998388031af577843baae572ac8ab6)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index 6288046..347b330 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -1297,14 +1297,14 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
+ spin_lock_init(&host->lock);
+
+ mmc->ops = &sh_mmcif_ops;
+- mmc->f_max = host->clk;
++ mmc->f_max = host->clk / 2;
+ /* close to 400KHz */
+- if (mmc->f_max < 51200000)
+- mmc->f_min = mmc->f_max / 128;
+- else if (mmc->f_max < 102400000)
+- mmc->f_min = mmc->f_max / 256;
++ if (host->clk < 51200000)
++ mmc->f_min = host->clk / 128;
++ else if (host->clk < 102400000)
++ mmc->f_min = host->clk / 256;
+ else
+- mmc->f_min = mmc->f_max / 512;
++ mmc->f_min = host->clk / 512;
+ if (pd->ocr)
+ mmc->ocr_avail = pd->ocr;
+ mmc->caps = MMC_CAP_MMC_HIGHSPEED;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0071-mmc-sh_mmcif-Simplify-calculation-of-mmc-f_min.patch b/patches.kzm9g/0071-mmc-sh_mmcif-Simplify-calculation-of-mmc-f_min.patch
new file mode 100644
index 00000000000000..a86157b48157da
--- /dev/null
+++ b/patches.kzm9g/0071-mmc-sh_mmcif-Simplify-calculation-of-mmc-f_min.patch
@@ -0,0 +1,44 @@
+From cf3d0f14aa4b001ace80b5535d6b1d6e84a0d0e2 Mon Sep 17 00:00:00 2001
+From: Simon Horman <horms@verge.net.au>
+Date: Wed, 28 Mar 2012 18:01:11 +0900
+Subject: mmc: sh_mmcif: Simplify calculation of mmc->f_min
+
+There is no need to tune mmc->f_min to a value near 400kHz as the MMC core
+begins testing frequencies at 400kHz regardless of the value of mmc->f_min.
+
+As suggested by Guennadi Liakhovetski.
+
+Cc: Magnus Damm <magnus.damm@gmail.com>
+Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+Tested-by: Cao Minh Hiep <hiepcm@gmail.com>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Chris Ball <cjb@laptop.org>
+(cherry picked from commit eb91b9118db8c05a5a1257b594b021d32b491254)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ drivers/mmc/host/sh_mmcif.c | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
+index 347b330..020c9cc 100644
+--- a/drivers/mmc/host/sh_mmcif.c
++++ b/drivers/mmc/host/sh_mmcif.c
+@@ -1298,13 +1298,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
+
+ mmc->ops = &sh_mmcif_ops;
+ mmc->f_max = host->clk / 2;
+- /* close to 400KHz */
+- if (host->clk < 51200000)
+- mmc->f_min = host->clk / 128;
+- else if (host->clk < 102400000)
+- mmc->f_min = host->clk / 256;
+- else
+- mmc->f_min = host->clk / 512;
++ mmc->f_min = host->clk / 512;
+ if (pd->ocr)
+ mmc->ocr_avail = pd->ocr;
+ mmc->caps = MMC_CAP_MMC_HIGHSPEED;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0072-ARM-mach-shmobile-clock-r8a7740-add-USB-clock.patch b/patches.kzm9g/0072-ARM-mach-shmobile-clock-r8a7740-add-USB-clock.patch
new file mode 100644
index 00000000000000..27f4312a233f86
--- /dev/null
+++ b/patches.kzm9g/0072-ARM-mach-shmobile-clock-r8a7740-add-USB-clock.patch
@@ -0,0 +1,203 @@
+From 30534687e4e814095198494bc946a63c55731d43 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>
+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 99c4d74..30535f4 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, MSTP323,
++ MSTP329, MSTP323, MSTP320,
++
++ MSTP416, MSTP407, MSTP406,
+
+ MSTP_NR
+ };
+@@ -281,6 +381,11 @@ static struct clk mstp_clks[MSTP_NR] = {
+
+ [MSTP329] = SH_CLK_MSTP32(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
+ [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[] = {
+@@ -299,6 +404,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]),
+@@ -335,6 +441,14 @@ static struct clk_lookup lookups[] = {
+
+ CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
+ 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.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0073-ALSA-workaround-change-the-timing-of-alsa_sound_last.patch b/patches.kzm9g/0073-ALSA-workaround-change-the-timing-of-alsa_sound_last.patch
new file mode 100644
index 00000000000000..e0d98cea4904de
--- /dev/null
+++ b/patches.kzm9g/0073-ALSA-workaround-change-the-timing-of-alsa_sound_last.patch
@@ -0,0 +1,38 @@
+From d7462814e127df262ab184179b807f388fe51c1f Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 19 Apr 2012 00:00:27 -0700
+Subject: ALSA: workaround: change the timing of alsa_sound_last_init()
+
+Current alsa_sound_last_init() was called as __initcall().
+So, on current ALSA, only devices that had been properly
+registered at this point were shown.
+So, it will show "No soundcards found" if driver requests
+probe deferment. it's often misleading.
+This patch delays the timing of alsa_sound_last_init()
+as workaround.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Reviwed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+(cherry picked from commit 590b4775d6b628c7ad215fd0335a0a787032e2dd)
+
+N.B: Not present in mainline yet
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/last.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/last.c b/sound/last.c
+index bdd0857..7ffc182 100644
+--- a/sound/last.c
++++ b/sound/last.c
+@@ -38,4 +38,4 @@ static int __init alsa_sound_last_init(void)
+ return 0;
+ }
+
+-__initcall(alsa_sound_last_init);
++late_initcall_sync(alsa_sound_last_init);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0074-ASoC-core-Optimise-and-refactor-pcm_new-to-pass-only.patch b/patches.kzm9g/0074-ASoC-core-Optimise-and-refactor-pcm_new-to-pass-only.patch
new file mode 100644
index 00000000000000..bd3ba2b7f43230
--- /dev/null
+++ b/patches.kzm9g/0074-ASoC-core-Optimise-and-refactor-pcm_new-to-pass-only.patch
@@ -0,0 +1,529 @@
+From c41e2859faba7ea13c8bf3bf54a5c25d8297a09c Mon Sep 17 00:00:00 2001
+From: Liam Girdwood <lrg@ti.com>
+Date: Tue, 7 Jun 2011 16:08:33 +0100
+Subject: ASoC: core - Optimise and refactor pcm_new() to pass only rtd
+
+Currently pcm_new() passes in 3 arguments :- card, pcm and DAI.
+
+Refactor this to only pass in 1 argument (i.e. the rtd) since struct rtd contains
+card, pcm and DAI along with other members too that are useful too.
+
+Signed-off-by: Liam Girdwood <lrg@ti.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 552d1ef6b5a98d7b95959d5b139071e3c90cebf1)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/sound/soc.h | 3 +--
+ sound/soc/atmel/atmel-pcm.c | 6 ++++--
+ sound/soc/au1x/dbdma2.c | 7 ++++---
+ sound/soc/blackfin/bf5xx-ac97-pcm.c | 6 ++++--
+ sound/soc/blackfin/bf5xx-i2s-pcm.c | 6 ++++--
+ sound/soc/blackfin/bf5xx-tdm-pcm.c | 6 ++++--
+ sound/soc/davinci/davinci-pcm.c | 6 ++++--
+ sound/soc/ep93xx/ep93xx-pcm.c | 6 ++++--
+ sound/soc/fsl/fsl_dma.c | 6 ++++--
+ sound/soc/fsl/mpc5200_dma.c | 7 ++++---
+ sound/soc/imx/imx-pcm-fiq.c | 8 +++++---
+ sound/soc/imx/imx-ssi.c | 7 ++++---
+ sound/soc/imx/imx-ssi.h | 3 +--
+ sound/soc/jz4740/jz4740-pcm.c | 6 ++++--
+ sound/soc/kirkwood/kirkwood-dma.c | 6 ++++--
+ sound/soc/mid-x86/sst_platform.c | 5 +++--
+ sound/soc/nuc900/nuc900-pcm.c | 7 +++++--
+ sound/soc/omap/omap-pcm.c | 6 ++++--
+ sound/soc/pxa/pxa2xx-pcm.c | 6 ++++--
+ sound/soc/s6000/s6000-pcm.c | 7 ++++---
+ sound/soc/samsung/dma.c | 6 ++++--
+ sound/soc/sh/dma-sh7760.c | 6 +++---
+ sound/soc/sh/fsi.c | 6 +++---
+ sound/soc/sh/siu_pcm.c | 5 +++--
+ sound/soc/soc-core.c | 3 +--
+ sound/soc/tegra/tegra_pcm.c | 6 ++++--
+ sound/soc/txx9/txx9aclc.c | 5 +++--
+ 27 files changed, 96 insertions(+), 61 deletions(-)
+
+diff --git a/include/sound/soc.h b/include/sound/soc.h
+index 3a4bd3a..e9db08c 100644
+--- a/include/sound/soc.h
++++ b/include/sound/soc.h
+@@ -623,8 +623,7 @@ struct snd_soc_platform_driver {
+ int (*resume)(struct snd_soc_dai *dai);
+
+ /* pcm creation and destruction */
+- int (*pcm_new)(struct snd_card *, struct snd_soc_dai *,
+- struct snd_pcm *);
++ int (*pcm_new)(struct snd_soc_pcm_runtime *);
+ void (*pcm_free)(struct snd_pcm *);
+
+ /*
+diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
+index d0e7532..42f699c 100644
+--- a/sound/soc/atmel/atmel-pcm.c
++++ b/sound/soc/atmel/atmel-pcm.c
+@@ -364,9 +364,11 @@ static struct snd_pcm_ops atmel_pcm_ops = {
+ \*--------------------------------------------------------------------------*/
+ static u64 atmel_pcm_dmamask = 0xffffffff;
+
+-static int atmel_pcm_new(struct snd_card *card,
+- struct snd_soc_dai *dai, struct snd_pcm *pcm)
++static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ int ret = 0;
+
+ if (!card->dev->dma_mask)
+diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
+index 10fdd28..20bb53a 100644
+--- a/sound/soc/au1x/dbdma2.c
++++ b/sound/soc/au1x/dbdma2.c
+@@ -319,10 +319,11 @@ static void au1xpsc_pcm_free_dma_buffers(struct snd_pcm *pcm)
+ snd_pcm_lib_preallocate_free_for_all(pcm);
+ }
+
+-static int au1xpsc_pcm_new(struct snd_card *card,
+- struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++static int au1xpsc_pcm_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_pcm *pcm = rtd->pcm;
++
+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+ card->dev, AU1XPSC_BUFFER_MIN_BYTES, (4096 * 1024) - 1);
+
+diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
+index 98b44b3..9e59f68 100644
+--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
++++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
+@@ -418,9 +418,11 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
+
+ static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
+
+-int bf5xx_pcm_ac97_new(struct snd_card *card, struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++int bf5xx_pcm_ac97_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ int ret = 0;
+
+ pr_debug("%s enter\n", __func__);
+diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
+index f1fd95b..c42fb73 100644
+--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
++++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
+@@ -257,9 +257,11 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
+
+ static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
+
+-int bf5xx_pcm_i2s_new(struct snd_card *card, struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ int ret = 0;
+
+ pr_debug("%s enter\n", __func__);
+diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
+index 07cfc7a..c95cc03 100644
+--- a/sound/soc/blackfin/bf5xx-tdm-pcm.c
++++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c
+@@ -283,9 +283,11 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
+
+ static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
+
+-static int bf5xx_pcm_tdm_new(struct snd_card *card, struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++static int bf5xx_pcm_tdm_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ int ret = 0;
+
+ if (!card->dev->dma_mask)
+diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
+index 9d35b8c..29759e1 100644
+--- a/sound/soc/davinci/davinci-pcm.c
++++ b/sound/soc/davinci/davinci-pcm.c
+@@ -811,9 +811,11 @@ static void davinci_pcm_free(struct snd_pcm *pcm)
+
+ static u64 davinci_pcm_dmamask = 0xffffffff;
+
+-static int davinci_pcm_new(struct snd_card *card,
+- struct snd_soc_dai *dai, struct snd_pcm *pcm)
++static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ int ret;
+
+ if (!card->dev->dma_mask)
+diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
+index a456e49..e27c417 100644
+--- a/sound/soc/ep93xx/ep93xx-pcm.c
++++ b/sound/soc/ep93xx/ep93xx-pcm.c
+@@ -266,9 +266,11 @@ static void ep93xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
+
+ static u64 ep93xx_pcm_dmamask = 0xffffffff;
+
+-static int ep93xx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ int ret = 0;
+
+ if (!card->dev->dma_mask)
+diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
+index 6680c0b..5312d1b 100644
+--- a/sound/soc/fsl/fsl_dma.c
++++ b/sound/soc/fsl/fsl_dma.c
+@@ -294,9 +294,11 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
+ * Regardless of where the memory is actually allocated, since the device can
+ * technically DMA to any 36-bit address, we do need to set the DMA mask to 36.
+ */
+-static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ static u64 fsl_dma_dmamask = DMA_BIT_MASK(36);
+ int ret;
+
+diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
+index cbaf8b7..61d2ecc 100644
+--- a/sound/soc/fsl/mpc5200_dma.c
++++ b/sound/soc/fsl/mpc5200_dma.c
+@@ -299,10 +299,11 @@ static struct snd_pcm_ops psc_dma_ops = {
+ };
+
+ static u64 psc_dma_dmamask = 0xffffffff;
+-static int psc_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++static int psc_dma_new(struct snd_soc_pcm_runtime *rtd)
+ {
+- struct snd_soc_pcm_runtime *rtd = pcm->private_data;
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ struct psc_dma *psc_dma = snd_soc_dai_get_drvdata(rtd->cpu_dai);
+ size_t size = psc_dma_hardware.buffer_bytes_max;
+ int rc = 0;
+diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c
+index 413b78d..309c59e 100644
+--- a/sound/soc/imx/imx-pcm-fiq.c
++++ b/sound/soc/imx/imx-pcm-fiq.c
+@@ -238,12 +238,14 @@ static struct snd_pcm_ops imx_pcm_ops = {
+
+ static int ssi_irq = 0;
+
+-static int imx_pcm_fiq_new(struct snd_card *card, struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ int ret;
+
+- ret = imx_pcm_new(card, dai, pcm);
++ ret = imx_pcm_new(rtd);
+ if (ret)
+ return ret;
+
+diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
+index 3b56254..3a676cd 100644
+--- a/sound/soc/imx/imx-ssi.c
++++ b/sound/soc/imx/imx-ssi.c
+@@ -388,10 +388,11 @@ static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
+
+ static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);
+
+-int imx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
+ {
+-
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ int ret = 0;
+
+ if (!card->dev->dma_mask)
+diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h
+index dc8a875..0a84cec 100644
+--- a/sound/soc/imx/imx-ssi.h
++++ b/sound/soc/imx/imx-ssi.h
+@@ -225,8 +225,7 @@ struct snd_soc_platform *imx_ssi_dma_mx2_init(struct platform_device *pdev,
+ struct imx_ssi *ssi);
+
+ int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
+-int imx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
+- struct snd_pcm *pcm);
++int imx_pcm_new(struct snd_soc_pcm_runtime *rtd);
+ void imx_pcm_free(struct snd_pcm *pcm);
+
+ /*
+diff --git a/sound/soc/jz4740/jz4740-pcm.c b/sound/soc/jz4740/jz4740-pcm.c
+index fb1483f..a7c9578 100644
+--- a/sound/soc/jz4740/jz4740-pcm.c
++++ b/sound/soc/jz4740/jz4740-pcm.c
+@@ -299,9 +299,11 @@ static void jz4740_pcm_free(struct snd_pcm *pcm)
+
+ static u64 jz4740_pcm_dmamask = DMA_BIT_MASK(32);
+
+-int jz4740_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++int jz4740_pcm_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ int ret = 0;
+
+ if (!card->dev->dma_mask)
+diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
+index e13c6ce..cd33de1 100644
+--- a/sound/soc/kirkwood/kirkwood-dma.c
++++ b/sound/soc/kirkwood/kirkwood-dma.c
+@@ -312,9 +312,11 @@ static int kirkwood_dma_preallocate_dma_buffer(struct snd_pcm *pcm,
+ return 0;
+ }
+
+-static int kirkwood_dma_new(struct snd_card *card,
+- struct snd_soc_dai *dai, struct snd_pcm *pcm)
++static int kirkwood_dma_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ int ret;
+
+ if (!card->dev->dma_mask)
+diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
+index 5a946b4..3e78260 100644
+--- a/sound/soc/mid-x86/sst_platform.c
++++ b/sound/soc/mid-x86/sst_platform.c
+@@ -402,9 +402,10 @@ static void sst_pcm_free(struct snd_pcm *pcm)
+ snd_pcm_lib_preallocate_free_for_all(pcm);
+ }
+
+-int sst_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ int retval = 0;
+
+ pr_debug("sst_pcm_new called\n");
+diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c
+index 8263f56..d589ef1 100644
+--- a/sound/soc/nuc900/nuc900-pcm.c
++++ b/sound/soc/nuc900/nuc900-pcm.c
+@@ -315,9 +315,12 @@ static void nuc900_dma_free_dma_buffers(struct snd_pcm *pcm)
+ }
+
+ static u64 nuc900_pcm_dmamask = DMA_BIT_MASK(32);
+-static int nuc900_dma_new(struct snd_card *card,
+- struct snd_soc_dai *dai, struct snd_pcm *pcm)
++static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
++
+ if (!card->dev->dma_mask)
+ card->dev->dma_mask = &nuc900_pcm_dmamask;
+ if (!card->dev->coherent_dma_mask)
+diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
+index e6a6b99..b2f5751 100644
+--- a/sound/soc/omap/omap-pcm.c
++++ b/sound/soc/omap/omap-pcm.c
+@@ -366,9 +366,11 @@ static void omap_pcm_free_dma_buffers(struct snd_pcm *pcm)
+ }
+ }
+
+-static int omap_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ int ret = 0;
+
+ if (!card->dev->dma_mask)
+diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
+index fab20a5..da28394 100644
+--- a/sound/soc/pxa/pxa2xx-pcm.c
++++ b/sound/soc/pxa/pxa2xx-pcm.c
+@@ -85,9 +85,11 @@ static struct snd_pcm_ops pxa2xx_pcm_ops = {
+
+ static u64 pxa2xx_pcm_dmamask = DMA_BIT_MASK(32);
+
+-static int pxa2xx_soc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++static int pxa2xx_soc_pcm_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ int ret = 0;
+
+ if (!card->dev->dma_mask)
+diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
+index ab3ccae..80c85fd 100644
+--- a/sound/soc/s6000/s6000-pcm.c
++++ b/sound/soc/s6000/s6000-pcm.c
+@@ -443,10 +443,11 @@ static void s6000_pcm_free(struct snd_pcm *pcm)
+
+ static u64 s6000_pcm_dmamask = DMA_BIT_MASK(32);
+
+-static int s6000_pcm_new(struct snd_card *card,
+- struct snd_soc_dai *dai, struct snd_pcm *pcm)
++static int s6000_pcm_new(struct snd_soc_pcm_runtime *runtime)
+ {
+- struct snd_soc_pcm_runtime *runtime = pcm->private_data;
++ struct snd_card *card = runtime->card->snd_card;
++ struct snd_soc_dai *dai = runtime->cpu_dai;
++ struct snd_pcm *pcm = runtime->pcm;
+ struct s6000_pcm_dma_params *params;
+ int res;
+
+diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
+index 5cb3b88..9465588 100644
+--- a/sound/soc/samsung/dma.c
++++ b/sound/soc/samsung/dma.c
+@@ -425,9 +425,11 @@ static void dma_free_dma_buffers(struct snd_pcm *pcm)
+
+ static u64 dma_mask = DMA_BIT_MASK(32);
+
+-static int dma_new(struct snd_card *card,
+- struct snd_soc_dai *dai, struct snd_pcm *pcm)
++static int dma_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ int ret = 0;
+
+ pr_debug("Entered %s\n", __func__);
+diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
+index c326d29..db74005 100644
+--- a/sound/soc/sh/dma-sh7760.c
++++ b/sound/soc/sh/dma-sh7760.c
+@@ -327,10 +327,10 @@ static void camelot_pcm_free(struct snd_pcm *pcm)
+ snd_pcm_lib_preallocate_free_for_all(pcm);
+ }
+
+-static int camelot_pcm_new(struct snd_card *card,
+- struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_pcm *pcm = rtd->pcm;
++
+ /* dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel
+ * in MMAP mode (i.e. aplay -M)
+ */
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 4a9da6b..339a1df 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -1129,10 +1129,10 @@ static void fsi_pcm_free(struct snd_pcm *pcm)
+ snd_pcm_lib_preallocate_free_for_all(pcm);
+ }
+
+-static int fsi_pcm_new(struct snd_card *card,
+- struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++static int fsi_pcm_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_pcm *pcm = rtd->pcm;
++
+ /*
+ * dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel
+ * in MMAP mode (i.e. aplay -M)
+diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
+index a423bab..f8f6816 100644
+--- a/sound/soc/sh/siu_pcm.c
++++ b/sound/soc/sh/siu_pcm.c
+@@ -527,10 +527,11 @@ static snd_pcm_uframes_t siu_pcm_pointer_dma(struct snd_pcm_substream *ss)
+ return bytes_to_frames(ss->runtime, ptr);
+ }
+
+-static int siu_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++static int siu_pcm_new(struct snd_soc_pcm_runtime *rtd)
+ {
+ /* card->dev == socdev->dev, see snd_soc_new_pcms() */
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_pcm *pcm = rtd->pcm;
+ struct siu_info *info = siu_i2s_data;
+ struct platform_device *pdev = to_platform_device(card->dev);
+ int ret;
+diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
+index e2bfe1d..f2a920a 100644
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -2157,8 +2157,7 @@ static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops);
+
+ if (platform->driver->pcm_new) {
+- ret = platform->driver->pcm_new(rtd->card->snd_card,
+- codec_dai, pcm);
++ ret = platform->driver->pcm_new(rtd);
+ if (ret < 0) {
+ pr_err("asoc: platform pcm constructor failed\n");
+ return ret;
+diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
+index 6201710..c7cfd96 100644
+--- a/sound/soc/tegra/tegra_pcm.c
++++ b/sound/soc/tegra/tegra_pcm.c
+@@ -327,9 +327,11 @@ static void tegra_pcm_deallocate_dma_buffer(struct snd_pcm *pcm, int stream)
+
+ static u64 tegra_dma_mask = DMA_BIT_MASK(32);
+
+-static int tegra_pcm_new(struct snd_card *card,
+- struct snd_soc_dai *dai, struct snd_pcm *pcm)
++static int tegra_pcm_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_card *card = rtd->card->snd_card;
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ int ret = 0;
+
+ if (!card->dev->dma_mask)
+diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c
+index f4aa4e0..34aa972 100644
+--- a/sound/soc/txx9/txx9aclc.c
++++ b/sound/soc/txx9/txx9aclc.c
+@@ -288,9 +288,10 @@ static void txx9aclc_pcm_free_dma_buffers(struct snd_pcm *pcm)
+ snd_pcm_lib_preallocate_free_for_all(pcm);
+ }
+
+-static int txx9aclc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
+- struct snd_pcm *pcm)
++static int txx9aclc_pcm_new(struct snd_soc_pcm_runtime *rtd)
+ {
++ struct snd_soc_dai *dai = rtd->cpu_dai;
++ struct snd_pcm *pcm = rtd->pcm;
+ struct platform_device *pdev = to_platform_device(dai->platform->dev);
+ struct txx9aclc_soc_device *dev;
+ struct resource *r;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0075-ASoC-core-Allow-components-to-probe-remove-in-sequen.patch b/patches.kzm9g/0075-ASoC-core-Allow-components-to-probe-remove-in-sequen.patch
new file mode 100644
index 00000000000000..7a32b263c33977
--- /dev/null
+++ b/patches.kzm9g/0075-ASoC-core-Allow-components-to-probe-remove-in-sequen.patch
@@ -0,0 +1,249 @@
+From 94df9e9b6182759ffe6a44fb699a5bd97bd5ca53 Mon Sep 17 00:00:00 2001
+From: Liam Girdwood <lrg@ti.com>
+Date: Tue, 7 Jun 2011 16:08:05 +0100
+Subject: ASoC: core - Allow components to probe/remove in sequence.
+
+Some ASoC components depend on other ASoC components to provide clocks and
+power resources in order to probe() and vice versa for remove().
+
+Allow components to be ordered so that components can be probed() and removed()
+in sequences that conform to their dependencies.
+
+Signed-off-by: Liam Girdwood <lrg@ti.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 0168bf0d130de83cd3532b834237c6228a6158dd)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/sound/soc-dai.h | 4 ++++
+ include/sound/soc.h | 18 +++++++++++++++
+ sound/soc/soc-core.c | 60 ++++++++++++++++++++++++++++++++-----------------
+ 3 files changed, 61 insertions(+), 21 deletions(-)
+
+diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
+index 1bafe95..5ad5f3a 100644
+--- a/include/sound/soc-dai.h
++++ b/include/sound/soc-dai.h
+@@ -209,6 +209,10 @@ struct snd_soc_dai_driver {
+ struct snd_soc_pcm_stream capture;
+ struct snd_soc_pcm_stream playback;
+ unsigned int symmetric_rates:1;
++
++ /* probe ordering - for components with runtime dependencies */
++ int probe_order;
++ int remove_order;
+ };
+
+ /*
+diff --git a/include/sound/soc.h b/include/sound/soc.h
+index e9db08c..447232c 100644
+--- a/include/sound/soc.h
++++ b/include/sound/soc.h
+@@ -203,6 +203,16 @@
+ SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xmask, xtexts, xvalues)
+
+ /*
++ * Component probe and remove ordering levels for components with runtime
++ * dependencies.
++ */
++#define SND_SOC_COMP_ORDER_FIRST -2
++#define SND_SOC_COMP_ORDER_EARLY -1
++#define SND_SOC_COMP_ORDER_NORMAL 0
++#define SND_SOC_COMP_ORDER_LATE 1
++#define SND_SOC_COMP_ORDER_LAST 2
++
++/*
+ * Bias levels
+ *
+ * @ON: Bias is fully on for audio playback and capture operations.
+@@ -612,6 +622,10 @@ struct snd_soc_codec_driver {
+
+ void (*seq_notifier)(struct snd_soc_dapm_context *,
+ enum snd_soc_dapm_type, int);
++
++ /* probe ordering - for components with runtime dependencies */
++ int probe_order;
++ int remove_order;
+ };
+
+ /* SoC platform interface */
+@@ -635,6 +649,10 @@ struct snd_soc_platform_driver {
+
+ /* platform stream ops */
+ struct snd_pcm_ops *ops;
++
++ /* probe ordering - for components with runtime dependencies */
++ int probe_order;
++ int remove_order;
+ };
+
+ struct snd_soc_platform {
+diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
+index f2a920a..841b1c9 100644
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -1396,7 +1396,7 @@ static void soc_remove_codec(struct snd_soc_codec *codec)
+ module_put(codec->dev->driver->owner);
+ }
+
+-static void soc_remove_dai_link(struct snd_soc_card *card, int num)
++static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
+ {
+ struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
+ struct snd_soc_codec *codec = rtd->codec;
+@@ -1413,7 +1413,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
+ }
+
+ /* remove the CODEC DAI */
+- if (codec_dai && codec_dai->probed) {
++ if (codec_dai && codec_dai->probed &&
++ codec_dai->driver->remove_order == order) {
+ if (codec_dai->driver->remove) {
+ err = codec_dai->driver->remove(codec_dai);
+ if (err < 0)
+@@ -1424,7 +1425,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
+ }
+
+ /* remove the platform */
+- if (platform && platform->probed) {
++ if (platform && platform->probed &&
++ platform->driver->remove_order == order) {
+ if (platform->driver->remove) {
+ err = platform->driver->remove(platform);
+ if (err < 0)
+@@ -1436,11 +1438,13 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
+ }
+
+ /* remove the CODEC */
+- if (codec && codec->probed)
++ if (codec && codec->probed &&
++ codec->driver->remove_order == order)
+ soc_remove_codec(codec);
+
+ /* remove the cpu_dai */
+- if (cpu_dai && cpu_dai->probed) {
++ if (cpu_dai && cpu_dai->probed &&
++ cpu_dai->driver->remove_order == order) {
+ if (cpu_dai->driver->remove) {
+ err = cpu_dai->driver->remove(cpu_dai);
+ if (err < 0)
+@@ -1454,11 +1458,13 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
+
+ static void soc_remove_dai_links(struct snd_soc_card *card)
+ {
+- int i;
+-
+- for (i = 0; i < card->num_rtd; i++)
+- soc_remove_dai_link(card, i);
++ int dai, order;
+
++ for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
++ order++) {
++ for (dai = 0; dai < card->num_rtd; dai++)
++ soc_remove_dai_link(card, dai, order);
++ }
+ card->num_rtd = 0;
+ }
+
+@@ -1599,7 +1605,7 @@ static int soc_post_component_init(struct snd_soc_card *card,
+ return 0;
+ }
+
+-static int soc_probe_dai_link(struct snd_soc_card *card, int num)
++static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
+ {
+ struct snd_soc_dai_link *dai_link = &card->dai_link[num];
+ struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
+@@ -1608,7 +1614,8 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
+ struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai;
+ int ret;
+
+- dev_dbg(card->dev, "probe %s dai link %d\n", card->name, num);
++ dev_dbg(card->dev, "probe %s dai link %d late %d\n",
++ card->name, num, order);
+
+ /* config components */
+ codec_dai->codec = codec;
+@@ -1620,7 +1627,8 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
+ rtd->pmdown_time = pmdown_time;
+
+ /* probe the cpu_dai */
+- if (!cpu_dai->probed) {
++ if (!cpu_dai->probed &&
++ cpu_dai->driver->probe_order == order) {
+ if (!try_module_get(cpu_dai->dev->driver->owner))
+ return -ENODEV;
+
+@@ -1639,14 +1647,16 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
+ }
+
+ /* probe the CODEC */
+- if (!codec->probed) {
++ if (!codec->probed &&
++ codec->driver->probe_order == order) {
+ ret = soc_probe_codec(card, codec);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* probe the platform */
+- if (!platform->probed) {
++ if (!platform->probed &&
++ platform->driver->probe_order == order) {
+ if (!try_module_get(platform->dev->driver->owner))
+ return -ENODEV;
+
+@@ -1665,7 +1675,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
+ }
+
+ /* probe the CODEC DAI */
+- if (!codec_dai->probed) {
++ if (!codec_dai->probed && codec_dai->driver->probe_order == order) {
+ if (codec_dai->driver->probe) {
+ ret = codec_dai->driver->probe(codec_dai);
+ if (ret < 0) {
+@@ -1680,6 +1690,10 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
+ list_add(&codec_dai->card_list, &card->dai_dev_list);
+ }
+
++ /* complete DAI probe during last probe */
++ if (order != SND_SOC_COMP_ORDER_LAST)
++ return 0;
++
+ /* DAPM dai link stream work */
+ INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
+
+@@ -1820,7 +1834,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
+ struct snd_soc_codec *codec;
+ struct snd_soc_codec_conf *codec_conf;
+ enum snd_soc_compress_type compress_type;
+- int ret, i;
++ int ret, i, order;
+
+ mutex_lock(&card->mutex);
+
+@@ -1898,12 +1912,16 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
+ goto card_probe_error;
+ }
+
+- for (i = 0; i < card->num_links; i++) {
+- ret = soc_probe_dai_link(card, i);
+- if (ret < 0) {
+- pr_err("asoc: failed to instantiate card %s: %d\n",
++ /* early DAI link probe */
++ for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
++ order++) {
++ for (i = 0; i < card->num_links; i++) {
++ ret = soc_probe_dai_link(card, i, order);
++ if (ret < 0) {
++ pr_err("asoc: failed to instantiate card %s: %d\n",
+ card->name, ret);
+- goto probe_dai_err;
++ goto probe_dai_err;
++ }
+ }
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0076-ASoC-core-Separate-out-PCM-operations-into-new-file.patch b/patches.kzm9g/0076-ASoC-core-Separate-out-PCM-operations-into-new-file.patch
new file mode 100644
index 00000000000000..a4e97ef1757301
--- /dev/null
+++ b/patches.kzm9g/0076-ASoC-core-Separate-out-PCM-operations-into-new-file.patch
@@ -0,0 +1,1333 @@
+From 481aa7d92ac3e22d6bc73a27f56efe7cec947585 Mon Sep 17 00:00:00 2001
+From: Liam Girdwood <lrg@ti.com>
+Date: Thu, 9 Jun 2011 14:45:53 +0100
+Subject: ASoC: core - Separate out PCM operations into new file.
+
+In preparation for Dynamic PCM support (AKA DSP support).
+
+There will be future patches that add support to allow PCMs to be dynamically
+routed to multiple DAIs at startup and also during stream runtime. This patch
+moves the ASoC core PCM operaitions into a new file called soc-pcm.c. This will
+in simplify the ASoC core features into distinct files.
+
+Signed-off-by: Liam Girdwood <lrg@ti.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit ddee627cf6bb601aa980104fc17d4f84201380be)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/Makefile | 2 +-
+ sound/soc/soc-core.c | 612 +-----------------------------------------------
+ sound/soc/soc-pcm.c | 639 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 641 insertions(+), 612 deletions(-)
+ create mode 100644 sound/soc/soc-pcm.c
+
+diff --git a/sound/soc/Makefile b/sound/soc/Makefile
+index 1ed61c5..adb5719 100644
+--- a/sound/soc/Makefile
++++ b/sound/soc/Makefile
+@@ -1,4 +1,4 @@
+-snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
++snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o soc-pcm.o
+
+ obj-$(CONFIG_SND_SOC) += snd-soc-core.o
+ obj-$(CONFIG_SND_SOC) += codecs/
+diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
+index 841b1c9..f5ec7d8 100644
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -45,7 +45,6 @@
+
+ #define NAME_SIZE 32
+
+-static DEFINE_MUTEX(pcm_mutex);
+ static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
+
+ #ifdef CONFIG_DEBUG_FS
+@@ -59,7 +58,7 @@ static LIST_HEAD(dai_list);
+ static LIST_HEAD(platform_list);
+ static LIST_HEAD(codec_list);
+
+-static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
++int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
+
+ /*
+ * This is a timeout to do a DAPM powerdown after a stream is closed().
+@@ -486,552 +485,6 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
+ }
+ #endif
+
+-static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
+-{
+- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+- struct snd_soc_dai *codec_dai = rtd->codec_dai;
+- int ret;
+-
+- if (!codec_dai->driver->symmetric_rates &&
+- !cpu_dai->driver->symmetric_rates &&
+- !rtd->dai_link->symmetric_rates)
+- return 0;
+-
+- /* This can happen if multiple streams are starting simultaneously -
+- * the second can need to get its constraints before the first has
+- * picked a rate. Complain and allow the application to carry on.
+- */
+- if (!rtd->rate) {
+- dev_warn(&rtd->dev,
+- "Not enforcing symmetric_rates due to race\n");
+- return 0;
+- }
+-
+- dev_dbg(&rtd->dev, "Symmetry forces %dHz rate\n", rtd->rate);
+-
+- ret = snd_pcm_hw_constraint_minmax(substream->runtime,
+- SNDRV_PCM_HW_PARAM_RATE,
+- rtd->rate, rtd->rate);
+- if (ret < 0) {
+- dev_err(&rtd->dev,
+- "Unable to apply rate symmetry constraint: %d\n", ret);
+- return ret;
+- }
+-
+- return 0;
+-}
+-
+-/*
+- * Called by ALSA when a PCM substream is opened, the runtime->hw record is
+- * then initialized and any private data can be allocated. This also calls
+- * startup for the cpu DAI, platform, machine and codec DAI.
+- */
+-static int soc_pcm_open(struct snd_pcm_substream *substream)
+-{
+- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+- struct snd_pcm_runtime *runtime = substream->runtime;
+- struct snd_soc_platform *platform = rtd->platform;
+- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+- struct snd_soc_dai *codec_dai = rtd->codec_dai;
+- struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver;
+- struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver;
+- int ret = 0;
+-
+- mutex_lock(&pcm_mutex);
+-
+- /* startup the audio subsystem */
+- if (cpu_dai->driver->ops->startup) {
+- ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
+- if (ret < 0) {
+- printk(KERN_ERR "asoc: can't open interface %s\n",
+- cpu_dai->name);
+- goto out;
+- }
+- }
+-
+- if (platform->driver->ops && platform->driver->ops->open) {
+- ret = platform->driver->ops->open(substream);
+- if (ret < 0) {
+- printk(KERN_ERR "asoc: can't open platform %s\n", platform->name);
+- goto platform_err;
+- }
+- }
+-
+- if (codec_dai->driver->ops->startup) {
+- ret = codec_dai->driver->ops->startup(substream, codec_dai);
+- if (ret < 0) {
+- printk(KERN_ERR "asoc: can't open codec %s\n",
+- codec_dai->name);
+- goto codec_dai_err;
+- }
+- }
+-
+- if (rtd->dai_link->ops && rtd->dai_link->ops->startup) {
+- ret = rtd->dai_link->ops->startup(substream);
+- if (ret < 0) {
+- printk(KERN_ERR "asoc: %s startup failed\n", rtd->dai_link->name);
+- goto machine_err;
+- }
+- }
+-
+- /* Check that the codec and cpu DAIs are compatible */
+- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+- runtime->hw.rate_min =
+- max(codec_dai_drv->playback.rate_min,
+- cpu_dai_drv->playback.rate_min);
+- runtime->hw.rate_max =
+- min(codec_dai_drv->playback.rate_max,
+- cpu_dai_drv->playback.rate_max);
+- runtime->hw.channels_min =
+- max(codec_dai_drv->playback.channels_min,
+- cpu_dai_drv->playback.channels_min);
+- runtime->hw.channels_max =
+- min(codec_dai_drv->playback.channels_max,
+- cpu_dai_drv->playback.channels_max);
+- runtime->hw.formats =
+- codec_dai_drv->playback.formats & cpu_dai_drv->playback.formats;
+- runtime->hw.rates =
+- codec_dai_drv->playback.rates & cpu_dai_drv->playback.rates;
+- if (codec_dai_drv->playback.rates
+- & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
+- runtime->hw.rates |= cpu_dai_drv->playback.rates;
+- if (cpu_dai_drv->playback.rates
+- & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
+- runtime->hw.rates |= codec_dai_drv->playback.rates;
+- } else {
+- runtime->hw.rate_min =
+- max(codec_dai_drv->capture.rate_min,
+- cpu_dai_drv->capture.rate_min);
+- runtime->hw.rate_max =
+- min(codec_dai_drv->capture.rate_max,
+- cpu_dai_drv->capture.rate_max);
+- runtime->hw.channels_min =
+- max(codec_dai_drv->capture.channels_min,
+- cpu_dai_drv->capture.channels_min);
+- runtime->hw.channels_max =
+- min(codec_dai_drv->capture.channels_max,
+- cpu_dai_drv->capture.channels_max);
+- runtime->hw.formats =
+- codec_dai_drv->capture.formats & cpu_dai_drv->capture.formats;
+- runtime->hw.rates =
+- codec_dai_drv->capture.rates & cpu_dai_drv->capture.rates;
+- if (codec_dai_drv->capture.rates
+- & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
+- runtime->hw.rates |= cpu_dai_drv->capture.rates;
+- if (cpu_dai_drv->capture.rates
+- & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
+- runtime->hw.rates |= codec_dai_drv->capture.rates;
+- }
+-
+- ret = -EINVAL;
+- snd_pcm_limit_hw_rates(runtime);
+- if (!runtime->hw.rates) {
+- printk(KERN_ERR "asoc: %s <-> %s No matching rates\n",
+- codec_dai->name, cpu_dai->name);
+- goto config_err;
+- }
+- if (!runtime->hw.formats) {
+- printk(KERN_ERR "asoc: %s <-> %s No matching formats\n",
+- codec_dai->name, cpu_dai->name);
+- goto config_err;
+- }
+- if (!runtime->hw.channels_min || !runtime->hw.channels_max ||
+- runtime->hw.channels_min > runtime->hw.channels_max) {
+- printk(KERN_ERR "asoc: %s <-> %s No matching channels\n",
+- codec_dai->name, cpu_dai->name);
+- goto config_err;
+- }
+-
+- /* Symmetry only applies if we've already got an active stream. */
+- if (cpu_dai->active || codec_dai->active) {
+- ret = soc_pcm_apply_symmetry(substream);
+- if (ret != 0)
+- goto config_err;
+- }
+-
+- pr_debug("asoc: %s <-> %s info:\n",
+- codec_dai->name, cpu_dai->name);
+- pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates);
+- pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
+- runtime->hw.channels_max);
+- pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
+- runtime->hw.rate_max);
+-
+- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+- cpu_dai->playback_active++;
+- codec_dai->playback_active++;
+- } else {
+- cpu_dai->capture_active++;
+- codec_dai->capture_active++;
+- }
+- cpu_dai->active++;
+- codec_dai->active++;
+- rtd->codec->active++;
+- mutex_unlock(&pcm_mutex);
+- return 0;
+-
+-config_err:
+- if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
+- rtd->dai_link->ops->shutdown(substream);
+-
+-machine_err:
+- if (codec_dai->driver->ops->shutdown)
+- codec_dai->driver->ops->shutdown(substream, codec_dai);
+-
+-codec_dai_err:
+- if (platform->driver->ops && platform->driver->ops->close)
+- platform->driver->ops->close(substream);
+-
+-platform_err:
+- if (cpu_dai->driver->ops->shutdown)
+- cpu_dai->driver->ops->shutdown(substream, cpu_dai);
+-out:
+- mutex_unlock(&pcm_mutex);
+- return ret;
+-}
+-
+-/*
+- * Power down the audio subsystem pmdown_time msecs after close is called.
+- * This is to ensure there are no pops or clicks in between any music tracks
+- * due to DAPM power cycling.
+- */
+-static void close_delayed_work(struct work_struct *work)
+-{
+- struct snd_soc_pcm_runtime *rtd =
+- container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
+- struct snd_soc_dai *codec_dai = rtd->codec_dai;
+-
+- mutex_lock(&pcm_mutex);
+-
+- pr_debug("pop wq checking: %s status: %s waiting: %s\n",
+- codec_dai->driver->playback.stream_name,
+- codec_dai->playback_active ? "active" : "inactive",
+- codec_dai->pop_wait ? "yes" : "no");
+-
+- /* are we waiting on this codec DAI stream */
+- if (codec_dai->pop_wait == 1) {
+- codec_dai->pop_wait = 0;
+- snd_soc_dapm_stream_event(rtd,
+- codec_dai->driver->playback.stream_name,
+- SND_SOC_DAPM_STREAM_STOP);
+- }
+-
+- mutex_unlock(&pcm_mutex);
+-}
+-
+-/*
+- * Called by ALSA when a PCM substream is closed. Private data can be
+- * freed here. The cpu DAI, codec DAI, machine and platform are also
+- * shutdown.
+- */
+-static int soc_codec_close(struct snd_pcm_substream *substream)
+-{
+- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+- struct snd_soc_platform *platform = rtd->platform;
+- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+- struct snd_soc_dai *codec_dai = rtd->codec_dai;
+- struct snd_soc_codec *codec = rtd->codec;
+-
+- mutex_lock(&pcm_mutex);
+-
+- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+- cpu_dai->playback_active--;
+- codec_dai->playback_active--;
+- } else {
+- cpu_dai->capture_active--;
+- codec_dai->capture_active--;
+- }
+-
+- cpu_dai->active--;
+- codec_dai->active--;
+- codec->active--;
+-
+- /* Muting the DAC suppresses artifacts caused during digital
+- * shutdown, for example from stopping clocks.
+- */
+- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+- snd_soc_dai_digital_mute(codec_dai, 1);
+-
+- if (cpu_dai->driver->ops->shutdown)
+- cpu_dai->driver->ops->shutdown(substream, cpu_dai);
+-
+- if (codec_dai->driver->ops->shutdown)
+- codec_dai->driver->ops->shutdown(substream, codec_dai);
+-
+- if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
+- rtd->dai_link->ops->shutdown(substream);
+-
+- if (platform->driver->ops && platform->driver->ops->close)
+- platform->driver->ops->close(substream);
+- cpu_dai->runtime = NULL;
+-
+- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+- /* start delayed pop wq here for playback streams */
+- codec_dai->pop_wait = 1;
+- schedule_delayed_work(&rtd->delayed_work,
+- msecs_to_jiffies(rtd->pmdown_time));
+- } else {
+- /* capture streams can be powered down now */
+- snd_soc_dapm_stream_event(rtd,
+- codec_dai->driver->capture.stream_name,
+- SND_SOC_DAPM_STREAM_STOP);
+- }
+-
+- mutex_unlock(&pcm_mutex);
+- return 0;
+-}
+-
+-/*
+- * Called by ALSA when the PCM substream is prepared, can set format, sample
+- * rate, etc. This function is non atomic and can be called multiple times,
+- * it can refer to the runtime info.
+- */
+-static int soc_pcm_prepare(struct snd_pcm_substream *substream)
+-{
+- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+- struct snd_soc_platform *platform = rtd->platform;
+- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+- struct snd_soc_dai *codec_dai = rtd->codec_dai;
+- int ret = 0;
+-
+- mutex_lock(&pcm_mutex);
+-
+- if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) {
+- ret = rtd->dai_link->ops->prepare(substream);
+- if (ret < 0) {
+- printk(KERN_ERR "asoc: machine prepare error\n");
+- goto out;
+- }
+- }
+-
+- if (platform->driver->ops && platform->driver->ops->prepare) {
+- ret = platform->driver->ops->prepare(substream);
+- if (ret < 0) {
+- printk(KERN_ERR "asoc: platform prepare error\n");
+- goto out;
+- }
+- }
+-
+- if (codec_dai->driver->ops->prepare) {
+- ret = codec_dai->driver->ops->prepare(substream, codec_dai);
+- if (ret < 0) {
+- printk(KERN_ERR "asoc: codec DAI prepare error\n");
+- goto out;
+- }
+- }
+-
+- if (cpu_dai->driver->ops->prepare) {
+- ret = cpu_dai->driver->ops->prepare(substream, cpu_dai);
+- if (ret < 0) {
+- printk(KERN_ERR "asoc: cpu DAI prepare error\n");
+- goto out;
+- }
+- }
+-
+- /* cancel any delayed stream shutdown that is pending */
+- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
+- codec_dai->pop_wait) {
+- codec_dai->pop_wait = 0;
+- cancel_delayed_work(&rtd->delayed_work);
+- }
+-
+- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+- snd_soc_dapm_stream_event(rtd,
+- codec_dai->driver->playback.stream_name,
+- SND_SOC_DAPM_STREAM_START);
+- else
+- snd_soc_dapm_stream_event(rtd,
+- codec_dai->driver->capture.stream_name,
+- SND_SOC_DAPM_STREAM_START);
+-
+- snd_soc_dai_digital_mute(codec_dai, 0);
+-
+-out:
+- mutex_unlock(&pcm_mutex);
+- return ret;
+-}
+-
+-/*
+- * Called by ALSA when the hardware params are set by application. This
+- * function can also be called multiple times and can allocate buffers
+- * (using snd_pcm_lib_* ). It's non-atomic.
+- */
+-static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
+- struct snd_pcm_hw_params *params)
+-{
+- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+- struct snd_soc_platform *platform = rtd->platform;
+- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+- struct snd_soc_dai *codec_dai = rtd->codec_dai;
+- int ret = 0;
+-
+- mutex_lock(&pcm_mutex);
+-
+- if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) {
+- ret = rtd->dai_link->ops->hw_params(substream, params);
+- if (ret < 0) {
+- printk(KERN_ERR "asoc: machine hw_params failed\n");
+- goto out;
+- }
+- }
+-
+- if (codec_dai->driver->ops->hw_params) {
+- ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai);
+- if (ret < 0) {
+- printk(KERN_ERR "asoc: can't set codec %s hw params\n",
+- codec_dai->name);
+- goto codec_err;
+- }
+- }
+-
+- if (cpu_dai->driver->ops->hw_params) {
+- ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai);
+- if (ret < 0) {
+- printk(KERN_ERR "asoc: interface %s hw params failed\n",
+- cpu_dai->name);
+- goto interface_err;
+- }
+- }
+-
+- if (platform->driver->ops && platform->driver->ops->hw_params) {
+- ret = platform->driver->ops->hw_params(substream, params);
+- if (ret < 0) {
+- printk(KERN_ERR "asoc: platform %s hw params failed\n",
+- platform->name);
+- goto platform_err;
+- }
+- }
+-
+- rtd->rate = params_rate(params);
+-
+-out:
+- mutex_unlock(&pcm_mutex);
+- return ret;
+-
+-platform_err:
+- if (cpu_dai->driver->ops->hw_free)
+- cpu_dai->driver->ops->hw_free(substream, cpu_dai);
+-
+-interface_err:
+- if (codec_dai->driver->ops->hw_free)
+- codec_dai->driver->ops->hw_free(substream, codec_dai);
+-
+-codec_err:
+- if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
+- rtd->dai_link->ops->hw_free(substream);
+-
+- mutex_unlock(&pcm_mutex);
+- return ret;
+-}
+-
+-/*
+- * Frees resources allocated by hw_params, can be called multiple times
+- */
+-static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
+-{
+- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+- struct snd_soc_platform *platform = rtd->platform;
+- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+- struct snd_soc_dai *codec_dai = rtd->codec_dai;
+- struct snd_soc_codec *codec = rtd->codec;
+-
+- mutex_lock(&pcm_mutex);
+-
+- /* apply codec digital mute */
+- if (!codec->active)
+- snd_soc_dai_digital_mute(codec_dai, 1);
+-
+- /* free any machine hw params */
+- if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
+- rtd->dai_link->ops->hw_free(substream);
+-
+- /* free any DMA resources */
+- if (platform->driver->ops && platform->driver->ops->hw_free)
+- platform->driver->ops->hw_free(substream);
+-
+- /* now free hw params for the DAIs */
+- if (codec_dai->driver->ops->hw_free)
+- codec_dai->driver->ops->hw_free(substream, codec_dai);
+-
+- if (cpu_dai->driver->ops->hw_free)
+- cpu_dai->driver->ops->hw_free(substream, cpu_dai);
+-
+- mutex_unlock(&pcm_mutex);
+- return 0;
+-}
+-
+-static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+-{
+- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+- struct snd_soc_platform *platform = rtd->platform;
+- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+- struct snd_soc_dai *codec_dai = rtd->codec_dai;
+- int ret;
+-
+- if (codec_dai->driver->ops->trigger) {
+- ret = codec_dai->driver->ops->trigger(substream, cmd, codec_dai);
+- if (ret < 0)
+- return ret;
+- }
+-
+- if (platform->driver->ops && platform->driver->ops->trigger) {
+- ret = platform->driver->ops->trigger(substream, cmd);
+- if (ret < 0)
+- return ret;
+- }
+-
+- if (cpu_dai->driver->ops->trigger) {
+- ret = cpu_dai->driver->ops->trigger(substream, cmd, cpu_dai);
+- if (ret < 0)
+- return ret;
+- }
+- return 0;
+-}
+-
+-/*
+- * soc level wrapper for pointer callback
+- * If cpu_dai, codec_dai, platform driver has the delay callback, than
+- * the runtime->delay will be updated accordingly.
+- */
+-static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
+-{
+- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+- struct snd_soc_platform *platform = rtd->platform;
+- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+- struct snd_soc_dai *codec_dai = rtd->codec_dai;
+- struct snd_pcm_runtime *runtime = substream->runtime;
+- snd_pcm_uframes_t offset = 0;
+- snd_pcm_sframes_t delay = 0;
+-
+- if (platform->driver->ops && platform->driver->ops->pointer)
+- offset = platform->driver->ops->pointer(substream);
+-
+- if (cpu_dai->driver->ops->delay)
+- delay += cpu_dai->driver->ops->delay(substream, cpu_dai);
+-
+- if (codec_dai->driver->ops->delay)
+- delay += codec_dai->driver->ops->delay(substream, codec_dai);
+-
+- if (platform->driver->delay)
+- delay += platform->driver->delay(substream, codec_dai);
+-
+- runtime->delay = delay;
+-
+- return offset;
+-}
+-
+-/* ASoC PCM operations */
+-static struct snd_pcm_ops soc_pcm_ops = {
+- .open = soc_pcm_open,
+- .close = soc_codec_close,
+- .hw_params = soc_pcm_hw_params,
+- .hw_free = soc_pcm_hw_free,
+- .prepare = soc_pcm_prepare,
+- .trigger = soc_pcm_trigger,
+- .pointer = soc_pcm_pointer,
+-};
+-
+ #ifdef CONFIG_PM_SLEEP
+ /* powers down audio subsystem for suspend */
+ int snd_soc_suspend(struct device *dev)
+@@ -1694,9 +1147,6 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
+ if (order != SND_SOC_COMP_ORDER_LAST)
+ return 0;
+
+- /* DAPM dai link stream work */
+- INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
+-
+ ret = soc_post_component_init(card, codec, num, 0);
+ if (ret)
+ return ret;
+@@ -2128,66 +1578,6 @@ static struct platform_driver soc_driver = {
+ .remove = soc_remove,
+ };
+
+-/* create a new pcm */
+-static int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
+-{
+- struct snd_soc_codec *codec = rtd->codec;
+- struct snd_soc_platform *platform = rtd->platform;
+- struct snd_soc_dai *codec_dai = rtd->codec_dai;
+- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+- struct snd_pcm *pcm;
+- char new_name[64];
+- int ret = 0, playback = 0, capture = 0;
+-
+- /* check client and interface hw capabilities */
+- snprintf(new_name, sizeof(new_name), "%s %s-%d",
+- rtd->dai_link->stream_name, codec_dai->name, num);
+-
+- if (codec_dai->driver->playback.channels_min)
+- playback = 1;
+- if (codec_dai->driver->capture.channels_min)
+- capture = 1;
+-
+- dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num,new_name);
+- ret = snd_pcm_new(rtd->card->snd_card, new_name,
+- num, playback, capture, &pcm);
+- if (ret < 0) {
+- printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name);
+- return ret;
+- }
+-
+- rtd->pcm = pcm;
+- pcm->private_data = rtd;
+- if (platform->driver->ops) {
+- soc_pcm_ops.mmap = platform->driver->ops->mmap;
+- soc_pcm_ops.pointer = platform->driver->ops->pointer;
+- soc_pcm_ops.ioctl = platform->driver->ops->ioctl;
+- soc_pcm_ops.copy = platform->driver->ops->copy;
+- soc_pcm_ops.silence = platform->driver->ops->silence;
+- soc_pcm_ops.ack = platform->driver->ops->ack;
+- soc_pcm_ops.page = platform->driver->ops->page;
+- }
+-
+- if (playback)
+- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops);
+-
+- if (capture)
+- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops);
+-
+- if (platform->driver->pcm_new) {
+- ret = platform->driver->pcm_new(rtd);
+- if (ret < 0) {
+- pr_err("asoc: platform pcm constructor failed\n");
+- return ret;
+- }
+- }
+-
+- pcm->private_free = platform->driver->pcm_free;
+- printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name,
+- cpu_dai->name);
+- return ret;
+-}
+-
+ /**
+ * snd_soc_codec_volatile_register: Report if a register is volatile.
+ *
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+new file mode 100644
+index 0000000..9bebee8
+--- /dev/null
++++ b/sound/soc/soc-pcm.c
+@@ -0,0 +1,639 @@
++/*
++ * soc-pcm.c -- ALSA SoC PCM
++ *
++ * Copyright 2005 Wolfson Microelectronics PLC.
++ * Copyright 2005 Openedhand Ltd.
++ * Copyright (C) 2010 Slimlogic Ltd.
++ * Copyright (C) 2010 Texas Instruments Inc.
++ *
++ * Authors: Liam Girdwood <lrg@ti.com>
++ * Mark Brown <broonie@opensource.wolfsonmicro.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/kernel.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/slab.h>
++#include <linux/workqueue.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/initval.h>
++
++static DEFINE_MUTEX(pcm_mutex);
++
++static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
++ struct snd_soc_dai *codec_dai = rtd->codec_dai;
++ int ret;
++
++ if (!codec_dai->driver->symmetric_rates &&
++ !cpu_dai->driver->symmetric_rates &&
++ !rtd->dai_link->symmetric_rates)
++ return 0;
++
++ /* This can happen if multiple streams are starting simultaneously -
++ * the second can need to get its constraints before the first has
++ * picked a rate. Complain and allow the application to carry on.
++ */
++ if (!rtd->rate) {
++ dev_warn(&rtd->dev,
++ "Not enforcing symmetric_rates due to race\n");
++ return 0;
++ }
++
++ dev_dbg(&rtd->dev, "Symmetry forces %dHz rate\n", rtd->rate);
++
++ ret = snd_pcm_hw_constraint_minmax(substream->runtime,
++ SNDRV_PCM_HW_PARAM_RATE,
++ rtd->rate, rtd->rate);
++ if (ret < 0) {
++ dev_err(&rtd->dev,
++ "Unable to apply rate symmetry constraint: %d\n", ret);
++ return ret;
++ }
++
++ return 0;
++}
++
++/*
++ * Called by ALSA when a PCM substream is opened, the runtime->hw record is
++ * then initialized and any private data can be allocated. This also calls
++ * startup for the cpu DAI, platform, machine and codec DAI.
++ */
++static int soc_pcm_open(struct snd_pcm_substream *substream)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ struct snd_soc_platform *platform = rtd->platform;
++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
++ struct snd_soc_dai *codec_dai = rtd->codec_dai;
++ struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver;
++ struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver;
++ int ret = 0;
++
++ mutex_lock(&pcm_mutex);
++
++ /* startup the audio subsystem */
++ if (cpu_dai->driver->ops->startup) {
++ ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
++ if (ret < 0) {
++ printk(KERN_ERR "asoc: can't open interface %s\n",
++ cpu_dai->name);
++ goto out;
++ }
++ }
++
++ if (platform->driver->ops && platform->driver->ops->open) {
++ ret = platform->driver->ops->open(substream);
++ if (ret < 0) {
++ printk(KERN_ERR "asoc: can't open platform %s\n", platform->name);
++ goto platform_err;
++ }
++ }
++
++ if (codec_dai->driver->ops->startup) {
++ ret = codec_dai->driver->ops->startup(substream, codec_dai);
++ if (ret < 0) {
++ printk(KERN_ERR "asoc: can't open codec %s\n",
++ codec_dai->name);
++ goto codec_dai_err;
++ }
++ }
++
++ if (rtd->dai_link->ops && rtd->dai_link->ops->startup) {
++ ret = rtd->dai_link->ops->startup(substream);
++ if (ret < 0) {
++ printk(KERN_ERR "asoc: %s startup failed\n", rtd->dai_link->name);
++ goto machine_err;
++ }
++ }
++
++ /* Check that the codec and cpu DAIs are compatible */
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++ runtime->hw.rate_min =
++ max(codec_dai_drv->playback.rate_min,
++ cpu_dai_drv->playback.rate_min);
++ runtime->hw.rate_max =
++ min(codec_dai_drv->playback.rate_max,
++ cpu_dai_drv->playback.rate_max);
++ runtime->hw.channels_min =
++ max(codec_dai_drv->playback.channels_min,
++ cpu_dai_drv->playback.channels_min);
++ runtime->hw.channels_max =
++ min(codec_dai_drv->playback.channels_max,
++ cpu_dai_drv->playback.channels_max);
++ runtime->hw.formats =
++ codec_dai_drv->playback.formats & cpu_dai_drv->playback.formats;
++ runtime->hw.rates =
++ codec_dai_drv->playback.rates & cpu_dai_drv->playback.rates;
++ if (codec_dai_drv->playback.rates
++ & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
++ runtime->hw.rates |= cpu_dai_drv->playback.rates;
++ if (cpu_dai_drv->playback.rates
++ & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
++ runtime->hw.rates |= codec_dai_drv->playback.rates;
++ } else {
++ runtime->hw.rate_min =
++ max(codec_dai_drv->capture.rate_min,
++ cpu_dai_drv->capture.rate_min);
++ runtime->hw.rate_max =
++ min(codec_dai_drv->capture.rate_max,
++ cpu_dai_drv->capture.rate_max);
++ runtime->hw.channels_min =
++ max(codec_dai_drv->capture.channels_min,
++ cpu_dai_drv->capture.channels_min);
++ runtime->hw.channels_max =
++ min(codec_dai_drv->capture.channels_max,
++ cpu_dai_drv->capture.channels_max);
++ runtime->hw.formats =
++ codec_dai_drv->capture.formats & cpu_dai_drv->capture.formats;
++ runtime->hw.rates =
++ codec_dai_drv->capture.rates & cpu_dai_drv->capture.rates;
++ if (codec_dai_drv->capture.rates
++ & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
++ runtime->hw.rates |= cpu_dai_drv->capture.rates;
++ if (cpu_dai_drv->capture.rates
++ & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
++ runtime->hw.rates |= codec_dai_drv->capture.rates;
++ }
++
++ ret = -EINVAL;
++ snd_pcm_limit_hw_rates(runtime);
++ if (!runtime->hw.rates) {
++ printk(KERN_ERR "asoc: %s <-> %s No matching rates\n",
++ codec_dai->name, cpu_dai->name);
++ goto config_err;
++ }
++ if (!runtime->hw.formats) {
++ printk(KERN_ERR "asoc: %s <-> %s No matching formats\n",
++ codec_dai->name, cpu_dai->name);
++ goto config_err;
++ }
++ if (!runtime->hw.channels_min || !runtime->hw.channels_max ||
++ runtime->hw.channels_min > runtime->hw.channels_max) {
++ printk(KERN_ERR "asoc: %s <-> %s No matching channels\n",
++ codec_dai->name, cpu_dai->name);
++ goto config_err;
++ }
++
++ /* Symmetry only applies if we've already got an active stream. */
++ if (cpu_dai->active || codec_dai->active) {
++ ret = soc_pcm_apply_symmetry(substream);
++ if (ret != 0)
++ goto config_err;
++ }
++
++ pr_debug("asoc: %s <-> %s info:\n",
++ codec_dai->name, cpu_dai->name);
++ pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates);
++ pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
++ runtime->hw.channels_max);
++ pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
++ runtime->hw.rate_max);
++
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++ cpu_dai->playback_active++;
++ codec_dai->playback_active++;
++ } else {
++ cpu_dai->capture_active++;
++ codec_dai->capture_active++;
++ }
++ cpu_dai->active++;
++ codec_dai->active++;
++ rtd->codec->active++;
++ mutex_unlock(&pcm_mutex);
++ return 0;
++
++config_err:
++ if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
++ rtd->dai_link->ops->shutdown(substream);
++
++machine_err:
++ if (codec_dai->driver->ops->shutdown)
++ codec_dai->driver->ops->shutdown(substream, codec_dai);
++
++codec_dai_err:
++ if (platform->driver->ops && platform->driver->ops->close)
++ platform->driver->ops->close(substream);
++
++platform_err:
++ if (cpu_dai->driver->ops->shutdown)
++ cpu_dai->driver->ops->shutdown(substream, cpu_dai);
++out:
++ mutex_unlock(&pcm_mutex);
++ return ret;
++}
++
++/*
++ * Power down the audio subsystem pmdown_time msecs after close is called.
++ * This is to ensure there are no pops or clicks in between any music tracks
++ * due to DAPM power cycling.
++ */
++static void close_delayed_work(struct work_struct *work)
++{
++ struct snd_soc_pcm_runtime *rtd =
++ container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
++ struct snd_soc_dai *codec_dai = rtd->codec_dai;
++
++ mutex_lock(&pcm_mutex);
++
++ pr_debug("pop wq checking: %s status: %s waiting: %s\n",
++ codec_dai->driver->playback.stream_name,
++ codec_dai->playback_active ? "active" : "inactive",
++ codec_dai->pop_wait ? "yes" : "no");
++
++ /* are we waiting on this codec DAI stream */
++ if (codec_dai->pop_wait == 1) {
++ codec_dai->pop_wait = 0;
++ snd_soc_dapm_stream_event(rtd,
++ codec_dai->driver->playback.stream_name,
++ SND_SOC_DAPM_STREAM_STOP);
++ }
++
++ mutex_unlock(&pcm_mutex);
++}
++
++/*
++ * Called by ALSA when a PCM substream is closed. Private data can be
++ * freed here. The cpu DAI, codec DAI, machine and platform are also
++ * shutdown.
++ */
++static int soc_codec_close(struct snd_pcm_substream *substream)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_platform *platform = rtd->platform;
++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
++ struct snd_soc_dai *codec_dai = rtd->codec_dai;
++ struct snd_soc_codec *codec = rtd->codec;
++
++ mutex_lock(&pcm_mutex);
++
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++ cpu_dai->playback_active--;
++ codec_dai->playback_active--;
++ } else {
++ cpu_dai->capture_active--;
++ codec_dai->capture_active--;
++ }
++
++ cpu_dai->active--;
++ codec_dai->active--;
++ codec->active--;
++
++ /* Muting the DAC suppresses artifacts caused during digital
++ * shutdown, for example from stopping clocks.
++ */
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++ snd_soc_dai_digital_mute(codec_dai, 1);
++
++ if (cpu_dai->driver->ops->shutdown)
++ cpu_dai->driver->ops->shutdown(substream, cpu_dai);
++
++ if (codec_dai->driver->ops->shutdown)
++ codec_dai->driver->ops->shutdown(substream, codec_dai);
++
++ if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
++ rtd->dai_link->ops->shutdown(substream);
++
++ if (platform->driver->ops && platform->driver->ops->close)
++ platform->driver->ops->close(substream);
++ cpu_dai->runtime = NULL;
++
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++ /* start delayed pop wq here for playback streams */
++ codec_dai->pop_wait = 1;
++ schedule_delayed_work(&rtd->delayed_work,
++ msecs_to_jiffies(rtd->pmdown_time));
++ } else {
++ /* capture streams can be powered down now */
++ snd_soc_dapm_stream_event(rtd,
++ codec_dai->driver->capture.stream_name,
++ SND_SOC_DAPM_STREAM_STOP);
++ }
++
++ mutex_unlock(&pcm_mutex);
++ return 0;
++}
++
++/*
++ * Called by ALSA when the PCM substream is prepared, can set format, sample
++ * rate, etc. This function is non atomic and can be called multiple times,
++ * it can refer to the runtime info.
++ */
++static int soc_pcm_prepare(struct snd_pcm_substream *substream)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_platform *platform = rtd->platform;
++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
++ struct snd_soc_dai *codec_dai = rtd->codec_dai;
++ int ret = 0;
++
++ mutex_lock(&pcm_mutex);
++
++ if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) {
++ ret = rtd->dai_link->ops->prepare(substream);
++ if (ret < 0) {
++ printk(KERN_ERR "asoc: machine prepare error\n");
++ goto out;
++ }
++ }
++
++ if (platform->driver->ops && platform->driver->ops->prepare) {
++ ret = platform->driver->ops->prepare(substream);
++ if (ret < 0) {
++ printk(KERN_ERR "asoc: platform prepare error\n");
++ goto out;
++ }
++ }
++
++ if (codec_dai->driver->ops->prepare) {
++ ret = codec_dai->driver->ops->prepare(substream, codec_dai);
++ if (ret < 0) {
++ printk(KERN_ERR "asoc: codec DAI prepare error\n");
++ goto out;
++ }
++ }
++
++ if (cpu_dai->driver->ops->prepare) {
++ ret = cpu_dai->driver->ops->prepare(substream, cpu_dai);
++ if (ret < 0) {
++ printk(KERN_ERR "asoc: cpu DAI prepare error\n");
++ goto out;
++ }
++ }
++
++ /* cancel any delayed stream shutdown that is pending */
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
++ codec_dai->pop_wait) {
++ codec_dai->pop_wait = 0;
++ cancel_delayed_work(&rtd->delayed_work);
++ }
++
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++ snd_soc_dapm_stream_event(rtd,
++ codec_dai->driver->playback.stream_name,
++ SND_SOC_DAPM_STREAM_START);
++ else
++ snd_soc_dapm_stream_event(rtd,
++ codec_dai->driver->capture.stream_name,
++ SND_SOC_DAPM_STREAM_START);
++
++ snd_soc_dai_digital_mute(codec_dai, 0);
++
++out:
++ mutex_unlock(&pcm_mutex);
++ return ret;
++}
++
++/*
++ * Called by ALSA when the hardware params are set by application. This
++ * function can also be called multiple times and can allocate buffers
++ * (using snd_pcm_lib_* ). It's non-atomic.
++ */
++static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_platform *platform = rtd->platform;
++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
++ struct snd_soc_dai *codec_dai = rtd->codec_dai;
++ int ret = 0;
++
++ mutex_lock(&pcm_mutex);
++
++ if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) {
++ ret = rtd->dai_link->ops->hw_params(substream, params);
++ if (ret < 0) {
++ printk(KERN_ERR "asoc: machine hw_params failed\n");
++ goto out;
++ }
++ }
++
++ if (codec_dai->driver->ops->hw_params) {
++ ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai);
++ if (ret < 0) {
++ printk(KERN_ERR "asoc: can't set codec %s hw params\n",
++ codec_dai->name);
++ goto codec_err;
++ }
++ }
++
++ if (cpu_dai->driver->ops->hw_params) {
++ ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai);
++ if (ret < 0) {
++ printk(KERN_ERR "asoc: interface %s hw params failed\n",
++ cpu_dai->name);
++ goto interface_err;
++ }
++ }
++
++ if (platform->driver->ops && platform->driver->ops->hw_params) {
++ ret = platform->driver->ops->hw_params(substream, params);
++ if (ret < 0) {
++ printk(KERN_ERR "asoc: platform %s hw params failed\n",
++ platform->name);
++ goto platform_err;
++ }
++ }
++
++ rtd->rate = params_rate(params);
++
++out:
++ mutex_unlock(&pcm_mutex);
++ return ret;
++
++platform_err:
++ if (cpu_dai->driver->ops->hw_free)
++ cpu_dai->driver->ops->hw_free(substream, cpu_dai);
++
++interface_err:
++ if (codec_dai->driver->ops->hw_free)
++ codec_dai->driver->ops->hw_free(substream, codec_dai);
++
++codec_err:
++ if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
++ rtd->dai_link->ops->hw_free(substream);
++
++ mutex_unlock(&pcm_mutex);
++ return ret;
++}
++
++/*
++ * Frees resources allocated by hw_params, can be called multiple times
++ */
++static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_platform *platform = rtd->platform;
++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
++ struct snd_soc_dai *codec_dai = rtd->codec_dai;
++ struct snd_soc_codec *codec = rtd->codec;
++
++ mutex_lock(&pcm_mutex);
++
++ /* apply codec digital mute */
++ if (!codec->active)
++ snd_soc_dai_digital_mute(codec_dai, 1);
++
++ /* free any machine hw params */
++ if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
++ rtd->dai_link->ops->hw_free(substream);
++
++ /* free any DMA resources */
++ if (platform->driver->ops && platform->driver->ops->hw_free)
++ platform->driver->ops->hw_free(substream);
++
++ /* now free hw params for the DAIs */
++ if (codec_dai->driver->ops->hw_free)
++ codec_dai->driver->ops->hw_free(substream, codec_dai);
++
++ if (cpu_dai->driver->ops->hw_free)
++ cpu_dai->driver->ops->hw_free(substream, cpu_dai);
++
++ mutex_unlock(&pcm_mutex);
++ return 0;
++}
++
++static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_platform *platform = rtd->platform;
++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
++ struct snd_soc_dai *codec_dai = rtd->codec_dai;
++ int ret;
++
++ if (codec_dai->driver->ops->trigger) {
++ ret = codec_dai->driver->ops->trigger(substream, cmd, codec_dai);
++ if (ret < 0)
++ return ret;
++ }
++
++ if (platform->driver->ops && platform->driver->ops->trigger) {
++ ret = platform->driver->ops->trigger(substream, cmd);
++ if (ret < 0)
++ return ret;
++ }
++
++ if (cpu_dai->driver->ops->trigger) {
++ ret = cpu_dai->driver->ops->trigger(substream, cmd, cpu_dai);
++ if (ret < 0)
++ return ret;
++ }
++ return 0;
++}
++
++/*
++ * soc level wrapper for pointer callback
++ * If cpu_dai, codec_dai, platform driver has the delay callback, than
++ * the runtime->delay will be updated accordingly.
++ */
++static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
++{
++ struct snd_soc_pcm_runtime *rtd = substream->private_data;
++ struct snd_soc_platform *platform = rtd->platform;
++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
++ struct snd_soc_dai *codec_dai = rtd->codec_dai;
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ snd_pcm_uframes_t offset = 0;
++ snd_pcm_sframes_t delay = 0;
++
++ if (platform->driver->ops && platform->driver->ops->pointer)
++ offset = platform->driver->ops->pointer(substream);
++
++ if (cpu_dai->driver->ops->delay)
++ delay += cpu_dai->driver->ops->delay(substream, cpu_dai);
++
++ if (codec_dai->driver->ops->delay)
++ delay += codec_dai->driver->ops->delay(substream, codec_dai);
++
++ if (platform->driver->delay)
++ delay += platform->driver->delay(substream, codec_dai);
++
++ runtime->delay = delay;
++
++ return offset;
++}
++
++/* ASoC PCM operations */
++static struct snd_pcm_ops soc_pcm_ops = {
++ .open = soc_pcm_open,
++ .close = soc_codec_close,
++ .hw_params = soc_pcm_hw_params,
++ .hw_free = soc_pcm_hw_free,
++ .prepare = soc_pcm_prepare,
++ .trigger = soc_pcm_trigger,
++ .pointer = soc_pcm_pointer,
++};
++
++/* create a new pcm */
++int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
++{
++ struct snd_soc_codec *codec = rtd->codec;
++ struct snd_soc_platform *platform = rtd->platform;
++ struct snd_soc_dai *codec_dai = rtd->codec_dai;
++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
++ struct snd_pcm *pcm;
++ char new_name[64];
++ int ret = 0, playback = 0, capture = 0;
++
++ /* check client and interface hw capabilities */
++ snprintf(new_name, sizeof(new_name), "%s %s-%d",
++ rtd->dai_link->stream_name, codec_dai->name, num);
++
++ if (codec_dai->driver->playback.channels_min)
++ playback = 1;
++ if (codec_dai->driver->capture.channels_min)
++ capture = 1;
++
++ dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num,new_name);
++ ret = snd_pcm_new(rtd->card->snd_card, new_name,
++ num, playback, capture, &pcm);
++ if (ret < 0) {
++ printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name);
++ return ret;
++ }
++
++ /* DAPM dai link stream work */
++ INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
++
++ rtd->pcm = pcm;
++ pcm->private_data = rtd;
++ if (platform->driver->ops) {
++ soc_pcm_ops.mmap = platform->driver->ops->mmap;
++ soc_pcm_ops.pointer = platform->driver->ops->pointer;
++ soc_pcm_ops.ioctl = platform->driver->ops->ioctl;
++ soc_pcm_ops.copy = platform->driver->ops->copy;
++ soc_pcm_ops.silence = platform->driver->ops->silence;
++ soc_pcm_ops.ack = platform->driver->ops->ack;
++ soc_pcm_ops.page = platform->driver->ops->page;
++ }
++
++ if (playback)
++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops);
++
++ if (capture)
++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops);
++
++ if (platform->driver->pcm_new) {
++ ret = platform->driver->pcm_new(rtd);
++ if (ret < 0) {
++ pr_err("asoc: platform pcm constructor failed\n");
++ return ret;
++ }
++ }
++
++ pcm->private_free = platform->driver->pcm_free;
++ printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name,
++ cpu_dai->name);
++ return ret;
++}
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0077-ASoC-core-PCM-mutex-per-rtd.patch b/patches.kzm9g/0077-ASoC-core-PCM-mutex-per-rtd.patch
new file mode 100644
index 00000000000000..2f91a0f4b76221
--- /dev/null
+++ b/patches.kzm9g/0077-ASoC-core-PCM-mutex-per-rtd.patch
@@ -0,0 +1,203 @@
+From 7c74178e9fd0dbf8b3e823a1fea0a0f4ab907afe Mon Sep 17 00:00:00 2001
+From: Liam Girdwood <lrg@ti.com>
+Date: Thu, 9 Jun 2011 17:04:39 +0100
+Subject: ASoC: core - PCM mutex per rtd
+
+In preparation for the new ASoC Dynamic PCM support (AKA DSP support).
+
+The new ASoC Dynamic PCM core allows DAIs to be dynamically re-routed
+at runtime between the PCM device end (or Frontend - FE) and the physical DAI
+(Backend - BE) using regular kcontrols (just like a hardware CODEC routes
+audio in the analog domain). The Dynamic PCM core therefore must be
+able to call PCM operations for both the Frontend and Backend(s) DAIs at
+the same time.
+
+Currently we have a global pcm_mutex that is used to serialise
+the ASoC PCM operations. This patch removes the global mutex
+and adds a mutex per RTD allowing the PCM operations to be reentrant and
+allow control of more than one DAI at at time. e.g. a frontend PCM hw_params()
+could configure multiple backend DAI hw_params() with similar or different
+hw parameters at the same time.
+
+Signed-off-by: Liam Girdwood <lrg@ti.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit b8c0dab9bf3373010e857a8d3f1b594c60a348dd)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/sound/soc.h | 8 ++++++++
+ sound/soc/soc-core.c | 1 +
+ sound/soc/soc-pcm.c | 28 ++++++++++++++--------------
+ 3 files changed, 23 insertions(+), 14 deletions(-)
+
+diff --git a/include/sound/soc.h b/include/sound/soc.h
+index 447232c..9e6d13e 100644
+--- a/include/sound/soc.h
++++ b/include/sound/soc.h
+@@ -268,6 +268,11 @@ enum snd_soc_compress_type {
+ SND_SOC_RBTREE_COMPRESSION
+ };
+
++enum snd_soc_pcm_subclass {
++ SND_SOC_PCM_CLASS_PCM = 0,
++ SND_SOC_PCM_CLASS_BE = 1,
++};
++
+ int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+ unsigned int freq, int dir);
+ int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
+@@ -806,6 +811,9 @@ struct snd_soc_pcm_runtime {
+ struct device dev;
+ struct snd_soc_card *card;
+ struct snd_soc_dai_link *dai_link;
++ struct mutex pcm_mutex;
++ enum snd_soc_pcm_subclass pcm_subclass;
++ struct snd_pcm_ops ops;
+
+ unsigned int complete:1;
+ unsigned int dev_registered:1;
+diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
+index f5ec7d8..71cf27f 100644
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -1034,6 +1034,7 @@ static int soc_post_component_init(struct snd_soc_card *card,
+ rtd->dev.parent = card->dev;
+ rtd->dev.release = rtd_release;
+ rtd->dev.init_name = name;
++ mutex_init(&rtd->pcm_mutex);
+ ret = device_register(&rtd->dev);
+ if (ret < 0) {
+ dev_err(card->dev,
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index 9bebee8..f4864b0 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -81,7 +81,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
+ struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver;
+ int ret = 0;
+
+- mutex_lock(&pcm_mutex);
++ mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+
+ /* startup the audio subsystem */
+ if (cpu_dai->driver->ops->startup) {
+@@ -211,7 +211,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
+ cpu_dai->active++;
+ codec_dai->active++;
+ rtd->codec->active++;
+- mutex_unlock(&pcm_mutex);
++ mutex_unlock(&rtd->pcm_mutex);
+ return 0;
+
+ config_err:
+@@ -230,7 +230,7 @@ platform_err:
+ if (cpu_dai->driver->ops->shutdown)
+ cpu_dai->driver->ops->shutdown(substream, cpu_dai);
+ out:
+- mutex_unlock(&pcm_mutex);
++ mutex_unlock(&rtd->pcm_mutex);
+ return ret;
+ }
+
+@@ -245,7 +245,7 @@ static void close_delayed_work(struct work_struct *work)
+ container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+
+- mutex_lock(&pcm_mutex);
++ mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+
+ pr_debug("pop wq checking: %s status: %s waiting: %s\n",
+ codec_dai->driver->playback.stream_name,
+@@ -260,7 +260,7 @@ static void close_delayed_work(struct work_struct *work)
+ SND_SOC_DAPM_STREAM_STOP);
+ }
+
+- mutex_unlock(&pcm_mutex);
++ mutex_unlock(&rtd->pcm_mutex);
+ }
+
+ /*
+@@ -276,7 +276,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_codec *codec = rtd->codec;
+
+- mutex_lock(&pcm_mutex);
++ mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ cpu_dai->playback_active--;
+@@ -321,7 +321,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
+ SND_SOC_DAPM_STREAM_STOP);
+ }
+
+- mutex_unlock(&pcm_mutex);
++ mutex_unlock(&rtd->pcm_mutex);
+ return 0;
+ }
+
+@@ -338,7 +338,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int ret = 0;
+
+- mutex_lock(&pcm_mutex);
++ mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+
+ if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) {
+ ret = rtd->dai_link->ops->prepare(substream);
+@@ -391,7 +391,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
+ snd_soc_dai_digital_mute(codec_dai, 0);
+
+ out:
+- mutex_unlock(&pcm_mutex);
++ mutex_unlock(&rtd->pcm_mutex);
+ return ret;
+ }
+
+@@ -409,7 +409,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ int ret = 0;
+
+- mutex_lock(&pcm_mutex);
++ mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+
+ if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) {
+ ret = rtd->dai_link->ops->hw_params(substream, params);
+@@ -449,7 +449,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
+ rtd->rate = params_rate(params);
+
+ out:
+- mutex_unlock(&pcm_mutex);
++ mutex_unlock(&rtd->pcm_mutex);
+ return ret;
+
+ platform_err:
+@@ -464,7 +464,7 @@ codec_err:
+ if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
+ rtd->dai_link->ops->hw_free(substream);
+
+- mutex_unlock(&pcm_mutex);
++ mutex_unlock(&rtd->pcm_mutex);
+ return ret;
+ }
+
+@@ -479,7 +479,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_codec *codec = rtd->codec;
+
+- mutex_lock(&pcm_mutex);
++ mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+
+ /* apply codec digital mute */
+ if (!codec->active)
+@@ -500,7 +500,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
+ if (cpu_dai->driver->ops->hw_free)
+ cpu_dai->driver->ops->hw_free(substream, cpu_dai);
+
+- mutex_unlock(&pcm_mutex);
++ mutex_unlock(&rtd->pcm_mutex);
+ return 0;
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0078-ASoC-Allow-DAI-formats-to-be-specified-in-the-dai_li.patch b/patches.kzm9g/0078-ASoC-Allow-DAI-formats-to-be-specified-in-the-dai_li.patch
new file mode 100644
index 00000000000000..6bf720a1e7e90b
--- /dev/null
+++ b/patches.kzm9g/0078-ASoC-Allow-DAI-formats-to-be-specified-in-the-dai_li.patch
@@ -0,0 +1,148 @@
+From 8e48ac5598f4d6425d2b703b87a3d51a7a546ba4 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Tue, 27 Sep 2011 16:41:01 +0100
+Subject: ASoC: Allow DAI formats to be specified in the dai_link
+
+For almost all machines the DAI format is a constant, always set to the
+same thing. This means that not only should we normally set it on init
+rather than in hw_params() (where it has been for historical reasons) we
+should also allow users to configure this by setting a variable in the
+dai_link structure. The combination of these two will make many machine
+drivers even more data driven.
+
+Implement a new dai_fmt field in the dai_link doing just that. Since 0 is
+a valid value for many format flags and we need to be able to tell if the
+field is actually set also add one to all the values used to configure
+formats.
+
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 75d9ac46b99280f5f381927ae75a9eaf21844d20)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/sound/soc-dai.h | 34 +++++++++++++++++-----------------
+ include/sound/soc.h | 2 ++
+ sound/soc/soc-core.c | 21 +++++++++++++++++++++
+ 3 files changed, 40 insertions(+), 17 deletions(-)
+
+diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
+index 5ad5f3a..5d56a06 100644
+--- a/include/sound/soc-dai.h
++++ b/include/sound/soc-dai.h
+@@ -24,13 +24,13 @@ struct snd_pcm_substream;
+ * Describes the physical PCM data formating and clocking. Add new formats
+ * to the end.
+ */
+-#define SND_SOC_DAIFMT_I2S 0 /* I2S mode */
+-#define SND_SOC_DAIFMT_RIGHT_J 1 /* Right Justified mode */
+-#define SND_SOC_DAIFMT_LEFT_J 2 /* Left Justified mode */
+-#define SND_SOC_DAIFMT_DSP_A 3 /* L data MSB after FRM LRC */
+-#define SND_SOC_DAIFMT_DSP_B 4 /* L data MSB during FRM LRC */
+-#define SND_SOC_DAIFMT_AC97 5 /* AC97 */
+-#define SND_SOC_DAIFMT_PDM 6 /* Pulse density modulation */
++#define SND_SOC_DAIFMT_I2S 1 /* I2S mode */
++#define SND_SOC_DAIFMT_RIGHT_J 2 /* Right Justified mode */
++#define SND_SOC_DAIFMT_LEFT_J 3 /* Left Justified mode */
++#define SND_SOC_DAIFMT_DSP_A 4 /* L data MSB after FRM LRC */
++#define SND_SOC_DAIFMT_DSP_B 5 /* L data MSB during FRM LRC */
++#define SND_SOC_DAIFMT_AC97 6 /* AC97 */
++#define SND_SOC_DAIFMT_PDM 7 /* Pulse density modulation */
+
+ /* left and right justified also known as MSB and LSB respectively */
+ #define SND_SOC_DAIFMT_MSB SND_SOC_DAIFMT_LEFT_J
+@@ -42,8 +42,8 @@ struct snd_pcm_substream;
+ * DAI bit clocks can be be gated (disabled) when the DAI is not
+ * sending or receiving PCM data in a frame. This can be used to save power.
+ */
+-#define SND_SOC_DAIFMT_CONT (0 << 4) /* continuous clock */
+-#define SND_SOC_DAIFMT_GATED (1 << 4) /* clock is gated */
++#define SND_SOC_DAIFMT_CONT (1 << 4) /* continuous clock */
++#define SND_SOC_DAIFMT_GATED (2 << 4) /* clock is gated */
+
+ /*
+ * DAI hardware signal inversions.
+@@ -51,10 +51,10 @@ struct snd_pcm_substream;
+ * Specifies whether the DAI can also support inverted clocks for the specified
+ * format.
+ */
+-#define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bit clock + frame */
+-#define SND_SOC_DAIFMT_NB_IF (1 << 8) /* normal BCLK + inv FRM */
+-#define SND_SOC_DAIFMT_IB_NF (2 << 8) /* invert BCLK + nor FRM */
+-#define SND_SOC_DAIFMT_IB_IF (3 << 8) /* invert BCLK + FRM */
++#define SND_SOC_DAIFMT_NB_NF (1 << 8) /* normal bit clock + frame */
++#define SND_SOC_DAIFMT_NB_IF (2 << 8) /* normal BCLK + inv FRM */
++#define SND_SOC_DAIFMT_IB_NF (3 << 8) /* invert BCLK + nor FRM */
++#define SND_SOC_DAIFMT_IB_IF (4 << 8) /* invert BCLK + FRM */
+
+ /*
+ * DAI hardware clock masters.
+@@ -63,10 +63,10 @@ struct snd_pcm_substream;
+ * i.e. if the codec is clk and FRM master then the interface is
+ * clk and frame slave.
+ */
+-#define SND_SOC_DAIFMT_CBM_CFM (0 << 12) /* codec clk & FRM master */
+-#define SND_SOC_DAIFMT_CBS_CFM (1 << 12) /* codec clk slave & FRM master */
+-#define SND_SOC_DAIFMT_CBM_CFS (2 << 12) /* codec clk master & frame slave */
+-#define SND_SOC_DAIFMT_CBS_CFS (3 << 12) /* codec clk & FRM slave */
++#define SND_SOC_DAIFMT_CBM_CFM (1 << 12) /* codec clk & FRM master */
++#define SND_SOC_DAIFMT_CBS_CFM (2 << 12) /* codec clk slave & FRM master */
++#define SND_SOC_DAIFMT_CBM_CFS (3 << 12) /* codec clk master & frame slave */
++#define SND_SOC_DAIFMT_CBS_CFS (4 << 12) /* codec clk & FRM slave */
+
+ #define SND_SOC_DAIFMT_FORMAT_MASK 0x000f
+ #define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0
+diff --git a/include/sound/soc.h b/include/sound/soc.h
+index 9e6d13e..811474e 100644
+--- a/include/sound/soc.h
++++ b/include/sound/soc.h
+@@ -683,6 +683,8 @@ struct snd_soc_dai_link {
+ const char *cpu_dai_name;
+ const char *codec_dai_name;
+
++ unsigned int dai_fmt; /* format to set on init */
++
+ /* Keep DAI active over suspend */
+ unsigned int ignore_suspend:1;
+
+diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
+index 71cf27f..11a889c 100644
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -1285,6 +1285,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
+ struct snd_soc_codec *codec;
+ struct snd_soc_codec_conf *codec_conf;
+ enum snd_soc_compress_type compress_type;
++ struct snd_soc_dai_link *dai_link;
+ int ret, i, order;
+
+ mutex_lock(&card->mutex);
+@@ -1397,6 +1398,26 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
+ snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
+ card->num_dapm_routes);
+
++ for (i = 0; i < card->num_links; i++) {
++ dai_link = &card->dai_link[i];
++
++ if (dai_link->dai_fmt) {
++ ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai,
++ dai_link->dai_fmt);
++ if (ret != 0)
++ dev_warn(card->rtd[i].codec_dai->dev,
++ "Failed to set DAI format: %d\n",
++ ret);
++
++ ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai,
++ dai_link->dai_fmt);
++ if (ret != 0)
++ dev_warn(card->rtd[i].cpu_dai->dev,
++ "Failed to set DAI format: %d\n",
++ ret);
++ }
++ }
++
+ snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
+ "%s", card->name);
+ snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0079-ASoC-Hold-runtime-PM-references-to-components-of-act.patch b/patches.kzm9g/0079-ASoC-Hold-runtime-PM-references-to-components-of-act.patch
new file mode 100644
index 00000000000000..5f75399fc1f070
--- /dev/null
+++ b/patches.kzm9g/0079-ASoC-Hold-runtime-PM-references-to-components-of-act.patch
@@ -0,0 +1,78 @@
+From a34733d7e91c1defeb73b851cb78e76db67a5e48 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Sat, 3 Dec 2011 20:14:31 +0000
+Subject: ASoC: Hold runtime PM references to components of active DAIs
+
+Every device that implements runtime power management for DAIs is doing
+it in pretty much the same way: in the startup callback they take a
+runtime PM reference and then in the shutdown callback they release that
+reference, keeping the device active while the DAI is active. Given the
+frequency with which this is done and the obviousness of the need to keep
+the device active in this period factor the code out into the core, taking
+references on the device for each CPU DAI, CODEC DAI and DMA device in the
+core.
+
+As runtime PM is reference counted this shouldn't interfere with any
+other reference holding by the drivers, and since (in common with the
+existing implementations) we don't check for errors on enabling it
+shouldn't matter if the device actually has runtime PM enabled or not.
+
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Tested-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
+(cherry picked from commit d6652ef8229e9953543f41d8e081c23e653f0044)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/soc-pcm.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index f4864b0..3047db8 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -19,6 +19,7 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
++#include <linux/pm_runtime.h>
+ #include <linux/slab.h>
+ #include <linux/workqueue.h>
+ #include <sound/core.h>
+@@ -81,6 +82,10 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
+ struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver;
+ int ret = 0;
+
++ pm_runtime_get_sync(cpu_dai->dev);
++ pm_runtime_get_sync(codec_dai->dev);
++ pm_runtime_get_sync(platform->dev);
++
+ mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
+
+ /* startup the audio subsystem */
+@@ -231,6 +236,11 @@ platform_err:
+ cpu_dai->driver->ops->shutdown(substream, cpu_dai);
+ out:
+ mutex_unlock(&rtd->pcm_mutex);
++
++ pm_runtime_put(platform->dev);
++ pm_runtime_put(codec_dai->dev);
++ pm_runtime_put(cpu_dai->dev);
++
+ return ret;
+ }
+
+@@ -322,6 +332,11 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
+ }
+
+ mutex_unlock(&rtd->pcm_mutex);
++
++ pm_runtime_put(platform->dev);
++ pm_runtime_put(codec_dai->dev);
++ pm_runtime_put(cpu_dai->dev);
++
+ return 0;
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0080-ASoC-sh-fsi-tidyup-parameter-of-fsi_stream_push.patch b/patches.kzm9g/0080-ASoC-sh-fsi-tidyup-parameter-of-fsi_stream_push.patch
new file mode 100644
index 00000000000000..6da2adc2603c4c
--- /dev/null
+++ b/patches.kzm9g/0080-ASoC-sh-fsi-tidyup-parameter-of-fsi_stream_push.patch
@@ -0,0 +1,64 @@
+From 239b4f1f31ed777afdb5bc02f968e831232f856b Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 23 May 2011 20:45:57 +0900
+Subject: ASoC: sh: fsi: tidyup parameter of fsi_stream_push
+
+It is possible to create buff_len and period_len
+from substream->runtime.
+This patch is preparation of tidyup unclear variable naming patch.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Liam Girdwood <lrg@ti.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 0ffe296addcfb8414ebad3d399859f9bf8f955d2)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 339a1df..9666a26 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -344,16 +344,15 @@ static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play)
+
+ static void fsi_stream_push(struct fsi_priv *fsi,
+ int is_play,
+- struct snd_pcm_substream *substream,
+- u32 buffer_len,
+- u32 period_len)
++ struct snd_pcm_substream *substream)
+ {
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
++ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ io->substream = substream;
+- io->buff_len = buffer_len;
++ io->buff_len = frames_to_bytes(runtime, runtime->buffer_size);
+ io->buff_offset = 0;
+- io->period_len = period_len;
++ io->period_len = frames_to_bytes(runtime, runtime->period_size);
+ io->period_num = 0;
+ io->oerr_num = -1; /* ignore 1st err */
+ io->uerr_num = -1; /* ignore 1st err */
+@@ -844,15 +843,12 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+ {
+ struct fsi_priv *fsi = fsi_get_priv(substream);
+- struct snd_pcm_runtime *runtime = substream->runtime;
+ int is_play = fsi_is_play(substream);
+ int ret = 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+- fsi_stream_push(fsi, is_play, substream,
+- frames_to_bytes(runtime, runtime->buffer_size),
+- frames_to_bytes(runtime, runtime->period_size));
++ fsi_stream_push(fsi, is_play, substream);
+ ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
+ fsi_irq_enable(fsi, is_play);
+ fsi_port_start(fsi);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0081-ASoC-sh-fsi-add-fsi_set_master_clk.patch b/patches.kzm9g/0081-ASoC-sh-fsi-add-fsi_set_master_clk.patch
new file mode 100644
index 00000000000000..51db7c0ddad5e8
--- /dev/null
+++ b/patches.kzm9g/0081-ASoC-sh-fsi-add-fsi_set_master_clk.patch
@@ -0,0 +1,273 @@
+From 6bddd5bd7705307cc504b2929d66939103b1d401 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 23 May 2011 20:46:18 +0900
+Subject: ASoC: sh: fsi: add fsi_set_master_clk
+
+Current FSI driver is using set_rate call back function which is for
+master mode.
+By this patch, it is used from fsi_set_master_clk.
+This patch is preparation of cleanup suspend/resume patch.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Liam Girdwood <lrg@ti.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 4f56cde17e3373219b56d2e9a91dbcd0ad228af7)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 164 ++++++++++++++++++++++++++++-------------------------
+ 1 file changed, 87 insertions(+), 77 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 9666a26..78a1631 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -558,6 +558,82 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
+ /*
+ * clock function
+ */
++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(master);
++ int fsi_ver = master->core->ver;
++ int ret;
++
++ ret = set_rate(dev, fsi_is_port_a(fsi), rate, enable);
++ if (ret < 0) /* error */
++ return ret;
++
++ if (!enable)
++ return 0;
++
++ if (ret > 0) {
++ u32 data = 0;
++
++ switch (ret & SH_FSI_ACKMD_MASK) {
++ default:
++ /* FALL THROUGH */
++ case SH_FSI_ACKMD_512:
++ data |= (0x0 << 12);
++ break;
++ case SH_FSI_ACKMD_256:
++ data |= (0x1 << 12);
++ break;
++ case SH_FSI_ACKMD_128:
++ data |= (0x2 << 12);
++ break;
++ case SH_FSI_ACKMD_64:
++ data |= (0x3 << 12);
++ break;
++ case SH_FSI_ACKMD_32:
++ if (fsi_ver < 2)
++ dev_err(dev, "unsupported ACKMD\n");
++ else
++ data |= (0x4 << 12);
++ break;
++ }
++
++ switch (ret & SH_FSI_BPFMD_MASK) {
++ default:
++ /* FALL THROUGH */
++ case SH_FSI_BPFMD_32:
++ data |= (0x0 << 8);
++ break;
++ case SH_FSI_BPFMD_64:
++ data |= (0x1 << 8);
++ break;
++ case SH_FSI_BPFMD_128:
++ data |= (0x2 << 8);
++ break;
++ case SH_FSI_BPFMD_256:
++ data |= (0x3 << 8);
++ break;
++ case SH_FSI_BPFMD_512:
++ data |= (0x4 << 8);
++ break;
++ case SH_FSI_BPFMD_16:
++ if (fsi_ver < 2)
++ dev_err(dev, "unsupported ACKMD\n");
++ else
++ data |= (0x7 << 8);
++ break;
++ }
++
++ fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data);
++ udelay(10);
++ ret = 0;
++ }
++
++ return ret;
++
++}
++
+ #define fsi_module_init(m, d) __fsi_module_clk_ctrl(m, d, 1)
+ #define fsi_module_kill(m, d) __fsi_module_clk_ctrl(m, d, 0)
+ static void __fsi_module_clk_ctrl(struct fsi_master *master,
+@@ -826,13 +902,11 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
+ {
+ struct fsi_priv *fsi = fsi_get_priv(substream);
+ int is_play = fsi_is_play(substream);
+- struct fsi_master *master = fsi_get_master(fsi);
+- set_rate_func set_rate = fsi_get_info_set_rate(master);
+
+ fsi_irq_disable(fsi, is_play);
+
+ if (fsi_is_clk_master(fsi))
+- set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
++ fsi_set_master_clk(dai->dev, fsi, fsi->rate, 0);
+
+ fsi->rate = 0;
+
+@@ -960,79 +1034,19 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+ {
+ struct fsi_priv *fsi = fsi_get_priv(substream);
+- struct fsi_master *master = fsi_get_master(fsi);
+- set_rate_func set_rate = fsi_get_info_set_rate(master);
+- int fsi_ver = master->core->ver;
+ long rate = params_rate(params);
+ int ret;
+
+ if (!fsi_is_clk_master(fsi))
+ return 0;
+
+- ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1);
+- if (ret < 0) /* error */
++ ret = fsi_set_master_clk(dai->dev, fsi, rate, 1);
++ if (ret < 0)
+ return ret;
+
+ fsi->rate = rate;
+- if (ret > 0) {
+- u32 data = 0;
+-
+- switch (ret & SH_FSI_ACKMD_MASK) {
+- default:
+- /* FALL THROUGH */
+- case SH_FSI_ACKMD_512:
+- data |= (0x0 << 12);
+- break;
+- case SH_FSI_ACKMD_256:
+- data |= (0x1 << 12);
+- break;
+- case SH_FSI_ACKMD_128:
+- data |= (0x2 << 12);
+- break;
+- case SH_FSI_ACKMD_64:
+- data |= (0x3 << 12);
+- break;
+- case SH_FSI_ACKMD_32:
+- if (fsi_ver < 2)
+- dev_err(dai->dev, "unsupported ACKMD\n");
+- else
+- data |= (0x4 << 12);
+- break;
+- }
+-
+- switch (ret & SH_FSI_BPFMD_MASK) {
+- default:
+- /* FALL THROUGH */
+- case SH_FSI_BPFMD_32:
+- data |= (0x0 << 8);
+- break;
+- case SH_FSI_BPFMD_64:
+- data |= (0x1 << 8);
+- break;
+- case SH_FSI_BPFMD_128:
+- data |= (0x2 << 8);
+- break;
+- case SH_FSI_BPFMD_256:
+- data |= (0x3 << 8);
+- break;
+- case SH_FSI_BPFMD_512:
+- data |= (0x4 << 8);
+- break;
+- case SH_FSI_BPFMD_16:
+- if (fsi_ver < 2)
+- dev_err(dai->dev, "unsupported ACKMD\n");
+- else
+- data |= (0x7 << 8);
+- break;
+- }
+-
+- fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data);
+- udelay(10);
+- ret = 0;
+- }
+
+ return ret;
+-
+ }
+
+ static struct snd_soc_dai_ops fsi_dai_ops = {
+@@ -1301,8 +1315,7 @@ static int fsi_remove(struct platform_device *pdev)
+ }
+
+ static void __fsi_suspend(struct fsi_priv *fsi,
+- struct device *dev,
+- set_rate_func set_rate)
++ struct device *dev)
+ {
+ fsi->saved_do_fmt = fsi_reg_read(fsi, DO_FMT);
+ fsi->saved_di_fmt = fsi_reg_read(fsi, DI_FMT);
+@@ -1311,12 +1324,11 @@ static void __fsi_suspend(struct fsi_priv *fsi,
+ fsi->saved_out_sel = fsi_reg_read(fsi, OUT_SEL);
+
+ if (fsi_is_clk_master(fsi))
+- set_rate(dev, fsi_is_port_a(fsi), fsi->rate, 0);
++ fsi_set_master_clk(dev, fsi, fsi->rate, 0);
+ }
+
+ static void __fsi_resume(struct fsi_priv *fsi,
+- struct device *dev,
+- set_rate_func set_rate)
++ struct device *dev)
+ {
+ fsi_reg_write(fsi, DO_FMT, fsi->saved_do_fmt);
+ fsi_reg_write(fsi, DI_FMT, fsi->saved_di_fmt);
+@@ -1325,18 +1337,17 @@ static void __fsi_resume(struct fsi_priv *fsi,
+ fsi_reg_write(fsi, OUT_SEL, fsi->saved_out_sel);
+
+ if (fsi_is_clk_master(fsi))
+- set_rate(dev, fsi_is_port_a(fsi), fsi->rate, 1);
++ fsi_set_master_clk(dev, fsi, fsi->rate, 1);
+ }
+
+ static int fsi_suspend(struct device *dev)
+ {
+ struct fsi_master *master = dev_get_drvdata(dev);
+- set_rate_func set_rate = fsi_get_info_set_rate(master);
+
+ pm_runtime_get_sync(dev);
+
+- __fsi_suspend(&master->fsia, dev, set_rate);
+- __fsi_suspend(&master->fsib, dev, set_rate);
++ __fsi_suspend(&master->fsia, dev);
++ __fsi_suspend(&master->fsib, dev);
+
+ master->saved_a_mclk = fsi_core_read(master, a_mclk);
+ master->saved_b_mclk = fsi_core_read(master, b_mclk);
+@@ -1355,7 +1366,6 @@ static int fsi_suspend(struct device *dev)
+ static int fsi_resume(struct device *dev)
+ {
+ struct fsi_master *master = dev_get_drvdata(dev);
+- set_rate_func set_rate = fsi_get_info_set_rate(master);
+
+ pm_runtime_get_sync(dev);
+
+@@ -1368,8 +1378,8 @@ static int fsi_resume(struct device *dev)
+ fsi_core_mask_set(master, iemsk, 0xffff, master->saved_iemsk);
+ fsi_core_mask_set(master, imsk, 0xffff, master->saved_imsk);
+
+- __fsi_resume(&master->fsia, dev, set_rate);
+- __fsi_resume(&master->fsib, dev, set_rate);
++ __fsi_resume(&master->fsia, dev);
++ __fsi_resume(&master->fsib, dev);
+
+ pm_runtime_put_sync(dev);
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0082-ASoC-sh-fsi-irq-control-moves-to-fsi_port_start-stop.patch b/patches.kzm9g/0082-ASoC-sh-fsi-irq-control-moves-to-fsi_port_start-stop.patch
new file mode 100644
index 00000000000000..98b7a8a5a53f8e
--- /dev/null
+++ b/patches.kzm9g/0082-ASoC-sh-fsi-irq-control-moves-to-fsi_port_start-stop.patch
@@ -0,0 +1,74 @@
+From 640c889570e0563c5a0e3bc7caf89bba5244d8b4 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 23 May 2011 20:46:23 +0900
+Subject: ASoC: sh: fsi: irq control moves to fsi_port_start/stop
+
+Using fsi_irq_enable/disable in fsi_port_start/stop is very natural.
+This patch is preparation of cleanup suspend/resume patch.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Liam Girdwood <lrg@ti.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 1ddddd36353c40fbf8faad955fcc26e05f656121)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 78a1631..c445e86 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -654,15 +654,20 @@ static void __fsi_module_clk_ctrl(struct fsi_master *master,
+ pm_runtime_put_sync(dev);
+ }
+
+-#define fsi_port_start(f) __fsi_port_clk_ctrl(f, 1)
+-#define fsi_port_stop(f) __fsi_port_clk_ctrl(f, 0)
+-static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int enable)
++#define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1)
++#define fsi_port_stop(f, i) __fsi_port_clk_ctrl(f, i, 0)
++static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable)
+ {
+ struct fsi_master *master = fsi_get_master(fsi);
+ u32 soft = fsi_is_port_a(fsi) ? PASR : PBSR;
+ u32 clk = fsi_is_port_a(fsi) ? CRA : CRB;
+ int is_master = fsi_is_clk_master(fsi);
+
++ if (enable)
++ fsi_irq_enable(fsi, is_play);
++ else
++ fsi_irq_disable(fsi, is_play);
++
+ fsi_master_mask_set(master, SOFT_RST, soft, (enable) ? soft : 0);
+ if (is_master)
+ fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
+@@ -901,9 +906,6 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+ {
+ struct fsi_priv *fsi = fsi_get_priv(substream);
+- int is_play = fsi_is_play(substream);
+-
+- fsi_irq_disable(fsi, is_play);
+
+ if (fsi_is_clk_master(fsi))
+ fsi_set_master_clk(dai->dev, fsi, fsi->rate, 0);
+@@ -924,12 +926,10 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+ case SNDRV_PCM_TRIGGER_START:
+ fsi_stream_push(fsi, is_play, substream);
+ ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
+- fsi_irq_enable(fsi, is_play);
+- fsi_port_start(fsi);
++ fsi_port_start(fsi, is_play);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+- fsi_port_stop(fsi);
+- fsi_irq_disable(fsi, is_play);
++ fsi_port_stop(fsi, is_play);
+ fsi_stream_pop(fsi, is_play);
+ break;
+ }
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0083-ASoC-sh-fsi-tidyup-unclear-variable-naming.patch b/patches.kzm9g/0083-ASoC-sh-fsi-tidyup-unclear-variable-naming.patch
new file mode 100644
index 00000000000000..98e9e9570ab38d
--- /dev/null
+++ b/patches.kzm9g/0083-ASoC-sh-fsi-tidyup-unclear-variable-naming.patch
@@ -0,0 +1,344 @@
+From f958aa05f1e92cc702ef0aabb8230172eb6f6275 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 23 May 2011 20:46:03 +0900
+Subject: ASoC: sh: fsi: tidyup unclear variable naming
+
+Some variables on this driver were a unclear naming,
+and were different unit (byte, frame, sample).
+And some functions had wrong name
+(ex. it returned "sample width" but name was "fsi_get_frame_width").
+This patch tidy-up this issue, and the minimum unit become "sample".
+Special thanks to Takashi YOSHII.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Liam Girdwood <lrg@ti.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 2e651bafa959c6e2620601c2c2e9b7c26f6a9c1a)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 182 +++++++++++++++++++++++++++++------------------------
+ 1 file changed, 100 insertions(+), 82 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index c445e86..98c8296 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -118,10 +118,38 @@ typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int ena
+ /*
+ * FSI driver use below type name for variable
+ *
+- * xxx_len : data length
+- * xxx_width : data width
+- * xxx_offset : data offset
+ * xxx_num : number of data
++ * xxx_pos : position of data
++ * xxx_capa : capacity of data
++ */
++
++/*
++ * period/frame/sample image
++ *
++ * ex) PCM (2ch)
++ *
++ * period pos period pos
++ * [n] [n + 1]
++ * |<-------------------- period--------------------->|
++ * ==|============================================ ... =|==
++ * | |
++ * ||<----- frame ----->|<------ frame ----->| ... |
++ * |+--------------------+--------------------+- ... |
++ * ||[ sample ][ sample ]|[ sample ][ sample ]| ... |
++ * |+--------------------+--------------------+- ... |
++ * ==|============================================ ... =|==
++ */
++
++/*
++ * FSI FIFO image
++ *
++ * | |
++ * | |
++ * | [ sample ] |
++ * | [ sample ] |
++ * | [ sample ] |
++ * | [ sample ] |
++ * --> go to codecs
+ */
+
+ /*
+@@ -131,12 +159,11 @@ typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int ena
+ struct fsi_stream {
+ struct snd_pcm_substream *substream;
+
+- int fifo_max_num;
+-
+- int buff_offset;
+- int buff_len;
+- int period_len;
+- int period_num;
++ int fifo_sample_capa; /* sample capacity of FSI FIFO */
++ int buff_sample_capa; /* sample capacity of ALSA buffer */
++ int buff_sample_pos; /* sample position of ALSA buffer */
++ int period_samples; /* sample number / 1 period */
++ int period_pos; /* current period position */
+
+ int uerr_num;
+ int oerr_num;
+@@ -342,6 +369,16 @@ static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play)
+ return shift;
+ }
+
++static int fsi_frame2sample(struct fsi_priv *fsi, int frames)
++{
++ return frames * fsi->chan_num;
++}
++
++static int fsi_sample2frame(struct fsi_priv *fsi, int samples)
++{
++ return samples / fsi->chan_num;
++}
++
+ static void fsi_stream_push(struct fsi_priv *fsi,
+ int is_play,
+ struct snd_pcm_substream *substream)
+@@ -350,10 +387,10 @@ static void fsi_stream_push(struct fsi_priv *fsi,
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ io->substream = substream;
+- io->buff_len = frames_to_bytes(runtime, runtime->buffer_size);
+- io->buff_offset = 0;
+- io->period_len = frames_to_bytes(runtime, runtime->period_size);
+- io->period_num = 0;
++ io->buff_sample_capa = fsi_frame2sample(fsi, runtime->buffer_size);
++ io->buff_sample_pos = 0;
++ io->period_samples = fsi_frame2sample(fsi, runtime->period_size);
++ io->period_pos = 0;
+ io->oerr_num = -1; /* ignore 1st err */
+ io->uerr_num = -1; /* ignore 1st err */
+ }
+@@ -371,47 +408,26 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
+ dev_err(dai->dev, "under_run = %d\n", io->uerr_num);
+
+ io->substream = NULL;
+- io->buff_len = 0;
+- io->buff_offset = 0;
+- io->period_len = 0;
+- io->period_num = 0;
++ io->buff_sample_capa = 0;
++ io->buff_sample_pos = 0;
++ io->period_samples = 0;
++ io->period_pos = 0;
+ io->oerr_num = 0;
+ io->uerr_num = 0;
+ }
+
+-static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
++static int fsi_get_current_fifo_samples(struct fsi_priv *fsi, int is_play)
+ {
+ u32 status;
+- int data_num;
++ int frames;
+
+ status = is_play ?
+ fsi_reg_read(fsi, DOFF_ST) :
+ fsi_reg_read(fsi, DIFF_ST);
+
+- data_num = 0x1ff & (status >> 8);
+- data_num *= fsi->chan_num;
+-
+- return data_num;
+-}
+-
+-static int fsi_len2num(int len, int width)
+-{
+- return len / width;
+-}
++ frames = 0x1ff & (status >> 8);
+
+-#define fsi_num2offset(a, b) fsi_num2len(a, b)
+-static int fsi_num2len(int num, int width)
+-{
+- return num * width;
+-}
+-
+-static int fsi_get_frame_width(struct fsi_priv *fsi, int is_play)
+-{
+- struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+- struct snd_pcm_substream *substream = io->substream;
+- struct snd_pcm_runtime *runtime = substream->runtime;
+-
+- return frames_to_bytes(runtime, 1) / fsi->chan_num;
++ return fsi_frame2sample(fsi, frames);
+ }
+
+ static void fsi_count_fifo_err(struct fsi_priv *fsi)
+@@ -443,8 +459,10 @@ static u8 *fsi_dma_get_area(struct fsi_priv *fsi, int stream)
+ {
+ int is_play = fsi_stream_is_play(stream);
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
++ struct snd_pcm_runtime *runtime = io->substream->runtime;
+
+- return io->substream->runtime->dma_area + io->buff_offset;
++ return runtime->dma_area +
++ samples_to_bytes(runtime, io->buff_sample_pos);
+ }
+
+ static void fsi_dma_soft_push16(struct fsi_priv *fsi, int num)
+@@ -683,13 +701,14 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
+ struct fsi_master *master = fsi_get_master(fsi);
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+ u32 shift, i;
++ int frame_capa;
+
+ /* get on-chip RAM capacity */
+ shift = fsi_master_read(master, FIFO_SZ);
+ shift >>= fsi_get_port_shift(fsi, is_play);
+ shift &= FIFO_SZ_MASK;
+- io->fifo_max_num = 256 << shift;
+- dev_dbg(dai->dev, "fifo = %d words\n", io->fifo_max_num);
++ frame_capa = 256 << shift;
++ dev_dbg(dai->dev, "fifo = %d words\n", frame_capa);
+
+ /*
+ * The maximum number of sample data varies depending
+@@ -711,9 +730,11 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
+ * 8 channels: 32 ( 32 x 8 = 256)
+ */
+ for (i = 1; i < fsi->chan_num; i <<= 1)
+- io->fifo_max_num >>= 1;
++ frame_capa >>= 1;
+ dev_dbg(dai->dev, "%d channel %d store\n",
+- fsi->chan_num, io->fifo_max_num);
++ fsi->chan_num, frame_capa);
++
++ io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa);
+
+ /*
+ * set interrupt generation factor
+@@ -734,10 +755,10 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
+ struct snd_pcm_substream *substream = NULL;
+ int is_play = fsi_stream_is_play(stream);
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+- int data_residue_num;
+- int data_num;
+- int data_num_max;
+- int ch_width;
++ int sample_residues;
++ int sample_width;
++ int samples;
++ int samples_max;
+ int over_period;
+ void (*fn)(struct fsi_priv *fsi, int size);
+
+@@ -753,36 +774,35 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
+ /* FSI FIFO has limit.
+ * So, this driver can not send periods data at a time
+ */
+- if (io->buff_offset >=
+- fsi_num2offset(io->period_num + 1, io->period_len)) {
++ if (io->buff_sample_pos >=
++ io->period_samples * (io->period_pos + 1)) {
+
+ over_period = 1;
+- io->period_num = (io->period_num + 1) % runtime->periods;
++ io->period_pos = (io->period_pos + 1) % runtime->periods;
+
+- if (0 == io->period_num)
+- io->buff_offset = 0;
++ if (0 == io->period_pos)
++ io->buff_sample_pos = 0;
+ }
+
+- /* get 1 channel data width */
+- ch_width = fsi_get_frame_width(fsi, is_play);
++ /* get 1 sample data width */
++ sample_width = samples_to_bytes(runtime, 1);
+
+- /* get residue data number of alsa */
+- data_residue_num = fsi_len2num(io->buff_len - io->buff_offset,
+- ch_width);
++ /* get number of residue samples */
++ sample_residues = io->buff_sample_capa - io->buff_sample_pos;
+
+ if (is_play) {
+ /*
+ * for play-back
+ *
+- * data_num_max : number of FSI fifo free space
+- * data_num : number of ALSA residue data
++ * samples_max : number of FSI fifo free samples space
++ * samples : number of ALSA residue samples
+ */
+- data_num_max = io->fifo_max_num * fsi->chan_num;
+- data_num_max -= fsi_get_fifo_data_num(fsi, is_play);
++ samples_max = io->fifo_sample_capa;
++ samples_max -= fsi_get_current_fifo_samples(fsi, is_play);
+
+- data_num = data_residue_num;
++ samples = sample_residues;
+
+- switch (ch_width) {
++ switch (sample_width) {
+ case 2:
+ fn = fsi_dma_soft_push16;
+ break;
+@@ -796,13 +816,13 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
+ /*
+ * for capture
+ *
+- * data_num_max : number of ALSA free space
+- * data_num : number of data in FSI fifo
++ * samples_max : number of ALSA free samples space
++ * samples : number of samples in FSI fifo
+ */
+- data_num_max = data_residue_num;
+- data_num = fsi_get_fifo_data_num(fsi, is_play);
++ samples_max = sample_residues;
++ samples = fsi_get_current_fifo_samples(fsi, is_play);
+
+- switch (ch_width) {
++ switch (sample_width) {
+ case 2:
+ fn = fsi_dma_soft_pop16;
+ break;
+@@ -814,12 +834,12 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
+ }
+ }
+
+- data_num = min(data_num, data_num_max);
++ samples = min(samples, samples_max);
+
+- fn(fsi, data_num);
++ fn(fsi, samples);
+
+- /* update buff_offset */
+- io->buff_offset += fsi_num2offset(data_num, ch_width);
++ /* update buff_sample_pos */
++ io->buff_sample_pos += samples;
+
+ if (over_period)
+ snd_pcm_period_elapsed(substream);
+@@ -1107,16 +1127,14 @@ static int fsi_hw_free(struct snd_pcm_substream *substream)
+
+ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
+ {
+- struct snd_pcm_runtime *runtime = substream->runtime;
+ struct fsi_priv *fsi = fsi_get_priv(substream);
+ struct fsi_stream *io = fsi_get_stream(fsi, fsi_is_play(substream));
+- long location;
++ int samples_pos = io->buff_sample_pos - 1;
+
+- location = (io->buff_offset - 1);
+- if (location < 0)
+- location = 0;
++ if (samples_pos < 0)
++ samples_pos = 0;
+
+- return bytes_to_frames(runtime, location);
++ return fsi_sample2frame(fsi, samples_pos);
+ }
+
+ static struct snd_pcm_ops fsi_pcm_ops = {
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0084-ASoC-sh-fsi-remove-pm_runtime-from-fsi_dai_set_fmt.patch b/patches.kzm9g/0084-ASoC-sh-fsi-remove-pm_runtime-from-fsi_dai_set_fmt.patch
new file mode 100644
index 00000000000000..af2fc0db301d94
--- /dev/null
+++ b/patches.kzm9g/0084-ASoC-sh-fsi-remove-pm_runtime-from-fsi_dai_set_fmt.patch
@@ -0,0 +1,160 @@
+From 387c7967931d638fd30d2a63ec171e42c71477bd Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 23 May 2011 20:46:07 +0900
+Subject: ASoC: sh: fsi: remove pm_runtime from fsi_dai_set_fmt.
+
+pm_runtime_get/put_sync were used to access FSI register in fsi_dai_set_fmt
+which is called when ALSA probe.
+But this register value will disappear after pm_runtime_put_sync
+if platform is supporting RuntimePM.
+To solve this issue, this patch adds new variable for format,
+and remove pm_runtime_get/put_sync from fsi_dai_set_fmt.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Liam Girdwood <lrg@ti.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 9478e0b60fb4a7adde72d4a86b826d396b607a61)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 52 ++++++++++++++++++++++++++++++++--------------------
+ 1 file changed, 32 insertions(+), 20 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 98c8296..0a09ea2 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -176,8 +176,12 @@ struct fsi_priv {
+ struct fsi_stream playback;
+ struct fsi_stream capture;
+
++ u32 do_fmt;
++ u32 di_fmt;
++
+ int chan_num:16;
+ int clk_master:1;
++ int spdif:1;
+
+ long rate;
+
+@@ -298,6 +302,11 @@ static int fsi_is_port_a(struct fsi_priv *fsi)
+ return fsi->master->base == fsi->base;
+ }
+
++static int fsi_is_spdif(struct fsi_priv *fsi)
++{
++ return fsi->spdif;
++}
++
+ static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
+ {
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+@@ -893,11 +902,16 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
+ {
+ struct fsi_priv *fsi = fsi_get_priv(substream);
+ u32 flags = fsi_get_info_flags(fsi);
+- u32 data;
++ u32 data = 0;
+ int is_play = fsi_is_play(substream);
+
+ pm_runtime_get_sync(dai->dev);
+
++ /* clock setting */
++ if (fsi_is_clk_master(fsi))
++ data = DIMD | DOMD;
++
++ fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data);
+
+ /* clock inversion (CKG2) */
+ data = 0;
+@@ -912,6 +926,16 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
+
+ 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);
++
++ /* spdif ? */
++ if (fsi_is_spdif(fsi)) {
++ fsi_spdif_clk_ctrl(fsi, 1);
++ fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
++ }
++
+ /* irq clear */
+ fsi_irq_disable(fsi, is_play);
+ fsi_irq_clear_status(fsi);
+@@ -974,8 +998,8 @@ static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt)
+ return -EINVAL;
+ }
+
+- fsi_reg_write(fsi, DO_FMT, data);
+- fsi_reg_write(fsi, DI_FMT, data);
++ fsi->do_fmt = data;
++ fsi->di_fmt = data;
+
+ return 0;
+ }
+@@ -990,11 +1014,10 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
+
+ data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
+ fsi->chan_num = 2;
+- fsi_spdif_clk_ctrl(fsi, 1);
+- fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
++ fsi->spdif = 1;
+
+- fsi_reg_write(fsi, DO_FMT, data);
+- fsi_reg_write(fsi, DI_FMT, data);
++ fsi->do_fmt = data;
++ fsi->di_fmt = data;
+
+ return 0;
+ }
+@@ -1005,32 +1028,24 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+ struct fsi_master *master = fsi_get_master(fsi);
+ set_rate_func set_rate = fsi_get_info_set_rate(master);
+ u32 flags = fsi_get_info_flags(fsi);
+- u32 data = 0;
+ int ret;
+
+- pm_runtime_get_sync(dai->dev);
+-
+ /* set master/slave audio interface */
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+- data = DIMD | DOMD;
+ fsi->clk_master = 1;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ break;
+ default:
+- ret = -EINVAL;
+- goto set_fmt_exit;
++ return -EINVAL;
+ }
+
+ if (fsi_is_clk_master(fsi) && !set_rate) {
+ dev_err(dai->dev, "platform doesn't have set_rate\n");
+- ret = -EINVAL;
+- goto set_fmt_exit;
++ return -EINVAL;
+ }
+
+- fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data);
+-
+ /* set format */
+ switch (flags & SH_FSI_FMT_MASK) {
+ case SH_FSI_FMT_DAI:
+@@ -1043,9 +1058,6 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+ ret = -EINVAL;
+ }
+
+-set_fmt_exit:
+- pm_runtime_put_sync(dai->dev);
+-
+ return ret;
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0085-ASoC-sh-fsi-make-sure-fsi_stream_push-pop-access-by-.patch b/patches.kzm9g/0085-ASoC-sh-fsi-make-sure-fsi_stream_push-pop-access-by-.patch
new file mode 100644
index 00000000000000..577fe89dd9c4f3
--- /dev/null
+++ b/patches.kzm9g/0085-ASoC-sh-fsi-make-sure-fsi_stream_push-pop-access-by-.patch
@@ -0,0 +1,62 @@
+From 9a2ab68a1322eb35bf0ac8176cf8d14052c4aefa Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 23 May 2011 20:46:13 +0900
+Subject: ASoC: sh: fsi: make sure fsi_stream_push/pop access by spin lock
+
+fsi_stream_push/pop might be called in same time.
+This patch protect it.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Liam Girdwood <lrg@ti.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 2da658927c9e28425ecb6b6a7a03094a012e8620)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 0a09ea2..e371db8 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -394,7 +394,10 @@ static void fsi_stream_push(struct fsi_priv *fsi,
+ {
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+ struct snd_pcm_runtime *runtime = substream->runtime;
++ struct fsi_master *master = fsi_get_master(fsi);
++ unsigned long flags;
+
++ spin_lock_irqsave(&master->lock, flags);
+ io->substream = substream;
+ io->buff_sample_capa = fsi_frame2sample(fsi, runtime->buffer_size);
+ io->buff_sample_pos = 0;
+@@ -402,13 +405,17 @@ static void fsi_stream_push(struct fsi_priv *fsi,
+ io->period_pos = 0;
+ io->oerr_num = -1; /* ignore 1st err */
+ io->uerr_num = -1; /* ignore 1st err */
++ spin_unlock_irqrestore(&master->lock, flags);
+ }
+
+ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
+ {
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+ struct snd_soc_dai *dai = fsi_get_dai(io->substream);
++ struct fsi_master *master = fsi_get_master(fsi);
++ unsigned long flags;
+
++ spin_lock_irqsave(&master->lock, flags);
+
+ if (io->oerr_num > 0)
+ dev_err(dai->dev, "over_run = %d\n", io->oerr_num);
+@@ -423,6 +430,7 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
+ io->period_pos = 0;
+ io->oerr_num = 0;
+ io->uerr_num = 0;
++ spin_unlock_irqrestore(&master->lock, flags);
+ }
+
+ static int fsi_get_current_fifo_samples(struct fsi_priv *fsi, int is_play)
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0086-ASoC-sh-fsi-remove-fsi_module_init-kill.patch b/patches.kzm9g/0086-ASoC-sh-fsi-remove-fsi_module_init-kill.patch
new file mode 100644
index 00000000000000..f6c8defb17fe75
--- /dev/null
+++ b/patches.kzm9g/0086-ASoC-sh-fsi-remove-fsi_module_init-kill.patch
@@ -0,0 +1,106 @@
+From 775ff31c0db6d3de98d58f4f4f6c1d7614eb0ebc Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 23 May 2011 20:46:30 +0900
+Subject: ASoC: sh: fsi: remove fsi_module_init/kill
+
+FSIA/B ports is enabled by default when power-on,
+and current FSI is supporting RuntimePM.
+In addition, current fsi_module_init/kill doesn't care
+simultaneous playback/recorde.
+This mean FSI port control is not needed.
+This patch remove fsi_module_init/kill
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Liam Girdwood <lrg@ti.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 4c481253311dd5940ae7c26eaff6c6f63bd41fd8)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 30 ------------------------------
+ 1 file changed, 30 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index e371db8..c9cf84d 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -669,32 +669,11 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
+
+ }
+
+-#define fsi_module_init(m, d) __fsi_module_clk_ctrl(m, d, 1)
+-#define fsi_module_kill(m, d) __fsi_module_clk_ctrl(m, d, 0)
+-static void __fsi_module_clk_ctrl(struct fsi_master *master,
+- struct device *dev,
+- int enable)
+-{
+- pm_runtime_get_sync(dev);
+-
+- if (enable) {
+- /* enable only SR */
+- fsi_master_mask_set(master, SOFT_RST, FSISR, FSISR);
+- fsi_master_mask_set(master, SOFT_RST, PASR | PBSR, 0);
+- } else {
+- /* clear all registers */
+- fsi_master_mask_set(master, SOFT_RST, FSISR, 0);
+- }
+-
+- pm_runtime_put_sync(dev);
+-}
+-
+ #define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1)
+ #define fsi_port_stop(f, i) __fsi_port_clk_ctrl(f, i, 0)
+ static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable)
+ {
+ struct fsi_master *master = fsi_get_master(fsi);
+- u32 soft = fsi_is_port_a(fsi) ? PASR : PBSR;
+ u32 clk = fsi_is_port_a(fsi) ? CRA : CRB;
+ int is_master = fsi_is_clk_master(fsi);
+
+@@ -703,7 +682,6 @@ static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable)
+ else
+ fsi_irq_disable(fsi, is_play);
+
+- fsi_master_mask_set(master, SOFT_RST, soft, (enable) ? soft : 0);
+ if (is_master)
+ fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
+ }
+@@ -1294,8 +1272,6 @@ static int fsi_probe(struct platform_device *pdev)
+ pm_runtime_enable(&pdev->dev);
+ dev_set_drvdata(&pdev->dev, master);
+
+- fsi_module_init(master, &pdev->dev);
+-
+ ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED,
+ id_entry->name, master);
+ if (ret) {
+@@ -1338,8 +1314,6 @@ static int fsi_remove(struct platform_device *pdev)
+
+ master = dev_get_drvdata(&pdev->dev);
+
+- fsi_module_kill(master, &pdev->dev);
+-
+ free_irq(master->irq, master);
+ pm_runtime_disable(&pdev->dev);
+
+@@ -1394,8 +1368,6 @@ static int fsi_suspend(struct device *dev)
+ master->saved_clk_rst = fsi_master_read(master, CLK_RST);
+ master->saved_soft_rst = fsi_master_read(master, SOFT_RST);
+
+- fsi_module_kill(master, dev);
+-
+ pm_runtime_put_sync(dev);
+
+ return 0;
+@@ -1407,8 +1379,6 @@ static int fsi_resume(struct device *dev)
+
+ pm_runtime_get_sync(dev);
+
+- fsi_module_init(master, dev);
+-
+ fsi_master_mask_set(master, SOFT_RST, 0xffff, master->saved_soft_rst);
+ fsi_master_mask_set(master, CLK_RST, 0xffff, master->saved_clk_rst);
+ fsi_core_mask_set(master, a_mclk, 0xffff, master->saved_a_mclk);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0087-ASoC-sh-fsi-cleanup-suspend-resume.patch b/patches.kzm9g/0087-ASoC-sh-fsi-cleanup-suspend-resume.patch
new file mode 100644
index 00000000000000..2396a52cbfcd75
--- /dev/null
+++ b/patches.kzm9g/0087-ASoC-sh-fsi-cleanup-suspend-resume.patch
@@ -0,0 +1,202 @@
+From fd2a98f748b7982d546c368f12e9c96d29e11559 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 23 May 2011 20:46:35 +0900
+Subject: ASoC: sh: fsi: cleanup suspend/resume
+
+Current FSI driver was using saved_xxx variable for suspend/resume.
+OTOH, the start and stop of power/clock are controlled by
+fsi_hw_startup/fsi_hw_shutdown in current FSI driver.
+The all necessary registers value are set by fsi_hw_startup.
+
+So, if fsi_hw_shutdown is called when "suspend" is generated,
+and fsi_hw_startup is called at "resume",
+the saved_xxx are not needed.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Liam Girdwood <lrg@ti.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit cda828cafe9df9a8b0687f1b8a17be2cd9cf1950)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 97 +++++++++++++++++++++++-------------------------------
+ 1 file changed, 42 insertions(+), 55 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index c9cf84d..d2e28e4 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -184,13 +184,6 @@ struct fsi_priv {
+ int spdif:1;
+
+ long rate;
+-
+- /* for suspend/resume */
+- u32 saved_do_fmt;
+- u32 saved_di_fmt;
+- u32 saved_ckg1;
+- u32 saved_ckg2;
+- u32 saved_out_sel;
+ };
+
+ struct fsi_core {
+@@ -211,14 +204,6 @@ struct fsi_master {
+ struct fsi_core *core;
+ struct sh_fsi_platform_info *info;
+ spinlock_t lock;
+-
+- /* for suspend/resume */
+- u32 saved_a_mclk;
+- u32 saved_b_mclk;
+- u32 saved_iemsk;
+- u32 saved_imsk;
+- u32 saved_clk_rst;
+- u32 saved_soft_rst;
+ };
+
+ /*
+@@ -388,6 +373,21 @@ static int fsi_sample2frame(struct fsi_priv *fsi, int samples)
+ return samples / fsi->chan_num;
+ }
+
++static int fsi_stream_is_working(struct fsi_priv *fsi,
++ int is_play)
++{
++ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
++ struct fsi_master *master = fsi_get_master(fsi);
++ unsigned long flags;
++ int ret;
++
++ spin_lock_irqsave(&master->lock, flags);
++ ret = !!io->substream;
++ spin_unlock_irqrestore(&master->lock, flags);
++
++ return ret;
++}
++
+ static void fsi_stream_push(struct fsi_priv *fsi,
+ int is_play,
+ struct snd_pcm_substream *substream)
+@@ -666,7 +666,6 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
+ }
+
+ return ret;
+-
+ }
+
+ #define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1)
+@@ -675,14 +674,13 @@ static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable)
+ {
+ struct fsi_master *master = fsi_get_master(fsi);
+ u32 clk = fsi_is_port_a(fsi) ? CRA : CRB;
+- int is_master = fsi_is_clk_master(fsi);
+
+ if (enable)
+ fsi_irq_enable(fsi, is_play);
+ else
+ fsi_irq_disable(fsi, is_play);
+
+- if (is_master)
++ if (fsi_is_clk_master(fsi))
+ fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
+ }
+
+@@ -1327,48 +1325,43 @@ static int fsi_remove(struct platform_device *pdev)
+ }
+
+ static void __fsi_suspend(struct fsi_priv *fsi,
++ int is_play,
+ struct device *dev)
+ {
+- fsi->saved_do_fmt = fsi_reg_read(fsi, DO_FMT);
+- fsi->saved_di_fmt = fsi_reg_read(fsi, DI_FMT);
+- fsi->saved_ckg1 = fsi_reg_read(fsi, CKG1);
+- fsi->saved_ckg2 = fsi_reg_read(fsi, CKG2);
+- fsi->saved_out_sel = fsi_reg_read(fsi, OUT_SEL);
++ if (!fsi_stream_is_working(fsi, is_play))
++ return;
+
+- if (fsi_is_clk_master(fsi))
+- fsi_set_master_clk(dev, fsi, fsi->rate, 0);
++ fsi_port_stop(fsi, is_play);
++ fsi_hw_shutdown(fsi, is_play, dev);
+ }
+
+ static void __fsi_resume(struct fsi_priv *fsi,
++ int is_play,
+ struct device *dev)
+ {
+- fsi_reg_write(fsi, DO_FMT, fsi->saved_do_fmt);
+- fsi_reg_write(fsi, DI_FMT, fsi->saved_di_fmt);
+- fsi_reg_write(fsi, CKG1, fsi->saved_ckg1);
+- fsi_reg_write(fsi, CKG2, fsi->saved_ckg2);
+- fsi_reg_write(fsi, OUT_SEL, fsi->saved_out_sel);
++ if (!fsi_stream_is_working(fsi, is_play))
++ return;
+
+- if (fsi_is_clk_master(fsi))
++ fsi_hw_startup(fsi, is_play, dev);
++
++ if (fsi_is_clk_master(fsi) && fsi->rate)
+ fsi_set_master_clk(dev, fsi, fsi->rate, 1);
++
++ fsi_port_start(fsi, is_play);
++
+ }
+
+ static int fsi_suspend(struct device *dev)
+ {
+ struct fsi_master *master = dev_get_drvdata(dev);
++ struct fsi_priv *fsia = &master->fsia;
++ struct fsi_priv *fsib = &master->fsib;
+
+- pm_runtime_get_sync(dev);
+-
+- __fsi_suspend(&master->fsia, dev);
+- __fsi_suspend(&master->fsib, dev);
++ __fsi_suspend(fsia, 1, dev);
++ __fsi_suspend(fsia, 0, dev);
+
+- master->saved_a_mclk = fsi_core_read(master, a_mclk);
+- master->saved_b_mclk = fsi_core_read(master, b_mclk);
+- master->saved_iemsk = fsi_core_read(master, iemsk);
+- master->saved_imsk = fsi_core_read(master, imsk);
+- master->saved_clk_rst = fsi_master_read(master, CLK_RST);
+- master->saved_soft_rst = fsi_master_read(master, SOFT_RST);
+-
+- pm_runtime_put_sync(dev);
++ __fsi_suspend(fsib, 1, dev);
++ __fsi_suspend(fsib, 0, dev);
+
+ return 0;
+ }
+@@ -1376,20 +1369,14 @@ static int fsi_suspend(struct device *dev)
+ static int fsi_resume(struct device *dev)
+ {
+ struct fsi_master *master = dev_get_drvdata(dev);
++ struct fsi_priv *fsia = &master->fsia;
++ struct fsi_priv *fsib = &master->fsib;
+
+- pm_runtime_get_sync(dev);
+-
+- fsi_master_mask_set(master, SOFT_RST, 0xffff, master->saved_soft_rst);
+- fsi_master_mask_set(master, CLK_RST, 0xffff, master->saved_clk_rst);
+- fsi_core_mask_set(master, a_mclk, 0xffff, master->saved_a_mclk);
+- fsi_core_mask_set(master, b_mclk, 0xffff, master->saved_b_mclk);
+- fsi_core_mask_set(master, iemsk, 0xffff, master->saved_iemsk);
+- fsi_core_mask_set(master, imsk, 0xffff, master->saved_imsk);
+-
+- __fsi_resume(&master->fsia, dev);
+- __fsi_resume(&master->fsib, dev);
++ __fsi_resume(fsia, 1, dev);
++ __fsi_resume(fsia, 0, dev);
+
+- pm_runtime_put_sync(dev);
++ __fsi_resume(fsib, 1, dev);
++ __fsi_resume(fsib, 0, dev);
+
+ return 0;
+ }
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0088-ASoC-sh-fsi-add-fsi_hw_startup-shutdown.patch b/patches.kzm9g/0088-ASoC-sh-fsi-add-fsi_hw_startup-shutdown.patch
new file mode 100644
index 00000000000000..ab0f66604fdf31
--- /dev/null
+++ b/patches.kzm9g/0088-ASoC-sh-fsi-add-fsi_hw_startup-shutdown.patch
@@ -0,0 +1,116 @@
+From fb099115bddf1865f0de965e6c137b8d8048e37f Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 23 May 2011 20:46:26 +0900
+Subject: ASoC: sh: fsi: add fsi_hw_startup/shutdown
+
+This patch is preparation of cleanup suspend/resume patch.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Acked-by: Liam Girdwood <lrg@ti.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 23ca853392aebdaa56c8138746deb2002e03d827)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 43 +++++++++++++++++++++++++++++--------------
+ 1 file changed, 29 insertions(+), 14 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index d2e28e4..8e112cc 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -689,7 +689,7 @@ static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable)
+ */
+ static void fsi_fifo_init(struct fsi_priv *fsi,
+ int is_play,
+- struct snd_soc_dai *dai)
++ struct device *dev)
+ {
+ struct fsi_master *master = fsi_get_master(fsi);
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+@@ -701,7 +701,7 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
+ shift >>= fsi_get_port_shift(fsi, is_play);
+ shift &= FIFO_SZ_MASK;
+ frame_capa = 256 << shift;
+- dev_dbg(dai->dev, "fifo = %d words\n", frame_capa);
++ dev_dbg(dev, "fifo = %d words\n", frame_capa);
+
+ /*
+ * The maximum number of sample data varies depending
+@@ -724,7 +724,7 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
+ */
+ for (i = 1; i < fsi->chan_num; i <<= 1)
+ frame_capa >>= 1;
+- dev_dbg(dai->dev, "%d channel %d store\n",
++ dev_dbg(dev, "%d channel %d store\n",
+ fsi->chan_num, frame_capa);
+
+ io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa);
+@@ -881,15 +881,14 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
+ * dai ops
+ */
+
+-static int fsi_dai_startup(struct snd_pcm_substream *substream,
+- struct snd_soc_dai *dai)
++static int fsi_hw_startup(struct fsi_priv *fsi,
++ int is_play,
++ struct device *dev)
+ {
+- struct fsi_priv *fsi = fsi_get_priv(substream);
+ u32 flags = fsi_get_info_flags(fsi);
+ u32 data = 0;
+- int is_play = fsi_is_play(substream);
+
+- pm_runtime_get_sync(dai->dev);
++ pm_runtime_get_sync(dev);
+
+ /* clock setting */
+ if (fsi_is_clk_master(fsi))
+@@ -925,22 +924,38 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
+ fsi_irq_clear_status(fsi);
+
+ /* fifo init */
+- fsi_fifo_init(fsi, is_play, dai);
++ fsi_fifo_init(fsi, is_play, dev);
+
+ return 0;
+ }
+
++static void fsi_hw_shutdown(struct fsi_priv *fsi,
++ int is_play,
++ struct device *dev)
++{
++ if (fsi_is_clk_master(fsi))
++ fsi_set_master_clk(dev, fsi, fsi->rate, 0);
++
++ pm_runtime_put_sync(dev);
++}
++
++static int fsi_dai_startup(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *dai)
++{
++ struct fsi_priv *fsi = fsi_get_priv(substream);
++ int is_play = fsi_is_play(substream);
++
++ return fsi_hw_startup(fsi, is_play, dai->dev);
++}
++
+ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+ {
+ struct fsi_priv *fsi = fsi_get_priv(substream);
++ int is_play = fsi_is_play(substream);
+
+- if (fsi_is_clk_master(fsi))
+- fsi_set_master_clk(dai->dev, fsi, fsi->rate, 0);
+-
++ fsi_hw_shutdown(fsi, is_play, dai->dev);
+ fsi->rate = 0;
+-
+- pm_runtime_put_sync(dai->dev);
+ }
+
+ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0089-sound-irq-Remove-IRQF_DISABLED.patch b/patches.kzm9g/0089-sound-irq-Remove-IRQF_DISABLED.patch
new file mode 100644
index 00000000000000..b08c273864047a
--- /dev/null
+++ b/patches.kzm9g/0089-sound-irq-Remove-IRQF_DISABLED.patch
@@ -0,0 +1,43 @@
+From 00e240dfffc278c30a57390dd1e129bcb4613e86 Mon Sep 17 00:00:00 2001
+From: Yong Zhang <yong.zhang0@gmail.com>
+Date: Thu, 22 Sep 2011 16:59:20 +0800
+Subject: sound: irq: Remove IRQF_DISABLED
+
+Since commit [e58aa3d2: genirq: Run irq handlers with interrupts disabled],
+We run all interrupt handlers with interrupts disabled
+and we even check and yell when an interrupt handler
+returns with interrupts enabled (see commit [b738a50a:
+genirq: Warn when handler enables interrupts]).
+
+So now this flag is a NOOP and can be removed.
+
+Signed-off-by: Yong Zhang <yong.zhang0@gmail.com>
+Acked-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+(cherry picked from commit 88e24c3a4b30a6bd361f2b5ce602667a8161b2e8)
+
+Cherry-picked changes for:
+ sound/soc/sh/fsi.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 8e112cc..1493ebf 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -1285,7 +1285,7 @@ static int fsi_probe(struct platform_device *pdev)
+ pm_runtime_enable(&pdev->dev);
+ dev_set_drvdata(&pdev->dev, master);
+
+- ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED,
++ ret = request_irq(irq, &fsi_interrupt, 0,
+ id_entry->name, master);
+ if (ret) {
+ dev_err(&pdev->dev, "irq request err\n");
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0090-ASoC-sh-use-correct-__iomem-annotations.patch b/patches.kzm9g/0090-ASoC-sh-use-correct-__iomem-annotations.patch
new file mode 100644
index 00000000000000..306c72004b8ccd
--- /dev/null
+++ b/patches.kzm9g/0090-ASoC-sh-use-correct-__iomem-annotations.patch
@@ -0,0 +1,66 @@
+From 03f1c40d29550119518b545adacb5cba60f2f67a Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Sun, 2 Oct 2011 22:28:02 +0200
+Subject: ASoC: sh: use correct __iomem annotations
+
+This removes a few unnecessary type casts and avoids
+sparse warnings.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 00d579b1ea1200820b504a3e3cbbdb079a5ee808)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 1493ebf..a32fd16 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -210,7 +210,7 @@ struct fsi_master {
+ * basic read write function
+ */
+
+-static void __fsi_reg_write(u32 reg, u32 data)
++static void __fsi_reg_write(u32 __iomem *reg, u32 data)
+ {
+ /* valid data area is 24bit */
+ data &= 0x00ffffff;
+@@ -218,12 +218,12 @@ static void __fsi_reg_write(u32 reg, u32 data)
+ __raw_writel(data, reg);
+ }
+
+-static u32 __fsi_reg_read(u32 reg)
++static u32 __fsi_reg_read(u32 __iomem *reg)
+ {
+ return __raw_readl(reg);
+ }
+
+-static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data)
++static void __fsi_reg_mask_set(u32 __iomem *reg, u32 mask, u32 data)
+ {
+ u32 val = __fsi_reg_read(reg);
+
+@@ -250,7 +250,7 @@ static u32 _fsi_master_read(struct fsi_master *master, u32 reg)
+ unsigned long flags;
+
+ spin_lock_irqsave(&master->lock, flags);
+- ret = __fsi_reg_read((u32)(master->base + reg));
++ ret = __fsi_reg_read(master->base + reg);
+ spin_unlock_irqrestore(&master->lock, flags);
+
+ return ret;
+@@ -264,7 +264,7 @@ static void _fsi_master_mask_set(struct fsi_master *master,
+ unsigned long flags;
+
+ spin_lock_irqsave(&master->lock, flags);
+- __fsi_reg_mask_set((u32)(master->base + reg), mask, data);
++ __fsi_reg_mask_set(master->base + reg, mask, data);
+ spin_unlock_irqrestore(&master->lock, flags);
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0091-sound-Add-module.h-to-the-previously-silent-sound-us.patch b/patches.kzm9g/0091-sound-Add-module.h-to-the-previously-silent-sound-us.patch
new file mode 100644
index 00000000000000..7ec039308d0198
--- /dev/null
+++ b/patches.kzm9g/0091-sound-Add-module.h-to-the-previously-silent-sound-us.patch
@@ -0,0 +1,63 @@
+From d8dddb115d296d8980cebee2527d6b4b875265b5 Mon Sep 17 00:00:00 2001
+From: Paul Gortmaker <paul.gortmaker@windriver.com>
+Date: Fri, 15 Jul 2011 12:38:28 -0400
+Subject: sound: Add module.h to the previously silent sound users
+
+Lots of sound drivers were getting module.h via the implicit presence
+of it in <linux/device.h> but we are going to clean that up. So
+fix up those users now.
+
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+(cherry picked from commit da155d5b40587815a4397e1a69382fe2366d940b)
+
+Cherry-picked changes to:
+ sound/soc/sh/fsi-ak4642.c
+ sound/soc/sh/fsi-da7210.c
+ sound/soc/sh/fsi.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi-ak4642.c | 1 +
+ sound/soc/sh/fsi-da7210.c | 1 +
+ sound/soc/sh/fsi.c | 1 +
+ 3 files changed, 3 insertions(+)
+
+diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
+index 770a71a..dff64b9 100644
+--- a/sound/soc/sh/fsi-ak4642.c
++++ b/sound/soc/sh/fsi-ak4642.c
+@@ -10,6 +10,7 @@
+ */
+
+ #include <linux/platform_device.h>
++#include <linux/module.h>
+ #include <sound/sh_fsi.h>
+
+ struct fsi_ak4642_data {
+diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
+index 59553fd..f5586b5b 100644
+--- a/sound/soc/sh/fsi-da7210.c
++++ b/sound/soc/sh/fsi-da7210.c
+@@ -11,6 +11,7 @@
+ */
+
+ #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)
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index a32fd16..3d7016e 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -16,6 +16,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/io.h>
+ #include <linux/slab.h>
++#include <linux/module.h>
+ #include <sound/soc.h>
+ #include <sound/sh_fsi.h>
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0092-ASoC-fsi-fixup-compile-warning.patch b/patches.kzm9g/0092-ASoC-fsi-fixup-compile-warning.patch
new file mode 100644
index 00000000000000..2b2f7751945fa3
--- /dev/null
+++ b/patches.kzm9g/0092-ASoC-fsi-fixup-compile-warning.patch
@@ -0,0 +1,50 @@
+From 0d869ebdf0e3bbde84cf3a2ef58d98470f49cc07 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 31 Oct 2011 22:11:53 -0700
+Subject: ASoC: fsi: fixup compile warning
+
+This patch fixup below warning
+
+${linux}/sound/soc/sh/fsi.c:442:3:\
+ warning: passing argument 1 of '__fsi_reg_read' makes pointer\
+ from integer without a cast
+${linux}/sound/soc/sh/fsi.c:517:3: \
+ warning: passing argument 1 of '__fsi_reg_write' makes pointer\
+ from integer without a cast
+${linux}/sound/soc/sh/fsi.c:663:3: \
+ warning: passing argument 1 of '__fsi_reg_mask_set' makes pointer\
+ from integer without a cast
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 8918b843aff3236de6301b1137434d3f0bc0a0f5)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 3d7016e..e620cb1 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -235,13 +235,13 @@ static void __fsi_reg_mask_set(u32 __iomem *reg, u32 mask, u32 data)
+ }
+
+ #define fsi_reg_write(p, r, d)\
+- __fsi_reg_write((u32)(p->base + REG_##r), d)
++ __fsi_reg_write((p->base + REG_##r), d)
+
+ #define fsi_reg_read(p, r)\
+- __fsi_reg_read((u32)(p->base + REG_##r))
++ __fsi_reg_read((p->base + REG_##r))
+
+ #define fsi_reg_mask_set(p, r, m, d)\
+- __fsi_reg_mask_set((u32)(p->base + REG_##r), m, d)
++ __fsi_reg_mask_set((p->base + REG_##r), m, d)
+
+ #define fsi_master_read(p, r) _fsi_master_read(p, MST_##r)
+ #define fsi_core_read(p, r) _fsi_master_read(p, p->core->r)
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0093-ASoC-fsi-add-valid-data-position-control-support.patch b/patches.kzm9g/0093-ASoC-fsi-add-valid-data-position-control-support.patch
new file mode 100644
index 00000000000000..c1da63cccf9693
--- /dev/null
+++ b/patches.kzm9g/0093-ASoC-fsi-add-valid-data-position-control-support.patch
@@ -0,0 +1,62 @@
+From e763c47fab9fe188a39d5428a76ec75223742b2e Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 6 Nov 2011 22:05:25 -0800
+Subject: ASoC: fsi: add valid data position control support
+
+FSI2 can control valid data position, like
+package in front/back or stream mode (16bit x 2).
+But current fsi driver is assuming it was in-back.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 65ff03f4624d12ad6c19a01a0af7385eda09e4a6)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index e620cb1..99ed610 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -32,7 +32,9 @@
+ #define REG_DIDT 0x0020
+ #define REG_DODT 0x0024
+ #define REG_MUTE_ST 0x0028
++#define REG_OUT_DMAC 0x002C
+ #define REG_OUT_SEL 0x0030
++#define REG_IN_DMAC 0x0038
+
+ /* master register */
+ #define MST_CLK_RST 0x0210
+@@ -886,6 +888,8 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
+ int is_play,
+ 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;
+
+@@ -920,6 +924,17 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
+ fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
+ }
+
++ /*
++ * FIXME
++ *
++ * FSI driver assumed that data package is in-back.
++ * 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));
++ }
++
+ /* irq clear */
+ fsi_irq_disable(fsi, is_play);
+ fsi_irq_clear_status(fsi);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0094-ASoC-Constify-snd_soc_dai_ops-structs.patch b/patches.kzm9g/0094-ASoC-Constify-snd_soc_dai_ops-structs.patch
new file mode 100644
index 00000000000000..7e67376df73f57
--- /dev/null
+++ b/patches.kzm9g/0094-ASoC-Constify-snd_soc_dai_ops-structs.patch
@@ -0,0 +1,169 @@
+From 1b06d3b9ab636321f4563d07584e88193bdbb245 Mon Sep 17 00:00:00 2001
+From: Lars-Peter Clausen <lars@metafoo.de>
+Date: Wed, 23 Nov 2011 11:40:40 +0100
+Subject: ASoC: Constify snd_soc_dai_ops structs
+
+Commit 1ee46ebd("ASoC: Make the DAI ops constant in the DAI structure")
+introduced the possibility to have constant DAI ops structures, yet this is
+barley used in both existing drivers and also new drivers being submitted,
+although none of them modifies its DAI ops structure. The later is not
+surprising since existing drivers are often used as templates for new drivers.
+So this patch just constifies all existing snd_soc_dai_ops structs to eliminate
+the issue altogether.
+
+The patch was generated with the following coccinelle semantic patch:
+// <smpl>
+@@
+identifier ops;
+@@
+-struct snd_soc_dai_ops ops =
++const struct snd_soc_dai_ops ops =
+{ ... };
+// </smpl>
+
+Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 85e7652d89293a6dab42bfd31f276f8bc072d4c5)
+
+Commits:
+
+ sound/soc/atmel/atmel_ssc_dai.c
+ sound/soc/au1x/psc-ac97.c
+ sound/soc/au1x/psc-i2s.c
+ sound/soc/blackfin/bf5xx-i2s.c
+ sound/soc/blackfin/bf5xx-tdm.c
+ sound/soc/codecs/88pm860x-codec.c
+ sound/soc/codecs/ac97.c
+ sound/soc/codecs/ad1836.c
+ sound/soc/codecs/ad193x.c
+ sound/soc/codecs/adau1373.c
+ sound/soc/codecs/adau1701.c
+ sound/soc/codecs/adav80x.c
+ sound/soc/codecs/ak4104.c
+ sound/soc/codecs/ak4535.c
+ sound/soc/codecs/ak4641.c
+ sound/soc/codecs/ak4642.c
+ sound/soc/codecs/ak4671.c
+ sound/soc/codecs/alc5623.c
+ sound/soc/codecs/alc5632.c
+ sound/soc/codecs/cq93vc.c
+ sound/soc/codecs/cs4270.c
+ sound/soc/codecs/cs4271.c
+ sound/soc/codecs/cs42l51.c
+ sound/soc/codecs/cs42l73.c
+ sound/soc/codecs/da7210.c
+ sound/soc/codecs/jz4740.c
+ sound/soc/codecs/max98088.c
+ sound/soc/codecs/max98095.c
+ sound/soc/codecs/max9850.c
+ sound/soc/codecs/rt5631.c
+ sound/soc/codecs/sgtl5000.c
+ sound/soc/codecs/sn95031.c
+ sound/soc/codecs/ssm2602.c
+ sound/soc/codecs/sta32x.c
+ sound/soc/codecs/stac9766.c
+ sound/soc/codecs/tlv320aic23.c
+ sound/soc/codecs/tlv320aic26.c
+ sound/soc/codecs/tlv320aic32x4.c
+ sound/soc/codecs/tlv320aic3x.c
+ sound/soc/codecs/tlv320dac33.c
+ sound/soc/codecs/twl4030.c
+ sound/soc/codecs/twl6040.c
+ sound/soc/codecs/uda134x.c
+ sound/soc/codecs/uda1380.c
+ sound/soc/codecs/wl1273.c
+ sound/soc/codecs/wm5100.c
+ sound/soc/codecs/wm8350.c
+ sound/soc/codecs/wm8400.c
+ sound/soc/codecs/wm8510.c
+ sound/soc/codecs/wm8523.c
+ sound/soc/codecs/wm8580.c
+ sound/soc/codecs/wm8711.c
+ sound/soc/codecs/wm8728.c
+ sound/soc/codecs/wm8731.c
+ sound/soc/codecs/wm8737.c
+ sound/soc/codecs/wm8741.c
+ sound/soc/codecs/wm8750.c
+ sound/soc/codecs/wm8753.c
+ sound/soc/codecs/wm8770.c
+ sound/soc/codecs/wm8776.c
+ sound/soc/codecs/wm8804.c
+ sound/soc/codecs/wm8900.c
+ sound/soc/codecs/wm8903.c
+ sound/soc/codecs/wm8904.c
+ sound/soc/codecs/wm8940.c
+ sound/soc/codecs/wm8955.c
+ sound/soc/codecs/wm8960.c
+ sound/soc/codecs/wm8961.c
+ sound/soc/codecs/wm8962.c
+ sound/soc/codecs/wm8971.c
+ sound/soc/codecs/wm8974.c
+ sound/soc/codecs/wm8978.c
+ sound/soc/codecs/wm8983.c
+ sound/soc/codecs/wm8985.c
+ sound/soc/codecs/wm8988.c
+ sound/soc/codecs/wm8990.c
+ sound/soc/codecs/wm8991.c
+ sound/soc/codecs/wm8993.c
+ sound/soc/codecs/wm8994.c
+ sound/soc/codecs/wm8995.c
+ sound/soc/codecs/wm8996.c
+ sound/soc/codecs/wm9081.c
+ sound/soc/codecs/wm9705.c
+ sound/soc/codecs/wm9712.c
+ sound/soc/codecs/wm9713.c
+ sound/soc/davinci/davinci-i2s.c
+ sound/soc/davinci/davinci-mcasp.c
+ sound/soc/davinci/davinci-vcif.c
+ sound/soc/ep93xx/ep93xx-ac97.c
+ sound/soc/ep93xx/ep93xx-i2s.c
+ sound/soc/fsl/fsl_ssi.c
+ sound/soc/fsl/mpc5200_psc_ac97.c
+ sound/soc/fsl/mpc5200_psc_i2s.c
+ sound/soc/imx/imx-ssi.c
+ sound/soc/jz4740/jz4740-i2s.c
+ sound/soc/kirkwood/kirkwood-i2s.c
+ sound/soc/mxs/mxs-saif.c
+ sound/soc/nuc900/nuc900-ac97.c
+ sound/soc/omap/ams-delta.c
+ sound/soc/omap/omap-hdmi.c
+ sound/soc/omap/omap-mcbsp.c
+ sound/soc/omap/omap-mcpdm.c
+ sound/soc/pxa/pxa-ssp.c
+ sound/soc/pxa/pxa2xx-ac97.c
+ sound/soc/pxa/pxa2xx-i2s.c
+ sound/soc/s6000/s6000-i2s.c
+ sound/soc/samsung/ac97.c
+ sound/soc/samsung/i2s.c
+ sound/soc/samsung/pcm.c
+ sound/soc/samsung/s3c2412-i2s.c
+ sound/soc/samsung/s3c24xx-i2s.c
+ sound/soc/samsung/spdif.c
+ sound/soc/sh/hac.c
+ sound/soc/sh/siu_dai.c
+ sound/soc/sh/ssi.c
+ sound/soc/soc-core.c
+ sound/soc/tegra/tegra_i2s.c
+ sound/soc/tegra/tegra_spdif.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 99ed610..aa30330 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -1096,7 +1096,7 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
+ return ret;
+ }
+
+-static struct snd_soc_dai_ops fsi_dai_ops = {
++static const struct snd_soc_dai_ops fsi_dai_ops = {
+ .startup = fsi_dai_startup,
+ .shutdown = fsi_dai_shutdown,
+ .trigger = fsi_dai_trigger,
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0095-ASoC-fsi-ak4642-modify-specification-method-of-FSI-a.patch b/patches.kzm9g/0095-ASoC-fsi-ak4642-modify-specification-method-of-FSI-a.patch
new file mode 100644
index 00000000000000..4989859efecccf
--- /dev/null
+++ b/patches.kzm9g/0095-ASoC-fsi-ak4642-modify-specification-method-of-FSI-a.patch
@@ -0,0 +1,272 @@
+From 8d40a58c9d7f03f7545bd01905bbe59ef789230a Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Wed, 23 Nov 2011 16:55:34 -0800
+Subject: ASoC: fsi-ak4642: modify specification method of FSI / ak464x
+
+Current fsi-ak4642 was using id_entry name in order to specify
+FSI port and ak464x codec.
+But it was no sense, no flexibility.
+Platform can specify FSI/ak464x pair by this patch.
+
+Acked-by: Paul Mundt <lethal@linux-sh.org>
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 45f3121615b2b354f7d95d30f795bc5fe0043e92)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-ap4evb.c | 15 ++++-
+ arch/arm/mach-shmobile/board-mackerel.c | 14 +++-
+ arch/sh/boards/mach-se/7724/setup.c | 14 +++-
+ include/sound/sh_fsi.h | 12 ++++
+ sound/soc/sh/fsi-ak4642.c | 114 +++-----------------------------
+ 5 files changed, 63 insertions(+), 106 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
+index 3cbf5bf..59f0d2c 100644
+--- a/arch/arm/mach-shmobile/board-ap4evb.c
++++ b/arch/arm/mach-shmobile/board-ap4evb.c
+@@ -757,9 +757,22 @@ static struct platform_device fsi_device = {
+ },
+ };
+
++static struct fsi_ak4642_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,
++};
++
+ static struct platform_device fsi_ak4643_device = {
+- .name = "sh_fsi2_a_ak4643",
++ .name = "fsi-ak4642-audio",
++ .dev = {
++ .platform_data = &fsi_info,
++ },
+ };
++
+ static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
+ .icb[0] = {
+ .meram_size = 0x100,
+diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
+index 70eca5a..c2faf11 100644
+--- a/arch/arm/mach-shmobile/board-mackerel.c
++++ b/arch/arm/mach-shmobile/board-mackerel.c
+@@ -970,8 +970,20 @@ static struct platform_device fsi_device = {
+ },
+ };
+
++static struct fsi_ak4642_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,
++};
++
+ static struct platform_device fsi_ak4643_device = {
+- .name = "sh_fsi2_a_ak4643",
++ .name = "fsi-ak4642-audio",
++ .dev = {
++ .platform_data = &fsi2_ak4643_info,
++ },
+ };
+
+ /*
+diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
+index 1342feb..abc4d12 100644
+--- a/arch/sh/boards/mach-se/7724/setup.c
++++ b/arch/sh/boards/mach-se/7724/setup.c
+@@ -314,8 +314,20 @@ static struct platform_device fsi_device = {
+ },
+ };
+
++static struct fsi_ak4642_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,
++};
++
+ static struct platform_device fsi_ak4642_device = {
+- .name = "sh_fsi_a_ak4642",
++ .name = "fsi-ak4642-audio",
++ .dev = {
++ .platform_data = &fsi_ak4642_info,
++ },
+ };
+
+ /* KEYSC in SoC (Needs SW33-2 set to ON) */
+diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h
+index 9a155f9..9b1aaca 100644
+--- a/include/sound/sh_fsi.h
++++ b/include/sound/sh_fsi.h
+@@ -78,4 +78,16 @@ struct sh_fsi_platform_info {
+ int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
+ };
+
++/*
++ * 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/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
+index dff64b9..11d2d7f 100644
+--- a/sound/soc/sh/fsi-ak4642.c
++++ b/sound/soc/sh/fsi-ak4642.c
+@@ -58,27 +58,23 @@ static struct platform_device *fsi_snd_device;
+ static int fsi_ak4642_probe(struct platform_device *pdev)
+ {
+ int ret = -ENOMEM;
+- const struct platform_device_id *id_entry;
+- struct fsi_ak4642_data *pdata;
++ struct fsi_ak4642_info *pinfo = pdev->dev.platform_data;
+
+- id_entry = pdev->id_entry;
+- if (!id_entry) {
+- dev_err(&pdev->dev, "unknown fsi ak4642\n");
+- return -ENODEV;
++ if (!pinfo) {
++ dev_err(&pdev->dev, "no info for fsi ak4642\n");
++ goto out;
+ }
+
+- pdata = (struct fsi_ak4642_data *)id_entry->driver_data;
+-
+- fsi_snd_device = platform_device_alloc("soc-audio", pdata->id);
++ fsi_snd_device = platform_device_alloc("soc-audio", pinfo->id);
+ if (!fsi_snd_device)
+ goto out;
+
+- fsi_dai_link.name = pdata->name;
+- fsi_dai_link.stream_name = pdata->name;
+- fsi_dai_link.cpu_dai_name = pdata->cpu_dai;
+- fsi_dai_link.platform_name = pdata->platform;
+- fsi_dai_link.codec_name = pdata->codec;
+- fsi_soc_card.name = pdata->card;
++ 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);
+@@ -96,100 +92,12 @@ static int fsi_ak4642_remove(struct platform_device *pdev)
+ return 0;
+ }
+
+-static struct fsi_ak4642_data fsi_a_ak4642 = {
+- .name = "AK4642",
+- .card = "FSIA-AK4642",
+- .cpu_dai = "fsia-dai",
+- .codec = "ak4642-codec.0-0012",
+- .platform = "sh_fsi.0",
+- .id = FSI_PORT_A,
+-};
+-
+-static struct fsi_ak4642_data fsi_b_ak4642 = {
+- .name = "AK4642",
+- .card = "FSIB-AK4642",
+- .cpu_dai = "fsib-dai",
+- .codec = "ak4642-codec.0-0012",
+- .platform = "sh_fsi.0",
+- .id = FSI_PORT_B,
+-};
+-
+-static struct fsi_ak4642_data fsi_a_ak4643 = {
+- .name = "AK4643",
+- .card = "FSIA-AK4643",
+- .cpu_dai = "fsia-dai",
+- .codec = "ak4642-codec.0-0013",
+- .platform = "sh_fsi.0",
+- .id = FSI_PORT_A,
+-};
+-
+-static struct fsi_ak4642_data fsi_b_ak4643 = {
+- .name = "AK4643",
+- .card = "FSIB-AK4643",
+- .cpu_dai = "fsib-dai",
+- .codec = "ak4642-codec.0-0013",
+- .platform = "sh_fsi.0",
+- .id = FSI_PORT_B,
+-};
+-
+-static struct fsi_ak4642_data fsi2_a_ak4642 = {
+- .name = "AK4642",
+- .card = "FSI2A-AK4642",
+- .cpu_dai = "fsia-dai",
+- .codec = "ak4642-codec.0-0012",
+- .platform = "sh_fsi2",
+- .id = FSI_PORT_A,
+-};
+-
+-static struct fsi_ak4642_data fsi2_b_ak4642 = {
+- .name = "AK4642",
+- .card = "FSI2B-AK4642",
+- .cpu_dai = "fsib-dai",
+- .codec = "ak4642-codec.0-0012",
+- .platform = "sh_fsi2",
+- .id = FSI_PORT_B,
+-};
+-
+-static struct fsi_ak4642_data fsi2_a_ak4643 = {
+- .name = "AK4643",
+- .card = "FSI2A-AK4643",
+- .cpu_dai = "fsia-dai",
+- .codec = "ak4642-codec.0-0013",
+- .platform = "sh_fsi2",
+- .id = FSI_PORT_A,
+-};
+-
+-static struct fsi_ak4642_data fsi2_b_ak4643 = {
+- .name = "AK4643",
+- .card = "FSI2B-AK4643",
+- .cpu_dai = "fsib-dai",
+- .codec = "ak4642-codec.0-0013",
+- .platform = "sh_fsi2",
+- .id = FSI_PORT_B,
+-};
+-
+-static struct platform_device_id fsi_id_table[] = {
+- /* FSI */
+- { "sh_fsi_a_ak4642", (kernel_ulong_t)&fsi_a_ak4642 },
+- { "sh_fsi_b_ak4642", (kernel_ulong_t)&fsi_b_ak4642 },
+- { "sh_fsi_a_ak4643", (kernel_ulong_t)&fsi_a_ak4643 },
+- { "sh_fsi_b_ak4643", (kernel_ulong_t)&fsi_b_ak4643 },
+-
+- /* FSI 2 */
+- { "sh_fsi2_a_ak4642", (kernel_ulong_t)&fsi2_a_ak4642 },
+- { "sh_fsi2_b_ak4642", (kernel_ulong_t)&fsi2_b_ak4642 },
+- { "sh_fsi2_a_ak4643", (kernel_ulong_t)&fsi2_a_ak4643 },
+- { "sh_fsi2_b_ak4643", (kernel_ulong_t)&fsi2_b_ak4643 },
+- {},
+-};
+-
+ static struct platform_driver fsi_ak4642 = {
+ .driver = {
+ .name = "fsi-ak4642-audio",
+ },
+ .probe = fsi_ak4642_probe,
+ .remove = fsi_ak4642_remove,
+- .id_table = fsi_id_table,
+ };
+
+ static int __init fsi_ak4642_init(void)
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0096-ASoC-Convert-sh-directory-to-module_platform_driver.patch b/patches.kzm9g/0096-ASoC-Convert-sh-directory-to-module_platform_driver.patch
new file mode 100644
index 00000000000000..2d3ef26867c324
--- /dev/null
+++ b/patches.kzm9g/0096-ASoC-Convert-sh-directory-to-module_platform_driver.patch
@@ -0,0 +1,100 @@
+From 2233778f0f0d254f7583d8de6e7e2a0cdacd828a Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@gmail.com>
+Date: Fri, 25 Nov 2011 10:15:07 +0800
+Subject: ASoC: Convert sh directory to module_platform_driver
+
+Factor out some boilerplate code.
+
+Signed-off-by: Axel Lin <axel.lin@gmail.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit cb5e87387cfa8172faca36682e2df069b006efdf)
+
+Conflicts:
+
+ sound/soc/sh/dma-sh7760.c
+ sound/soc/sh/hac.c
+ sound/soc/sh/siu_dai.c
+ sound/soc/sh/ssi.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi-ak4642.c | 13 +------------
+ sound/soc/sh/fsi-hdmi.c | 13 +------------
+ sound/soc/sh/fsi.c | 13 +------------
+ 3 files changed, 3 insertions(+), 36 deletions(-)
+
+diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
+index 11d2d7f..eb52778 100644
+--- a/sound/soc/sh/fsi-ak4642.c
++++ b/sound/soc/sh/fsi-ak4642.c
+@@ -100,18 +100,7 @@ static struct platform_driver fsi_ak4642 = {
+ .remove = fsi_ak4642_remove,
+ };
+
+-static int __init fsi_ak4642_init(void)
+-{
+- return platform_driver_register(&fsi_ak4642);
+-}
+-
+-static void __exit fsi_ak4642_exit(void)
+-{
+- platform_driver_unregister(&fsi_ak4642);
+-}
+-
+-module_init(fsi_ak4642_init);
+-module_exit(fsi_ak4642_exit);
++module_platform_driver(fsi_ak4642);
+
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION("Generic SH4 FSI-AK4642 sound card");
+diff --git a/sound/soc/sh/fsi-hdmi.c b/sound/soc/sh/fsi-hdmi.c
+index d3d9fd8..31c4806 100644
+--- a/sound/soc/sh/fsi-hdmi.c
++++ b/sound/soc/sh/fsi-hdmi.c
+@@ -109,18 +109,7 @@ static struct platform_driver fsi_hdmi = {
+ .id_table = fsi_id_table,
+ };
+
+-static int __init fsi_hdmi_init(void)
+-{
+- return platform_driver_register(&fsi_hdmi);
+-}
+-
+-static void __exit fsi_hdmi_exit(void)
+-{
+- platform_driver_unregister(&fsi_hdmi);
+-}
+-
+-module_init(fsi_hdmi_init);
+-module_exit(fsi_hdmi_exit);
++module_platform_driver(fsi_hdmi);
+
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION("Generic SH4 FSI-HDMI sound card");
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index aa30330..a27c306 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -1468,18 +1468,7 @@ static struct platform_driver fsi_driver = {
+ .id_table = fsi_id_table,
+ };
+
+-static int __init fsi_mobile_init(void)
+-{
+- return platform_driver_register(&fsi_driver);
+-}
+-
+-static void __exit fsi_mobile_exit(void)
+-{
+- platform_driver_unregister(&fsi_driver);
+-}
+-
+-module_init(fsi_mobile_init);
+-module_exit(fsi_mobile_exit);
++module_platform_driver(fsi_driver);
+
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION("SuperH onchip FSI audio driver");
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0097-ASoC-Use-core-pm_runtime-callbacks-for-fsi.patch b/patches.kzm9g/0097-ASoC-Use-core-pm_runtime-callbacks-for-fsi.patch
new file mode 100644
index 00000000000000..73ea9f9eb091b1
--- /dev/null
+++ b/patches.kzm9g/0097-ASoC-Use-core-pm_runtime-callbacks-for-fsi.patch
@@ -0,0 +1,41 @@
+From 8ed88c1062c61083442b13d3a30c68594fe8e8bb Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Sat, 3 Dec 2011 20:22:18 +0000
+Subject: ASoC: Use core pm_runtime callbacks for fsi
+
+Now that the core holds a pm_runtime reference to the device while the
+link is active there is no need for the driver to do so.
+
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 27f478a65ff7b67b843250f0a2d1e8b306bf57b6)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index a27c306..db6c89a 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -893,8 +893,6 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
+ u32 flags = fsi_get_info_flags(fsi);
+ u32 data = 0;
+
+- pm_runtime_get_sync(dev);
+-
+ /* clock setting */
+ if (fsi_is_clk_master(fsi))
+ data = DIMD | DOMD;
+@@ -951,8 +949,6 @@ static void fsi_hw_shutdown(struct fsi_priv *fsi,
+ {
+ if (fsi_is_clk_master(fsi))
+ fsi_set_master_clk(dev, fsi, fsi->rate, 0);
+-
+- pm_runtime_put_sync(dev);
+ }
+
+ static int fsi_dai_startup(struct snd_pcm_substream *substream,
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0098-ASoC-sh-Add-.owner-to-struct-snd_soc_card.patch b/patches.kzm9g/0098-ASoC-sh-Add-.owner-to-struct-snd_soc_card.patch
new file mode 100644
index 00000000000000..202ef0fdaad866
--- /dev/null
+++ b/patches.kzm9g/0098-ASoC-sh-Add-.owner-to-struct-snd_soc_card.patch
@@ -0,0 +1,67 @@
+From 5b12148992d0314cb7380b8112fda136fdfcea21 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@gmail.com>
+Date: Fri, 23 Dec 2011 14:53:32 +0800
+Subject: ASoC: sh: Add .owner to struct snd_soc_card
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add missing .owner of struct snd_soc_card. This prevents the module from being
+removed from underneath its users.
+
+Reported-by: Lothar Waßmann <LW@KARO-electronics.de>
+Signed-off-by: Axel Lin <axel.lin@gmail.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 4a7042e59908231fc046aac88bd98454d886052d)
+
+Conflicts:
+
+ sound/soc/sh/migor.c
+ sound/soc/sh/sh7760-ac97.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi-ak4642.c | 1 +
+ sound/soc/sh/fsi-da7210.c | 1 +
+ sound/soc/sh/fsi-hdmi.c | 1 +
+ 3 files changed, 3 insertions(+)
+
+diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
+index eb52778..97f540a 100644
+--- a/sound/soc/sh/fsi-ak4642.c
++++ b/sound/soc/sh/fsi-ak4642.c
+@@ -49,6 +49,7 @@ static struct snd_soc_dai_link fsi_dai_link = {
+ };
+
+ static struct snd_soc_card fsi_soc_card = {
++ .owner = THIS_MODULE,
+ .dai_link = &fsi_dai_link,
+ .num_links = 1,
+ };
+diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
+index f5586b5b..1dd3354 100644
+--- a/sound/soc/sh/fsi-da7210.c
++++ b/sound/soc/sh/fsi-da7210.c
+@@ -44,6 +44,7 @@ static struct snd_soc_dai_link fsi_da7210_dai = {
+
+ static struct snd_soc_card fsi_soc_card = {
+ .name = "FSI-DA7210",
++ .owner = THIS_MODULE,
+ .dai_link = &fsi_da7210_dai,
+ .num_links = 1,
+ };
+diff --git a/sound/soc/sh/fsi-hdmi.c b/sound/soc/sh/fsi-hdmi.c
+index 31c4806..edb4359 100644
+--- a/sound/soc/sh/fsi-hdmi.c
++++ b/sound/soc/sh/fsi-hdmi.c
+@@ -38,6 +38,7 @@ static struct snd_soc_dai_link fsi_dai_link = {
+ };
+
+ static struct snd_soc_card fsi_soc_card = {
++ .owner = THIS_MODULE,
+ .dai_link = &fsi_dai_link,
+ .num_links = 1,
+ };
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0099-ASoC-fsi-Remove-unneeded-empty-runtime-PM-callbacks.patch b/patches.kzm9g/0099-ASoC-fsi-Remove-unneeded-empty-runtime-PM-callbacks.patch
new file mode 100644
index 00000000000000..17080d74156a09
--- /dev/null
+++ b/patches.kzm9g/0099-ASoC-fsi-Remove-unneeded-empty-runtime-PM-callbacks.patch
@@ -0,0 +1,47 @@
+From 9d4fdf34b1a908b8e82f8eaede7368f5a7eaed49 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Wed, 25 Jan 2012 19:55:56 +0000
+Subject: ASoC: fsi: Remove unneeded empty runtime PM callbacks
+
+The runtime PM core no longer requires any callbacks so don't provide
+empty ones for it any more.
+
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit bc122e34469de6ec4b7ca96d3a41724f9e4b1cf4)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 14 --------------
+ 1 file changed, 14 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index db6c89a..3241e5b 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -1408,23 +1408,9 @@ static int fsi_resume(struct device *dev)
+ return 0;
+ }
+
+-static int fsi_runtime_nop(struct device *dev)
+-{
+- /* Runtime PM callback shared between ->runtime_suspend()
+- * and ->runtime_resume(). Simply returns success.
+- *
+- * This driver re-initializes all registers after
+- * pm_runtime_get_sync() anyway so there is no need
+- * to save and restore registers here.
+- */
+- return 0;
+-}
+-
+ static struct dev_pm_ops fsi_pm_ops = {
+ .suspend = fsi_suspend,
+ .resume = fsi_resume,
+- .runtime_suspend = fsi_runtime_nop,
+- .runtime_resume = fsi_runtime_nop,
+ };
+
+ static struct fsi_core fsi1_core = {
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0100-ASoC-fsi-reduce-runtime-calculation-by-using-pre-set.patch b/patches.kzm9g/0100-ASoC-fsi-reduce-runtime-calculation-by-using-pre-set.patch
new file mode 100644
index 00000000000000..efef18df2ab60d
--- /dev/null
+++ b/patches.kzm9g/0100-ASoC-fsi-reduce-runtime-calculation-by-using-pre-set.patch
@@ -0,0 +1,81 @@
+From cb292ccc4561167afa92984b935da321e74f7b6c Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:50:09 -0800
+Subject: ASoC: fsi: reduce runtime calculation by using pre-setting
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit c1e6f10ea94715f00cce4c9aaf7fc91fb34ec52d)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 3241e5b..0d78740 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -167,6 +167,7 @@ struct fsi_stream {
+ int buff_sample_pos; /* sample position of ALSA buffer */
+ int period_samples; /* sample number / 1 period */
+ int period_pos; /* current period position */
++ int sample_width; /* sample width */
+
+ int uerr_num;
+ int oerr_num;
+@@ -406,6 +407,7 @@ static void fsi_stream_push(struct fsi_priv *fsi,
+ io->buff_sample_pos = 0;
+ io->period_samples = fsi_frame2sample(fsi, runtime->period_size);
+ io->period_pos = 0;
++ io->sample_width = samples_to_bytes(runtime, 1);
+ io->oerr_num = -1; /* ignore 1st err */
+ io->uerr_num = -1; /* ignore 1st err */
+ spin_unlock_irqrestore(&master->lock, flags);
+@@ -431,6 +433,7 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
+ io->buff_sample_pos = 0;
+ io->period_samples = 0;
+ io->period_pos = 0;
++ io->sample_width = 0;
+ io->oerr_num = 0;
+ io->uerr_num = 0;
+ spin_unlock_irqrestore(&master->lock, flags);
+@@ -752,7 +755,6 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
+ int is_play = fsi_stream_is_play(stream);
+ struct fsi_stream *io = fsi_get_stream(fsi, is_play);
+ int sample_residues;
+- int sample_width;
+ int samples;
+ int samples_max;
+ int over_period;
+@@ -780,9 +782,6 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
+ io->buff_sample_pos = 0;
+ }
+
+- /* get 1 sample data width */
+- sample_width = samples_to_bytes(runtime, 1);
+-
+ /* get number of residue samples */
+ sample_residues = io->buff_sample_capa - io->buff_sample_pos;
+
+@@ -798,7 +797,7 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
+
+ samples = sample_residues;
+
+- switch (sample_width) {
++ switch (io->sample_width) {
+ case 2:
+ fn = fsi_dma_soft_push16;
+ break;
+@@ -818,7 +817,7 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
+ samples_max = sample_residues;
+ samples = fsi_get_current_fifo_samples(fsi, is_play);
+
+- switch (sample_width) {
++ switch (io->sample_width) {
+ case 2:
+ fn = fsi_dma_soft_pop16;
+ break;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0101-ASoC-fsi-tidyup-fsi_stream_xx-functions-were-gathere.patch b/patches.kzm9g/0101-ASoC-fsi-tidyup-fsi_stream_xx-functions-were-gathere.patch
new file mode 100644
index 00000000000000..9424b5e2f2a430
--- /dev/null
+++ b/patches.kzm9g/0101-ASoC-fsi-tidyup-fsi_stream_xx-functions-were-gathere.patch
@@ -0,0 +1,204 @@
+From 679d4975b9babdd83189da8b5f5d90f1a60a84d0 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:50:35 -0800
+Subject: ASoC: fsi: tidyup: fsi_stream_xx() functions were gathered
+
+This patch gathered fsi_stream_xxx() functions in order to make it readable.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 4e62d84d9da5190c303d6408180fbfee414d25bc)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 115 ++++++++++++++++++++++++++---------------------------
+ 1 file changed, 57 insertions(+), 58 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 0d78740..162416e 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -338,22 +338,6 @@ static u32 fsi_get_info_flags(struct fsi_priv *fsi)
+ master->info->portb_flags;
+ }
+
+-static inline int fsi_stream_is_play(int stream)
+-{
+- return stream == SNDRV_PCM_STREAM_PLAYBACK;
+-}
+-
+-static inline int fsi_is_play(struct snd_pcm_substream *substream)
+-{
+- return fsi_stream_is_play(substream->stream);
+-}
+-
+-static inline struct fsi_stream *fsi_get_stream(struct fsi_priv *fsi,
+- int is_play)
+-{
+- return is_play ? &fsi->playback : &fsi->capture;
+-}
+-
+ static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play)
+ {
+ int is_porta = fsi_is_port_a(fsi);
+@@ -377,10 +361,60 @@ static int fsi_sample2frame(struct fsi_priv *fsi, int samples)
+ return samples / fsi->chan_num;
+ }
+
++static int fsi_get_current_fifo_samples(struct fsi_priv *fsi, int is_play)
++{
++ u32 status;
++ int frames;
++
++ status = is_play ?
++ fsi_reg_read(fsi, DOFF_ST) :
++ fsi_reg_read(fsi, DIFF_ST);
++
++ frames = 0x1ff & (status >> 8);
++
++ return fsi_frame2sample(fsi, frames);
++}
++
++static void fsi_count_fifo_err(struct fsi_priv *fsi)
++{
++ u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
++ u32 istatus = fsi_reg_read(fsi, DIFF_ST);
++
++ if (ostatus & ERR_OVER)
++ fsi->playback.oerr_num++;
++
++ if (ostatus & ERR_UNDER)
++ fsi->playback.uerr_num++;
++
++ if (istatus & ERR_OVER)
++ fsi->capture.oerr_num++;
++
++ if (istatus & ERR_UNDER)
++ fsi->capture.uerr_num++;
++
++ fsi_reg_write(fsi, DOFF_ST, 0);
++ fsi_reg_write(fsi, DIFF_ST, 0);
++}
++
++/*
++ * fsi_stream_xx() function
++ */
++#define fsi_is_play(substream) fsi_stream_is_play(substream->stream)
++static inline int fsi_stream_is_play(int stream)
++{
++ return stream == SNDRV_PCM_STREAM_PLAYBACK;
++}
++
++static inline struct fsi_stream *fsi_stream_get(struct fsi_priv *fsi,
++ int is_play)
++{
++ return is_play ? &fsi->playback : &fsi->capture;
++}
++
+ static int fsi_stream_is_working(struct fsi_priv *fsi,
+ int is_play)
+ {
+- struct fsi_stream *io = fsi_get_stream(fsi, is_play);
++ struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+ struct fsi_master *master = fsi_get_master(fsi);
+ unsigned long flags;
+ int ret;
+@@ -396,7 +430,7 @@ static void fsi_stream_push(struct fsi_priv *fsi,
+ int is_play,
+ struct snd_pcm_substream *substream)
+ {
+- struct fsi_stream *io = fsi_get_stream(fsi, is_play);
++ struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct fsi_master *master = fsi_get_master(fsi);
+ unsigned long flags;
+@@ -415,7 +449,7 @@ static void fsi_stream_push(struct fsi_priv *fsi,
+
+ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
+ {
+- struct fsi_stream *io = fsi_get_stream(fsi, is_play);
++ struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+ struct snd_soc_dai *dai = fsi_get_dai(io->substream);
+ struct fsi_master *master = fsi_get_master(fsi);
+ unsigned long flags;
+@@ -439,41 +473,6 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
+ spin_unlock_irqrestore(&master->lock, flags);
+ }
+
+-static int fsi_get_current_fifo_samples(struct fsi_priv *fsi, int is_play)
+-{
+- u32 status;
+- int frames;
+-
+- status = is_play ?
+- fsi_reg_read(fsi, DOFF_ST) :
+- fsi_reg_read(fsi, DIFF_ST);
+-
+- frames = 0x1ff & (status >> 8);
+-
+- return fsi_frame2sample(fsi, frames);
+-}
+-
+-static void fsi_count_fifo_err(struct fsi_priv *fsi)
+-{
+- u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
+- u32 istatus = fsi_reg_read(fsi, DIFF_ST);
+-
+- if (ostatus & ERR_OVER)
+- fsi->playback.oerr_num++;
+-
+- if (ostatus & ERR_UNDER)
+- fsi->playback.uerr_num++;
+-
+- if (istatus & ERR_OVER)
+- fsi->capture.oerr_num++;
+-
+- if (istatus & ERR_UNDER)
+- fsi->capture.uerr_num++;
+-
+- fsi_reg_write(fsi, DOFF_ST, 0);
+- fsi_reg_write(fsi, DIFF_ST, 0);
+-}
+-
+ /*
+ * dma function
+ */
+@@ -481,7 +480,7 @@ static void fsi_count_fifo_err(struct fsi_priv *fsi)
+ static u8 *fsi_dma_get_area(struct fsi_priv *fsi, int stream)
+ {
+ int is_play = fsi_stream_is_play(stream);
+- struct fsi_stream *io = fsi_get_stream(fsi, is_play);
++ struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+ struct snd_pcm_runtime *runtime = io->substream->runtime;
+
+ return runtime->dma_area +
+@@ -698,7 +697,7 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
+ struct device *dev)
+ {
+ struct fsi_master *master = fsi_get_master(fsi);
+- struct fsi_stream *io = fsi_get_stream(fsi, is_play);
++ struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+ u32 shift, i;
+ int frame_capa;
+
+@@ -753,7 +752,7 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
+ struct snd_pcm_runtime *runtime;
+ struct snd_pcm_substream *substream = NULL;
+ int is_play = fsi_stream_is_play(stream);
+- struct fsi_stream *io = fsi_get_stream(fsi, is_play);
++ struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+ int sample_residues;
+ int samples;
+ int samples_max;
+@@ -1150,7 +1149,7 @@ static int fsi_hw_free(struct snd_pcm_substream *substream)
+ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
+ {
+ struct fsi_priv *fsi = fsi_get_priv(substream);
+- struct fsi_stream *io = fsi_get_stream(fsi, fsi_is_play(substream));
++ struct fsi_stream *io = fsi_stream_get(fsi, fsi_is_play(substream));
+ int samples_pos = io->buff_sample_pos - 1;
+
+ if (samples_pos < 0)
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0102-ASoC-fsi-data-push-pop-calculation-part-was-divided.patch b/patches.kzm9g/0102-ASoC-fsi-data-push-pop-calculation-part-was-divided.patch
new file mode 100644
index 00000000000000..e675f10253a609
--- /dev/null
+++ b/patches.kzm9g/0102-ASoC-fsi-data-push-pop-calculation-part-was-divided.patch
@@ -0,0 +1,159 @@
+From 3e4950e7f7503851e01dbdf5547513567442ac56 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:50:59 -0800
+Subject: ASoC: fsi: data push/pop calculation part was divided
+
+Next transfer data size of "push" and "pop" had calculated on shared function.
+But it was not readable code.
+This patch divided it into for push, and for pop.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 376cf38a90507f82d22b951b7776557aefe6109c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 104 +++++++++++++++++++++++------------------------------
+ 1 file changed, 45 insertions(+), 59 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 162416e..cbb5643 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -747,17 +747,14 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
+ }
+ }
+
+-static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
++static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, struct fsi_stream *io,
++ void (*run16)(struct fsi_priv *fsi, int size),
++ void (*run32)(struct fsi_priv *fsi, int size),
++ int samples)
+ {
+ struct snd_pcm_runtime *runtime;
+- struct snd_pcm_substream *substream = NULL;
+- int is_play = fsi_stream_is_play(stream);
+- struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+- int sample_residues;
+- int samples;
+- int samples_max;
++ struct snd_pcm_substream *substream;
+ int over_period;
+- void (*fn)(struct fsi_priv *fsi, int size);
+
+ if (!fsi ||
+ !io->substream ||
+@@ -781,57 +778,17 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
+ io->buff_sample_pos = 0;
+ }
+
+- /* get number of residue samples */
+- sample_residues = io->buff_sample_capa - io->buff_sample_pos;
+-
+- if (is_play) {
+- /*
+- * for play-back
+- *
+- * samples_max : number of FSI fifo free samples space
+- * samples : number of ALSA residue samples
+- */
+- samples_max = io->fifo_sample_capa;
+- samples_max -= fsi_get_current_fifo_samples(fsi, is_play);
+-
+- samples = sample_residues;
+-
+- switch (io->sample_width) {
+- case 2:
+- fn = fsi_dma_soft_push16;
+- break;
+- case 4:
+- fn = fsi_dma_soft_push32;
+- break;
+- default:
+- return -EINVAL;
+- }
+- } else {
+- /*
+- * for capture
+- *
+- * samples_max : number of ALSA free samples space
+- * samples : number of samples in FSI fifo
+- */
+- samples_max = sample_residues;
+- samples = fsi_get_current_fifo_samples(fsi, is_play);
+-
+- switch (io->sample_width) {
+- case 2:
+- fn = fsi_dma_soft_pop16;
+- break;
+- case 4:
+- fn = fsi_dma_soft_pop32;
+- break;
+- default:
+- return -EINVAL;
+- }
++ switch (io->sample_width) {
++ case 2:
++ run16(fsi, samples);
++ break;
++ case 4:
++ run32(fsi, samples);
++ break;
++ default:
++ return -EINVAL;
+ }
+
+- samples = min(samples, samples_max);
+-
+- fn(fsi, samples);
+-
+ /* update buff_sample_pos */
+ io->buff_sample_pos += samples;
+
+@@ -843,12 +800,41 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
+
+ static int fsi_data_pop(struct fsi_priv *fsi)
+ {
+- return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_CAPTURE);
++ int is_play = fsi_stream_is_play(SNDRV_PCM_STREAM_CAPTURE);
++ int sample_residues; /* samples in FSI fifo */
++ int sample_space; /* ALSA free samples space */
++ int samples;
++ struct fsi_stream *io = fsi_stream_get(fsi, is_play);
++
++ sample_residues = fsi_get_current_fifo_samples(fsi, is_play);
++ sample_space = io->buff_sample_capa - io->buff_sample_pos;
++
++ samples = min(sample_residues, sample_space);
++
++ return fsi_fifo_data_ctrl(fsi, io,
++ fsi_dma_soft_pop16,
++ fsi_dma_soft_pop32,
++ samples);
+ }
+
+ static int fsi_data_push(struct fsi_priv *fsi)
+ {
+- return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_PLAYBACK);
++ int is_play = fsi_stream_is_play(SNDRV_PCM_STREAM_PLAYBACK);
++ int sample_residues; /* ALSA residue samples */
++ int sample_space; /* FSI fifo free samples space */
++ int samples;
++ struct fsi_stream *io = fsi_stream_get(fsi, is_play);
++
++ sample_residues = io->buff_sample_capa - io->buff_sample_pos;
++ sample_space = io->fifo_sample_capa -
++ fsi_get_current_fifo_samples(fsi, is_play);
++
++ samples = min(sample_residues, sample_space);
++
++ return fsi_fifo_data_ctrl(fsi, io,
++ fsi_dma_soft_push16,
++ fsi_dma_soft_push32,
++ samples);
+ }
+
+ static irqreturn_t fsi_interrupt(int irq, void *data)
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0103-ASoC-fsi-rename-fsi_dma_soft_xxx-to-fsi_pio_xxx.patch b/patches.kzm9g/0103-ASoC-fsi-rename-fsi_dma_soft_xxx-to-fsi_pio_xxx.patch
new file mode 100644
index 00000000000000..e41eb638bfa5cf
--- /dev/null
+++ b/patches.kzm9g/0103-ASoC-fsi-rename-fsi_dma_soft_xxx-to-fsi_pio_xxx.patch
@@ -0,0 +1,114 @@
+From ed808e04615f0b7e7ac019974418b8d32af510de Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:51:14 -0800
+Subject: ASoC: fsi: rename fsi_dma_soft_xxx() to fsi_pio_xxx()
+
+This is preparation for DMAEngine support
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit d78629e2a4457149bd21fdb0cdbbb1c3ec019d96)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index cbb5643..05307ac 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -474,10 +474,10 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
+ }
+
+ /*
+- * dma function
++ * pio function
+ */
+
+-static u8 *fsi_dma_get_area(struct fsi_priv *fsi, int stream)
++static u8 *fsi_pio_get_area(struct fsi_priv *fsi, int stream)
+ {
+ int is_play = fsi_stream_is_play(stream);
+ struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+@@ -487,47 +487,47 @@ static u8 *fsi_dma_get_area(struct fsi_priv *fsi, int stream)
+ samples_to_bytes(runtime, io->buff_sample_pos);
+ }
+
+-static void fsi_dma_soft_push16(struct fsi_priv *fsi, int num)
++static void fsi_pio_push16(struct fsi_priv *fsi, int num)
+ {
+ u16 *start;
+ int i;
+
+- start = (u16 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK);
++ start = (u16 *)fsi_pio_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK);
+
+ for (i = 0; i < num; i++)
+ fsi_reg_write(fsi, DODT, ((u32)*(start + i) << 8));
+ }
+
+-static void fsi_dma_soft_pop16(struct fsi_priv *fsi, int num)
++static void fsi_pio_pop16(struct fsi_priv *fsi, int num)
+ {
+ u16 *start;
+ int i;
+
+- start = (u16 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE);
++ start = (u16 *)fsi_pio_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE);
+
+
+ for (i = 0; i < num; i++)
+ *(start + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8);
+ }
+
+-static void fsi_dma_soft_push32(struct fsi_priv *fsi, int num)
++static void fsi_pio_push32(struct fsi_priv *fsi, int num)
+ {
+ u32 *start;
+ int i;
+
+- start = (u32 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK);
++ start = (u32 *)fsi_pio_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK);
+
+
+ for (i = 0; i < num; i++)
+ fsi_reg_write(fsi, DODT, *(start + i));
+ }
+
+-static void fsi_dma_soft_pop32(struct fsi_priv *fsi, int num)
++static void fsi_pio_pop32(struct fsi_priv *fsi, int num)
+ {
+ u32 *start;
+ int i;
+
+- start = (u32 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE);
++ start = (u32 *)fsi_pio_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE);
+
+ for (i = 0; i < num; i++)
+ *(start + i) = fsi_reg_read(fsi, DIDT);
+@@ -812,8 +812,8 @@ static int fsi_data_pop(struct fsi_priv *fsi)
+ samples = min(sample_residues, sample_space);
+
+ return fsi_fifo_data_ctrl(fsi, io,
+- fsi_dma_soft_pop16,
+- fsi_dma_soft_pop32,
++ fsi_pio_pop16,
++ fsi_pio_pop32,
+ samples);
+ }
+
+@@ -832,8 +832,8 @@ static int fsi_data_push(struct fsi_priv *fsi)
+ samples = min(sample_residues, sample_space);
+
+ return fsi_fifo_data_ctrl(fsi, io,
+- fsi_dma_soft_push16,
+- fsi_dma_soft_push32,
++ fsi_pio_push16,
++ fsi_pio_push32,
+ samples);
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0104-ASoC-fsi-tidyup-move-fsi_fifo_init-onto-fsi_hw_start.patch b/patches.kzm9g/0104-ASoC-fsi-tidyup-move-fsi_fifo_init-onto-fsi_hw_start.patch
new file mode 100644
index 00000000000000..4d8d3d2e539940
--- /dev/null
+++ b/patches.kzm9g/0104-ASoC-fsi-tidyup-move-fsi_fifo_init-onto-fsi_hw_start.patch
@@ -0,0 +1,146 @@
+From 4960931dddb3441619911b0fc1913646252466f0 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:51:29 -0800
+Subject: ASoC: fsi: tidyup: move fsi_fifo_init() onto fsi_hw_startup()
+
+fsi_fifo_init() is called only from fsi_hw_startup()
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit b49e8027810b674dc0bf0ba3d629c5fae52d78f3)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 109 ++++++++++++++++++++++++++---------------------------
+ 1 file changed, 54 insertions(+), 55 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 05307ac..79485ed 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -692,61 +692,6 @@ static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable)
+ /*
+ * ctrl function
+ */
+-static void fsi_fifo_init(struct fsi_priv *fsi,
+- int is_play,
+- struct device *dev)
+-{
+- struct fsi_master *master = fsi_get_master(fsi);
+- struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+- u32 shift, i;
+- int frame_capa;
+-
+- /* get on-chip RAM capacity */
+- shift = fsi_master_read(master, FIFO_SZ);
+- shift >>= fsi_get_port_shift(fsi, is_play);
+- shift &= FIFO_SZ_MASK;
+- frame_capa = 256 << shift;
+- dev_dbg(dev, "fifo = %d words\n", frame_capa);
+-
+- /*
+- * The maximum number of sample data varies depending
+- * on the number of channels selected for the format.
+- *
+- * FIFOs are used in 4-channel units in 3-channel mode
+- * and in 8-channel units in 5- to 7-channel mode
+- * meaning that more FIFOs than the required size of DPRAM
+- * are used.
+- *
+- * ex) if 256 words of DP-RAM is connected
+- * 1 channel: 256 (256 x 1 = 256)
+- * 2 channels: 128 (128 x 2 = 256)
+- * 3 channels: 64 ( 64 x 3 = 192)
+- * 4 channels: 64 ( 64 x 4 = 256)
+- * 5 channels: 32 ( 32 x 5 = 160)
+- * 6 channels: 32 ( 32 x 6 = 192)
+- * 7 channels: 32 ( 32 x 7 = 224)
+- * 8 channels: 32 ( 32 x 8 = 256)
+- */
+- for (i = 1; i < fsi->chan_num; i <<= 1)
+- frame_capa >>= 1;
+- dev_dbg(dev, "%d channel %d store\n",
+- fsi->chan_num, frame_capa);
+-
+- io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa);
+-
+- /*
+- * set interrupt generation factor
+- * clear FIFO
+- */
+- if (is_play) {
+- fsi_reg_write(fsi, DOFF_CTL, IRQ_HALF);
+- fsi_reg_mask_set(fsi, DOFF_CTL, FIFO_CLR, FIFO_CLR);
+- } else {
+- fsi_reg_write(fsi, DIFF_CTL, IRQ_HALF);
+- fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
+- }
+-}
+-
+ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, struct fsi_stream *io,
+ void (*run16)(struct fsi_priv *fsi, int size),
+ void (*run32)(struct fsi_priv *fsi, int size),
+@@ -867,6 +812,60 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
+ /*
+ * dai ops
+ */
++static void fsi_fifo_init(struct fsi_priv *fsi,
++ int is_play,
++ struct device *dev)
++{
++ struct fsi_master *master = fsi_get_master(fsi);
++ struct fsi_stream *io = fsi_stream_get(fsi, is_play);
++ u32 shift, i;
++ int frame_capa;
++
++ /* get on-chip RAM capacity */
++ shift = fsi_master_read(master, FIFO_SZ);
++ shift >>= fsi_get_port_shift(fsi, is_play);
++ shift &= FIFO_SZ_MASK;
++ frame_capa = 256 << shift;
++ dev_dbg(dev, "fifo = %d words\n", frame_capa);
++
++ /*
++ * The maximum number of sample data varies depending
++ * on the number of channels selected for the format.
++ *
++ * FIFOs are used in 4-channel units in 3-channel mode
++ * and in 8-channel units in 5- to 7-channel mode
++ * meaning that more FIFOs than the required size of DPRAM
++ * are used.
++ *
++ * ex) if 256 words of DP-RAM is connected
++ * 1 channel: 256 (256 x 1 = 256)
++ * 2 channels: 128 (128 x 2 = 256)
++ * 3 channels: 64 ( 64 x 3 = 192)
++ * 4 channels: 64 ( 64 x 4 = 256)
++ * 5 channels: 32 ( 32 x 5 = 160)
++ * 6 channels: 32 ( 32 x 6 = 192)
++ * 7 channels: 32 ( 32 x 7 = 224)
++ * 8 channels: 32 ( 32 x 8 = 256)
++ */
++ for (i = 1; i < fsi->chan_num; i <<= 1)
++ frame_capa >>= 1;
++ dev_dbg(dev, "%d channel %d store\n",
++ fsi->chan_num, frame_capa);
++
++ io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa);
++
++ /*
++ * set interrupt generation factor
++ * clear FIFO
++ */
++ if (is_play) {
++ fsi_reg_write(fsi, DOFF_CTL, IRQ_HALF);
++ fsi_reg_mask_set(fsi, DOFF_CTL, FIFO_CLR, FIFO_CLR);
++ } else {
++ fsi_reg_write(fsi, DIFF_CTL, IRQ_HALF);
++ fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
++ }
++}
+
+ static int fsi_hw_startup(struct fsi_priv *fsi,
+ int is_play,
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0105-ASoC-fsi-remove-unnecessary-parameter-from-fsi_hw_sh.patch b/patches.kzm9g/0105-ASoC-fsi-remove-unnecessary-parameter-from-fsi_hw_sh.patch
new file mode 100644
index 00000000000000..148b9f44361e29
--- /dev/null
+++ b/patches.kzm9g/0105-ASoC-fsi-remove-unnecessary-parameter-from-fsi_hw_sh.patch
@@ -0,0 +1,51 @@
+From 6e68b51cdc84f44faaaa97ca596a1c88260b89d8 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:51:53 -0800
+Subject: ASoC: fsi: remove unnecessary parameter from fsi_hw_shutdown()
+
+This is preparation for DMAEngine support
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 41bba151939e21e21d18f7df005ce3a06714a69a)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 79485ed..a0a9c36 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -927,7 +927,6 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
+ }
+
+ static void fsi_hw_shutdown(struct fsi_priv *fsi,
+- int is_play,
+ struct device *dev)
+ {
+ if (fsi_is_clk_master(fsi))
+@@ -947,9 +946,8 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+ {
+ struct fsi_priv *fsi = fsi_get_priv(substream);
+- int is_play = fsi_is_play(substream);
+
+- fsi_hw_shutdown(fsi, is_play, dai->dev);
++ fsi_hw_shutdown(fsi, dai->dev);
+ fsi->rate = 0;
+ }
+
+@@ -1342,7 +1340,7 @@ static void __fsi_suspend(struct fsi_priv *fsi,
+ return;
+
+ fsi_port_stop(fsi, is_play);
+- fsi_hw_shutdown(fsi, is_play, dev);
++ fsi_hw_shutdown(fsi, dev);
+ }
+
+ static void __fsi_resume(struct fsi_priv *fsi,
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0106-ASoC-fsi-rename-fsi_stream_push-pop-to-fsi_stream_in.patch b/patches.kzm9g/0106-ASoC-fsi-rename-fsi_stream_push-pop-to-fsi_stream_in.patch
new file mode 100644
index 00000000000000..2da6f9f51d8d90
--- /dev/null
+++ b/patches.kzm9g/0106-ASoC-fsi-rename-fsi_stream_push-pop-to-fsi_stream_in.patch
@@ -0,0 +1,57 @@
+From 8c2feb4527500fa4c1cc1f060fb73985b18a5969 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:52:07 -0800
+Subject: ASoC: fsi: rename fsi_stream_push/pop() to fsi_stream_init/quit()
+
+This is preparation for DMAEngine support
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 8c4152951cab90b52406afc72b62e9590bbe2d85)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index a0a9c36..2e2663b 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -426,7 +426,7 @@ static int fsi_stream_is_working(struct fsi_priv *fsi,
+ return ret;
+ }
+
+-static void fsi_stream_push(struct fsi_priv *fsi,
++static void fsi_stream_init(struct fsi_priv *fsi,
+ int is_play,
+ struct snd_pcm_substream *substream)
+ {
+@@ -447,7 +447,7 @@ static void fsi_stream_push(struct fsi_priv *fsi,
+ spin_unlock_irqrestore(&master->lock, flags);
+ }
+
+-static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
++static void fsi_stream_quit(struct fsi_priv *fsi, int is_play)
+ {
+ struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+ struct snd_soc_dai *dai = fsi_get_dai(io->substream);
+@@ -960,13 +960,13 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+- fsi_stream_push(fsi, is_play, substream);
++ fsi_stream_init(fsi, is_play, substream);
+ ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
+ fsi_port_start(fsi, is_play);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ fsi_port_stop(fsi, is_play);
+- fsi_stream_pop(fsi, is_play);
++ fsi_stream_quit(fsi, is_play);
+ break;
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0107-ASoC-fsi-modify-fsi_pio_get_area-parameter-and-using.patch b/patches.kzm9g/0107-ASoC-fsi-modify-fsi_pio_get_area-parameter-and-using.patch
new file mode 100644
index 00000000000000..838c0ddddbcbd2
--- /dev/null
+++ b/patches.kzm9g/0107-ASoC-fsi-modify-fsi_pio_get_area-parameter-and-using.patch
@@ -0,0 +1,127 @@
+From 2994ced4ba0546e601874e43b36f9bc6011a49f6 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:52:38 -0800
+Subject: ASoC: fsi: modify fsi_pio_get_area() parameter and using position
+
+This patch modify fsi_pio_get_area() parameter to use
+struct fsi_stream, and used it on fsi_fifo_data_ctrl().
+This is just prepare cleanup for DMAEngine support.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 95b0cf05976b7d0571e283b1fcd4c32095018cd6)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 43 +++++++++++++++++--------------------------
+ 1 file changed, 17 insertions(+), 26 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 2e2663b..c814d8a 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -477,58 +477,46 @@ static void fsi_stream_quit(struct fsi_priv *fsi, int is_play)
+ * pio function
+ */
+
+-static u8 *fsi_pio_get_area(struct fsi_priv *fsi, int stream)
++static u8 *fsi_pio_get_area(struct fsi_priv *fsi, struct fsi_stream *io)
+ {
+- int is_play = fsi_stream_is_play(stream);
+- struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+ struct snd_pcm_runtime *runtime = io->substream->runtime;
+
+ return runtime->dma_area +
+ samples_to_bytes(runtime, io->buff_sample_pos);
+ }
+
+-static void fsi_pio_push16(struct fsi_priv *fsi, int num)
++static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int num)
+ {
+- u16 *start;
++ u16 *start = (u16 *)_buf;
+ int i;
+
+- start = (u16 *)fsi_pio_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK);
+-
+ for (i = 0; i < num; i++)
+ fsi_reg_write(fsi, DODT, ((u32)*(start + i) << 8));
+ }
+
+-static void fsi_pio_pop16(struct fsi_priv *fsi, int num)
++static void fsi_pio_pop16(struct fsi_priv *fsi, u8 *_buf, int num)
+ {
+- u16 *start;
++ u16 *start = (u16 *)_buf;
+ int i;
+
+- start = (u16 *)fsi_pio_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE);
+-
+-
+ for (i = 0; i < num; i++)
+ *(start + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8);
+ }
+
+-static void fsi_pio_push32(struct fsi_priv *fsi, int num)
++static void fsi_pio_push32(struct fsi_priv *fsi, u8 *_buf, int num)
+ {
+- u32 *start;
++ u32 *start = (u32 *)_buf;
+ int i;
+
+- start = (u32 *)fsi_pio_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK);
+-
+-
+ for (i = 0; i < num; i++)
+ fsi_reg_write(fsi, DODT, *(start + i));
+ }
+
+-static void fsi_pio_pop32(struct fsi_priv *fsi, int num)
++static void fsi_pio_pop32(struct fsi_priv *fsi, u8 *_buf, int num)
+ {
+- u32 *start;
++ u32 *start = (u32 *)_buf;
+ int i;
+
+- start = (u32 *)fsi_pio_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE);
+-
+ for (i = 0; i < num; i++)
+ *(start + i) = fsi_reg_read(fsi, DIDT);
+ }
+@@ -693,12 +681,13 @@ static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable)
+ * ctrl function
+ */
+ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, struct fsi_stream *io,
+- void (*run16)(struct fsi_priv *fsi, int size),
+- void (*run32)(struct fsi_priv *fsi, int size),
+- int samples)
++ void (*run16)(struct fsi_priv *fsi, u8 *buf, int samples),
++ void (*run32)(struct fsi_priv *fsi, u8 *buf, int samples),
++ int samples)
+ {
+ struct snd_pcm_runtime *runtime;
+ struct snd_pcm_substream *substream;
++ u8 *buf;
+ int over_period;
+
+ if (!fsi ||
+@@ -723,12 +712,14 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, struct fsi_stream *io,
+ io->buff_sample_pos = 0;
+ }
+
++ buf = fsi_pio_get_area(fsi, io);
++
+ switch (io->sample_width) {
+ case 2:
+- run16(fsi, samples);
++ run16(fsi, buf, samples);
+ break;
+ case 4:
+- run32(fsi, samples);
++ run32(fsi, buf, samples);
+ break;
+ default:
+ return -EINVAL;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0108-ASoC-fsi-re-define-fsi_is_play-and-fsi_stream_is_pla.patch b/patches.kzm9g/0108-ASoC-fsi-re-define-fsi_is_play-and-fsi_stream_is_pla.patch
new file mode 100644
index 00000000000000..c284e895279f66
--- /dev/null
+++ b/patches.kzm9g/0108-ASoC-fsi-re-define-fsi_is_play-and-fsi_stream_is_pla.patch
@@ -0,0 +1,70 @@
+From 3e44f2caa7c0f3ce9496d578f1fea695c5e5646f Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:54:02 -0800
+Subject: ASoC: fsi: re-define fsi_is_play() and fsi_stream_is_play()
+
+This patch re-define fsi_is_play() and fsi_stream_is_play().
+fsi_data_pop/push() function keeps direct value of "is_play" at this point,
+but it will be removed soon.
+This is just prepare cleanup for DMAEngine support.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit a449e46754616a13e1bee649e37bcdf10d1b794a)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index c814d8a..1cbe474 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -296,6 +296,11 @@ static int fsi_is_spdif(struct fsi_priv *fsi)
+ return fsi->spdif;
+ }
+
++static int fsi_is_play(struct snd_pcm_substream *substream)
++{
++ return substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
++}
++
+ static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
+ {
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+@@ -399,10 +404,10 @@ static void fsi_count_fifo_err(struct fsi_priv *fsi)
+ /*
+ * fsi_stream_xx() function
+ */
+-#define fsi_is_play(substream) fsi_stream_is_play(substream->stream)
+-static inline int fsi_stream_is_play(int stream)
++static inline int fsi_stream_is_play(struct fsi_priv *fsi,
++ struct fsi_stream *io)
+ {
+- return stream == SNDRV_PCM_STREAM_PLAYBACK;
++ return &fsi->playback == io;
+ }
+
+ static inline struct fsi_stream *fsi_stream_get(struct fsi_priv *fsi,
+@@ -736,7 +741,7 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, struct fsi_stream *io,
+
+ static int fsi_data_pop(struct fsi_priv *fsi)
+ {
+- int is_play = fsi_stream_is_play(SNDRV_PCM_STREAM_CAPTURE);
++ int is_play = 0;
+ int sample_residues; /* samples in FSI fifo */
+ int sample_space; /* ALSA free samples space */
+ int samples;
+@@ -755,7 +760,7 @@ static int fsi_data_pop(struct fsi_priv *fsi)
+
+ static int fsi_data_push(struct fsi_priv *fsi)
+ {
+- int is_play = fsi_stream_is_play(SNDRV_PCM_STREAM_PLAYBACK);
++ int is_play = 1;
+ int sample_residues; /* ALSA residue samples */
+ int sample_space; /* FSI fifo free samples space */
+ int samples;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0109-ASoC-fsi-use-fsi_stream-in-fsi_get_current_fifo_samp.patch b/patches.kzm9g/0109-ASoC-fsi-use-fsi_stream-in-fsi_get_current_fifo_samp.patch
new file mode 100644
index 00000000000000..0b895fb7e55e04
--- /dev/null
+++ b/patches.kzm9g/0109-ASoC-fsi-use-fsi_stream-in-fsi_get_current_fifo_samp.patch
@@ -0,0 +1,64 @@
+From 374adbfae43dc4d5b0f0f9e7b14841df24cceea1 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:55:26 -0800
+Subject: ASoC: fsi: use fsi_stream in fsi_get_current_fifo_samples()
+ parameter
+
+fsi_get_current_fifo_samples() uses fsi_stream instead of is_play.
+This is just prepare cleanup for DMAEngine support.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 7b1b3331e65e47b6abb32be0a3db46bcf423145a)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 1cbe474..24dbe16 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -210,6 +210,8 @@ struct fsi_master {
+ spinlock_t lock;
+ };
+
++static int fsi_stream_is_play(struct fsi_priv *fsi, struct fsi_stream *io);
++
+ /*
+ * basic read write function
+ */
+@@ -366,8 +368,10 @@ static int fsi_sample2frame(struct fsi_priv *fsi, int samples)
+ return samples / fsi->chan_num;
+ }
+
+-static int fsi_get_current_fifo_samples(struct fsi_priv *fsi, int is_play)
++static int fsi_get_current_fifo_samples(struct fsi_priv *fsi,
++ struct fsi_stream *io)
+ {
++ int is_play = fsi_stream_is_play(fsi, io);
+ u32 status;
+ int frames;
+
+@@ -747,7 +751,7 @@ static int fsi_data_pop(struct fsi_priv *fsi)
+ int samples;
+ struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+
+- sample_residues = fsi_get_current_fifo_samples(fsi, is_play);
++ sample_residues = fsi_get_current_fifo_samples(fsi, io);
+ sample_space = io->buff_sample_capa - io->buff_sample_pos;
+
+ samples = min(sample_residues, sample_space);
+@@ -768,7 +772,7 @@ static int fsi_data_push(struct fsi_priv *fsi)
+
+ sample_residues = io->buff_sample_capa - io->buff_sample_pos;
+ sample_space = io->fifo_sample_capa -
+- fsi_get_current_fifo_samples(fsi, is_play);
++ fsi_get_current_fifo_samples(fsi, io);
+
+ samples = min(sample_residues, sample_space);
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0110-ASoC-fsi-add-fsi_stream_handler-and-PIO-handler.patch b/patches.kzm9g/0110-ASoC-fsi-add-fsi_stream_handler-and-PIO-handler.patch
new file mode 100644
index 00000000000000..3346eefd93f023
--- /dev/null
+++ b/patches.kzm9g/0110-ASoC-fsi-add-fsi_stream_handler-and-PIO-handler.patch
@@ -0,0 +1,286 @@
+From bb1acd92639a1c3dae57bbc1d457fba98f084a6d Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:55:55 -0800
+Subject: ASoC: fsi: add fsi_stream_handler and PIO handler
+
+This patch adds struct fsi_stream_handler and defined fsi_pio_push/pop_handler.
+these are controled by fsi_steam_xxx() function.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 5e97313ac483f03a9af661aada356980fe310e0d)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 118 insertions(+), 15 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 24dbe16..b02886a 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -159,18 +159,27 @@ typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int ena
+ * struct
+ */
+
++struct fsi_stream_handler;
+ struct fsi_stream {
+- struct snd_pcm_substream *substream;
+
++ /*
++ * these are initialized by fsi_stream_init()
++ */
++ struct snd_pcm_substream *substream;
+ int fifo_sample_capa; /* sample capacity of FSI FIFO */
+ int buff_sample_capa; /* sample capacity of ALSA buffer */
+ int buff_sample_pos; /* sample position of ALSA buffer */
+ int period_samples; /* sample number / 1 period */
+ int period_pos; /* current period position */
+ int sample_width; /* sample width */
+-
+ int uerr_num;
+ int oerr_num;
++
++ /*
++ * thse are initialized by fsi_handler_init()
++ */
++ struct fsi_stream_handler *handler;
++ struct fsi_priv *priv;
+ };
+
+ struct fsi_priv {
+@@ -190,6 +199,16 @@ struct fsi_priv {
+ long rate;
+ };
+
++struct fsi_stream_handler {
++ int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io);
++ int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io);
++ int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io);
++};
++#define fsi_stream_handler_call(io, func, args...) \
++ (!(io) ? -ENODEV : \
++ !((io)->handler->func) ? 0 : \
++ (io)->handler->func(args))
++
+ struct fsi_core {
+ int ver;
+
+@@ -435,6 +454,11 @@ static int fsi_stream_is_working(struct fsi_priv *fsi,
+ return ret;
+ }
+
++static struct fsi_priv *fsi_stream_to_priv(struct fsi_stream *io)
++{
++ return io->priv;
++}
++
+ static void fsi_stream_init(struct fsi_priv *fsi,
+ int is_play,
+ struct snd_pcm_substream *substream)
+@@ -482,6 +506,53 @@ static void fsi_stream_quit(struct fsi_priv *fsi, int is_play)
+ spin_unlock_irqrestore(&master->lock, flags);
+ }
+
++static int fsi_stream_transfer(struct fsi_stream *io)
++{
++ struct fsi_priv *fsi = fsi_stream_to_priv(io);
++ if (!fsi)
++ return -EIO;
++
++ return fsi_stream_handler_call(io, transfer, fsi, io);
++}
++
++static int fsi_stream_probe(struct fsi_priv *fsi)
++{
++ struct fsi_stream *io;
++ int ret1, ret2;
++
++ io = &fsi->playback;
++ ret1 = fsi_stream_handler_call(io, probe, fsi, io);
++
++ io = &fsi->capture;
++ ret2 = fsi_stream_handler_call(io, probe, fsi, io);
++
++ if (ret1 < 0)
++ return ret1;
++ if (ret2 < 0)
++ return ret2;
++
++ return 0;
++}
++
++static int fsi_stream_remove(struct fsi_priv *fsi)
++{
++ struct fsi_stream *io;
++ int ret1, ret2;
++
++ io = &fsi->playback;
++ ret1 = fsi_stream_handler_call(io, remove, fsi, io);
++
++ io = &fsi->capture;
++ ret2 = fsi_stream_handler_call(io, remove, fsi, io);
++
++ if (ret1 < 0)
++ return ret1;
++ if (ret2 < 0)
++ return ret2;
++
++ return 0;
++}
++
+ /*
+ * pio function
+ */
+@@ -743,13 +814,11 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, struct fsi_stream *io,
+ return 0;
+ }
+
+-static int fsi_data_pop(struct fsi_priv *fsi)
++static int fsi_pio_pop(struct fsi_priv *fsi, struct fsi_stream *io)
+ {
+- int is_play = 0;
+ int sample_residues; /* samples in FSI fifo */
+ int sample_space; /* ALSA free samples space */
+ int samples;
+- struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+
+ sample_residues = fsi_get_current_fifo_samples(fsi, io);
+ sample_space = io->buff_sample_capa - io->buff_sample_pos;
+@@ -762,13 +831,11 @@ static int fsi_data_pop(struct fsi_priv *fsi)
+ samples);
+ }
+
+-static int fsi_data_push(struct fsi_priv *fsi)
++static int fsi_pio_push(struct fsi_priv *fsi, struct fsi_stream *io)
+ {
+- int is_play = 1;
+ int sample_residues; /* ALSA residue samples */
+ int sample_space; /* FSI fifo free samples space */
+ int samples;
+- struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+
+ sample_residues = io->buff_sample_capa - io->buff_sample_pos;
+ sample_space = io->fifo_sample_capa -
+@@ -782,6 +849,14 @@ static int fsi_data_push(struct fsi_priv *fsi)
+ samples);
+ }
+
++static struct fsi_stream_handler fsi_pio_push_handler = {
++ .transfer = fsi_pio_push,
++};
++
++static struct fsi_stream_handler fsi_pio_pop_handler = {
++ .transfer = fsi_pio_pop,
++};
++
+ static irqreturn_t fsi_interrupt(int irq, void *data)
+ {
+ struct fsi_master *master = data;
+@@ -792,13 +867,13 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
+ fsi_master_mask_set(master, SOFT_RST, IR, IR);
+
+ if (int_st & AB_IO(1, AO_SHIFT))
+- fsi_data_push(&master->fsia);
++ fsi_stream_transfer(&master->fsia.playback);
+ if (int_st & AB_IO(1, BO_SHIFT))
+- fsi_data_push(&master->fsib);
++ fsi_stream_transfer(&master->fsib.playback);
+ if (int_st & AB_IO(1, AI_SHIFT))
+- fsi_data_pop(&master->fsia);
++ fsi_stream_transfer(&master->fsia.capture);
+ if (int_st & AB_IO(1, BI_SHIFT))
+- fsi_data_pop(&master->fsib);
++ fsi_stream_transfer(&master->fsib.capture);
+
+ fsi_count_fifo_err(&master->fsia);
+ fsi_count_fifo_err(&master->fsib);
+@@ -955,14 +1030,16 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+ {
+ struct fsi_priv *fsi = fsi_get_priv(substream);
++ struct fsi_stream *io = fsi_stream_get(fsi, fsi_is_play(substream));
+ int is_play = fsi_is_play(substream);
+ int ret = 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ fsi_stream_init(fsi, is_play, substream);
+- ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
+- fsi_port_start(fsi, is_play);
++ ret = fsi_stream_transfer(io);
++ if (0 == ret)
++ fsi_port_start(fsi, is_play);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ fsi_port_stop(fsi, is_play);
+@@ -1224,6 +1301,13 @@ static struct snd_soc_platform_driver fsi_soc_platform = {
+ /*
+ * platform function
+ */
++static void fsi_handler_init(struct fsi_priv *fsi)
++{
++ fsi->playback.handler = &fsi_pio_push_handler; /* default PIO */
++ fsi->playback.priv = fsi;
++ fsi->capture.handler = &fsi_pio_pop_handler; /* default PIO */
++ fsi->capture.priv = fsi;
++}
+
+ static int fsi_probe(struct platform_device *pdev)
+ {
+@@ -1270,10 +1354,22 @@ static int fsi_probe(struct platform_device *pdev)
+ /* FSI A setting */
+ master->fsia.base = master->base;
+ master->fsia.master = master;
++ fsi_handler_init(&master->fsia);
++ ret = fsi_stream_probe(&master->fsia);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "FSIA stream probe failed\n");
++ goto exit_iounmap;
++ }
+
+ /* FSI B setting */
+ master->fsib.base = master->base + 0x40;
+ master->fsib.master = master;
++ fsi_handler_init(&master->fsib);
++ ret = fsi_stream_probe(&master->fsib);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "FSIB stream probe failed\n");
++ goto exit_fsia;
++ }
+
+ pm_runtime_enable(&pdev->dev);
+ dev_set_drvdata(&pdev->dev, master);
+@@ -1282,7 +1378,7 @@ static int fsi_probe(struct platform_device *pdev)
+ id_entry->name, master);
+ if (ret) {
+ dev_err(&pdev->dev, "irq request err\n");
+- goto exit_iounmap;
++ goto exit_fsib;
+ }
+
+ ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform);
+@@ -1304,6 +1400,10 @@ exit_snd_soc:
+ snd_soc_unregister_platform(&pdev->dev);
+ exit_free_irq:
+ free_irq(irq, master);
++exit_fsib:
++ fsi_stream_remove(&master->fsib);
++exit_fsia:
++ fsi_stream_remove(&master->fsia);
+ exit_iounmap:
+ iounmap(master->base);
+ pm_runtime_disable(&pdev->dev);
+@@ -1326,6 +1426,9 @@ static int fsi_remove(struct platform_device *pdev)
+ snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai));
+ snd_soc_unregister_platform(&pdev->dev);
+
++ fsi_stream_remove(&master->fsia);
++ fsi_stream_remove(&master->fsib);
++
+ iounmap(master->base);
+ kfree(master);
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0111-ASoC-fsi-tidyup-fsi_pio_xxx-are-gathered.patch b/patches.kzm9g/0111-ASoC-fsi-tidyup-fsi_pio_xxx-are-gathered.patch
new file mode 100644
index 00000000000000..2adddb04fdefd7
--- /dev/null
+++ b/patches.kzm9g/0111-ASoC-fsi-tidyup-fsi_pio_xxx-are-gathered.patch
@@ -0,0 +1,152 @@
+From e31af8e7b9e4d0bffdab4e6c614f6b181bea962b Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:56:27 -0800
+Subject: ASoC: fsi: tidyup: fsi_pio_xxx() are gathered
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 1b0ca1a0c056c7c97b18e363f939f0635ca093af)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 101 ++++++++++++++++++++++++++---------------------------
+ 1 file changed, 49 insertions(+), 52 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index b02886a..7c93b7c 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -554,54 +554,6 @@ static int fsi_stream_remove(struct fsi_priv *fsi)
+ }
+
+ /*
+- * pio function
+- */
+-
+-static u8 *fsi_pio_get_area(struct fsi_priv *fsi, struct fsi_stream *io)
+-{
+- struct snd_pcm_runtime *runtime = io->substream->runtime;
+-
+- return runtime->dma_area +
+- samples_to_bytes(runtime, io->buff_sample_pos);
+-}
+-
+-static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int num)
+-{
+- u16 *start = (u16 *)_buf;
+- int i;
+-
+- for (i = 0; i < num; i++)
+- fsi_reg_write(fsi, DODT, ((u32)*(start + i) << 8));
+-}
+-
+-static void fsi_pio_pop16(struct fsi_priv *fsi, u8 *_buf, int num)
+-{
+- u16 *start = (u16 *)_buf;
+- int i;
+-
+- for (i = 0; i < num; i++)
+- *(start + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8);
+-}
+-
+-static void fsi_pio_push32(struct fsi_priv *fsi, u8 *_buf, int num)
+-{
+- u32 *start = (u32 *)_buf;
+- int i;
+-
+- for (i = 0; i < num; i++)
+- fsi_reg_write(fsi, DODT, *(start + i));
+-}
+-
+-static void fsi_pio_pop32(struct fsi_priv *fsi, u8 *_buf, int num)
+-{
+- u32 *start = (u32 *)_buf;
+- int i;
+-
+- for (i = 0; i < num; i++)
+- *(start + i) = fsi_reg_read(fsi, DIDT);
+-}
+-
+-/*
+ * irq function
+ */
+
+@@ -757,10 +709,55 @@ static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable)
+ fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
+ }
+
++
+ /*
+- * ctrl function
++ * pio data transfer handler
+ */
+-static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, struct fsi_stream *io,
++static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples)
++{
++ u16 *buf = (u16 *)_buf;
++ int i;
++
++ 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)
++{
++ u16 *buf = (u16 *)_buf;
++ int i;
++
++ for (i = 0; i < samples; i++)
++ *(buf + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8);
++}
++
++static void fsi_pio_push32(struct fsi_priv *fsi, u8 *_buf, int samples)
++{
++ u32 *buf = (u32 *)_buf;
++ int i;
++
++ for (i = 0; i < samples; i++)
++ fsi_reg_write(fsi, DODT, *(buf + i));
++}
++
++static void fsi_pio_pop32(struct fsi_priv *fsi, u8 *_buf, int samples)
++{
++ u32 *buf = (u32 *)_buf;
++ int i;
++
++ for (i = 0; i < samples; i++)
++ *(buf + i) = fsi_reg_read(fsi, DIDT);
++}
++
++static u8 *fsi_pio_get_area(struct fsi_priv *fsi, struct fsi_stream *io)
++{
++ struct snd_pcm_runtime *runtime = io->substream->runtime;
++
++ return runtime->dma_area +
++ samples_to_bytes(runtime, io->buff_sample_pos);
++}
++
++static int fsi_pio_transfer(struct fsi_priv *fsi, struct fsi_stream *io,
+ void (*run16)(struct fsi_priv *fsi, u8 *buf, int samples),
+ void (*run32)(struct fsi_priv *fsi, u8 *buf, int samples),
+ int samples)
+@@ -825,7 +822,7 @@ static int fsi_pio_pop(struct fsi_priv *fsi, struct fsi_stream *io)
+
+ samples = min(sample_residues, sample_space);
+
+- return fsi_fifo_data_ctrl(fsi, io,
++ return fsi_pio_transfer(fsi, io,
+ fsi_pio_pop16,
+ fsi_pio_pop32,
+ samples);
+@@ -843,7 +840,7 @@ static int fsi_pio_push(struct fsi_priv *fsi, struct fsi_stream *io)
+
+ samples = min(sample_residues, sample_space);
+
+- return fsi_fifo_data_ctrl(fsi, io,
++ return fsi_pio_transfer(fsi, io,
+ fsi_pio_push16,
+ fsi_pio_push32,
+ samples);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0112-ASoC-fsi-don-t-use-is_play-as-a-parameter-of-fsi-fun.patch b/patches.kzm9g/0112-ASoC-fsi-don-t-use-is_play-as-a-parameter-of-fsi-fun.patch
new file mode 100644
index 00000000000000..1c02a3dc1a42e8
--- /dev/null
+++ b/patches.kzm9g/0112-ASoC-fsi-don-t-use-is_play-as-a-parameter-of-fsi-fun.patch
@@ -0,0 +1,291 @@
+From a1e81ab5ca7241fefe487653f39c9bcb665e3c3e Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:56:57 -0800
+Subject: ASoC: fsi: don't use is_play as a parameter of fsi functions
+
+is_play should be kept as local valuable.
+it prepare cleanup for DMAEngine support
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 938e2a8da5b2c1cb21c200e97736259948a3d12c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 94 ++++++++++++++++++++++++++----------------------------
+ 1 file changed, 45 insertions(+), 49 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 7c93b7c..7dec144 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -364,8 +364,9 @@ static u32 fsi_get_info_flags(struct fsi_priv *fsi)
+ master->info->portb_flags;
+ }
+
+-static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play)
++static u32 fsi_get_port_shift(struct fsi_priv *fsi, struct fsi_stream *io)
+ {
++ int is_play = fsi_stream_is_play(fsi, io);
+ int is_porta = fsi_is_port_a(fsi);
+ u32 shift;
+
+@@ -434,15 +435,14 @@ static inline int fsi_stream_is_play(struct fsi_priv *fsi,
+ }
+
+ static inline struct fsi_stream *fsi_stream_get(struct fsi_priv *fsi,
+- int is_play)
++ struct snd_pcm_substream *substream)
+ {
+- return is_play ? &fsi->playback : &fsi->capture;
++ return fsi_is_play(substream) ? &fsi->playback : &fsi->capture;
+ }
+
+ static int fsi_stream_is_working(struct fsi_priv *fsi,
+- int is_play)
++ struct fsi_stream *io)
+ {
+- struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+ struct fsi_master *master = fsi_get_master(fsi);
+ unsigned long flags;
+ int ret;
+@@ -460,10 +460,9 @@ static struct fsi_priv *fsi_stream_to_priv(struct fsi_stream *io)
+ }
+
+ static void fsi_stream_init(struct fsi_priv *fsi,
+- int is_play,
++ struct fsi_stream *io,
+ struct snd_pcm_substream *substream)
+ {
+- struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct fsi_master *master = fsi_get_master(fsi);
+ unsigned long flags;
+@@ -480,9 +479,8 @@ static void fsi_stream_init(struct fsi_priv *fsi,
+ spin_unlock_irqrestore(&master->lock, flags);
+ }
+
+-static void fsi_stream_quit(struct fsi_priv *fsi, int is_play)
++static void fsi_stream_quit(struct fsi_priv *fsi, struct fsi_stream *io)
+ {
+- struct fsi_stream *io = fsi_stream_get(fsi, is_play);
+ struct snd_soc_dai *dai = fsi_get_dai(io->substream);
+ struct fsi_master *master = fsi_get_master(fsi);
+ unsigned long flags;
+@@ -557,18 +555,18 @@ static int fsi_stream_remove(struct fsi_priv *fsi)
+ * irq function
+ */
+
+-static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
++static void fsi_irq_enable(struct fsi_priv *fsi, struct fsi_stream *io)
+ {
+- u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play));
++ u32 data = AB_IO(1, fsi_get_port_shift(fsi, io));
+ struct fsi_master *master = fsi_get_master(fsi);
+
+ fsi_core_mask_set(master, imsk, data, data);
+ fsi_core_mask_set(master, iemsk, data, data);
+ }
+
+-static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
++static void fsi_irq_disable(struct fsi_priv *fsi, struct fsi_stream *io)
+ {
+- u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play));
++ u32 data = AB_IO(1, fsi_get_port_shift(fsi, io));
+ struct fsi_master *master = fsi_get_master(fsi);
+
+ fsi_core_mask_set(master, imsk, data, 0);
+@@ -585,8 +583,8 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
+ u32 data = 0;
+ struct fsi_master *master = fsi_get_master(fsi);
+
+- data |= AB_IO(1, fsi_get_port_shift(fsi, 0));
+- data |= AB_IO(1, fsi_get_port_shift(fsi, 1));
++ data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->playback));
++ data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->capture));
+
+ /* clear interrupt factor */
+ fsi_core_mask_set(master, int_st, data, 0);
+@@ -695,15 +693,16 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
+
+ #define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1)
+ #define fsi_port_stop(f, i) __fsi_port_clk_ctrl(f, i, 0)
+-static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable)
++static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, struct fsi_stream *io,
++ int enable)
+ {
+ struct fsi_master *master = fsi_get_master(fsi);
+ u32 clk = fsi_is_port_a(fsi) ? CRA : CRB;
+
+ if (enable)
+- fsi_irq_enable(fsi, is_play);
++ fsi_irq_enable(fsi, io);
+ else
+- fsi_irq_disable(fsi, is_play);
++ fsi_irq_disable(fsi, io);
+
+ if (fsi_is_clk_master(fsi))
+ fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
+@@ -885,17 +884,17 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
+ * dai ops
+ */
+ static void fsi_fifo_init(struct fsi_priv *fsi,
+- int is_play,
++ struct fsi_stream *io,
+ struct device *dev)
+ {
+ struct fsi_master *master = fsi_get_master(fsi);
+- struct fsi_stream *io = fsi_stream_get(fsi, is_play);
++ int is_play = fsi_stream_is_play(fsi, io);
+ u32 shift, i;
+ int frame_capa;
+
+ /* get on-chip RAM capacity */
+ shift = fsi_master_read(master, FIFO_SZ);
+- shift >>= fsi_get_port_shift(fsi, is_play);
++ shift >>= fsi_get_port_shift(fsi, io);
+ shift &= FIFO_SZ_MASK;
+ frame_capa = 256 << shift;
+ dev_dbg(dev, "fifo = %d words\n", frame_capa);
+@@ -940,7 +939,7 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
+ }
+
+ static int fsi_hw_startup(struct fsi_priv *fsi,
+- int is_play,
++ struct fsi_stream *io,
+ struct device *dev)
+ {
+ struct fsi_master *master = fsi_get_master(fsi);
+@@ -989,11 +988,11 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
+ }
+
+ /* irq clear */
+- fsi_irq_disable(fsi, is_play);
++ fsi_irq_disable(fsi, io);
+ fsi_irq_clear_status(fsi);
+
+ /* fifo init */
+- fsi_fifo_init(fsi, is_play, dev);
++ fsi_fifo_init(fsi, io, dev);
+
+ return 0;
+ }
+@@ -1009,9 +1008,8 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+ {
+ struct fsi_priv *fsi = fsi_get_priv(substream);
+- int is_play = fsi_is_play(substream);
+
+- return fsi_hw_startup(fsi, is_play, dai->dev);
++ return fsi_hw_startup(fsi, fsi_stream_get(fsi, substream), dai->dev);
+ }
+
+ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
+@@ -1027,20 +1025,19 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+ {
+ struct fsi_priv *fsi = fsi_get_priv(substream);
+- struct fsi_stream *io = fsi_stream_get(fsi, fsi_is_play(substream));
+- int is_play = fsi_is_play(substream);
++ struct fsi_stream *io = fsi_stream_get(fsi, substream);
+ int ret = 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+- fsi_stream_init(fsi, is_play, substream);
++ fsi_stream_init(fsi, io, substream);
+ ret = fsi_stream_transfer(io);
+ if (0 == ret)
+- fsi_port_start(fsi, is_play);
++ fsi_port_start(fsi, io);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+- fsi_port_stop(fsi, is_play);
+- fsi_stream_quit(fsi, is_play);
++ fsi_port_stop(fsi, io);
++ fsi_stream_quit(fsi, io);
+ break;
+ }
+
+@@ -1206,7 +1203,7 @@ static int fsi_hw_free(struct snd_pcm_substream *substream)
+ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
+ {
+ struct fsi_priv *fsi = fsi_get_priv(substream);
+- struct fsi_stream *io = fsi_stream_get(fsi, fsi_is_play(substream));
++ struct fsi_stream *io = fsi_stream_get(fsi, substream);
+ int samples_pos = io->buff_sample_pos - 1;
+
+ if (samples_pos < 0)
+@@ -1433,30 +1430,29 @@ static int fsi_remove(struct platform_device *pdev)
+ }
+
+ static void __fsi_suspend(struct fsi_priv *fsi,
+- int is_play,
++ struct fsi_stream *io,
+ struct device *dev)
+ {
+- if (!fsi_stream_is_working(fsi, is_play))
++ if (!fsi_stream_is_working(fsi, io))
+ return;
+
+- fsi_port_stop(fsi, is_play);
++ fsi_port_stop(fsi, io);
+ fsi_hw_shutdown(fsi, dev);
+ }
+
+ static void __fsi_resume(struct fsi_priv *fsi,
+- int is_play,
++ struct fsi_stream *io,
+ struct device *dev)
+ {
+- if (!fsi_stream_is_working(fsi, is_play))
++ if (!fsi_stream_is_working(fsi, io))
+ return;
+
+- fsi_hw_startup(fsi, is_play, dev);
++ fsi_hw_startup(fsi, io, dev);
+
+ if (fsi_is_clk_master(fsi) && fsi->rate)
+ fsi_set_master_clk(dev, fsi, fsi->rate, 1);
+
+- fsi_port_start(fsi, is_play);
+-
++ fsi_port_start(fsi, io);
+ }
+
+ static int fsi_suspend(struct device *dev)
+@@ -1465,11 +1461,11 @@ static int fsi_suspend(struct device *dev)
+ struct fsi_priv *fsia = &master->fsia;
+ struct fsi_priv *fsib = &master->fsib;
+
+- __fsi_suspend(fsia, 1, dev);
+- __fsi_suspend(fsia, 0, dev);
++ __fsi_suspend(fsia, &fsia->playback, dev);
++ __fsi_suspend(fsia, &fsia->capture, dev);
+
+- __fsi_suspend(fsib, 1, dev);
+- __fsi_suspend(fsib, 0, dev);
++ __fsi_suspend(fsib, &fsib->playback, dev);
++ __fsi_suspend(fsib, &fsib->capture, dev);
+
+ return 0;
+ }
+@@ -1480,11 +1476,11 @@ static int fsi_resume(struct device *dev)
+ struct fsi_priv *fsia = &master->fsia;
+ struct fsi_priv *fsib = &master->fsib;
+
+- __fsi_resume(fsia, 1, dev);
+- __fsi_resume(fsia, 0, dev);
++ __fsi_resume(fsia, &fsia->playback, dev);
++ __fsi_resume(fsia, &fsia->capture, dev);
+
+- __fsi_resume(fsib, 1, dev);
+- __fsi_resume(fsib, 0, dev);
++ __fsi_resume(fsib, &fsib->playback, dev);
++ __fsi_resume(fsib, &fsib->capture, dev);
+
+ return 0;
+ }
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0113-ASoC-fsi-add-.start_stop-handler-to-fsi_stream_handl.patch b/patches.kzm9g/0113-ASoC-fsi-add-.start_stop-handler-to-fsi_stream_handl.patch
new file mode 100644
index 00000000000000..5ab76b525e120c
--- /dev/null
+++ b/patches.kzm9g/0113-ASoC-fsi-add-.start_stop-handler-to-fsi_stream_handl.patch
@@ -0,0 +1,129 @@
+From fa8ef8395e2e672608fb808bdc7261b25c561d1d Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:57:25 -0800
+Subject: ASoC: fsi: add .start_stop handler to fsi_stream_handler
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 180346ede352b12c72c5aeba2fc806fd32880c16)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 51 +++++++++++++++++++++++++++++----------------------
+ 1 file changed, 29 insertions(+), 22 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 7dec144..8d05e59 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -203,6 +203,8 @@ struct fsi_stream_handler {
+ int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io);
+ 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,
++ int enable);
+ };
+ #define fsi_stream_handler_call(io, func, args...) \
+ (!(io) ? -ENODEV : \
+@@ -513,6 +515,12 @@ static int fsi_stream_transfer(struct fsi_stream *io)
+ return fsi_stream_handler_call(io, transfer, fsi, io);
+ }
+
++#define fsi_stream_start(fsi, io)\
++ fsi_stream_handler_call(io, start_stop, fsi, io, 1)
++
++#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)
+ {
+ struct fsi_stream *io;
+@@ -691,24 +699,6 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
+ return ret;
+ }
+
+-#define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1)
+-#define fsi_port_stop(f, i) __fsi_port_clk_ctrl(f, i, 0)
+-static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, struct fsi_stream *io,
+- int enable)
+-{
+- struct fsi_master *master = fsi_get_master(fsi);
+- u32 clk = fsi_is_port_a(fsi) ? CRA : CRB;
+-
+- if (enable)
+- fsi_irq_enable(fsi, io);
+- else
+- fsi_irq_disable(fsi, io);
+-
+- if (fsi_is_clk_master(fsi))
+- fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
+-}
+-
+-
+ /*
+ * pio data transfer handler
+ */
+@@ -845,12 +835,29 @@ static int fsi_pio_push(struct fsi_priv *fsi, struct fsi_stream *io)
+ samples);
+ }
+
++static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
++ int enable)
++{
++ struct fsi_master *master = fsi_get_master(fsi);
++ u32 clk = fsi_is_port_a(fsi) ? CRA : CRB;
++
++ if (enable)
++ fsi_irq_enable(fsi, io);
++ else
++ fsi_irq_disable(fsi, io);
++
++ if (fsi_is_clk_master(fsi))
++ fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
++}
++
+ static struct fsi_stream_handler fsi_pio_push_handler = {
+ .transfer = fsi_pio_push,
++ .start_stop = fsi_pio_start_stop,
+ };
+
+ static struct fsi_stream_handler fsi_pio_pop_handler = {
+ .transfer = fsi_pio_pop,
++ .start_stop = fsi_pio_start_stop,
+ };
+
+ static irqreturn_t fsi_interrupt(int irq, void *data)
+@@ -1033,10 +1040,10 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+ fsi_stream_init(fsi, io, substream);
+ ret = fsi_stream_transfer(io);
+ if (0 == ret)
+- fsi_port_start(fsi, io);
++ fsi_stream_start(fsi, io);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+- fsi_port_stop(fsi, io);
++ fsi_stream_stop(fsi, io);
+ fsi_stream_quit(fsi, io);
+ break;
+ }
+@@ -1436,7 +1443,7 @@ static void __fsi_suspend(struct fsi_priv *fsi,
+ if (!fsi_stream_is_working(fsi, io))
+ return;
+
+- fsi_port_stop(fsi, io);
++ fsi_stream_stop(fsi, io);
+ fsi_hw_shutdown(fsi, dev);
+ }
+
+@@ -1452,7 +1459,7 @@ static void __fsi_resume(struct fsi_priv *fsi,
+ if (fsi_is_clk_master(fsi) && fsi->rate)
+ fsi_set_master_clk(dev, fsi, fsi->rate, 1);
+
+- fsi_port_start(fsi, io);
++ fsi_stream_start(fsi, io);
+ }
+
+ static int fsi_suspend(struct device *dev)
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0114-ASoC-fsi-fsi_stream_is_working-care-substream-runtim.patch b/patches.kzm9g/0114-ASoC-fsi-fsi_stream_is_working-care-substream-runtim.patch
new file mode 100644
index 00000000000000..8ee621e129fe06
--- /dev/null
+++ b/patches.kzm9g/0114-ASoC-fsi-fsi_stream_is_working-care-substream-runtim.patch
@@ -0,0 +1,41 @@
+From fefc4953a08d796f8e66ab7e388b589f7a564aaa Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:57:40 -0800
+Subject: ASoC: fsi: fsi_stream_is_working() care substream->runtime
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 97df81873e9c1391319dd818bc4b6856517e4939)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 8d05e59..1e10184 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -450,7 +450,7 @@ static int fsi_stream_is_working(struct fsi_priv *fsi,
+ int ret;
+
+ spin_lock_irqsave(&master->lock, flags);
+- ret = !!io->substream;
++ ret = !!(io->substream && io->substream->runtime);
+ spin_unlock_irqrestore(&master->lock, flags);
+
+ return ret;
+@@ -756,9 +756,7 @@ static int fsi_pio_transfer(struct fsi_priv *fsi, struct fsi_stream *io,
+ u8 *buf;
+ int over_period;
+
+- if (!fsi ||
+- !io->substream ||
+- !io->substream->runtime)
++ if (!fsi_stream_is_working(fsi, io))
+ return -EINVAL;
+
+ over_period = 0;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0115-ASoC-fsi-PortA-B-information-was-controlled-by-sh_fs.patch b/patches.kzm9g/0115-ASoC-fsi-PortA-B-information-was-controlled-by-sh_fs.patch
new file mode 100644
index 00000000000000..c2e73b55c5f5c9
--- /dev/null
+++ b/patches.kzm9g/0115-ASoC-fsi-PortA-B-information-was-controlled-by-sh_fs.patch
@@ -0,0 +1,285 @@
+From f6427f8081fdd148aeefb37a02f1603584529935 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:58:48 -0800
+Subject: ASoC: fsi: PortA/B information was controlled by sh_fsi_port_info
+
+Current FSI got each PortA/B parameter by porta_flags/portb_flags from platform.
+And .set_rate function was shared for PortA/B.
+This structure was not readable and not flexible.
+This patch adds sh_fsi_port_info, and its own settings was added on each platform.
+it is preparation for DMAEngine support
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit fec691e73bf20e1c8e6ecd8e3725e4745bec4e21)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-ap4evb.c | 30 +++++++++++-------------------
+ arch/arm/mach-shmobile/board-mackerel.c | 18 ++++++++----------
+ arch/sh/boards/mach-ecovec24/setup.c | 4 +++-
+ arch/sh/boards/mach-se/7724/setup.c | 4 +++-
+ include/sound/sh_fsi.h | 10 +++++++---
+ sound/soc/sh/fsi.c | 32 ++++++++++++++++----------------
+ 6 files changed, 48 insertions(+), 50 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
+index 59f0d2c..e969a15 100644
+--- a/arch/arm/mach-shmobile/board-ap4evb.c
++++ b/arch/arm/mach-shmobile/board-ap4evb.c
+@@ -712,26 +712,18 @@ fsi_set_rate_end:
+ return ret;
+ }
+
+-static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
+-{
+- int ret;
+-
+- if (is_porta)
+- ret = fsi_ak4642_set_rate(dev, rate, enable);
+- else
+- ret = fsi_hdmi_set_rate(dev, rate, enable);
+-
+- return ret;
+-}
+-
+ static struct sh_fsi_platform_info fsi_info = {
+- .porta_flags = SH_FSI_BRS_INV,
+-
+- .portb_flags = SH_FSI_BRS_INV |
+- SH_FSI_BRM_INV |
+- SH_FSI_LRS_INV |
+- SH_FSI_FMT_SPDIF,
+- .set_rate = fsi_set_rate,
++ .port_a = {
++ .flags = SH_FSI_BRS_INV,
++ .set_rate = fsi_ak4642_set_rate,
++ },
++ .port_b = {
++ .flags = SH_FSI_BRS_INV |
++ SH_FSI_BRM_INV |
++ SH_FSI_LRS_INV |
++ SH_FSI_FMT_SPDIF,
++ .set_rate = fsi_hdmi_set_rate,
++ },
+ };
+
+ static struct resource fsi_resources[] = {
+diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
+index c2faf11..9207a56 100644
+--- a/arch/arm/mach-shmobile/board-mackerel.c
++++ b/arch/arm/mach-shmobile/board-mackerel.c
+@@ -881,7 +881,7 @@ static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
+ return clk_enable(clk);
+ }
+
+-static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
++static int fsi_b_set_rate(struct device *dev, int rate, int enable)
+ {
+ struct clk *fsib_clk;
+ struct clk *fdiv_clk = &sh7372_fsidivb_clk;
+@@ -890,10 +890,6 @@ static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
+ int ackmd_bpfmd;
+ int ret;
+
+- /* FSIA is slave mode. nothing to do here */
+- if (is_porta)
+- return 0;
+-
+ /* clock start */
+ switch (rate) {
+ case 44100:
+@@ -937,14 +933,16 @@ fsi_set_rate_end:
+ }
+
+ static struct sh_fsi_platform_info fsi_info = {
+- .porta_flags = SH_FSI_BRS_INV,
+-
+- .portb_flags = SH_FSI_BRS_INV |
++ .port_a = {
++ .flags = SH_FSI_BRS_INV,
++ },
++ .port_b = {
++ .flags = SH_FSI_BRS_INV |
+ SH_FSI_BRM_INV |
+ SH_FSI_LRS_INV |
+ SH_FSI_FMT_SPDIF,
+-
+- .set_rate = fsi_set_rate,
++ .set_rate = fsi_b_set_rate,
++ }
+ };
+
+ static struct resource fsi_resources[] = {
+diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
+index 15e3bfd..9c09829 100644
+--- a/arch/sh/boards/mach-ecovec24/setup.c
++++ b/arch/sh/boards/mach-ecovec24/setup.c
+@@ -790,7 +790,9 @@ static struct platform_device camera_devices[] = {
+
+ /* FSI */
+ static struct sh_fsi_platform_info fsi_info = {
+- .portb_flags = SH_FSI_BRS_INV,
++ .port_b = {
++ .flags = SH_FSI_BRS_INV,
++ },
+ };
+
+ static struct resource fsi_resources[] = {
+diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
+index abc4d12..7c66a3d 100644
+--- a/arch/sh/boards/mach-se/7724/setup.c
++++ b/arch/sh/boards/mach-se/7724/setup.c
+@@ -285,7 +285,9 @@ static struct platform_device ceu1_device = {
+ /* FSI */
+ /* change J20, J21, J22 pin to 1-2 connection to use slave mode */
+ static struct sh_fsi_platform_info fsi_info = {
+- .porta_flags = SH_FSI_BRS_INV,
++ .port_a = {
++ .flags = SH_FSI_BRS_INV,
++ },
+ };
+
+ static struct resource fsi_resources[] = {
+diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h
+index 9b1aaca..78cd77a 100644
+--- a/include/sound/sh_fsi.h
++++ b/include/sound/sh_fsi.h
+@@ -72,10 +72,14 @@
+ #define SH_FSI_BPFMD_32 (5 << 4)
+ #define SH_FSI_BPFMD_16 (6 << 4)
+
++struct sh_fsi_port_info {
++ unsigned long flags;
++ int (*set_rate)(struct device *dev, int rate, int enable);
++};
++
+ struct sh_fsi_platform_info {
+- unsigned long porta_flags;
+- unsigned long portb_flags;
+- int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
++ struct sh_fsi_port_info port_a;
++ struct sh_fsi_port_info port_b;
+ };
+
+ /*
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 1e10184..75d0cda 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -116,7 +116,7 @@
+
+ #define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
+
+-typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int enable);
++typedef int (*set_rate_func)(struct device *dev, int rate, int enable);
+
+ /*
+ * FSI driver use below type name for variable
+@@ -185,6 +185,7 @@ struct fsi_stream {
+ struct fsi_priv {
+ void __iomem *base;
+ struct fsi_master *master;
++ struct sh_fsi_port_info *info;
+
+ struct fsi_stream playback;
+ struct fsi_stream capture;
+@@ -227,7 +228,6 @@ struct fsi_master {
+ struct fsi_priv fsia;
+ struct fsi_priv fsib;
+ struct fsi_core *core;
+- struct sh_fsi_platform_info *info;
+ spinlock_t lock;
+ };
+
+@@ -346,24 +346,20 @@ static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
+ return fsi_get_priv_frm_dai(fsi_get_dai(substream));
+ }
+
+-static set_rate_func fsi_get_info_set_rate(struct fsi_master *master)
++static set_rate_func fsi_get_info_set_rate(struct fsi_priv *fsi)
+ {
+- if (!master->info)
++ if (!fsi->info)
+ return NULL;
+
+- return master->info->set_rate;
++ return fsi->info->set_rate;
+ }
+
+ static u32 fsi_get_info_flags(struct fsi_priv *fsi)
+ {
+- int is_porta = fsi_is_port_a(fsi);
+- struct fsi_master *master = fsi_get_master(fsi);
+-
+- if (!master->info)
++ if (!fsi->info)
+ return 0;
+
+- return is_porta ? master->info->porta_flags :
+- master->info->portb_flags;
++ return fsi->info->flags;
+ }
+
+ static u32 fsi_get_port_shift(struct fsi_priv *fsi, struct fsi_stream *io)
+@@ -628,11 +624,14 @@ 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(master);
++ set_rate_func set_rate = fsi_get_info_set_rate(fsi);
+ int fsi_ver = master->core->ver;
+ int ret;
+
+- ret = set_rate(dev, fsi_is_port_a(fsi), rate, enable);
++ if (!set_rate)
++ return 0;
++
++ ret = set_rate(dev, rate, enable);
+ if (ret < 0) /* error */
+ return ret;
+
+@@ -1093,8 +1092,7 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
+ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+ {
+ struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
+- struct fsi_master *master = fsi_get_master(fsi);
+- set_rate_func set_rate = fsi_get_info_set_rate(master);
++ set_rate_func set_rate = fsi_get_info_set_rate(fsi);
+ u32 flags = fsi_get_info_flags(fsi);
+ int ret;
+
+@@ -1312,6 +1310,7 @@ static int fsi_probe(struct platform_device *pdev)
+ {
+ struct fsi_master *master;
+ const struct platform_device_id *id_entry;
++ struct sh_fsi_platform_info *info = pdev->dev.platform_data;
+ struct resource *res;
+ unsigned int irq;
+ int ret;
+@@ -1346,13 +1345,13 @@ static int fsi_probe(struct platform_device *pdev)
+
+ /* master setting */
+ master->irq = irq;
+- master->info = pdev->dev.platform_data;
+ master->core = (struct fsi_core *)id_entry->driver_data;
+ spin_lock_init(&master->lock);
+
+ /* FSI A setting */
+ master->fsia.base = master->base;
+ master->fsia.master = master;
++ master->fsia.info = &info->port_a;
+ fsi_handler_init(&master->fsia);
+ ret = fsi_stream_probe(&master->fsia);
+ if (ret < 0) {
+@@ -1363,6 +1362,7 @@ static int fsi_probe(struct platform_device *pdev)
+ /* FSI B setting */
+ master->fsib.base = master->base + 0x40;
+ master->fsib.master = master;
++ master->fsib.info = &info->port_b;
+ fsi_handler_init(&master->fsib);
+ ret = fsi_stream_probe(&master->fsib);
+ if (ret < 0) {
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0116-ASoC-fsi-add-.init-.quit-handler-support.patch b/patches.kzm9g/0116-ASoC-fsi-add-.init-.quit-handler-support.patch
new file mode 100644
index 00000000000000..c52a74dac8d60a
--- /dev/null
+++ b/patches.kzm9g/0116-ASoC-fsi-add-.init-.quit-handler-support.patch
@@ -0,0 +1,48 @@
+From 9f742c8745ad3dc5d35f20f7960914021773b346 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:59:02 -0800
+Subject: ASoC: fsi: add .init/.quit handler support
+
+This is preparation for DMAEngine support
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 83344027cacf1944fe180907fa98ee4116ef33ea)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 75d0cda..79a0afb 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -201,6 +201,8 @@ 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 (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io);
+ int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io);
+@@ -474,6 +476,7 @@ static void fsi_stream_init(struct fsi_priv *fsi,
+ io->sample_width = samples_to_bytes(runtime, 1);
+ io->oerr_num = -1; /* ignore 1st err */
+ io->uerr_num = -1; /* ignore 1st err */
++ fsi_stream_handler_call(io, init, fsi, io);
+ spin_unlock_irqrestore(&master->lock, flags);
+ }
+
+@@ -491,6 +494,7 @@ static void fsi_stream_quit(struct fsi_priv *fsi, struct fsi_stream *io)
+ if (io->uerr_num > 0)
+ dev_err(dai->dev, "under_run = %d\n", io->uerr_num);
+
++ fsi_stream_handler_call(io, quit, fsi, io);
+ io->substream = NULL;
+ io->buff_sample_capa = 0;
+ io->buff_sample_pos = 0;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0117-ASoC-fsi-fixup-fsi_pointer-calculation-method.patch b/patches.kzm9g/0117-ASoC-fsi-fixup-fsi_pointer-calculation-method.patch
new file mode 100644
index 00000000000000..92bbecdf5f1aff
--- /dev/null
+++ b/patches.kzm9g/0117-ASoC-fsi-fixup-fsi_pointer-calculation-method.patch
@@ -0,0 +1,42 @@
+From a7a2edc574ad5ea06820d9c52a14a22981b8d6f0 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Wed, 8 Feb 2012 16:57:29 -0800
+Subject: ASoC: fsi: fixup fsi_pointer() calculation method
+
+current fsi_pointer() calculation was not correct for FSI driver.
+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 1987877d869027ab63dc9df515e11f19279a8091)
+
+Conflicts:
+
+ sound/soc/sh/fsi.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 79a0afb..1374680 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -1211,12 +1211,8 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
+ {
+ struct fsi_priv *fsi = fsi_get_priv(substream);
+ struct fsi_stream *io = fsi_stream_get(fsi, substream);
+- int samples_pos = io->buff_sample_pos - 1;
+
+- if (samples_pos < 0)
+- samples_pos = 0;
+-
+- return fsi_sample2frame(fsi, samples_pos);
++ return fsi_sample2frame(fsi, io->buff_sample_pos);
+ }
+
+ static struct snd_pcm_ops fsi_pcm_ops = {
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0118-ASoC-fsi-Add-DMAEngine-support.patch b/patches.kzm9g/0118-ASoC-fsi-Add-DMAEngine-support.patch
new file mode 100644
index 00000000000000..b54ad8d37586df
--- /dev/null
+++ b/patches.kzm9g/0118-ASoC-fsi-Add-DMAEngine-support.patch
@@ -0,0 +1,316 @@
+From 815f3e601467b439fa67c58bc2386d7b148e89b7 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 3 Feb 2012 00:59:33 -0800
+Subject: ASoC: fsi: Add DMAEngine support
+
+This patch supports DMAEngine to FSI driver.
+It supports only Tx case at this point.
+If platform/cpu doesn't support DMAEngine, FSI driver will
+use PIO transfer.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 7da9ced6066c654a22836c24bae509ef323e10a8)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/sound/sh_fsi.h | 2 +
+ sound/soc/sh/fsi.c | 232 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 234 insertions(+)
+
+diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h
+index 78cd77a..b457e87 100644
+--- a/include/sound/sh_fsi.h
++++ b/include/sound/sh_fsi.h
+@@ -74,6 +74,8 @@
+
+ struct sh_fsi_port_info {
+ unsigned long flags;
++ int tx_id;
++ int rx_id;
+ int (*set_rate)(struct device *dev, int rate, int enable);
+ };
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 1374680..378cc5b 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -13,8 +13,11 @@
+ */
+
+ #include <linux/delay.h>
++#include <linux/dma-mapping.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/io.h>
++#include <linux/scatterlist.h>
++#include <linux/sh_dma.h>
+ #include <linux/slab.h>
+ #include <linux/module.h>
+ #include <sound/soc.h>
+@@ -53,6 +56,7 @@
+
+ /* DO_FMT */
+ /* DI_FMT */
++#define CR_BWS_MASK (0x3 << 20) /* FSI2 */
+ #define CR_BWS_24 (0x0 << 20) /* FSI2 */
+ #define CR_BWS_16 (0x1 << 20) /* FSI2 */
+ #define CR_BWS_20 (0x2 << 20) /* FSI2 */
+@@ -68,6 +72,15 @@
+ #define CR_TDM (0x4 << 4)
+ #define CR_TDM_D (0x5 << 4)
+
++/* OUT_DMAC */
++/* IN_DMAC */
++#define VDMD_MASK (0x3 << 4)
++#define VDMD_FRONT (0x0 << 4) /* Package in front */
++#define VDMD_BACK (0x1 << 4) /* Package in back */
++#define VDMD_STREAM (0x2 << 4) /* Stream mode(16bit * 2) */
++
++#define DMA_ON (0x1 << 0)
++
+ /* DOFF_CTL */
+ /* DIFF_CTL */
+ #define IRQ_HALF 0x00100000
+@@ -180,6 +193,14 @@ struct fsi_stream {
+ */
+ struct fsi_stream_handler *handler;
+ struct fsi_priv *priv;
++
++ /*
++ * these are for DMAEngine
++ */
++ struct dma_chan *chan;
++ struct sh_dmae_slave slave; /* see fsi_handler_init() */
++ struct tasklet_struct tasklet;
++ dma_addr_t dma;
+ };
+
+ struct fsi_priv {
+@@ -889,6 +910,212 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
+ }
+
+ /*
++ * dma data transfer handler
++ */
++static int fsi_dma_init(struct fsi_priv *fsi, struct fsi_stream *io)
++{
++ struct snd_pcm_runtime *runtime = io->substream->runtime;
++ struct snd_soc_dai *dai = fsi_get_dai(io->substream);
++ enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
++ DMA_TO_DEVICE : DMA_FROM_DEVICE;
++
++ io->dma = dma_map_single(dai->dev, runtime->dma_area,
++ snd_pcm_lib_buffer_bytes(io->substream), dir);
++ return 0;
++}
++
++static int fsi_dma_quit(struct fsi_priv *fsi, struct fsi_stream *io)
++{
++ struct snd_soc_dai *dai = fsi_get_dai(io->substream);
++ enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
++ DMA_TO_DEVICE : DMA_FROM_DEVICE;
++
++ dma_unmap_single(dai->dev, io->dma,
++ snd_pcm_lib_buffer_bytes(io->substream), dir);
++ return 0;
++}
++
++static void fsi_dma_complete(void *data)
++{
++ struct fsi_stream *io = (struct fsi_stream *)data;
++ struct fsi_priv *fsi = fsi_stream_to_priv(io);
++ struct snd_pcm_runtime *runtime = io->substream->runtime;
++ struct snd_soc_dai *dai = fsi_get_dai(io->substream);
++ 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,
++ samples_to_bytes(runtime, io->period_samples), dir);
++
++ io->buff_sample_pos += io->period_samples;
++ io->period_pos++;
++
++ if (io->period_pos >= runtime->periods) {
++ io->period_pos = 0;
++ io->buff_sample_pos = 0;
++ }
++
++ fsi_count_fifo_err(fsi);
++ fsi_stream_transfer(io);
++
++ 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_tasklet(unsigned long data)
++{
++ struct fsi_stream *io = (struct fsi_stream *)data;
++ 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;
++
++ if (!fsi_stream_is_working(fsi, io))
++ 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);
++ buf = fsi_dma_get_area(io);
++
++ dma_sync_single_for_device(dai->dev, io->dma, 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 = chan->device->device_prep_slave_sg(chan, &sg, 1, dir,
++ DMA_PREP_INTERRUPT |
++ DMA_CTRL_ACK);
++ if (!desc) {
++ dev_err(dai->dev, "device_prep_slave_sg() fail\n");
++ return;
++ }
++
++ desc->callback = fsi_dma_complete;
++ desc->callback_param = io;
++
++ cookie = desc->tx_submit(desc);
++ if (cookie < 0) {
++ dev_err(dai->dev, "tx_submit() fail\n");
++ return;
++ }
++
++ dma_async_issue_pending(chan);
++
++ /*
++ * FIXME
++ *
++ * In DMAEngine case, codec and FSI cannot be started simultaneously
++ * since FSI is using tasklet.
++ * Therefore, in capture case, probably FSI FIFO will have got
++ * overflow error in this point.
++ * in that case, DMA cannot start transfer until error was cleared.
++ */
++ if (!is_play) {
++ if (ERR_OVER & fsi_reg_read(fsi, DIFF_ST)) {
++ fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
++ fsi_reg_write(fsi, DIFF_ST, 0);
++ }
++ }
++}
++
++static bool fsi_dma_filter(struct dma_chan *chan, void *param)
++{
++ struct sh_dmae_slave *slave = param;
++
++ chan->private = slave;
++
++ return true;
++}
++
++static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io)
++{
++ tasklet_schedule(&io->tasklet);
++
++ return 0;
++}
++
++static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
++ int start)
++{
++ u32 bws;
++ u32 dma;
++
++ 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);
++}
++
++static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io)
++{
++ dma_cap_mask_t mask;
++
++ dma_cap_zero(mask);
++ dma_cap_set(DMA_SLAVE, mask);
++
++ io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave);
++ if (!io->chan)
++ return -EIO;
++
++ tasklet_init(&io->tasklet, fsi_dma_do_tasklet, (unsigned long)io);
++
++ return 0;
++}
++
++static int fsi_dma_remove(struct fsi_priv *fsi, struct fsi_stream *io)
++{
++ tasklet_kill(&io->tasklet);
++
++ fsi_stream_stop(fsi, io);
++
++ if (io->chan)
++ dma_release_channel(io->chan);
++
++ io->chan = NULL;
++ return 0;
++}
++
++static struct fsi_stream_handler fsi_dma_push_handler = {
++ .init = fsi_dma_init,
++ .quit = fsi_dma_quit,
++ .probe = fsi_dma_probe,
++ .transfer = fsi_dma_transfer,
++ .remove = fsi_dma_remove,
++ .start_stop = fsi_dma_push_start_stop,
++};
++
++/*
+ * dai ops
+ */
+ static void fsi_fifo_init(struct fsi_priv *fsi,
+@@ -1304,6 +1531,11 @@ static void fsi_handler_init(struct fsi_priv *fsi)
+ fsi->playback.priv = fsi;
+ fsi->capture.handler = &fsi_pio_pop_handler; /* default PIO */
+ 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;
++ }
+ }
+
+ static int fsi_probe(struct platform_device *pdev)
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0119-ASoC-fsi-update-for-dmaengine-prep_slave_sg-fallout.patch b/patches.kzm9g/0119-ASoC-fsi-update-for-dmaengine-prep_slave_sg-fallout.patch
new file mode 100644
index 00000000000000..993e4a8926debb
--- /dev/null
+++ b/patches.kzm9g/0119-ASoC-fsi-update-for-dmaengine-prep_slave_sg-fallout.patch
@@ -0,0 +1,47 @@
+From d6964a7fc8d9cfbc0257030e420ed6dddc4f9a87 Mon Sep 17 00:00:00 2001
+From: Paul Mundt <lethal@linux-sh.org>
+Date: Tue, 17 Apr 2012 19:13:04 -0700
+Subject: ASoC: fsi: update for dmaengine prep_slave_sg fallout.
+
+Leading up to the ->device_prep_slave_sg change in
+185ecb5f4fd43911c35956d4cc7d94a1da30417f 'dmaengine: add context
+parameter to prep_slave_sg and prep_dma_cyclic' a generic wrapper was
+added in place to guard against the API change, though the fsi driver
+wasn't updated in the process (presumably its dmaengine support hadn't
+been merged yet at the time). This trivially switches over to the new
+wrapper and gets it building again.
+
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit cdf27f373781d8740b874b0b5c18142df32ebb52)
+
+N.B: This is not present in mainline yet
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/fsi.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
+index 378cc5b..74ed2df 100644
+--- a/sound/soc/sh/fsi.c
++++ b/sound/soc/sh/fsi.c
+@@ -1001,11 +1001,10 @@ static void fsi_dma_do_tasklet(unsigned long data)
+ sg_dma_address(&sg) = buf;
+ sg_dma_len(&sg) = len;
+
+- desc = chan->device->device_prep_slave_sg(chan, &sg, 1, dir,
+- DMA_PREP_INTERRUPT |
+- DMA_CTRL_ACK);
++ desc = dmaengine_prep_slave_sg(chan, &sg, 1, dir,
++ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc) {
+- dev_err(dai->dev, "device_prep_slave_sg() fail\n");
++ dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n");
+ return;
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0120-ASoC-add-generic-simple-card-support.patch b/patches.kzm9g/0120-ASoC-add-generic-simple-card-support.patch
new file mode 100644
index 00000000000000..55e724c70d040d
--- /dev/null
+++ b/patches.kzm9g/0120-ASoC-add-generic-simple-card-support.patch
@@ -0,0 +1,241 @@
+From 9e1c94e5b246c84b209c492495aee356c9c5a697 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)
+
+N.B: Not present in mainline yet
+
+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 8224db5..73e4a6f 100644
+--- a/sound/soc/Kconfig
++++ b/sound/soc/Kconfig
+@@ -61,5 +61,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 adb5719..bb3caf8 100644
+--- a/sound/soc/Makefile
++++ b/sound/soc/Makefile
+@@ -2,6 +2,7 @@ snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o so
+
+ 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.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0121-ASoC-sh-fsi-select-simple-card-on-Kconfig.patch b/patches.kzm9g/0121-ASoC-sh-fsi-select-simple-card-on-Kconfig.patch
new file mode 100644
index 00000000000000..5c478bb8f2f33f
--- /dev/null
+++ b/patches.kzm9g/0121-ASoC-sh-fsi-select-simple-card-on-Kconfig.patch
@@ -0,0 +1,34 @@
+From 466e94a3b185d97436c0ad54eac135d4127f2c61 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 8 Apr 2012 21:20:08 -0700
+Subject: ASoC: sh: fsi: select simple-card on Kconfig
+
+Current SuperH FSI require simple-card driver as sound card.
+This patch select it on Kconfig when FSI was selected.
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit cd04461e2f491c81d30fb3b234cf43db3f098103)
+
+N.B: Not present in mainline yet
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/sh/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
+index d8e06a6..fb8abc1 100644
+--- a/sound/soc/sh/Kconfig
++++ b/sound/soc/sh/Kconfig
+@@ -22,6 +22,7 @@ config SND_SOC_SH4_SSI
+
+ config SND_SOC_SH4_FSI
+ tristate "SH4 FSI support"
++ select SND_SIMPLE_CARD
+ help
+ This option enables FSI sound support
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0122-ASoC-ak4642-convert-to-soc-cache.patch b/patches.kzm9g/0122-ASoC-ak4642-convert-to-soc-cache.patch
new file mode 100644
index 00000000000000..8af07324da4b95
--- /dev/null
+++ b/patches.kzm9g/0122-ASoC-ak4642-convert-to-soc-cache.patch
@@ -0,0 +1,162 @@
+From 7e7b8eea233be75675adf28e0b77f8925cd3f294 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@gmail.com>
+Date: Tue, 11 Oct 2011 20:20:53 +0800
+Subject: ASoC: ak4642: convert to soc-cache
+
+Signed-off-by: Axel Lin <axel.lin@gmail.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit b91470bb374ed7db0448696ec85a3ed4785da2ee)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/codecs/ak4642.c | 82 +++++++----------------------------------------
+ 1 file changed, 12 insertions(+), 70 deletions(-)
+
+diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
+index 7d45197..30c8e2c 100644
+--- a/sound/soc/codecs/ak4642.c
++++ b/sound/soc/codecs/ak4642.c
+@@ -156,7 +156,6 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
+ struct ak4642_priv {
+ unsigned int sysclk;
+ enum snd_soc_control_type control_type;
+- void *control_data;
+ };
+
+ /*
+@@ -175,64 +174,6 @@ static const u8 ak4642_reg[AK4642_CACHEREGNUM] = {
+ 0x00,
+ };
+
+-/*
+- * read ak4642 register cache
+- */
+-static inline unsigned int ak4642_read_reg_cache(struct snd_soc_codec *codec,
+- unsigned int reg)
+-{
+- u16 *cache = codec->reg_cache;
+- if (reg >= AK4642_CACHEREGNUM)
+- return -1;
+- return cache[reg];
+-}
+-
+-/*
+- * write ak4642 register cache
+- */
+-static inline void ak4642_write_reg_cache(struct snd_soc_codec *codec,
+- u16 reg, unsigned int value)
+-{
+- u16 *cache = codec->reg_cache;
+- if (reg >= AK4642_CACHEREGNUM)
+- return;
+-
+- cache[reg] = value;
+-}
+-
+-/*
+- * write to the AK4642 register space
+- */
+-static int ak4642_write(struct snd_soc_codec *codec, unsigned int reg,
+- unsigned int value)
+-{
+- u8 data[2];
+-
+- /* data is
+- * D15..D8 AK4642 register offset
+- * D7...D0 register data
+- */
+- data[0] = reg & 0xff;
+- data[1] = value & 0xff;
+-
+- if (codec->hw_write(codec->control_data, data, 2) == 2) {
+- ak4642_write_reg_cache(codec, reg, value);
+- return 0;
+- } else
+- return -EIO;
+-}
+-
+-static int ak4642_sync(struct snd_soc_codec *codec)
+-{
+- u16 *cache = codec->reg_cache;
+- int i, r = 0;
+-
+- for (i = 0; i < AK4642_CACHEREGNUM; i++)
+- r |= ak4642_write(codec, i, cache[i]);
+-
+- return r;
+-};
+-
+ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+ {
+@@ -252,8 +193,8 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
+ */
+ snd_soc_update_bits(codec, MD_CTL4, DACH, DACH);
+ snd_soc_update_bits(codec, MD_CTL3, BST1, BST1);
+- ak4642_write(codec, L_IVC, 0x91); /* volume */
+- ak4642_write(codec, R_IVC, 0x91); /* volume */
++ snd_soc_write(codec, L_IVC, 0x91); /* volume */
++ snd_soc_write(codec, R_IVC, 0x91); /* volume */
+ snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC,
+ PMVCM | PMMIN | PMDAC);
+ snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP);
+@@ -272,9 +213,9 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
+ * This operation came from example code of
+ * "ASAHI KASEI AK4642" (japanese) manual p94.
+ */
+- ak4642_write(codec, SG_SL1, PMMP | MGAIN0);
+- ak4642_write(codec, TIMER, ZTM(0x3) | WTM(0x3));
+- ak4642_write(codec, ALC_CTL1, ALC | LMTH0);
++ snd_soc_write(codec, SG_SL1, PMMP | MGAIN0);
++ snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3));
++ snd_soc_write(codec, ALC_CTL1, ALC | LMTH0);
+ snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL,
+ PMVCM | PMADL);
+ snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR);
+@@ -462,7 +403,7 @@ static struct snd_soc_dai_driver ak4642_dai = {
+
+ static int ak4642_resume(struct snd_soc_codec *codec)
+ {
+- ak4642_sync(codec);
++ snd_soc_cache_sync(codec);
+ return 0;
+ }
+
+@@ -470,11 +411,15 @@ static int ak4642_resume(struct snd_soc_codec *codec)
+ static int ak4642_probe(struct snd_soc_codec *codec)
+ {
+ struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
++ int ret;
+
+ dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
+
+- codec->hw_write = (hw_write_t)i2c_master_send;
+- codec->control_data = ak4642->control_data;
++ ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type);
++ if (ret < 0) {
++ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
++ return ret;
++ }
+
+ snd_soc_add_controls(codec, ak4642_snd_controls,
+ ARRAY_SIZE(ak4642_snd_controls));
+@@ -485,8 +430,6 @@ static int ak4642_probe(struct snd_soc_codec *codec)
+ static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
+ .probe = ak4642_probe,
+ .resume = ak4642_resume,
+- .read = ak4642_read_reg_cache,
+- .write = ak4642_write,
+ .reg_cache_size = ARRAY_SIZE(ak4642_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = ak4642_reg,
+@@ -504,7 +447,6 @@ static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, ak4642);
+- ak4642->control_data = i2c;
+ ak4642->control_type = SND_SOC_I2C;
+
+ ret = snd_soc_register_codec(&i2c->dev,
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0123-ASoC-ak4642-ak4642-was-tested.patch b/patches.kzm9g/0123-ASoC-ak4642-ak4642-was-tested.patch
new file mode 100644
index 00000000000000..d2b3c3629faf05
--- /dev/null
+++ b/patches.kzm9g/0123-ASoC-ak4642-ak4642-was-tested.patch
@@ -0,0 +1,32 @@
+From 10f6b67d626f47c3a8e2ff83181f8ca85f8c39b9 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 6 Nov 2011 22:04:53 -0800
+Subject: ASoC: ak4642: ak4642 was tested
+
+ak4642 was tested by ms7724se board
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 202113912ba117b5c5f36e45529921b4cca4be6a)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/codecs/ak4642.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
+index 30c8e2c..96f6e2f 100644
+--- a/sound/soc/codecs/ak4642.c
++++ b/sound/soc/codecs/ak4642.c
+@@ -18,7 +18,7 @@
+ * This is very simple driver.
+ * It can use headphone output / stereo input only
+ *
+- * AK4642 is not tested.
++ * AK4642 is tested.
+ * AK4643 is tested.
+ */
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0124-ASoC-ak4642-add-ak4642_set_bias_level.patch b/patches.kzm9g/0124-ASoC-ak4642-add-ak4642_set_bias_level.patch
new file mode 100644
index 00000000000000..734a854e68588f
--- /dev/null
+++ b/patches.kzm9g/0124-ASoC-ak4642-add-ak4642_set_bias_level.patch
@@ -0,0 +1,88 @@
+From 9c25a0a4023775793af9678041183eb80b268ac5 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 10 Nov 2011 16:21:01 -0800
+Subject: ASoC: ak4642: add ak4642_set_bias_level()
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit ed2dd7da35cad3115c38fd42eecbecae899a1d7a)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/codecs/ak4642.c | 33 +++++++++++++++++++++++++++++----
+ 1 file changed, 29 insertions(+), 4 deletions(-)
+
+diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
+index 96f6e2f..8946580 100644
+--- a/sound/soc/codecs/ak4642.c
++++ b/sound/soc/codecs/ak4642.c
+@@ -195,8 +195,8 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
+ snd_soc_update_bits(codec, MD_CTL3, BST1, BST1);
+ snd_soc_write(codec, L_IVC, 0x91); /* volume */
+ snd_soc_write(codec, R_IVC, 0x91); /* volume */
+- snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC,
+- PMVCM | PMMIN | PMDAC);
++ snd_soc_update_bits(codec, PW_MGMT1, PMMIN | PMDAC,
++ PMMIN | PMDAC);
+ snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP);
+ snd_soc_update_bits(codec, PW_MGMT2, HPMTN, HPMTN);
+ } else {
+@@ -216,8 +216,7 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
+ snd_soc_write(codec, SG_SL1, PMMP | MGAIN0);
+ snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3));
+ snd_soc_write(codec, ALC_CTL1, ALC | LMTH0);
+- snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL,
+- PMVCM | PMADL);
++ snd_soc_update_bits(codec, PW_MGMT1, PMADL, PMADL);
+ snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR);
+ }
+
+@@ -375,6 +374,22 @@ static int ak4642_dai_hw_params(struct snd_pcm_substream *substream,
+ return 0;
+ }
+
++static int ak4642_set_bias_level(struct snd_soc_codec *codec,
++ enum snd_soc_bias_level level)
++{
++ switch (level) {
++ case SND_SOC_BIAS_OFF:
++ snd_soc_write(codec, PW_MGMT1, 0x00);
++ break;
++ default:
++ snd_soc_update_bits(codec, PW_MGMT1, PMVCM, PMVCM);
++ break;
++ }
++ codec->dapm.bias_level = level;
++
++ return 0;
++}
++
+ static struct snd_soc_dai_ops ak4642_dai_ops = {
+ .startup = ak4642_dai_startup,
+ .shutdown = ak4642_dai_shutdown,
+@@ -424,12 +439,22 @@ static int ak4642_probe(struct snd_soc_codec *codec)
+ snd_soc_add_controls(codec, ak4642_snd_controls,
+ ARRAY_SIZE(ak4642_snd_controls));
+
++ ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++
++ return 0;
++}
++
++static int ak4642_remove(struct snd_soc_codec *codec)
++{
++ ak4642_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+ }
+
+ static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
+ .probe = ak4642_probe,
++ .remove = ak4642_remove,
+ .resume = ak4642_resume,
++ .set_bias_level = ak4642_set_bias_level,
+ .reg_cache_size = ARRAY_SIZE(ak4642_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = ak4642_reg,
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0125-ASoC-ak4642-add-DAPM-support-for-HeadPhone-Output.patch b/patches.kzm9g/0125-ASoC-ak4642-add-DAPM-support-for-HeadPhone-Output.patch
new file mode 100644
index 00000000000000..821fa3dc100ae5
--- /dev/null
+++ b/patches.kzm9g/0125-ASoC-ak4642-add-DAPM-support-for-HeadPhone-Output.patch
@@ -0,0 +1,95 @@
+From 846a99689a9e20740e47fa868766f9bc56afd969 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 10 Nov 2011 16:21:31 -0800
+Subject: ASoC: ak4642: add DAPM support for HeadPhone Output
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 24747daea5610676fd1e2c2ca603c8822a085c87)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/codecs/ak4642.c | 44 +++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 35 insertions(+), 9 deletions(-)
+
+diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
+index 8946580..dd0c835 100644
+--- a/sound/soc/codecs/ak4642.c
++++ b/sound/soc/codecs/ak4642.c
+@@ -151,6 +151,37 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
+ 0, 0xFF, 1, out_tlv),
+ };
+
++static const struct snd_kcontrol_new ak4642_hpout_mixer_controls[] = {
++ SOC_DAPM_SINGLE("DACH", MD_CTL4, 0, 1, 0),
++};
++
++static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
++
++ /* Outputs */
++ SND_SOC_DAPM_OUTPUT("HPOUTL"),
++ SND_SOC_DAPM_OUTPUT("HPOUTR"),
++
++ SND_SOC_DAPM_MIXER("HPOUTL Mixer", PW_MGMT2, 5, 0,
++ &ak4642_hpout_mixer_controls[0],
++ ARRAY_SIZE(ak4642_hpout_mixer_controls)),
++
++ SND_SOC_DAPM_MIXER("HPOUTR Mixer", PW_MGMT2, 4, 0,
++ &ak4642_hpout_mixer_controls[0],
++ ARRAY_SIZE(ak4642_hpout_mixer_controls)),
++
++ /* DAC */
++ SND_SOC_DAPM_DAC("DAC", "HiFi Playback", PW_MGMT1, 2, 0),
++};
++
++static const struct snd_soc_dapm_route ak4642_intercon[] = {
++
++ /* Outputs */
++ {"HPOUTL", NULL, "HPOUTL Mixer"},
++ {"HPOUTR", NULL, "HPOUTR Mixer"},
++
++ {"HPOUTL Mixer", "DACH", "DAC"},
++ {"HPOUTR Mixer", "DACH", "DAC"},
++};
+
+ /* codec private data */
+ struct ak4642_priv {
+@@ -191,13 +222,8 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
+ * This operation came from example code of
+ * "ASAHI KASEI AK4642" (japanese) manual p97.
+ */
+- snd_soc_update_bits(codec, MD_CTL4, DACH, DACH);
+- snd_soc_update_bits(codec, MD_CTL3, BST1, BST1);
+ snd_soc_write(codec, L_IVC, 0x91); /* volume */
+ snd_soc_write(codec, R_IVC, 0x91); /* volume */
+- snd_soc_update_bits(codec, PW_MGMT1, PMMIN | PMDAC,
+- PMMIN | PMDAC);
+- snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP);
+ snd_soc_update_bits(codec, PW_MGMT2, HPMTN, HPMTN);
+ } else {
+ /*
+@@ -232,10 +258,6 @@ static void ak4642_dai_shutdown(struct snd_pcm_substream *substream,
+ if (is_play) {
+ /* stop headphone output */
+ snd_soc_update_bits(codec, PW_MGMT2, HPMTN, 0);
+- snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, 0);
+- snd_soc_update_bits(codec, PW_MGMT1, PMMIN | PMDAC, 0);
+- snd_soc_update_bits(codec, MD_CTL3, BST1, 0);
+- snd_soc_update_bits(codec, MD_CTL4, DACH, 0);
+ } else {
+ /* stop stereo input */
+ snd_soc_update_bits(codec, PW_MGMT1, PMADL, 0);
+@@ -458,6 +480,10 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
+ .reg_cache_size = ARRAY_SIZE(ak4642_reg),
+ .reg_word_size = sizeof(u8),
+ .reg_cache_default = ak4642_reg,
++ .dapm_widgets = ak4642_dapm_widgets,
++ .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets),
++ .dapm_routes = ak4642_intercon,
++ .num_dapm_routes = ARRAY_SIZE(ak4642_intercon),
+ };
+
+ #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0126-ASoC-ak4642-add-headphone-mute-switch-control.patch b/patches.kzm9g/0126-ASoC-ak4642-add-headphone-mute-switch-control.patch
new file mode 100644
index 00000000000000..9cb4990d757059
--- /dev/null
+++ b/patches.kzm9g/0126-ASoC-ak4642-add-headphone-mute-switch-control.patch
@@ -0,0 +1,47 @@
+From f77165fc08deee82107e20f35969d07a20340f94 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 10 Nov 2011 16:21:42 -0800
+Subject: ASoC: ak4642: add headphone mute switch control
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 3c7035268c2c89942fe51a61833d1066b4a766eb)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/codecs/ak4642.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
+index dd0c835..f728181 100644
+--- a/sound/soc/codecs/ak4642.c
++++ b/sound/soc/codecs/ak4642.c
+@@ -149,6 +149,8 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
+
+ SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC,
+ 0, 0xFF, 1, out_tlv),
++
++ SOC_SINGLE("Headphone Switch", PW_MGMT2, 6, 1, 0),
+ };
+
+ static const struct snd_kcontrol_new ak4642_hpout_mixer_controls[] = {
+@@ -224,7 +226,6 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
+ */
+ snd_soc_write(codec, L_IVC, 0x91); /* volume */
+ snd_soc_write(codec, R_IVC, 0x91); /* volume */
+- snd_soc_update_bits(codec, PW_MGMT2, HPMTN, HPMTN);
+ } else {
+ /*
+ * start stereo input
+@@ -256,8 +257,6 @@ static void ak4642_dai_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_codec *codec = dai->codec;
+
+ if (is_play) {
+- /* stop headphone output */
+- snd_soc_update_bits(codec, PW_MGMT2, HPMTN, 0);
+ } else {
+ /* stop stereo input */
+ snd_soc_update_bits(codec, PW_MGMT1, PMADL, 0);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0127-ASoC-ak4642-add-Line-out-support.patch b/patches.kzm9g/0127-ASoC-ak4642-add-Line-out-support.patch
new file mode 100644
index 00000000000000..7f11a0f54fa8b9
--- /dev/null
+++ b/patches.kzm9g/0127-ASoC-ak4642-add-Line-out-support.patch
@@ -0,0 +1,61 @@
+From 5b5d2d5ef56e2faf823428eecd05c9fdc6d5945f Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 10 Nov 2011 16:21:55 -0800
+Subject: ASoC: ak4642: add Line out support
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit e8c83dbfb7fc0c3cec141112524906b029a1f413)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/codecs/ak4642.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
+index f728181..0f2ee7f 100644
+--- a/sound/soc/codecs/ak4642.c
++++ b/sound/soc/codecs/ak4642.c
+@@ -157,11 +157,16 @@ static const struct snd_kcontrol_new ak4642_hpout_mixer_controls[] = {
+ SOC_DAPM_SINGLE("DACH", MD_CTL4, 0, 1, 0),
+ };
+
++static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = {
++ SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0),
++};
++
+ static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
+
+ /* Outputs */
+ SND_SOC_DAPM_OUTPUT("HPOUTL"),
+ SND_SOC_DAPM_OUTPUT("HPOUTR"),
++ SND_SOC_DAPM_OUTPUT("LINEOUT"),
+
+ SND_SOC_DAPM_MIXER("HPOUTL Mixer", PW_MGMT2, 5, 0,
+ &ak4642_hpout_mixer_controls[0],
+@@ -171,6 +176,10 @@ static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
+ &ak4642_hpout_mixer_controls[0],
+ ARRAY_SIZE(ak4642_hpout_mixer_controls)),
+
++ SND_SOC_DAPM_MIXER("LINEOUT Mixer", PW_MGMT1, 3, 0,
++ &ak4642_lout_mixer_controls[0],
++ ARRAY_SIZE(ak4642_lout_mixer_controls)),
++
+ /* DAC */
+ SND_SOC_DAPM_DAC("DAC", "HiFi Playback", PW_MGMT1, 2, 0),
+ };
+@@ -180,9 +189,11 @@ static const struct snd_soc_dapm_route ak4642_intercon[] = {
+ /* Outputs */
+ {"HPOUTL", NULL, "HPOUTL Mixer"},
+ {"HPOUTR", NULL, "HPOUTR Mixer"},
++ {"LINEOUT", NULL, "LINEOUT Mixer"},
+
+ {"HPOUTL Mixer", "DACH", "DAC"},
+ {"HPOUTR Mixer", "DACH", "DAC"},
++ {"LINEOUT Mixer", "DACL", "DAC"},
+ };
+
+ /* codec private data */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0128-ASoC-ak4642-add-ak4648-support.patch b/patches.kzm9g/0128-ASoC-ak4642-add-ak4648-support.patch
new file mode 100644
index 00000000000000..4a8bd0825771a8
--- /dev/null
+++ b/patches.kzm9g/0128-ASoC-ak4642-add-ak4648-support.patch
@@ -0,0 +1,115 @@
+From 03977c4c632d21018c3b9bcc076c3b62aeb91579 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 10 Nov 2011 16:22:05 -0800
+Subject: ASoC: ak4642: add ak4648 support
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit a9317e8b6b53ab61d3ee764b6456596efd8c83b7)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/codecs/ak4642.c | 44 ++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 36 insertions(+), 8 deletions(-)
+
+diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
+index 0f2ee7f..8a12db4 100644
+--- a/sound/soc/codecs/ak4642.c
++++ b/sound/soc/codecs/ak4642.c
+@@ -20,6 +20,7 @@
+ *
+ * AK4642 is tested.
+ * AK4643 is tested.
++ * AK4648 is tested.
+ */
+
+ #include <linux/delay.h>
+@@ -70,8 +71,6 @@
+ #define HP_MS 0x23
+ #define SPK_MS 0x24
+
+-#define AK4642_CACHEREGNUM 0x25
+-
+ /* PW_MGMT1*/
+ #define PMVCM (1 << 6) /* VCOM Power Management */
+ #define PMMIN (1 << 5) /* MIN Input Power Management */
+@@ -205,7 +204,7 @@ struct ak4642_priv {
+ /*
+ * ak4642 register cache
+ */
+-static const u8 ak4642_reg[AK4642_CACHEREGNUM] = {
++static const u8 ak4642_reg[] = {
+ 0x00, 0x00, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x00,
+ 0xe1, 0xe1, 0x18, 0x00,
+@@ -218,6 +217,19 @@ static const u8 ak4642_reg[AK4642_CACHEREGNUM] = {
+ 0x00,
+ };
+
++static const u8 ak4648_reg[] = {
++ 0x00, 0x00, 0x01, 0x00,
++ 0x02, 0x00, 0x00, 0x00,
++ 0xe1, 0xe1, 0x18, 0x00,
++ 0xe1, 0x18, 0x11, 0xb8,
++ 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x88, 0x88, 0x08,
++};
++
+ static int ak4642_dai_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+ {
+@@ -487,9 +499,23 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
+ .remove = ak4642_remove,
+ .resume = ak4642_resume,
+ .set_bias_level = ak4642_set_bias_level,
+- .reg_cache_size = ARRAY_SIZE(ak4642_reg),
++ .reg_cache_default = ak4642_reg, /* ak4642 reg */
++ .reg_cache_size = ARRAY_SIZE(ak4642_reg), /* ak4642 reg */
++ .reg_word_size = sizeof(u8),
++ .dapm_widgets = ak4642_dapm_widgets,
++ .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets),
++ .dapm_routes = ak4642_intercon,
++ .num_dapm_routes = ARRAY_SIZE(ak4642_intercon),
++};
++
++static struct snd_soc_codec_driver soc_codec_dev_ak4648 = {
++ .probe = ak4642_probe,
++ .remove = ak4642_remove,
++ .resume = ak4642_resume,
++ .set_bias_level = ak4642_set_bias_level,
++ .reg_cache_default = ak4648_reg, /* ak4648 reg */
++ .reg_cache_size = ARRAY_SIZE(ak4648_reg), /* ak4648 reg */
+ .reg_word_size = sizeof(u8),
+- .reg_cache_default = ak4642_reg,
+ .dapm_widgets = ak4642_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets),
+ .dapm_routes = ak4642_intercon,
+@@ -511,7 +537,8 @@ static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
+ ak4642->control_type = SND_SOC_I2C;
+
+ ret = snd_soc_register_codec(&i2c->dev,
+- &soc_codec_dev_ak4642, &ak4642_dai, 1);
++ (struct snd_soc_codec_driver *)id->driver_data,
++ &ak4642_dai, 1);
+ if (ret < 0)
+ kfree(ak4642);
+ return ret;
+@@ -525,8 +552,9 @@ static __devexit int ak4642_i2c_remove(struct i2c_client *client)
+ }
+
+ static const struct i2c_device_id ak4642_i2c_id[] = {
+- { "ak4642", 0 },
+- { "ak4643", 0 },
++ { "ak4642", (kernel_ulong_t)&soc_codec_dev_ak4642 },
++ { "ak4643", (kernel_ulong_t)&soc_codec_dev_ak4642 },
++ { "ak4648", (kernel_ulong_t)&soc_codec_dev_ak4648 },
+ { }
+ };
+ MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0129-ASoC-Remove-driver-versioning-from-ak4642.patch b/patches.kzm9g/0129-ASoC-Remove-driver-versioning-from-ak4642.patch
new file mode 100644
index 00000000000000..5b32a8991315bf
--- /dev/null
+++ b/patches.kzm9g/0129-ASoC-Remove-driver-versioning-from-ak4642.patch
@@ -0,0 +1,41 @@
+From 5433d40ad2e432a05413d77baa7a3c0869fcc75c Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Sun, 27 Nov 2011 12:11:46 +0000
+Subject: ASoC: Remove driver versioning from ak4642
+
+It's never been updated so it can't be that useful and it makes the
+driver needlessly chatty.
+
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 679acec1f240b433dc3879714655b6c6452385ea)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/codecs/ak4642.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
+index 8a12db4..a04eebf 100644
+--- a/sound/soc/codecs/ak4642.c
++++ b/sound/soc/codecs/ak4642.c
+@@ -31,8 +31,6 @@
+ #include <sound/initval.h>
+ #include <sound/tlv.h>
+
+-#define AK4642_VERSION "0.0.1"
+-
+ #define PW_MGMT1 0x00
+ #define PW_MGMT2 0x01
+ #define SG_SL1 0x02
+@@ -472,8 +470,6 @@ static int ak4642_probe(struct snd_soc_codec *codec)
+ struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
+ int ret;
+
+- dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
+-
+ ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0130-ASoC-Convert-ak4642-to-devm_kzalloc.patch b/patches.kzm9g/0130-ASoC-Convert-ak4642-to-devm_kzalloc.patch
new file mode 100644
index 00000000000000..a9af28c5a85b10
--- /dev/null
+++ b/patches.kzm9g/0130-ASoC-Convert-ak4642-to-devm_kzalloc.patch
@@ -0,0 +1,47 @@
+From de89e5feef647f18b97650663538b91a7c11754c Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@gmail.com>
+Date: Tue, 20 Dec 2011 14:40:12 +0800
+Subject: ASoC: Convert ak4642 to devm_kzalloc()
+
+Signed-off-by: Axel Lin <axel.lin@gmail.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit 2ff49eea9b8a1d92c2ab09d803dfdc06f4f8e74b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/codecs/ak4642.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
+index a04eebf..2cdcea2 100644
+--- a/sound/soc/codecs/ak4642.c
++++ b/sound/soc/codecs/ak4642.c
+@@ -525,7 +525,8 @@ static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
+ struct ak4642_priv *ak4642;
+ int ret;
+
+- ak4642 = kzalloc(sizeof(struct ak4642_priv), GFP_KERNEL);
++ ak4642 = devm_kzalloc(&i2c->dev, sizeof(struct ak4642_priv),
++ GFP_KERNEL);
+ if (!ak4642)
+ return -ENOMEM;
+
+@@ -535,15 +536,12 @@ static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
+ ret = snd_soc_register_codec(&i2c->dev,
+ (struct snd_soc_codec_driver *)id->driver_data,
+ &ak4642_dai, 1);
+- if (ret < 0)
+- kfree(ak4642);
+ return ret;
+ }
+
+ static __devexit int ak4642_i2c_remove(struct i2c_client *client)
+ {
+ snd_soc_unregister_codec(&client->dev);
+- kfree(i2c_get_clientdata(client));
+ return 0;
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0131-ASoC-ak4642-fixup-HeadPhone-L-R-dapm-settings.patch b/patches.kzm9g/0131-ASoC-ak4642-fixup-HeadPhone-L-R-dapm-settings.patch
new file mode 100644
index 00000000000000..fb79827dfd5a65
--- /dev/null
+++ b/patches.kzm9g/0131-ASoC-ak4642-fixup-HeadPhone-L-R-dapm-settings.patch
@@ -0,0 +1,85 @@
+From 74ca5f2a0fe5cb5938687814e9dbceb6e0da98fd Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 20 Feb 2012 20:14:16 -0800
+Subject: ASoC: ak4642: fixup HeadPhone L/R dapm settings
+
+Current ak4642 driver had wrong dapm settings for headphone L/R.
+If you select headphone L, and select R after that,
+headphone L setting was removed by R settings.
+
+This patch fixes it up.
+It provides just "Headphone Enable" to user side
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+(cherry picked from commit e555cf363167f09efae96d32a363e24c4de16b7b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ sound/soc/codecs/ak4642.c | 31 ++++++++++++++++---------------
+ 1 file changed, 16 insertions(+), 15 deletions(-)
+
+diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
+index 2cdcea2..6a9516ca 100644
+--- a/sound/soc/codecs/ak4642.c
++++ b/sound/soc/codecs/ak4642.c
+@@ -146,13 +146,10 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
+
+ SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC,
+ 0, 0xFF, 1, out_tlv),
+-
+- SOC_SINGLE("Headphone Switch", PW_MGMT2, 6, 1, 0),
+ };
+
+-static const struct snd_kcontrol_new ak4642_hpout_mixer_controls[] = {
+- SOC_DAPM_SINGLE("DACH", MD_CTL4, 0, 1, 0),
+-};
++static const struct snd_kcontrol_new ak4642_headphone_control =
++ SOC_DAPM_SINGLE("Switch", PW_MGMT2, 6, 1, 0);
+
+ static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = {
+ SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0),
+@@ -165,13 +162,12 @@ static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
+ SND_SOC_DAPM_OUTPUT("HPOUTR"),
+ SND_SOC_DAPM_OUTPUT("LINEOUT"),
+
+- SND_SOC_DAPM_MIXER("HPOUTL Mixer", PW_MGMT2, 5, 0,
+- &ak4642_hpout_mixer_controls[0],
+- ARRAY_SIZE(ak4642_hpout_mixer_controls)),
++ SND_SOC_DAPM_PGA("HPL Out", PW_MGMT2, 5, 0, NULL, 0),
++ SND_SOC_DAPM_PGA("HPR Out", PW_MGMT2, 4, 0, NULL, 0),
++ SND_SOC_DAPM_SWITCH("Headphone Enable", SND_SOC_NOPM, 0, 0,
++ &ak4642_headphone_control),
+
+- SND_SOC_DAPM_MIXER("HPOUTR Mixer", PW_MGMT2, 4, 0,
+- &ak4642_hpout_mixer_controls[0],
+- ARRAY_SIZE(ak4642_hpout_mixer_controls)),
++ SND_SOC_DAPM_PGA("DACH", MD_CTL4, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("LINEOUT Mixer", PW_MGMT1, 3, 0,
+ &ak4642_lout_mixer_controls[0],
+@@ -184,12 +180,17 @@ static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
+ static const struct snd_soc_dapm_route ak4642_intercon[] = {
+
+ /* Outputs */
+- {"HPOUTL", NULL, "HPOUTL Mixer"},
+- {"HPOUTR", NULL, "HPOUTR Mixer"},
++ {"HPOUTL", NULL, "HPL Out"},
++ {"HPOUTR", NULL, "HPR Out"},
+ {"LINEOUT", NULL, "LINEOUT Mixer"},
+
+- {"HPOUTL Mixer", "DACH", "DAC"},
+- {"HPOUTR Mixer", "DACH", "DAC"},
++ {"HPL Out", NULL, "Headphone Enable"},
++ {"HPR Out", NULL, "Headphone Enable"},
++
++ {"Headphone Enable", "Switch", "DACH"},
++
++ {"DACH", NULL, "DAC"},
++
+ {"LINEOUT Mixer", "DACL", "DAC"},
+ };
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0132-ARM-mach-shmobile-clock-r8a7740-add-SDHI-clock.patch b/patches.kzm9g/0132-ARM-mach-shmobile-clock-r8a7740-add-SDHI-clock.patch
new file mode 100644
index 00000000000000..6b9c9ad480c4c7
--- /dev/null
+++ b/patches.kzm9g/0132-ARM-mach-shmobile-clock-r8a7740-add-SDHI-clock.patch
@@ -0,0 +1,54 @@
+From 08bfd254a0ea22a80db19e5b13cb6f7fa745ee5d 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
+
+N.B: Not present upstream yet
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+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 30535f4..5c6b548 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, MSTP323, MSTP320,
++ MSTP314, MSTP313,
+
+- MSTP416, MSTP407, MSTP406,
++ MSTP416, MSTP415, MSTP407, MSTP406,
+
+ MSTP_NR
+ };
+@@ -382,8 +383,11 @@ static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP329] = SH_CLK_MSTP32(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
+ [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 */
+ };
+@@ -442,6 +446,10 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
+ 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.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0133-ARM-mach-shmobile-clock-r8a7740-add-MMCIF-clock.patch b/patches.kzm9g/0133-ARM-mach-shmobile-clock-r8a7740-add-MMCIF-clock.patch
new file mode 100644
index 00000000000000..1540498275ec9a
--- /dev/null
+++ b/patches.kzm9g/0133-ARM-mach-shmobile-clock-r8a7740-add-MMCIF-clock.patch
@@ -0,0 +1,45 @@
+From 1e625ddaa54bdddc2e7c97a6776634b257512de4 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
+
+N.B: Not present upstream yet
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+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 5c6b548..927d42a 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, MSTP323, MSTP320,
+- MSTP314, MSTP313,
++ MSTP314, MSTP313, MSTP312,
+
+ MSTP416, MSTP415, MSTP407, MSTP406,
+
+@@ -385,6 +385,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 */
+@@ -448,6 +449,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.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0134-ARM-mach-shmobile-r8a7740-reserve-DMA-memory-for-the.patch b/patches.kzm9g/0134-ARM-mach-shmobile-r8a7740-reserve-DMA-memory-for-the.patch
new file mode 100644
index 00000000000000..932f3f973a4284
--- /dev/null
+++ b/patches.kzm9g/0134-ARM-mach-shmobile-r8a7740-reserve-DMA-memory-for-the.patch
@@ -0,0 +1,44 @@
+From daaa13e4d7c9028792b6b51ef2e147993c6e9c91 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.
+
+N.B: Not present upstream yet
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+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 74e5234..5d92def 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>
+@@ -59,6 +60,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.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0135-ARM-mach-shmobile-clock-r8a7740-add-FSI-clock.patch b/patches.kzm9g/0135-ARM-mach-shmobile-clock-r8a7740-add-FSI-clock.patch
new file mode 100644
index 00000000000000..4dd3b048f6d7a9
--- /dev/null
+++ b/patches.kzm9g/0135-ARM-mach-shmobile-clock-r8a7740-add-FSI-clock.patch
@@ -0,0 +1,45 @@
+From d46a82ccbc9c9caf9116bc62737f6ba9470012dc Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 24 Apr 2012 02:20:41 -0700
+Subject: ARM: mach-shmobile: clock-r8a7740: add FSI clock
+
+N.B: Not present upstream yet
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+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 927d42a..89a2f9d 100644
+--- a/arch/arm/mach-shmobile/clock-r8a7740.c
++++ b/arch/arm/mach-shmobile/clock-r8a7740.c
+@@ -355,7 +355,7 @@ enum {
+ MSTP222,
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+
+- MSTP329, MSTP323, MSTP320,
++ MSTP329, MSTP328, MSTP323, MSTP320,
+ MSTP314, MSTP313, MSTP312,
+
+ MSTP416, MSTP415, MSTP407, MSTP406,
+@@ -381,6 +381,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 */
+ [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 20, 0), /* USBF */
+ [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
+@@ -445,6 +446,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]),
+ CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP320]),
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0136-ARM-mach-shmobile-armadillo800eva-add-SDHI0-support.patch b/patches.kzm9g/0136-ARM-mach-shmobile-armadillo800eva-add-SDHI0-support.patch
new file mode 100644
index 00000000000000..fa5ba75066c6ed
--- /dev/null
+++ b/patches.kzm9g/0136-ARM-mach-shmobile-armadillo800eva-add-SDHI0-support.patch
@@ -0,0 +1,131 @@
+From f33fc2bf482665a0dc1d0fed1e0a180268235c11 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>
+
+N.B: Not present upstream yet
+
+Conflicts:
+
+ arch/arm/mach-shmobile/board-armadillo800eva.c
+
+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 c2affc4..fa5b541 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -28,6 +28,9 @@
+ #include <linux/gpio_keys.h>
+ #include <linux/sh_eth.h>
+ #include <linux/videodev2.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>
+@@ -184,6 +187,55 @@ static struct platform_device lcdc0_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[] = {
+ {
+@@ -222,6 +274,7 @@ static struct platform_device *eva_devices[] __initdata = {
+ &lcdc0_device,
+ &gpio_keys_device,
+ &sh_eth_device,
++ &sdhi0_device,
+ };
+
+ /*
+@@ -302,6 +355,24 @@ static void __init eva_init(void)
+ gpio_request(GPIO_PORT18, NULL); /* PHY_RST */
+ gpio_direction_output(GPIO_PORT18, 1);
+
++ /* 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.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0137-ARM-mach-shmobile-armadillo800eva-add-SDHI1-support.patch b/patches.kzm9g/0137-ARM-mach-shmobile-armadillo800eva-add-SDHI1-support.patch
new file mode 100644
index 00000000000000..95899dc599baa6
--- /dev/null
+++ b/patches.kzm9g/0137-ARM-mach-shmobile-armadillo800eva-add-SDHI1-support.patch
@@ -0,0 +1,110 @@
+From 4c5dd88a2bfcca6a2bf0119f8a792e40e3280b22 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)
+
+N.B: Not present upstream yet
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+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 fa5b541..2f4b7f9 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -90,7 +90,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-+---------------+----------------------------
+ * 00 | JTAG | SH-X2
+@@ -236,6 +236,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[] = {
+ {
+@@ -382,6 +420,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.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0138-ARM-mach-shmobile-armadillo800eva-add-MMCIF-support.patch b/patches.kzm9g/0138-ARM-mach-shmobile-armadillo800eva-add-MMCIF-support.patch
new file mode 100644
index 00000000000000..90e1fde9b80810
--- /dev/null
+++ b/patches.kzm9g/0138-ARM-mach-shmobile-armadillo800eva-add-MMCIF-support.patch
@@ -0,0 +1,105 @@
+From 31b40a107a29865822e41b242ffc8eb75f7faf08 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
+
+N.B: Not present upstream yet
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+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 2f4b7f9..eb97618 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -30,6 +30,7 @@
+ #include <linux/videodev2.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>
+@@ -274,6 +275,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[] = {
+ {
+@@ -313,6 +352,7 @@ static struct platform_device *eva_devices[] __initdata = {
+ &gpio_keys_device,
+ &sh_eth_device,
+ &sdhi0_device,
++ &sh_mmcif_device,
+ };
+
+ /*
+@@ -412,6 +452,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.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0139-ARM-mach-shmobile-armadillo800eva-Add-FSI-WM8978-sup.patch b/patches.kzm9g/0139-ARM-mach-shmobile-armadillo800eva-Add-FSI-WM8978-sup.patch
new file mode 100644
index 00000000000000..eb3642658f3d70
--- /dev/null
+++ b/patches.kzm9g/0139-ARM-mach-shmobile-armadillo800eva-Add-FSI-WM8978-sup.patch
@@ -0,0 +1,181 @@
+From bbfe67adb04a9203585aa910f5697c13a89db7d8 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 24 Apr 2012 02:20:57 -0700
+Subject: ARM: mach-shmobile: armadillo800eva: Add FSI-WM8978 support
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+
+N.B: Not present upstream yet
+
+Conflicts:
+
+ arch/arm/mach-shmobile/board-armadillo800eva.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/Kconfig | 1 +
+ arch/arm/mach-shmobile/board-armadillo800eva.c | 97 ++++++++++++++++++++++++++
+ 2 files changed, 98 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
+index 7a1b589..91a4f32 100644
+--- a/arch/arm/mach-shmobile/Kconfig
++++ b/arch/arm/mach-shmobile/Kconfig
+@@ -79,6 +79,7 @@ config MACH_ARMADILLO800EVA
+ bool "Armadillo-800 EVA board"
+ depends on ARCH_R8A7740
+ select ARCH_REQUIRE_GPIOLIB
++ select SND_SOC_WM8978 if SND_SIMPLE_CARD
+
+ comment "SH-Mobile System Configuration"
+
+diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
+index eb97618..0dc387b 100644
+--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
+@@ -42,6 +42,8 @@
+ #include <asm/hardware/cache-l2x0.h>
+ #include <mach/r8a7740.h>
+ #include <video/sh_mobile_lcdc.h>
++#include <sound/sh_fsi.h>
++#include <sound/simple_card.h>
+
+ /*
+ * CON1 Camera Module
+@@ -101,6 +103,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);
++}
++
+ /* Ether */
+ static struct sh_eth_plat_data sh_eth_platdata = {
+ .phy = 0x00, /* LAN8710A */
+@@ -313,12 +337,68 @@ static struct platform_device sh_mmcif_device = {
+ .resource = sh_mmcif_resources,
+ };
+
++/* FSI-WM8978 */
++static struct sh_fsi_platform_info fsi_info = {
++ .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,
++ },
++};
++
++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",
++ .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),
++ },
+ };
+
+ /* GPIO KEY */
+@@ -353,11 +433,15 @@ static struct platform_device *eva_devices[] __initdata = {
+ &sh_eth_device,
+ &sdhi0_device,
+ &sh_mmcif_device,
++ &fsi_device,
++ &fsi_wm8978_device,
+ };
+
+ /*
+ * board init
+ */
++#define GPIO_PORT7CR 0xe6050007
++#define GPIO_PORT8CR 0xe6050008
+ static void __init eva_init(void)
+ {
+ r8a7740_pinmux_init();
+@@ -468,6 +552,19 @@ static void __init eva_init(void)
+ gpio_request(GPIO_FN_MMC1_D6_PORT143, NULL);
+ gpio_request(GPIO_FN_MMC1_D7_PORT142, NULL);
+
++ /* FSI */
++ gpio_request(GPIO_FN_FSIAIBT, NULL);
++ gpio_request(GPIO_FN_FSIAILR, NULL);
++ gpio_request(GPIO_FN_FSIAOMC, NULL);
++ gpio_request(GPIO_FN_FSIACK, 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.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0140-ARM-mach-shmobile-Add-support-for-PINT-though-INTC-m.patch b/patches.kzm9g/0140-ARM-mach-shmobile-Add-support-for-PINT-though-INTC-m.patch
new file mode 100644
index 00000000000000..c4a8edb5e25d1b
--- /dev/null
+++ b/patches.kzm9g/0140-ARM-mach-shmobile-Add-support-for-PINT-though-INTC-m.patch
@@ -0,0 +1,80 @@
+From 6bd2390c23f97b846328d2f6f87cd786b3954d6c Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Mon, 17 Oct 2011 18:00:35 +0900
+Subject: ARM: mach-shmobile: Add support for PINT though INTC macros
+
+Add a INTC_PINT() macro with various helper bits to allow SoCs
+like sh73a0 to suppor the PINT hardware using regular INTC tables.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 91c088ae17c62f7741d9563e36935bc7a69a7e9e)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/include/mach/intc.h | 51 ++++++++++++++++++++++++++++++
+ 1 file changed, 51 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/include/mach/intc.h b/arch/arm/mach-shmobile/include/mach/intc.h
+index 1cd8b36..8b22258 100644
+--- a/arch/arm/mach-shmobile/include/mach/intc.h
++++ b/arch/arm/mach-shmobile/include/mach/intc.h
+@@ -192,4 +192,55 @@ static struct intc_desc p ## _desc __initdata = { \
+ p ## _sense_registers, p ## _ack_registers) \
+ }
+
++#define INTC_PINT_E_EMPTY
++#define INTC_PINT_E_NONE 0, 0, 0, 0, 0, 0, 0, 0,
++#define INTC_PINT_E(p) \
++ PINT ## p ## 0, PINT ## p ## 1, PINT ## p ## 2, PINT ## p ## 3, \
++ PINT ## p ## 4, PINT ## p ## 5, PINT ## p ## 6, PINT ## p ## 7,
++
++#define INTC_PINT_V_NONE
++#define INTC_PINT_V(p, vect) \
++ vect(PINT ## p ## 0, 0), vect(PINT ## p ## 1, 1), \
++ vect(PINT ## p ## 2, 2), vect(PINT ## p ## 3, 3), \
++ vect(PINT ## p ## 4, 4), vect(PINT ## p ## 5, 5), \
++ vect(PINT ## p ## 6, 6), vect(PINT ## p ## 7, 7),
++
++#define INTC_PINT(p, mask_reg, sense_base, str, \
++ enums_1, enums_2, enums_3, enums_4, \
++ vect_1, vect_2, vect_3, vect_4, \
++ mask_a, mask_b, mask_c, mask_d, \
++ sense_a, sense_b, sense_c, sense_d) \
++ \
++enum { \
++ PINT ## p ## _UNUSED = 0, \
++ enums_1 enums_2 enums_3 enums_4 \
++}; \
++ \
++static struct intc_vect p ## _vectors[] __initdata = { \
++ vect_1 vect_2 vect_3 vect_4 \
++}; \
++ \
++static struct intc_mask_reg p ## _mask_registers[] __initdata = { \
++ { mask_reg, 0, 32, /* PINTER */ \
++ { mask_a mask_b mask_c mask_d } } \
++}; \
++ \
++static struct intc_sense_reg p ## _sense_registers[] __initdata = { \
++ { sense_base + 0x00, 16, 2, /* PINTCR */ \
++ { sense_a } }, \
++ { sense_base + 0x04, 16, 2, /* PINTCR */ \
++ { sense_b } }, \
++ { sense_base + 0x08, 16, 2, /* PINTCR */ \
++ { sense_c } }, \
++ { sense_base + 0x0c, 16, 2, /* PINTCR */ \
++ { sense_d } }, \
++}; \
++ \
++static struct intc_desc p ## _desc __initdata = { \
++ .name = str, \
++ .hw = INTC_HW_DESC(p ## _vectors, NULL, \
++ p ## _mask_registers, NULL, \
++ p ## _sense_registers, NULL), \
++}
++
+ #endif /* __ASM_MACH_INTC_H */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0141-irq-Track-the-owner-of-irq-descriptor.patch b/patches.kzm9g/0141-irq-Track-the-owner-of-irq-descriptor.patch
new file mode 100644
index 00000000000000..f8e709694bd6f8
--- /dev/null
+++ b/patches.kzm9g/0141-irq-Track-the-owner-of-irq-descriptor.patch
@@ -0,0 +1,260 @@
+From b26b3d7e3cb934148b64b1276087761b30a5b1be Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
+Date: Mon, 11 Jul 2011 12:17:31 +0200
+Subject: irq: Track the owner of irq descriptor
+
+Interrupt descriptors can be allocated from modules. The interrupts
+are used by other modules, but we have no refcount on the module which
+provides the interrupts and there is no way to establish one on the
+device level as the interrupt using module is agnostic to the fact
+that the interrupt is provided by a module rather than by some builtin
+interrupt controller.
+
+To prevent removal of the interrupt providing module, we can track the
+owner of the interrupt descriptor, which also provides the relevant
+irq chip functions in the irq descriptor.
+
+request/setup_irq() can now acquire a refcount on the owner module to
+prevent unloading. free_irq() drops the refcount.
+
+Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
+Link: http://lkml.kernel.org/r/20110711101731.GA13804@Chamillionaire.breakpoint.cc
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+(cherry picked from commit b6873807a7143b7d6d8b06809295e559d07d7deb)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/irq.h | 11 ++++++++++-
+ include/linux/irqdesc.h | 1 +
+ kernel/irq/irqdesc.c | 36 ++++++++++++++++++++++++------------
+ kernel/irq/manage.c | 17 +++++++++++++----
+ 4 files changed, 48 insertions(+), 17 deletions(-)
+
+diff --git a/include/linux/irq.h b/include/linux/irq.h
+index 094c211..58d1e49 100644
+--- a/include/linux/irq.h
++++ b/include/linux/irq.h
+@@ -23,6 +23,7 @@
+ #include <linux/errno.h>
+ #include <linux/topology.h>
+ #include <linux/wait.h>
++#include <linux/module.h>
+
+ #include <asm/irq.h>
+ #include <asm/ptrace.h>
+@@ -548,7 +549,15 @@ static inline struct msi_desc *irq_data_get_msi(struct irq_data *d)
+ return d->msi_desc;
+ }
+
+-int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node);
++int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
++ struct module *owner);
++
++static inline int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt,
++ int node)
++{
++ return __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE);
++}
++
+ void irq_free_descs(unsigned int irq, unsigned int cnt);
+ int irq_reserve_irqs(unsigned int from, unsigned int cnt);
+
+diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
+index 2d921b3..150134a 100644
+--- a/include/linux/irqdesc.h
++++ b/include/linux/irqdesc.h
+@@ -66,6 +66,7 @@ struct irq_desc {
+ #ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *dir;
+ #endif
++ struct module *owner;
+ const char *name;
+ } ____cacheline_internodealigned_in_smp;
+
+diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
+index 4c60a50..cb65d03 100644
+--- a/kernel/irq/irqdesc.c
++++ b/kernel/irq/irqdesc.c
+@@ -70,7 +70,8 @@ static inline void desc_smp_init(struct irq_desc *desc, int node) { }
+ static inline int desc_node(struct irq_desc *desc) { return 0; }
+ #endif
+
+-static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node)
++static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
++ struct module *owner)
+ {
+ int cpu;
+
+@@ -86,6 +87,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node)
+ desc->irq_count = 0;
+ desc->irqs_unhandled = 0;
+ desc->name = NULL;
++ desc->owner = owner;
+ for_each_possible_cpu(cpu)
+ *per_cpu_ptr(desc->kstat_irqs, cpu) = 0;
+ desc_smp_init(desc, node);
+@@ -128,7 +130,7 @@ static void free_masks(struct irq_desc *desc)
+ static inline void free_masks(struct irq_desc *desc) { }
+ #endif
+
+-static struct irq_desc *alloc_desc(int irq, int node)
++static struct irq_desc *alloc_desc(int irq, int node, struct module *owner)
+ {
+ struct irq_desc *desc;
+ gfp_t gfp = GFP_KERNEL;
+@@ -147,7 +149,7 @@ static struct irq_desc *alloc_desc(int irq, int node)
+ raw_spin_lock_init(&desc->lock);
+ lockdep_set_class(&desc->lock, &irq_desc_lock_class);
+
+- desc_set_defaults(irq, desc, node);
++ desc_set_defaults(irq, desc, node, owner);
+
+ return desc;
+
+@@ -173,13 +175,14 @@ static void free_desc(unsigned int irq)
+ kfree(desc);
+ }
+
+-static int alloc_descs(unsigned int start, unsigned int cnt, int node)
++static int alloc_descs(unsigned int start, unsigned int cnt, int node,
++ struct module *owner)
+ {
+ struct irq_desc *desc;
+ int i;
+
+ for (i = 0; i < cnt; i++) {
+- desc = alloc_desc(start + i, node);
++ desc = alloc_desc(start + i, node, owner);
+ if (!desc)
+ goto err;
+ mutex_lock(&sparse_irq_lock);
+@@ -227,7 +230,7 @@ int __init early_irq_init(void)
+ nr_irqs = initcnt;
+
+ for (i = 0; i < initcnt; i++) {
+- desc = alloc_desc(i, node);
++ desc = alloc_desc(i, node, NULL);
+ set_bit(i, allocated_irqs);
+ irq_insert_desc(i, desc);
+ }
+@@ -261,7 +264,7 @@ int __init early_irq_init(void)
+ alloc_masks(&desc[i], GFP_KERNEL, node);
+ raw_spin_lock_init(&desc[i].lock);
+ lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
+- desc_set_defaults(i, &desc[i], node);
++ desc_set_defaults(i, &desc[i], node, NULL);
+ }
+ return arch_early_irq_init();
+ }
+@@ -276,8 +279,16 @@ static void free_desc(unsigned int irq)
+ dynamic_irq_cleanup(irq);
+ }
+
+-static inline int alloc_descs(unsigned int start, unsigned int cnt, int node)
++static inline int alloc_descs(unsigned int start, unsigned int cnt, int node,
++ struct module *owner)
+ {
++ u32 i;
++
++ for (i = 0; i < cnt; i++) {
++ struct irq_desc *desc = irq_to_desc(start + i);
++
++ desc->owner = owner;
++ }
+ return start;
+ }
+
+@@ -337,7 +348,8 @@ EXPORT_SYMBOL_GPL(irq_free_descs);
+ * Returns the first irq number or error code
+ */
+ int __ref
+-irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node)
++__irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
++ struct module *owner)
+ {
+ int start, ret;
+
+@@ -366,13 +378,13 @@ irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node)
+
+ bitmap_set(allocated_irqs, start, cnt);
+ mutex_unlock(&sparse_irq_lock);
+- return alloc_descs(start, cnt, node);
++ return alloc_descs(start, cnt, node, owner);
+
+ err:
+ mutex_unlock(&sparse_irq_lock);
+ return ret;
+ }
+-EXPORT_SYMBOL_GPL(irq_alloc_descs);
++EXPORT_SYMBOL_GPL(__irq_alloc_descs);
+
+ /**
+ * irq_reserve_irqs - mark irqs allocated
+@@ -440,7 +452,7 @@ void dynamic_irq_cleanup(unsigned int irq)
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&desc->lock, flags);
+- desc_set_defaults(irq, desc, desc_node(desc));
++ desc_set_defaults(irq, desc, desc_node(desc), NULL);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+
+diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
+index bbc6a35..83fb6f5 100644
+--- a/kernel/irq/manage.c
++++ b/kernel/irq/manage.c
+@@ -889,6 +889,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
+
+ if (desc->irq_data.chip == &no_irq_chip)
+ return -ENOSYS;
++ if (!try_module_get(desc->owner))
++ return -ENODEV;
+ /*
+ * Some drivers like serial.c use request_irq() heavily,
+ * so we have to be careful not to interfere with a
+@@ -912,8 +914,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
+ */
+ nested = irq_settings_is_nested_thread(desc);
+ if (nested) {
+- if (!new->thread_fn)
+- return -EINVAL;
++ if (!new->thread_fn) {
++ ret = -EINVAL;
++ goto out_mput;
++ }
+ /*
+ * Replace the primary handler which was provided from
+ * the driver for non nested interrupt handling by the
+@@ -935,8 +939,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
+
+ t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
+ new->name);
+- if (IS_ERR(t))
+- return PTR_ERR(t);
++ if (IS_ERR(t)) {
++ ret = PTR_ERR(t);
++ goto out_mput;
++ }
+ /*
+ * We keep the reference to the task struct even if
+ * the thread dies to avoid that the interrupt code
+@@ -1133,6 +1139,8 @@ out_thread:
+ kthread_stop(t);
+ put_task_struct(t);
+ }
++out_mput:
++ module_put(desc->owner);
+ return ret;
+ }
+
+@@ -1241,6 +1249,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
+ put_task_struct(action->thread);
+ }
+
++ module_put(desc->owner);
+ return action;
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0142-irq-add-irq_domain-translation-infrastructure.patch b/patches.kzm9g/0142-irq-add-irq_domain-translation-infrastructure.patch
new file mode 100644
index 00000000000000..bdee569a1a2b3c
--- /dev/null
+++ b/patches.kzm9g/0142-irq-add-irq_domain-translation-infrastructure.patch
@@ -0,0 +1,400 @@
+From 9a23bed05c4e337589f8e76bed25c843979b77d5 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@secretlab.ca>
+Date: Tue, 26 Jul 2011 03:19:06 -0600
+Subject: irq: add irq_domain translation infrastructure
+
+This patch adds irq_domain infrastructure for translating from
+hardware irq numbers to linux irqs. This is particularly important
+for architectures adding device tree support because the current
+implementation (excluding PowerPC and SPARC) cannot handle
+translation for more than a single interrupt controller. irq_domain
+supports device tree translation for any number of interrupt
+controllers.
+
+This patch converts x86, Microblaze, ARM and MIPS to use irq_domain
+for device tree irq translation. x86 is untested beyond compiling it,
+irq_domain is enabled for MIPS and Microblaze, but the old behaviour is
+preserved until the core code is modified to actually register an
+irq_domain yet. On ARM it works and is required for much of the new
+ARM device tree board support.
+
+PowerPC has /not/ been converted to use this new infrastructure. It
+is still missing some features before it can replace the virq
+infrastructure already in powerpc (see documentation on
+irq_domain_map/unmap for details). Followup patches will add the
+missing pieces and migrate PowerPC to use irq_domain.
+
+SPARC has its own method of managing interrupts from the device tree
+and is unaffected by this change.
+
+Acked-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+(cherry picked from commit 08a543ad33fc188650801bd36eed4ffe272643e1)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/Kconfig | 1 +
+ arch/arm/include/asm/prom.h | 5 --
+ arch/arm/kernel/devtree.c | 14 -----
+ include/linux/irq.h | 6 +++
+ include/linux/irqdomain.h | 81 +++++++++++++++++++++++++++++
+ include/linux/of_irq.h | 4 ++
+ kernel/irq/Kconfig | 4 ++
+ kernel/irq/Makefile | 1 +
+ kernel/irq/irqdomain.c | 122 ++++++++++++++++++++++++++++++++++++++++++++
+ 9 files changed, 219 insertions(+), 19 deletions(-)
+ create mode 100644 include/linux/irqdomain.h
+ create mode 100644 kernel/irq/irqdomain.c
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index f9b212e..d7f1a02 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1705,6 +1705,7 @@ config USE_OF
+ bool "Flattened Device Tree support"
+ select OF
+ select OF_EARLY_FLATTREE
++ select IRQ_DOMAIN
+ help
+ Include support for flattened device tree machine descriptions.
+
+diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h
+index 11b8708..6f65ca8 100644
+--- a/arch/arm/include/asm/prom.h
++++ b/arch/arm/include/asm/prom.h
+@@ -16,11 +16,6 @@
+ #include <asm/setup.h>
+ #include <asm/irq.h>
+
+-static inline void irq_dispose_mapping(unsigned int virq)
+-{
+- return;
+-}
+-
+ extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
+ extern void arm_dt_memblock_reserve(void);
+
+diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
+index 0cdd7b4..1a33e9d 100644
+--- a/arch/arm/kernel/devtree.c
++++ b/arch/arm/kernel/devtree.c
+@@ -132,17 +132,3 @@ struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
+
+ return mdesc_best;
+ }
+-
+-/**
+- * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
+- *
+- * Currently the mapping mechanism is trivial; simple flat hwirq numbers are
+- * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not
+- * supported.
+- */
+-unsigned int irq_create_of_mapping(struct device_node *controller,
+- const u32 *intspec, unsigned int intsize)
+-{
+- return intspec[0];
+-}
+-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
+diff --git a/include/linux/irq.h b/include/linux/irq.h
+index 58d1e49..d65dfca 100644
+--- a/include/linux/irq.h
++++ b/include/linux/irq.h
+@@ -114,14 +114,18 @@ enum {
+ };
+
+ struct msi_desc;
++struct irq_domain;
+
+ /**
+ * struct irq_data - per irq and irq chip data passed down to chip functions
+ * @irq: interrupt number
++ * @hwirq: hardware interrupt number, local to the interrupt domain
+ * @node: node index useful for balancing
+ * @state_use_accessors: status information for irq chip functions.
+ * Use accessor functions to deal with it
+ * @chip: low level interrupt hardware access
++ * @domain: Interrupt translation domain; responsible for mapping
++ * between hwirq number and linux irq number.
+ * @handler_data: per-IRQ data for the irq_chip methods
+ * @chip_data: platform-specific per-chip private data for the chip
+ * methods, to allow shared chip implementations
+@@ -134,9 +138,11 @@ struct msi_desc;
+ */
+ struct irq_data {
+ unsigned int irq;
++ unsigned long hwirq;
+ unsigned int node;
+ unsigned int state_use_accessors;
+ struct irq_chip *chip;
++ struct irq_domain *domain;
+ void *handler_data;
+ void *chip_data;
+ struct msi_desc *msi_desc;
+diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
+new file mode 100644
+index 0000000..8f2c10a
+--- /dev/null
++++ b/include/linux/irqdomain.h
+@@ -0,0 +1,81 @@
++/*
++ * irq_domain - IRQ translation domains
++ *
++ * Translation infrastructure between hw and linux irq numbers. This is
++ * helpful for interrupt controllers to implement mapping between hardware
++ * irq numbers and the Linux irq number space.
++ *
++ * irq_domains also have a hook for translating device tree interrupt
++ * representation into a hardware irq number that can be mapped back to a
++ * Linux irq number without any extra platform support code.
++ *
++ * irq_domain is expected to be embedded in an interrupt controller's private
++ * data structure.
++ */
++#ifndef _LINUX_IRQDOMAIN_H
++#define _LINUX_IRQDOMAIN_H
++
++#include <linux/irq.h>
++
++#ifdef CONFIG_IRQ_DOMAIN
++struct device_node;
++struct irq_domain;
++
++/**
++ * struct irq_domain_ops - Methods for irq_domain objects
++ * @to_irq: (optional) given a local hardware irq number, return the linux
++ * irq number. If to_irq is not implemented, then the irq_domain
++ * will use this translation: irq = (domain->irq_base + hwirq)
++ * @dt_translate: Given a device tree node and interrupt specifier, decode
++ * the hardware irq number and linux irq type value.
++ */
++struct irq_domain_ops {
++ unsigned int (*to_irq)(struct irq_domain *d, unsigned long hwirq);
++
++#ifdef CONFIG_OF
++ int (*dt_translate)(struct irq_domain *d, struct device_node *node,
++ const u32 *intspec, unsigned int intsize,
++ unsigned long *out_hwirq, unsigned int *out_type);
++#endif /* CONFIG_OF */
++};
++
++/**
++ * struct irq_domain - Hardware interrupt number translation object
++ * @list: Element in global irq_domain list.
++ * @irq_base: Start of irq_desc range assigned to the irq_domain. The creator
++ * of the irq_domain is responsible for allocating the array of
++ * irq_desc structures.
++ * @nr_irq: Number of irqs managed by the irq domain
++ * @ops: pointer to irq_domain methods
++ * @priv: private data pointer for use by owner. Not touched by irq_domain
++ * core code.
++ * @of_node: (optional) Pointer to device tree nodes associated with the
++ * irq_domain. Used when decoding device tree interrupt specifiers.
++ */
++struct irq_domain {
++ struct list_head list;
++ unsigned int irq_base;
++ unsigned int nr_irq;
++ const struct irq_domain_ops *ops;
++ void *priv;
++ struct device_node *of_node;
++};
++
++/**
++ * irq_domain_to_irq() - Translate from a hardware irq to a linux irq number
++ *
++ * Returns the linux irq number associated with a hardware irq. By default,
++ * the mapping is irq == domain->irq_base + hwirq, but this mapping can
++ * be overridden if the irq_domain implements a .to_irq() hook.
++ */
++static inline unsigned int irq_domain_to_irq(struct irq_domain *d,
++ unsigned long hwirq)
++{
++ return d->ops->to_irq ? d->ops->to_irq(d, hwirq) : d->irq_base + hwirq;
++}
++
++extern void irq_domain_add(struct irq_domain *domain);
++extern void irq_domain_del(struct irq_domain *domain);
++#endif /* CONFIG_IRQ_DOMAIN */
++
++#endif /* _LINUX_IRQDOMAIN_H */
+diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
+index e6955f5..cd2e61c 100644
+--- a/include/linux/of_irq.h
++++ b/include/linux/of_irq.h
+@@ -63,6 +63,9 @@ extern int of_irq_map_one(struct device_node *device, int index,
+ extern unsigned int irq_create_of_mapping(struct device_node *controller,
+ const u32 *intspec,
+ unsigned int intsize);
++#ifdef CONFIG_IRQ_DOMAIN
++extern void irq_dispose_mapping(unsigned int irq);
++#endif
+ extern int of_irq_to_resource(struct device_node *dev, int index,
+ struct resource *r);
+ extern int of_irq_count(struct device_node *dev);
+@@ -70,6 +73,7 @@ extern int of_irq_to_resource_table(struct device_node *dev,
+ struct resource *res, int nr_irqs);
+ extern struct device_node *of_irq_find_parent(struct device_node *child);
+
++
+ #endif /* CONFIG_OF_IRQ */
+ #endif /* CONFIG_OF */
+ #endif /* __OF_IRQ_H */
+diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
+index d1d051b3..5a38bf4 100644
+--- a/kernel/irq/Kconfig
++++ b/kernel/irq/Kconfig
+@@ -52,6 +52,10 @@ config IRQ_EDGE_EOI_HANDLER
+ config GENERIC_IRQ_CHIP
+ bool
+
++# Generic irq_domain hw <--> linux irq number translation
++config IRQ_DOMAIN
++ bool
++
+ # Support forced irq threading
+ config IRQ_FORCED_THREADING
+ bool
+diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile
+index 7329005..fff1738 100644
+--- a/kernel/irq/Makefile
++++ b/kernel/irq/Makefile
+@@ -2,6 +2,7 @@
+ obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o
+ obj-$(CONFIG_GENERIC_IRQ_CHIP) += generic-chip.o
+ obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
++obj-$(CONFIG_IRQ_DOMAIN) += irqdomain.o
+ obj-$(CONFIG_PROC_FS) += proc.o
+ obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o
+ obj-$(CONFIG_PM_SLEEP) += pm.o
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+new file mode 100644
+index 0000000..29c7bd4
+--- /dev/null
++++ b/kernel/irq/irqdomain.c
+@@ -0,0 +1,122 @@
++#include <linux/irq.h>
++#include <linux/irqdomain.h>
++#include <linux/module.h>
++#include <linux/mutex.h>
++#include <linux/of.h>
++
++static LIST_HEAD(irq_domain_list);
++static DEFINE_MUTEX(irq_domain_mutex);
++
++/**
++ * irq_domain_add() - Register an irq_domain
++ * @domain: ptr to initialized irq_domain structure
++ *
++ * Registers an irq_domain structure. The irq_domain must at a minimum be
++ * initialized with an ops structure pointer, and either a ->to_irq hook or
++ * a valid irq_base value. Everything else is optional.
++ */
++void irq_domain_add(struct irq_domain *domain)
++{
++ struct irq_data *d;
++ int hwirq;
++
++ /*
++ * This assumes that the irq_domain owner has already allocated
++ * the irq_descs. This block will be removed when support for dynamic
++ * allocation of irq_descs is added to irq_domain.
++ */
++ for (hwirq = 0; hwirq < domain->nr_irq; hwirq++) {
++ d = irq_get_irq_data(irq_domain_to_irq(domain, hwirq));
++ if (d || d->domain) {
++ /* things are broken; just report, don't clean up */
++ WARN(1, "error: irq_desc already assigned to a domain");
++ return;
++ }
++ d->domain = domain;
++ d->hwirq = hwirq;
++ }
++
++ mutex_lock(&irq_domain_mutex);
++ list_add(&domain->list, &irq_domain_list);
++ mutex_unlock(&irq_domain_mutex);
++}
++
++/**
++ * irq_domain_del() - Unregister an irq_domain
++ * @domain: ptr to registered irq_domain.
++ */
++void irq_domain_del(struct irq_domain *domain)
++{
++ struct irq_data *d;
++ int hwirq;
++
++ mutex_lock(&irq_domain_mutex);
++ list_del(&domain->list);
++ mutex_unlock(&irq_domain_mutex);
++
++ /* Clear the irq_domain assignments */
++ for (hwirq = 0; hwirq < domain->nr_irq; hwirq++) {
++ d = irq_get_irq_data(irq_domain_to_irq(domain, hwirq));
++ d->domain = NULL;
++ }
++}
++
++#if defined(CONFIG_OF_IRQ)
++/**
++ * irq_create_of_mapping() - Map a linux irq number from a DT interrupt spec
++ *
++ * Used by the device tree interrupt mapping code to translate a device tree
++ * interrupt specifier to a valid linux irq number. Returns either a valid
++ * linux IRQ number or 0.
++ *
++ * When the caller no longer need the irq number returned by this function it
++ * should arrange to call irq_dispose_mapping().
++ */
++unsigned int irq_create_of_mapping(struct device_node *controller,
++ const u32 *intspec, unsigned int intsize)
++{
++ struct irq_domain *domain;
++ unsigned long hwirq;
++ unsigned int irq, type;
++ int rc = -EINVAL;
++
++ /* Find a domain which can translate the irq spec */
++ mutex_lock(&irq_domain_mutex);
++ list_for_each_entry(domain, &irq_domain_list, list) {
++ if (!domain->ops->dt_translate)
++ continue;
++ rc = domain->ops->dt_translate(domain, controller,
++ intspec, intsize, &hwirq, &type);
++ if (rc == 0)
++ break;
++ }
++ mutex_unlock(&irq_domain_mutex);
++
++ if (rc != 0)
++ return 0;
++
++ irq = irq_domain_to_irq(domain, hwirq);
++ if (type != IRQ_TYPE_NONE)
++ irq_set_irq_type(irq, type);
++ pr_debug("%s: mapped hwirq=%i to irq=%i, flags=%x\n",
++ controller->full_name, (int)hwirq, irq, type);
++ return irq;
++}
++EXPORT_SYMBOL_GPL(irq_create_of_mapping);
++
++/**
++ * irq_dispose_mapping() - Discard a mapping created by irq_create_of_mapping()
++ * @irq: linux irq number to be discarded
++ *
++ * Calling this function indicates the caller no longer needs a reference to
++ * the linux irq number returned by a prior call to irq_create_of_mapping().
++ */
++void irq_dispose_mapping(unsigned int irq)
++{
++ /*
++ * nothing yet; will be filled when support for dynamic allocation of
++ * irq_descs is added to irq_domain
++ */
++}
++EXPORT_SYMBOL_GPL(irq_dispose_mapping);
++#endif /* CONFIG_OF_IRQ */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0143-dt-irq-add-irq_domain_generate_simple-helper.patch b/patches.kzm9g/0143-dt-irq-add-irq_domain_generate_simple-helper.patch
new file mode 100644
index 00000000000000..725586004ea22b
--- /dev/null
+++ b/patches.kzm9g/0143-dt-irq-add-irq_domain_generate_simple-helper.patch
@@ -0,0 +1,122 @@
+From 3105f044552138b2b05fa35fd4af2290997dfcb1 Mon Sep 17 00:00:00 2001
+From: Grant Likely <grant.likely@secretlab.ca>
+Date: Tue, 26 Jul 2011 03:19:06 -0600
+Subject: dt/irq: add irq_domain_generate_simple() helper
+
+irq_domain_generate_simple() is an easy way to generate an irq translation
+domain for simple irq controllers. It assumes a flat 1:1 mapping from
+hardware irq number to an offset of the first linux irq number assigned
+to the controller
+
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+(cherry picked from commit 7e71330169d8056536b299290544980bccc6b300)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/irqdomain.h | 10 ++++++++
+ kernel/irq/irqdomain.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 68 insertions(+)
+
+diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
+index 8f2c10a..e807ad6 100644
+--- a/include/linux/irqdomain.h
++++ b/include/linux/irqdomain.h
+@@ -16,6 +16,7 @@
+ #define _LINUX_IRQDOMAIN_H
+
+ #include <linux/irq.h>
++#include <linux/mod_devicetable.h>
+
+ #ifdef CONFIG_IRQ_DOMAIN
+ struct device_node;
+@@ -78,4 +79,13 @@ extern void irq_domain_add(struct irq_domain *domain);
+ extern void irq_domain_del(struct irq_domain *domain);
+ #endif /* CONFIG_IRQ_DOMAIN */
+
++#if defined(CONFIG_IRQ_DOMAIN) && defined(CONFIG_OF_IRQ)
++extern void irq_domain_add_simple(struct device_node *controller, int irq_base);
++extern void irq_domain_generate_simple(const struct of_device_id *match,
++ u64 phys_base, unsigned int irq_start);
++#else /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */
++static inline void irq_domain_generate_simple(const struct of_device_id *match,
++ u64 phys_base, unsigned int irq_start) { }
++#endif /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */
++
+ #endif /* _LINUX_IRQDOMAIN_H */
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index 29c7bd4..d5828da 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -3,6 +3,8 @@
+ #include <linux/module.h>
+ #include <linux/mutex.h>
+ #include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/slab.h>
+
+ static LIST_HEAD(irq_domain_list);
+ static DEFINE_MUTEX(irq_domain_mutex);
+@@ -119,4 +121,60 @@ void irq_dispose_mapping(unsigned int irq)
+ */
+ }
+ EXPORT_SYMBOL_GPL(irq_dispose_mapping);
++
++int irq_domain_simple_dt_translate(struct irq_domain *d,
++ struct device_node *controller,
++ const u32 *intspec, unsigned int intsize,
++ unsigned long *out_hwirq, unsigned int *out_type)
++{
++ if (d->of_node != controller)
++ return -EINVAL;
++ if (intsize < 1)
++ return -EINVAL;
++
++ *out_hwirq = intspec[0];
++ *out_type = IRQ_TYPE_NONE;
++ if (intsize > 1)
++ *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
++ return 0;
++}
++
++struct irq_domain_ops irq_domain_simple_ops = {
++ .dt_translate = irq_domain_simple_dt_translate,
++};
++EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
++
++/**
++ * irq_domain_create_simple() - Set up a 'simple' translation range
++ */
++void irq_domain_add_simple(struct device_node *controller, int irq_base)
++{
++ struct irq_domain *domain;
++
++ domain = kzalloc(sizeof(*domain), GFP_KERNEL);
++ if (!domain) {
++ WARN_ON(1);
++ return;
++ }
++
++ domain->irq_base = irq_base;
++ domain->of_node = of_node_get(controller);
++ domain->ops = &irq_domain_simple_ops;
++ irq_domain_add(domain);
++}
++EXPORT_SYMBOL_GPL(irq_domain_add_simple);
++
++void irq_domain_generate_simple(const struct of_device_id *match,
++ u64 phys_base, unsigned int irq_start)
++{
++ struct device_node *node;
++ pr_info("looking for phys_base=%llx, irq_start=%i\n",
++ (unsigned long long) phys_base, (int) irq_start);
++ node = of_find_matching_node_by_address(NULL, match, phys_base);
++ if (node)
++ irq_domain_add_simple(node, irq_start);
++ else
++ pr_info("no node found\n");
++}
++EXPORT_SYMBOL_GPL(irq_domain_generate_simple);
+ #endif /* CONFIG_OF_IRQ */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0144-irq-Add-declaration-of-irq_domain_simple_ops-to-irqd.patch b/patches.kzm9g/0144-irq-Add-declaration-of-irq_domain_simple_ops-to-irqd.patch
new file mode 100644
index 00000000000000..5b27c51a0589f8
--- /dev/null
+++ b/patches.kzm9g/0144-irq-Add-declaration-of-irq_domain_simple_ops-to-irqd.patch
@@ -0,0 +1,41 @@
+From b4ba6a778992d1529517e6a5cd03cf1778529292 Mon Sep 17 00:00:00 2001
+From: Rob Herring <robherring2@gmail.com>
+Date: Wed, 14 Sep 2011 11:31:36 -0500
+Subject: irq: Add declaration of irq_domain_simple_ops to irqdomain.h
+
+irq_domain_simple_ops is exported, but is not declared in irqdomain.h,
+so add it.
+
+Signed-off-by: Rob Herring <rob.herring@calxeda.com>
+Cc: Grant Likely <grant.likely@secretlab.ca>
+Cc: marc.zyngier@arm.com
+Cc: thomas.abraham@linaro.org
+Cc: jamie@jamieiles.com
+Cc: b-cousson@ti.com
+Cc: shawn.guo@linaro.org
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: devicetree-discuss@lists.ozlabs.org
+Link: http://lkml.kernel.org/r/1316017900-19918-2-git-send-email-robherring2@gmail.com
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+(cherry picked from commit 5bd078dda4d4fbdb4bd138a6bd5b6e274c019ed2)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/irqdomain.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
+index e807ad6..3ad553e 100644
+--- a/include/linux/irqdomain.h
++++ b/include/linux/irqdomain.h
+@@ -80,6 +80,7 @@ extern void irq_domain_del(struct irq_domain *domain);
+ #endif /* CONFIG_IRQ_DOMAIN */
+
+ #if defined(CONFIG_IRQ_DOMAIN) && defined(CONFIG_OF_IRQ)
++extern struct irq_domain_ops irq_domain_simple_ops;
+ extern void irq_domain_add_simple(struct device_node *controller, int irq_base);
+ extern void irq_domain_generate_simple(const struct of_device_id *match,
+ u64 phys_base, unsigned int irq_start);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0145-irq-Fix-check-for-already-initialized-irq_domain-in-.patch b/patches.kzm9g/0145-irq-Fix-check-for-already-initialized-irq_domain-in-.patch
new file mode 100644
index 00000000000000..5378b2c7454bfa
--- /dev/null
+++ b/patches.kzm9g/0145-irq-Fix-check-for-already-initialized-irq_domain-in-.patch
@@ -0,0 +1,56 @@
+From e2aede6a87e8875da05a181d1b46d7ae99f3a3d6 Mon Sep 17 00:00:00 2001
+From: Rob Herring <robherring2@gmail.com>
+Date: Wed, 14 Sep 2011 11:31:37 -0500
+Subject: irq: Fix check for already initialized irq_domain in irq_domain_add
+
+The sanity check in irq_domain_add() tests desc->irq_data != NULL or
+irq_data->domain != NULL. This prevents adding an irq_domain to a irq
+descriptor when irq_data exists, which true when the irq descriptor
+exists.
+
+This went unnoticed so far as the simple domain code did not enter
+this code path because domain->nr_irqs is always 0 for the simple domains.
+
+Split the check for irq_data == NULL out and have a separate warning
+for it.
+
+[ tglx: Made the check for irq_data == NULL separate ]
+
+Signed-off-by: Rob Herring <rob.herring@calxeda.com>
+Cc: Grant Likely <grant.likely@secretlab.ca>
+Cc: marc.zyngier@arm.com
+Cc: thomas.abraham@linaro.org
+Cc: jamie@jamieiles.com
+Cc: b-cousson@ti.com
+Cc: shawn.guo@linaro.org
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: devicetree-discuss@lists.ozlabs.org
+Link: http://lkml.kernel.org/r/1316017900-19918-3-git-send-email-robherring2@gmail.com
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+(cherry picked from commit eef24afb28561a5a9f4be8f8da97735b7e6a826f)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ kernel/irq/irqdomain.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index d5828da..b57a377 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -29,7 +29,11 @@ void irq_domain_add(struct irq_domain *domain)
+ */
+ for (hwirq = 0; hwirq < domain->nr_irq; hwirq++) {
+ d = irq_get_irq_data(irq_domain_to_irq(domain, hwirq));
+- if (d || d->domain) {
++ if (!d) {
++ WARN(1, "error: assigning domain to non existant irq_desc");
++ return;
++ }
++ if (d->domain) {
+ /* things are broken; just report, don't clean up */
+ WARN(1, "error: irq_desc already assigned to a domain");
+ return;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0146-irq-support-domains-with-non-zero-hwirq-base.patch b/patches.kzm9g/0146-irq-support-domains-with-non-zero-hwirq-base.patch
new file mode 100644
index 00000000000000..0815ecc54dd9d4
--- /dev/null
+++ b/patches.kzm9g/0146-irq-support-domains-with-non-zero-hwirq-base.patch
@@ -0,0 +1,113 @@
+From a5214f58a7b1bd8881d0b99b2bf728149ece07df Mon Sep 17 00:00:00 2001
+From: Rob Herring <rob.herring@calxeda.com>
+Date: Fri, 30 Sep 2011 10:48:38 -0500
+Subject: irq: support domains with non-zero hwirq base
+
+Interrupt controllers can have non-zero starting value for h/w irq numbers.
+Adding support in irq_domain allows the domain hwirq numbering to match
+the interrupt controllers' numbering.
+
+As this makes looping over irqs for a domain more complicated, add loop
+iterators to iterate over all hwirqs and irqs for a domain.
+
+Signed-off-by: Rob Herring <rob.herring@calxeda.com>
+Reviewed-by: Jamie Iles <jamie@jamieiles.com>
+Tested-by: Thomas Abraham <thomas.abraham@linaro.org>
+Acked-by: Grant Likely <grant.likely@secretlab.ca>
+Acked-by: Thomas Gleixner <tglx@linutronix.de>
+(cherry picked from commit 6d274309d0e64bdbdb6c50945ca2964596e8fa5a)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/irqdomain.h | 16 +++++++++++++++-
+ kernel/irq/irqdomain.c | 12 ++++++------
+ 2 files changed, 21 insertions(+), 7 deletions(-)
+
+diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
+index 3ad553e..99834e58 100644
+--- a/include/linux/irqdomain.h
++++ b/include/linux/irqdomain.h
+@@ -47,6 +47,7 @@ struct irq_domain_ops {
+ * of the irq_domain is responsible for allocating the array of
+ * irq_desc structures.
+ * @nr_irq: Number of irqs managed by the irq domain
++ * @hwirq_base: Starting number for hwirqs managed by the irq domain
+ * @ops: pointer to irq_domain methods
+ * @priv: private data pointer for use by owner. Not touched by irq_domain
+ * core code.
+@@ -57,6 +58,7 @@ struct irq_domain {
+ struct list_head list;
+ unsigned int irq_base;
+ unsigned int nr_irq;
++ unsigned int hwirq_base;
+ const struct irq_domain_ops *ops;
+ void *priv;
+ struct device_node *of_node;
+@@ -72,9 +74,21 @@ struct irq_domain {
+ static inline unsigned int irq_domain_to_irq(struct irq_domain *d,
+ unsigned long hwirq)
+ {
+- return d->ops->to_irq ? d->ops->to_irq(d, hwirq) : d->irq_base + hwirq;
++ if (d->ops->to_irq)
++ return d->ops->to_irq(d, hwirq);
++ if (WARN_ON(hwirq < d->hwirq_base))
++ return 0;
++ return d->irq_base + hwirq - d->hwirq_base;
+ }
+
++#define irq_domain_for_each_hwirq(d, hw) \
++ for (hw = d->hwirq_base; hw < d->hwirq_base + d->nr_irq; hw++)
++
++#define irq_domain_for_each_irq(d, hw, irq) \
++ for (hw = d->hwirq_base, irq = irq_domain_to_irq(d, hw); \
++ hw < d->hwirq_base + d->nr_irq; \
++ hw++, irq = irq_domain_to_irq(d, hw))
++
+ extern void irq_domain_add(struct irq_domain *domain);
+ extern void irq_domain_del(struct irq_domain *domain);
+ #endif /* CONFIG_IRQ_DOMAIN */
+diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
+index b57a377..200ce83 100644
+--- a/kernel/irq/irqdomain.c
++++ b/kernel/irq/irqdomain.c
+@@ -20,15 +20,15 @@ static DEFINE_MUTEX(irq_domain_mutex);
+ void irq_domain_add(struct irq_domain *domain)
+ {
+ struct irq_data *d;
+- int hwirq;
++ int hwirq, irq;
+
+ /*
+ * This assumes that the irq_domain owner has already allocated
+ * the irq_descs. This block will be removed when support for dynamic
+ * allocation of irq_descs is added to irq_domain.
+ */
+- for (hwirq = 0; hwirq < domain->nr_irq; hwirq++) {
+- d = irq_get_irq_data(irq_domain_to_irq(domain, hwirq));
++ irq_domain_for_each_irq(domain, hwirq, irq) {
++ d = irq_get_irq_data(irq);
+ if (!d) {
+ WARN(1, "error: assigning domain to non existant irq_desc");
+ return;
+@@ -54,15 +54,15 @@ void irq_domain_add(struct irq_domain *domain)
+ void irq_domain_del(struct irq_domain *domain)
+ {
+ struct irq_data *d;
+- int hwirq;
++ int hwirq, irq;
+
+ mutex_lock(&irq_domain_mutex);
+ list_del(&domain->list);
+ mutex_unlock(&irq_domain_mutex);
+
+ /* Clear the irq_domain assignments */
+- for (hwirq = 0; hwirq < domain->nr_irq; hwirq++) {
+- d = irq_get_irq_data(irq_domain_to_irq(domain, hwirq));
++ irq_domain_for_each_irq(domain, hwirq, irq) {
++ d = irq_get_irq_data(irq);
+ d->domain = NULL;
+ }
+ }
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0147-genirq-Add-support-for-per-cpu-dev_id-interrupts.patch b/patches.kzm9g/0147-genirq-Add-support-for-per-cpu-dev_id-interrupts.patch
new file mode 100644
index 00000000000000..4f7bf8b3c9170b
--- /dev/null
+++ b/patches.kzm9g/0147-genirq-Add-support-for-per-cpu-dev_id-interrupts.patch
@@ -0,0 +1,769 @@
+From 2fa1dad96b9e8bff660071418480512a2539ce85 Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <marc.zyngier@arm.com>
+Date: Fri, 23 Sep 2011 17:03:06 +0100
+Subject: genirq: Add support for per-cpu dev_id interrupts
+
+The ARM GIC interrupt controller offers per CPU interrupts (PPIs),
+which are usually used to connect local timers to each core. Each CPU
+has its own private interface to the GIC, and only sees the PPIs that
+are directly connect to it.
+
+While these timers are separate devices and have a separate interrupt
+line to a core, they all use the same IRQ number.
+
+For these devices, request_irq() is not the right API as it assumes
+that an IRQ number is visible by a number of CPUs (through the
+affinity setting), but makes it very awkward to express that an IRQ
+number can be handled by all CPUs, and yet be a different interrupt
+line on each CPU, requiring a different dev_id cookie to be passed
+back to the handler.
+
+The *_percpu_irq() functions is designed to overcome these
+limitations, by providing a per-cpu dev_id vector:
+
+int request_percpu_irq(unsigned int irq, irq_handler_t handler,
+ const char *devname, void __percpu *percpu_dev_id);
+void free_percpu_irq(unsigned int, void __percpu *);
+int setup_percpu_irq(unsigned int irq, struct irqaction *new);
+void remove_percpu_irq(unsigned int irq, struct irqaction *act);
+void enable_percpu_irq(unsigned int irq);
+void disable_percpu_irq(unsigned int irq);
+
+The API has a number of limitations:
+- no interrupt sharing
+- no threading
+- common handler across all the CPUs
+
+Once the interrupt is requested using setup_percpu_irq() or
+request_percpu_irq(), it must be enabled by each core that wishes its
+local interrupt to be delivered.
+
+Based on an initial patch by Thomas Gleixner.
+
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Cc: linux-arm-kernel@lists.infradead.org
+Link: http://lkml.kernel.org/r/1316793788-14500-2-git-send-email-marc.zyngier@arm.com
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+(cherry picked from commit 31d9d9b6d83030f748d013e61502fa5477e2ac0e)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/interrupt.h | 38 ++++++---
+ include/linux/irq.h | 16 +++-
+ include/linux/irqdesc.h | 1 +
+ kernel/irq/chip.c | 64 +++++++++++++--
+ kernel/irq/internals.h | 19 +++--
+ kernel/irq/irqdesc.c | 32 +++++++-
+ kernel/irq/manage.c | 202 +++++++++++++++++++++++++++++++++++++++++++---
+ kernel/irq/settings.h | 7 ++
+ 8 files changed, 345 insertions(+), 34 deletions(-)
+
+diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
+index b9490bf..6fe4e3c 100644
+--- a/include/linux/interrupt.h
++++ b/include/linux/interrupt.h
+@@ -98,6 +98,7 @@ typedef irqreturn_t (*irq_handler_t)(int, void *);
+ * @flags: flags (see IRQF_* above)
+ * @name: name of the device
+ * @dev_id: cookie to identify the device
++ * @percpu_dev_id: cookie to identify the device
+ * @next: pointer to the next irqaction for shared interrupts
+ * @irq: interrupt number
+ * @dir: pointer to the proc/irq/NN/name entry
+@@ -107,17 +108,18 @@ typedef irqreturn_t (*irq_handler_t)(int, void *);
+ * @thread_mask: bitmask for keeping track of @thread activity
+ */
+ struct irqaction {
+- irq_handler_t handler;
+- unsigned long flags;
+- void *dev_id;
+- struct irqaction *next;
+- int irq;
+- irq_handler_t thread_fn;
+- struct task_struct *thread;
+- unsigned long thread_flags;
+- unsigned long thread_mask;
+- const char *name;
+- struct proc_dir_entry *dir;
++ irq_handler_t handler;
++ unsigned long flags;
++ void *dev_id;
++ void __percpu *percpu_dev_id;
++ struct irqaction *next;
++ int irq;
++ irq_handler_t thread_fn;
++ struct task_struct *thread;
++ unsigned long thread_flags;
++ unsigned long thread_mask;
++ const char *name;
++ struct proc_dir_entry *dir;
+ } ____cacheline_internodealigned_in_smp;
+
+ extern irqreturn_t no_action(int cpl, void *dev_id);
+@@ -139,6 +141,10 @@ extern int __must_check
+ request_any_context_irq(unsigned int irq, irq_handler_t handler,
+ unsigned long flags, const char *name, void *dev_id);
+
++extern int __must_check
++request_percpu_irq(unsigned int irq, irq_handler_t handler,
++ const char *devname, void __percpu *percpu_dev_id);
++
+ extern void exit_irq_thread(void);
+ #else
+
+@@ -167,10 +173,18 @@ request_any_context_irq(unsigned int irq, irq_handler_t handler,
+ return request_irq(irq, handler, flags, name, dev_id);
+ }
+
++static inline int __must_check
++request_percpu_irq(unsigned int irq, irq_handler_t handler,
++ const char *devname, void __percpu *percpu_dev_id)
++{
++ return request_irq(irq, handler, 0, devname, percpu_dev_id);
++}
++
+ static inline void exit_irq_thread(void) { }
+ #endif
+
+ extern void free_irq(unsigned int, void *);
++extern void free_percpu_irq(unsigned int, void __percpu *);
+
+ struct device;
+
+@@ -210,7 +224,9 @@ extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
+
+ extern void disable_irq_nosync(unsigned int irq);
+ extern void disable_irq(unsigned int irq);
++extern void disable_percpu_irq(unsigned int irq);
+ extern void enable_irq(unsigned int irq);
++extern void enable_percpu_irq(unsigned int irq);
+
+ /* The following three functions are for the core kernel use only. */
+ #ifdef CONFIG_GENERIC_HARDIRQS
+diff --git a/include/linux/irq.h b/include/linux/irq.h
+index d65dfca..b6cbe62 100644
+--- a/include/linux/irq.h
++++ b/include/linux/irq.h
+@@ -66,6 +66,7 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data);
+ * IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set)
+ * IRQ_MOVE_PCNTXT - Interrupt can be migrated from process context
+ * IRQ_NESTED_TRHEAD - Interrupt nests into another thread
++ * IRQ_PER_CPU_DEVID - Dev_id is a per-cpu variable
+ */
+ enum {
+ IRQ_TYPE_NONE = 0x00000000,
+@@ -88,12 +89,13 @@ enum {
+ IRQ_MOVE_PCNTXT = (1 << 14),
+ IRQ_NESTED_THREAD = (1 << 15),
+ IRQ_NOTHREAD = (1 << 16),
++ IRQ_PER_CPU_DEVID = (1 << 17),
+ };
+
+ #define IRQF_MODIFY_MASK \
+ (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \
+ IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \
+- IRQ_PER_CPU | IRQ_NESTED_THREAD)
++ IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID)
+
+ #define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING)
+
+@@ -372,6 +374,8 @@ enum {
+ struct irqaction;
+ extern int setup_irq(unsigned int irq, struct irqaction *new);
+ extern void remove_irq(unsigned int irq, struct irqaction *act);
++extern int setup_percpu_irq(unsigned int irq, struct irqaction *new);
++extern void remove_percpu_irq(unsigned int irq, struct irqaction *act);
+
+ extern void irq_cpu_online(void);
+ extern void irq_cpu_offline(void);
+@@ -399,6 +403,7 @@ extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc);
+ extern void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc);
+ extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc);
+ extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc);
++extern void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc);
+ extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc);
+ extern void handle_nested_irq(unsigned int irq);
+
+@@ -427,6 +432,8 @@ static inline void irq_set_chip_and_handler(unsigned int irq, struct irq_chip *c
+ irq_set_chip_and_handler_name(irq, chip, handle, NULL);
+ }
+
++extern int irq_set_percpu_devid(unsigned int irq);
++
+ extern void
+ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
+ const char *name);
+@@ -488,6 +495,13 @@ static inline void irq_set_nested_thread(unsigned int irq, bool nest)
+ irq_clear_status_flags(irq, IRQ_NESTED_THREAD);
+ }
+
++static inline void irq_set_percpu_devid_flags(unsigned int irq)
++{
++ irq_set_status_flags(irq,
++ IRQ_NOAUTOEN | IRQ_PER_CPU | IRQ_NOTHREAD |
++ IRQ_NOPROBE | IRQ_PER_CPU_DEVID);
++}
++
+ /* Handle dynamic irq creation and destruction */
+ extern unsigned int create_irq_nr(unsigned int irq_want, int node);
+ extern int create_irq(void);
+diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
+index 150134a..6b69c2c 100644
+--- a/include/linux/irqdesc.h
++++ b/include/linux/irqdesc.h
+@@ -53,6 +53,7 @@ struct irq_desc {
+ unsigned long last_unhandled; /* Aging timer for unhandled count */
+ unsigned int irqs_unhandled;
+ raw_spinlock_t lock;
++ struct cpumask *percpu_enabled;
+ #ifdef CONFIG_SMP
+ const struct cpumask *affinity_hint;
+ struct irq_affinity_notify *affinity_notify;
+diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
+index 990965e..25784d6 100644
+--- a/kernel/irq/chip.c
++++ b/kernel/irq/chip.c
+@@ -26,7 +26,7 @@
+ int irq_set_chip(unsigned int irq, struct irq_chip *chip)
+ {
+ unsigned long flags;
+- struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
++ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
+
+ if (!desc)
+ return -EINVAL;
+@@ -54,7 +54,7 @@ EXPORT_SYMBOL(irq_set_chip);
+ int irq_set_irq_type(unsigned int irq, unsigned int type)
+ {
+ unsigned long flags;
+- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
++ struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
+ int ret = 0;
+
+ if (!desc)
+@@ -77,7 +77,7 @@ EXPORT_SYMBOL(irq_set_irq_type);
+ int irq_set_handler_data(unsigned int irq, void *data)
+ {
+ unsigned long flags;
+- struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
++ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
+
+ if (!desc)
+ return -EINVAL;
+@@ -97,7 +97,7 @@ EXPORT_SYMBOL(irq_set_handler_data);
+ int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry)
+ {
+ unsigned long flags;
+- struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
++ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
+
+ if (!desc)
+ return -EINVAL;
+@@ -118,7 +118,7 @@ int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry)
+ int irq_set_chip_data(unsigned int irq, void *data)
+ {
+ unsigned long flags;
+- struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
++ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
+
+ if (!desc)
+ return -EINVAL;
+@@ -206,6 +206,24 @@ void irq_disable(struct irq_desc *desc)
+ }
+ }
+
++void irq_percpu_enable(struct irq_desc *desc, unsigned int cpu)
++{
++ if (desc->irq_data.chip->irq_enable)
++ desc->irq_data.chip->irq_enable(&desc->irq_data);
++ else
++ desc->irq_data.chip->irq_unmask(&desc->irq_data);
++ cpumask_set_cpu(cpu, desc->percpu_enabled);
++}
++
++void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu)
++{
++ if (desc->irq_data.chip->irq_disable)
++ desc->irq_data.chip->irq_disable(&desc->irq_data);
++ else
++ desc->irq_data.chip->irq_mask(&desc->irq_data);
++ cpumask_clear_cpu(cpu, desc->percpu_enabled);
++}
++
+ static inline void mask_ack_irq(struct irq_desc *desc)
+ {
+ if (desc->irq_data.chip->irq_mask_ack)
+@@ -567,12 +585,44 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
+ chip->irq_eoi(&desc->irq_data);
+ }
+
++/**
++ * handle_percpu_devid_irq - Per CPU local irq handler with per cpu dev ids
++ * @irq: the interrupt number
++ * @desc: the interrupt description structure for this irq
++ *
++ * Per CPU interrupts on SMP machines without locking requirements. Same as
++ * handle_percpu_irq() above but with the following extras:
++ *
++ * action->percpu_dev_id is a pointer to percpu variables which
++ * contain the real device id for the cpu on which this handler is
++ * called
++ */
++void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc)
++{
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++ struct irqaction *action = desc->action;
++ void *dev_id = __this_cpu_ptr(action->percpu_dev_id);
++ irqreturn_t res;
++
++ kstat_incr_irqs_this_cpu(irq, desc);
++
++ if (chip->irq_ack)
++ chip->irq_ack(&desc->irq_data);
++
++ trace_irq_handler_entry(irq, action);
++ res = action->handler(irq, dev_id);
++ trace_irq_handler_exit(irq, action, res);
++
++ if (chip->irq_eoi)
++ chip->irq_eoi(&desc->irq_data);
++}
++
+ void
+ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
+ const char *name)
+ {
+ unsigned long flags;
+- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
++ struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
+
+ if (!desc)
+ return;
+@@ -616,7 +666,7 @@ irq_set_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
+ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
+ {
+ unsigned long flags;
+- struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
++ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
+
+ if (!desc)
+ return;
+diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
+index 62efdc4..e1a8b64 100644
+--- a/kernel/irq/internals.h
++++ b/kernel/irq/internals.h
+@@ -71,6 +71,8 @@ extern int irq_startup(struct irq_desc *desc, bool resend);
+ extern void irq_shutdown(struct irq_desc *desc);
+ extern void irq_enable(struct irq_desc *desc);
+ extern void irq_disable(struct irq_desc *desc);
++extern void irq_percpu_enable(struct irq_desc *desc, unsigned int cpu);
++extern void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu);
+ extern void mask_irq(struct irq_desc *desc);
+ extern void unmask_irq(struct irq_desc *desc);
+
+@@ -114,14 +116,21 @@ static inline void chip_bus_sync_unlock(struct irq_desc *desc)
+ desc->irq_data.chip->irq_bus_sync_unlock(&desc->irq_data);
+ }
+
++#define _IRQ_DESC_CHECK (1 << 0)
++#define _IRQ_DESC_PERCPU (1 << 1)
++
++#define IRQ_GET_DESC_CHECK_GLOBAL (_IRQ_DESC_CHECK)
++#define IRQ_GET_DESC_CHECK_PERCPU (_IRQ_DESC_CHECK | _IRQ_DESC_PERCPU)
++
+ struct irq_desc *
+-__irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus);
++__irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus,
++ unsigned int check);
+ void __irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags, bool bus);
+
+ static inline struct irq_desc *
+-irq_get_desc_buslock(unsigned int irq, unsigned long *flags)
++irq_get_desc_buslock(unsigned int irq, unsigned long *flags, unsigned int check)
+ {
+- return __irq_get_desc_lock(irq, flags, true);
++ return __irq_get_desc_lock(irq, flags, true, check);
+ }
+
+ static inline void
+@@ -131,9 +140,9 @@ irq_put_desc_busunlock(struct irq_desc *desc, unsigned long flags)
+ }
+
+ static inline struct irq_desc *
+-irq_get_desc_lock(unsigned int irq, unsigned long *flags)
++irq_get_desc_lock(unsigned int irq, unsigned long *flags, unsigned int check)
+ {
+- return __irq_get_desc_lock(irq, flags, false);
++ return __irq_get_desc_lock(irq, flags, false, check);
+ }
+
+ static inline void
+diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
+index cb65d03..028e377 100644
+--- a/kernel/irq/irqdesc.c
++++ b/kernel/irq/irqdesc.c
+@@ -423,11 +423,22 @@ unsigned int irq_get_next_irq(unsigned int offset)
+ }
+
+ struct irq_desc *
+-__irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus)
++__irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus,
++ unsigned int check)
+ {
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ if (desc) {
++ if (check & _IRQ_DESC_CHECK) {
++ if ((check & _IRQ_DESC_PERCPU) &&
++ !irq_settings_is_per_cpu_devid(desc))
++ return NULL;
++
++ if (!(check & _IRQ_DESC_PERCPU) &&
++ irq_settings_is_per_cpu_devid(desc))
++ return NULL;
++ }
++
+ if (bus)
+ chip_bus_lock(desc);
+ raw_spin_lock_irqsave(&desc->lock, *flags);
+@@ -442,6 +453,25 @@ void __irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags, bool bus)
+ chip_bus_sync_unlock(desc);
+ }
+
++int irq_set_percpu_devid(unsigned int irq)
++{
++ struct irq_desc *desc = irq_to_desc(irq);
++
++ if (!desc)
++ return -EINVAL;
++
++ if (desc->percpu_enabled)
++ return -EINVAL;
++
++ desc->percpu_enabled = kzalloc(sizeof(*desc->percpu_enabled), GFP_KERNEL);
++
++ if (!desc->percpu_enabled)
++ return -ENOMEM;
++
++ irq_set_percpu_devid_flags(irq);
++ return 0;
++}
++
+ /**
+ * dynamic_irq_cleanup - cleanup a dynamically allocated irq
+ * @irq: irq number to initialize
+diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
+index 83fb6f5..7923849 100644
+--- a/kernel/irq/manage.c
++++ b/kernel/irq/manage.c
+@@ -195,7 +195,7 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *mask)
+ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
+ {
+ unsigned long flags;
+- struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
++ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
+
+ if (!desc)
+ return -EINVAL;
+@@ -356,7 +356,7 @@ void __disable_irq(struct irq_desc *desc, unsigned int irq, bool suspend)
+ static int __disable_irq_nosync(unsigned int irq)
+ {
+ unsigned long flags;
+- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
++ struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
+
+ if (!desc)
+ return -EINVAL;
+@@ -448,7 +448,7 @@ void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume)
+ void enable_irq(unsigned int irq)
+ {
+ unsigned long flags;
+- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
++ struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
+
+ if (!desc)
+ return;
+@@ -491,7 +491,7 @@ static int set_irq_wake_real(unsigned int irq, unsigned int on)
+ int irq_set_irq_wake(unsigned int irq, unsigned int on)
+ {
+ unsigned long flags;
+- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
++ struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
+ int ret = 0;
+
+ if (!desc)
+@@ -532,7 +532,7 @@ EXPORT_SYMBOL(irq_set_irq_wake);
+ int can_request_irq(unsigned int irq, unsigned long irqflags)
+ {
+ unsigned long flags;
+- struct irq_desc *desc = irq_get_desc_lock(irq, &flags);
++ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
+ int canrequest = 0;
+
+ if (!desc)
+@@ -1156,6 +1156,8 @@ int setup_irq(unsigned int irq, struct irqaction *act)
+ int retval;
+ struct irq_desc *desc = irq_to_desc(irq);
+
++ if (WARN_ON(irq_settings_is_per_cpu_devid(desc)))
++ return -EINVAL;
+ chip_bus_lock(desc);
+ retval = __setup_irq(irq, desc, act);
+ chip_bus_sync_unlock(desc);
+@@ -1164,7 +1166,7 @@ int setup_irq(unsigned int irq, struct irqaction *act)
+ }
+ EXPORT_SYMBOL_GPL(setup_irq);
+
+- /*
++/*
+ * Internal function to unregister an irqaction - used to free
+ * regular and special interrupts that are part of the architecture.
+ */
+@@ -1262,7 +1264,10 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
+ */
+ void remove_irq(unsigned int irq, struct irqaction *act)
+ {
+- __free_irq(irq, act->dev_id);
++ struct irq_desc *desc = irq_to_desc(irq);
++
++ if (desc && !WARN_ON(irq_settings_is_per_cpu_devid(desc)))
++ __free_irq(irq, act->dev_id);
+ }
+ EXPORT_SYMBOL_GPL(remove_irq);
+
+@@ -1284,7 +1289,7 @@ void free_irq(unsigned int irq, void *dev_id)
+ {
+ struct irq_desc *desc = irq_to_desc(irq);
+
+- if (!desc)
++ if (!desc || WARN_ON(irq_settings_is_per_cpu_devid(desc)))
+ return;
+
+ #ifdef CONFIG_SMP
+@@ -1362,7 +1367,8 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
+ if (!desc)
+ return -EINVAL;
+
+- if (!irq_settings_can_request(desc))
++ if (!irq_settings_can_request(desc) ||
++ WARN_ON(irq_settings_is_per_cpu_devid(desc)))
+ return -EINVAL;
+
+ if (!handler) {
+@@ -1447,3 +1453,181 @@ int request_any_context_irq(unsigned int irq, irq_handler_t handler,
+ return !ret ? IRQC_IS_HARDIRQ : ret;
+ }
+ EXPORT_SYMBOL_GPL(request_any_context_irq);
++
++void enable_percpu_irq(unsigned int irq)
++{
++ unsigned int cpu = smp_processor_id();
++ unsigned long flags;
++ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_PERCPU);
++
++ if (!desc)
++ return;
++
++ irq_percpu_enable(desc, cpu);
++ irq_put_desc_unlock(desc, flags);
++}
++
++void disable_percpu_irq(unsigned int irq)
++{
++ unsigned int cpu = smp_processor_id();
++ unsigned long flags;
++ struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_PERCPU);
++
++ if (!desc)
++ return;
++
++ irq_percpu_disable(desc, cpu);
++ irq_put_desc_unlock(desc, flags);
++}
++
++/*
++ * Internal function to unregister a percpu irqaction.
++ */
++static struct irqaction *__free_percpu_irq(unsigned int irq, void __percpu *dev_id)
++{
++ struct irq_desc *desc = irq_to_desc(irq);
++ struct irqaction *action;
++ unsigned long flags;
++
++ WARN(in_interrupt(), "Trying to free IRQ %d from IRQ context!\n", irq);
++
++ if (!desc)
++ return NULL;
++
++ raw_spin_lock_irqsave(&desc->lock, flags);
++
++ action = desc->action;
++ if (!action || action->percpu_dev_id != dev_id) {
++ WARN(1, "Trying to free already-free IRQ %d\n", irq);
++ goto bad;
++ }
++
++ if (!cpumask_empty(desc->percpu_enabled)) {
++ WARN(1, "percpu IRQ %d still enabled on CPU%d!\n",
++ irq, cpumask_first(desc->percpu_enabled));
++ goto bad;
++ }
++
++ /* Found it - now remove it from the list of entries: */
++ desc->action = NULL;
++
++ raw_spin_unlock_irqrestore(&desc->lock, flags);
++
++ unregister_handler_proc(irq, action);
++
++ module_put(desc->owner);
++ return action;
++
++bad:
++ raw_spin_unlock_irqrestore(&desc->lock, flags);
++ return NULL;
++}
++
++/**
++ * remove_percpu_irq - free a per-cpu interrupt
++ * @irq: Interrupt line to free
++ * @act: irqaction for the interrupt
++ *
++ * Used to remove interrupts statically setup by the early boot process.
++ */
++void remove_percpu_irq(unsigned int irq, struct irqaction *act)
++{
++ struct irq_desc *desc = irq_to_desc(irq);
++
++ if (desc && irq_settings_is_per_cpu_devid(desc))
++ __free_percpu_irq(irq, act->percpu_dev_id);
++}
++
++/**
++ * free_percpu_irq - free an interrupt allocated with request_percpu_irq
++ * @irq: Interrupt line to free
++ * @dev_id: Device identity to free
++ *
++ * Remove a percpu interrupt handler. The handler is removed, but
++ * the interrupt line is not disabled. This must be done on each
++ * CPU before calling this function. The function does not return
++ * until any executing interrupts for this IRQ have completed.
++ *
++ * This function must not be called from interrupt context.
++ */
++void free_percpu_irq(unsigned int irq, void __percpu *dev_id)
++{
++ struct irq_desc *desc = irq_to_desc(irq);
++
++ if (!desc || !irq_settings_is_per_cpu_devid(desc))
++ return;
++
++ chip_bus_lock(desc);
++ kfree(__free_percpu_irq(irq, dev_id));
++ chip_bus_sync_unlock(desc);
++}
++
++/**
++ * setup_percpu_irq - setup a per-cpu interrupt
++ * @irq: Interrupt line to setup
++ * @act: irqaction for the interrupt
++ *
++ * Used to statically setup per-cpu interrupts in the early boot process.
++ */
++int setup_percpu_irq(unsigned int irq, struct irqaction *act)
++{
++ struct irq_desc *desc = irq_to_desc(irq);
++ int retval;
++
++ if (!desc || !irq_settings_is_per_cpu_devid(desc))
++ return -EINVAL;
++ chip_bus_lock(desc);
++ retval = __setup_irq(irq, desc, act);
++ chip_bus_sync_unlock(desc);
++
++ return retval;
++}
++
++/**
++ * request_percpu_irq - allocate a percpu interrupt line
++ * @irq: Interrupt line to allocate
++ * @handler: Function to be called when the IRQ occurs.
++ * @devname: An ascii name for the claiming device
++ * @dev_id: A percpu cookie passed back to the handler function
++ *
++ * This call allocates interrupt resources, but doesn't
++ * automatically enable the interrupt. It has to be done on each
++ * CPU using enable_percpu_irq().
++ *
++ * Dev_id must be globally unique. It is a per-cpu variable, and
++ * the handler gets called with the interrupted CPU's instance of
++ * that variable.
++ */
++int request_percpu_irq(unsigned int irq, irq_handler_t handler,
++ const char *devname, void __percpu *dev_id)
++{
++ struct irqaction *action;
++ struct irq_desc *desc;
++ int retval;
++
++ if (!dev_id)
++ return -EINVAL;
++
++ desc = irq_to_desc(irq);
++ if (!desc || !irq_settings_can_request(desc) ||
++ !irq_settings_is_per_cpu_devid(desc))
++ return -EINVAL;
++
++ action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
++ if (!action)
++ return -ENOMEM;
++
++ action->handler = handler;
++ action->flags = IRQF_PERCPU;
++ action->name = devname;
++ action->percpu_dev_id = dev_id;
++
++ chip_bus_lock(desc);
++ retval = __setup_irq(irq, desc, action);
++ chip_bus_sync_unlock(desc);
++
++ if (retval)
++ kfree(action);
++
++ return retval;
++}
+diff --git a/kernel/irq/settings.h b/kernel/irq/settings.h
+index f166783..1162f10 100644
+--- a/kernel/irq/settings.h
++++ b/kernel/irq/settings.h
+@@ -13,6 +13,7 @@ enum {
+ _IRQ_MOVE_PCNTXT = IRQ_MOVE_PCNTXT,
+ _IRQ_NO_BALANCING = IRQ_NO_BALANCING,
+ _IRQ_NESTED_THREAD = IRQ_NESTED_THREAD,
++ _IRQ_PER_CPU_DEVID = IRQ_PER_CPU_DEVID,
+ _IRQF_MODIFY_MASK = IRQF_MODIFY_MASK,
+ };
+
+@@ -24,6 +25,7 @@ enum {
+ #define IRQ_NOTHREAD GOT_YOU_MORON
+ #define IRQ_NOAUTOEN GOT_YOU_MORON
+ #define IRQ_NESTED_THREAD GOT_YOU_MORON
++#define IRQ_PER_CPU_DEVID GOT_YOU_MORON
+ #undef IRQF_MODIFY_MASK
+ #define IRQF_MODIFY_MASK GOT_YOU_MORON
+
+@@ -39,6 +41,11 @@ static inline bool irq_settings_is_per_cpu(struct irq_desc *desc)
+ return desc->status_use_accessors & _IRQ_PER_CPU;
+ }
+
++static inline bool irq_settings_is_per_cpu_devid(struct irq_desc *desc)
++{
++ return desc->status_use_accessors & _IRQ_PER_CPU_DEVID;
++}
++
+ static inline void irq_settings_set_per_cpu(struct irq_desc *desc)
+ {
+ desc->status_use_accessors |= _IRQ_PER_CPU;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0148-ARM-introduce-handle_IRQ-not-to-dump-exception-stack.patch b/patches.kzm9g/0148-ARM-introduce-handle_IRQ-not-to-dump-exception-stack.patch
new file mode 100644
index 00000000000000..32f68f4a6ed50c
--- /dev/null
+++ b/patches.kzm9g/0148-ARM-introduce-handle_IRQ-not-to-dump-exception-stack.patch
@@ -0,0 +1,123 @@
+From ef24b31c6a52daa9cdf20cfe63c5dab8c8186926 Mon Sep 17 00:00:00 2001
+From: Russell King - ARM Linux <linux@arm.linux.org.uk>
+Date: Mon, 11 Jul 2011 22:25:43 +0100
+Subject: ARM: introduce handle_IRQ() not to dump exception stack
+
+On Mon, Jul 11, 2011 at 3:52 PM, Russell King - ARM Linux
+<linux@arm.linux.org.uk> wrote:
+
+...
+
+> The __exception annotation on a function causes this to happen:
+>
+> [<c002406c>] (asm_do_IRQ+0x6c/0x8c) from [<c0024b84>]
+> (__irq_svc+0x44/0xcc)
+> Exception stack(0xc3897c78 to 0xc3897cc0)
+> 7c60: 4022d320 4022e000
+> 7c80: 08000075 00001000 c32273c0 c03ce1c0 c2b49b78 4022d000 c2b420b4 00000001
+> 7ca0: 00000000 c3897cfc 00000000 c3897cc0 c00afc54 c002edd8 00000013 ffffffff
+>
+> Where that stack dump represents the pt_regs for the exception which
+> happened. Any function found in while unwinding will cause this to
+> be printed.
+>
+> If you insert a C function between the IRQ assembly and asm_do_IRQ,
+> the
+> dump you get from asm_do_IRQ will be the stack for your function,
+> not
+> the pt_regs. That makes the feature useless.
+>
+
+When __irq_svc - or any of the other exception handling assembly code -
+calls the C code, the stack pointer will be pointing at the pt_regs
+structure.
+
+All the entry points into C code from the exception handling code are
+marked with __exception or __exception_irq_enter to indicate that they
+are one of the functions which has pt_regs above them.
+
+Normally, when you've entered asm_do_IRQ() you will have this stack
+layout (higher address towards top):
+
+ pt_regs
+ asm_do_IRQ frame
+
+If you insert a C function between the exception assembly code and
+asm_do_IRQ, you end up with this stack layout instead:
+
+ pt_regs
+ your function frame
+ asm_do_IRQ frame
+
+This means when we unwind, we'll get to asm_do_IRQ, and rather than
+dumping out the pt_regs, we'll dump out your functions stack frame
+instead, because that's what is above the asm_do_IRQ stack frame
+rather than the expected pt_regs structure.
+
+The fix is to introduce handle_IRQ() for no exception stack dump, so
+it can be called with MULTI_IRQ_HANDLER is selected and a C function
+is between the assembly code and the actual IRQ handling code.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
+(cherry picked from commit a4841e39f7ca85ee2a40803ebac6221c6d8822c0)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/include/asm/irq.h | 1 +
+ arch/arm/kernel/irq.c | 19 ++++++++++++++-----
+ 2 files changed, 15 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h
+index 2721a58..5a526af 100644
+--- a/arch/arm/include/asm/irq.h
++++ b/arch/arm/include/asm/irq.h
+@@ -23,6 +23,7 @@ struct pt_regs;
+ extern void migrate_irqs(void);
+
+ extern void asm_do_IRQ(unsigned int, struct pt_regs *);
++void handle_IRQ(unsigned int, struct pt_regs *);
+ void init_IRQ(void);
+
+ #endif
+diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
+index 83bbad0..dbc1f41 100644
+--- a/arch/arm/kernel/irq.c
++++ b/arch/arm/kernel/irq.c
+@@ -67,12 +67,12 @@ int arch_show_interrupts(struct seq_file *p, int prec)
+ }
+
+ /*
+- * do_IRQ handles all hardware IRQ's. Decoded IRQs should not
+- * come via this function. Instead, they should provide their
+- * own 'handler'
++ * handle_IRQ handles all hardware IRQ's. Decoded IRQs should
++ * not come via this function. Instead, they should provide their
++ * own 'handler'. Used by platform code implementing C-based 1st
++ * level decoding.
+ */
+-asmlinkage void __exception_irq_entry
+-asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
++void handle_IRQ(unsigned int irq, struct pt_regs *regs)
+ {
+ struct pt_regs *old_regs = set_irq_regs(regs);
+
+@@ -97,6 +97,15 @@ asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
+ set_irq_regs(old_regs);
+ }
+
++/*
++ * asm_do_IRQ is the interface to be used from assembly code.
++ */
++asmlinkage void __exception_irq_entry
++asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
++{
++ handle_IRQ(irq, regs);
++}
++
+ void set_irq_flags(unsigned int irq, unsigned int iflags)
+ {
+ unsigned long clr = 0, set = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0149-ARM-GIC-move-gic_chip_data-structure-declaration-to-.patch b/patches.kzm9g/0149-ARM-GIC-move-gic_chip_data-structure-declaration-to-.patch
new file mode 100644
index 00000000000000..fabd6f1a934fe0
--- /dev/null
+++ b/patches.kzm9g/0149-ARM-GIC-move-gic_chip_data-structure-declaration-to-.patch
@@ -0,0 +1,59 @@
+From eb34882abb20009f826539498f60d94406fd7aca Mon Sep 17 00:00:00 2001
+From: Changhwan Youn <chaos.youn@samsung.com>
+Date: Sat, 16 Jul 2011 10:49:47 +0900
+Subject: ARM: GIC: move gic_chip_data structure declaration to header
+
+Since Samsung EXYNOS4210 cannot support register banking in GIC,
+so needs to update CPU interface base address.
+The 'gic_chip_data' is used for it, this patch moves gic_chip_data
+structure declaraton to arch/arm/include/asm/hardware/gic.h to use
+it.
+
+Cc: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Changhwan Youn <chaos.youn@samsung.com>
+Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
+(cherry picked from commit e807acbc6fd1d5ff115f9a8eae0c1af6cf1c46c6)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/common/gic.c | 6 ------
+ arch/arm/include/asm/hardware/gic.h | 6 ++++++
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index 4ddd0a6..23564ed 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -38,12 +38,6 @@ static DEFINE_SPINLOCK(irq_controller_lock);
+ /* Address of GIC 0 CPU interface */
+ void __iomem *gic_cpu_base_addr __read_mostly;
+
+-struct gic_chip_data {
+- unsigned int irq_offset;
+- void __iomem *dist_base;
+- void __iomem *cpu_base;
+-};
+-
+ /*
+ * Supported arch specific GIC irq extension.
+ * Default make them NULL.
+diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
+index 0691f9d..435d3f8 100644
+--- a/arch/arm/include/asm/hardware/gic.h
++++ b/arch/arm/include/asm/hardware/gic.h
+@@ -41,6 +41,12 @@ void gic_secondary_init(unsigned int);
+ void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
+ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
+ void gic_enable_ppi(unsigned int);
++
++struct gic_chip_data {
++ unsigned int irq_offset;
++ void __iomem *dist_base;
++ void __iomem *cpu_base;
++};
+ #endif
+
+ #endif
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0150-ARM-CPU-hotplug-fix-abuse-of-irqdesc-node.patch b/patches.kzm9g/0150-ARM-CPU-hotplug-fix-abuse-of-irqdesc-node.patch
new file mode 100644
index 00000000000000..d0fe540f728d32
--- /dev/null
+++ b/patches.kzm9g/0150-ARM-CPU-hotplug-fix-abuse-of-irqdesc-node.patch
@@ -0,0 +1,55 @@
+From 937519bccf58b2af70bfaf0b199c9fe8a6bab3b5 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Thu, 21 Jul 2011 14:51:13 +0100
+Subject: ARM: CPU hotplug: fix abuse of irqdesc->node
+
+irqdesc's node member is supposed to mark the numa node number for the
+interrupt. Our use of it is non-standard. Remove this, replacing the
+functionality with a test of the affinity mask.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+(cherry picked from commit 2ef75701d1711a1feee2a82b42a2597ddc05f88b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/common/gic.c | 1 -
+ arch/arm/kernel/irq.c | 10 ++--------
+ 2 files changed, 2 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index 23564ed..2ba61e5 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -183,7 +183,6 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
+ bit = 1 << (cpu + shift);
+
+ spin_lock(&irq_controller_lock);
+- d->node = cpu;
+ val = readl_relaxed(reg) & ~mask;
+ writel_relaxed(val | bit, reg);
+ spin_unlock(&irq_controller_lock);
+diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
+index dbc1f41..3e34b1f 100644
+--- a/arch/arm/kernel/irq.c
++++ b/arch/arm/kernel/irq.c
+@@ -175,15 +175,9 @@ void migrate_irqs(void)
+ bool affinity_broken = false;
+
+ raw_spin_lock(&desc->lock);
+- do {
+- if (desc->action == NULL)
+- break;
+-
+- if (d->node != cpu)
+- break;
+-
++ if (desc->action != NULL &&
++ cpumask_test_cpu(smp_processor_id(), d->affinity))
+ affinity_broken = migrate_one_irq(d);
+- } while (0);
+ raw_spin_unlock(&desc->lock);
+
+ if (affinity_broken && printk_ratelimit())
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0151-ARM-GIC-avoid-routing-interrupts-to-offline-CPUs.patch b/patches.kzm9g/0151-ARM-GIC-avoid-routing-interrupts-to-offline-CPUs.patch
new file mode 100644
index 00000000000000..dcf5e862855203
--- /dev/null
+++ b/patches.kzm9g/0151-ARM-GIC-avoid-routing-interrupts-to-offline-CPUs.patch
@@ -0,0 +1,52 @@
+From aada114ebfda78d2fba02d654fa67b075e31d27d Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Thu, 21 Jul 2011 15:00:57 +0100
+Subject: ARM: GIC: avoid routing interrupts to offline CPUs
+
+The irq_set_affinity() method can be called with masks which include
+offline CPUs. This allows offline CPUs to have interrupts routed to
+them by writing to /proc/irq/*/smp_affinity after hotplug has taken
+a CPU offline. Fix this by ensuring that we select a target CPU
+present in both the required affinity and the online CPU mask.
+
+Ensure that we return IRQ_SET_MASK_OK (which happens to be 0) on
+success to ensure generic code copies the new mask into the irq_data
+structure.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+(cherry picked from commit 5dfc54e087c15f823ee9b6541d2f0f314e69cbed)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/common/gic.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index 2ba61e5..3227ca9 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -173,10 +173,10 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
+ {
+ void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
+ unsigned int shift = (d->irq % 4) * 8;
+- unsigned int cpu = cpumask_first(mask_val);
++ unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
+ u32 val, mask, bit;
+
+- if (cpu >= 8)
++ if (cpu >= 8 || cpu >= nr_cpu_ids)
+ return -EINVAL;
+
+ mask = 0xff << shift;
+@@ -187,7 +187,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
+ writel_relaxed(val | bit, reg);
+ spin_unlock(&irq_controller_lock);
+
+- return 0;
++ return IRQ_SET_MASK_OK;
+ }
+ #endif
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0152-ARM-gic-Use-cpu-pm-notifiers-to-save-gic-state.patch b/patches.kzm9g/0152-ARM-gic-Use-cpu-pm-notifiers-to-save-gic-state.patch
new file mode 100644
index 00000000000000..6e4f4718efcfe6
--- /dev/null
+++ b/patches.kzm9g/0152-ARM-gic-Use-cpu-pm-notifiers-to-save-gic-state.patch
@@ -0,0 +1,268 @@
+From ca0bcbc7836024b138b86d00c9c8e61c14ad4716 Mon Sep 17 00:00:00 2001
+From: Colin Cross <ccross@android.com>
+Date: Thu, 10 Feb 2011 12:54:10 -0800
+Subject: ARM: gic: Use cpu pm notifiers to save gic state
+
+When the cpu is powered down in a low power mode, the gic cpu
+interface may be reset, and when the cpu cluster is powered
+down, the gic distributor may also be reset.
+
+This patch uses CPU_PM_ENTER and CPU_PM_EXIT notifiers to save
+and restore the gic cpu interface registers, and the
+CPU_CLUSTER_PM_ENTER and CPU_CLUSTER_PM_EXIT notifiers to save
+and restore the gic distributor registers.
+
+Original-author: Gary King <gking@nvidia.com>
+Signed-off-by: Colin Cross <ccross@android.com>
+Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
+Tested-and-Acked-by: Shawn Guo <shawn.guo@linaro.org>
+Tested-by: Vishwanath BS <vishwanath.bs@ti.com>
+(cherry picked from commit 254056f3b12563c11e6dbcfad2fbfce20a4f3302)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/common/gic.c | 187 ++++++++++++++++++++++++++++++++++++
+ arch/arm/include/asm/hardware/gic.h | 8 ++
+ 2 files changed, 195 insertions(+)
+
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index 3227ca9..66c7c48 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -26,6 +26,7 @@
+ #include <linux/kernel.h>
+ #include <linux/list.h>
+ #include <linux/smp.h>
++#include <linux/cpu_pm.h>
+ #include <linux/cpumask.h>
+ #include <linux/io.h>
+
+@@ -276,6 +277,8 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
+ if (gic_irqs > 1020)
+ gic_irqs = 1020;
+
++ gic->gic_irqs = gic_irqs;
++
+ /*
+ * Set all global interrupts to be level triggered, active low.
+ */
+@@ -343,6 +346,189 @@ static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
+ writel_relaxed(1, base + GIC_CPU_CTRL);
+ }
+
++#ifdef CONFIG_CPU_PM
++/*
++ * Saves the GIC distributor registers during suspend or idle. Must be called
++ * with interrupts disabled but before powering down the GIC. After calling
++ * this function, no interrupts will be delivered by the GIC, and another
++ * platform-specific wakeup source must be enabled.
++ */
++static void gic_dist_save(unsigned int gic_nr)
++{
++ unsigned int gic_irqs;
++ void __iomem *dist_base;
++ int i;
++
++ if (gic_nr >= MAX_GIC_NR)
++ BUG();
++
++ gic_irqs = gic_data[gic_nr].gic_irqs;
++ dist_base = gic_data[gic_nr].dist_base;
++
++ if (!dist_base)
++ return;
++
++ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
++ gic_data[gic_nr].saved_spi_conf[i] =
++ readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
++
++ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
++ gic_data[gic_nr].saved_spi_target[i] =
++ readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4);
++
++ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
++ gic_data[gic_nr].saved_spi_enable[i] =
++ readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
++}
++
++/*
++ * Restores the GIC distributor registers during resume or when coming out of
++ * idle. Must be called before enabling interrupts. If a level interrupt
++ * that occured while the GIC was suspended is still present, it will be
++ * handled normally, but any edge interrupts that occured will not be seen by
++ * the GIC and need to be handled by the platform-specific wakeup source.
++ */
++static void gic_dist_restore(unsigned int gic_nr)
++{
++ unsigned int gic_irqs;
++ unsigned int i;
++ void __iomem *dist_base;
++
++ if (gic_nr >= MAX_GIC_NR)
++ BUG();
++
++ gic_irqs = gic_data[gic_nr].gic_irqs;
++ dist_base = gic_data[gic_nr].dist_base;
++
++ if (!dist_base)
++ return;
++
++ writel_relaxed(0, dist_base + GIC_DIST_CTRL);
++
++ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
++ writel_relaxed(gic_data[gic_nr].saved_spi_conf[i],
++ dist_base + GIC_DIST_CONFIG + i * 4);
++
++ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
++ writel_relaxed(0xa0a0a0a0,
++ dist_base + GIC_DIST_PRI + i * 4);
++
++ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
++ writel_relaxed(gic_data[gic_nr].saved_spi_target[i],
++ dist_base + GIC_DIST_TARGET + i * 4);
++
++ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
++ writel_relaxed(gic_data[gic_nr].saved_spi_enable[i],
++ dist_base + GIC_DIST_ENABLE_SET + i * 4);
++
++ writel_relaxed(1, dist_base + GIC_DIST_CTRL);
++}
++
++static void gic_cpu_save(unsigned int gic_nr)
++{
++ int i;
++ u32 *ptr;
++ void __iomem *dist_base;
++ void __iomem *cpu_base;
++
++ if (gic_nr >= MAX_GIC_NR)
++ BUG();
++
++ dist_base = gic_data[gic_nr].dist_base;
++ cpu_base = gic_data[gic_nr].cpu_base;
++
++ if (!dist_base || !cpu_base)
++ return;
++
++ ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_enable);
++ for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
++ ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
++
++ ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_conf);
++ for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
++ ptr[i] = readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
++
++}
++
++static void gic_cpu_restore(unsigned int gic_nr)
++{
++ int i;
++ u32 *ptr;
++ void __iomem *dist_base;
++ void __iomem *cpu_base;
++
++ if (gic_nr >= MAX_GIC_NR)
++ BUG();
++
++ dist_base = gic_data[gic_nr].dist_base;
++ cpu_base = gic_data[gic_nr].cpu_base;
++
++ if (!dist_base || !cpu_base)
++ return;
++
++ ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_enable);
++ for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
++ writel_relaxed(ptr[i], dist_base + GIC_DIST_ENABLE_SET + i * 4);
++
++ ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_conf);
++ for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
++ writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
++
++ for (i = 0; i < DIV_ROUND_UP(32, 4); i++)
++ writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4);
++
++ writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK);
++ writel_relaxed(1, cpu_base + GIC_CPU_CTRL);
++}
++
++static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)
++{
++ int i;
++
++ for (i = 0; i < MAX_GIC_NR; i++) {
++ switch (cmd) {
++ case CPU_PM_ENTER:
++ gic_cpu_save(i);
++ break;
++ case CPU_PM_ENTER_FAILED:
++ case CPU_PM_EXIT:
++ gic_cpu_restore(i);
++ break;
++ case CPU_CLUSTER_PM_ENTER:
++ gic_dist_save(i);
++ break;
++ case CPU_CLUSTER_PM_ENTER_FAILED:
++ case CPU_CLUSTER_PM_EXIT:
++ gic_dist_restore(i);
++ break;
++ }
++ }
++
++ return NOTIFY_OK;
++}
++
++static struct notifier_block gic_notifier_block = {
++ .notifier_call = gic_notifier,
++};
++
++static void __init gic_pm_init(struct gic_chip_data *gic)
++{
++ gic->saved_ppi_enable = __alloc_percpu(DIV_ROUND_UP(32, 32) * 4,
++ sizeof(u32));
++ BUG_ON(!gic->saved_ppi_enable);
++
++ gic->saved_ppi_conf = __alloc_percpu(DIV_ROUND_UP(32, 16) * 4,
++ sizeof(u32));
++ BUG_ON(!gic->saved_ppi_conf);
++
++ cpu_pm_register_notifier(&gic_notifier_block);
++}
++#else
++static void __init gic_pm_init(struct gic_chip_data *gic)
++{
++}
++#endif
++
+ void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
+ void __iomem *dist_base, void __iomem *cpu_base)
+ {
+@@ -360,6 +546,7 @@ void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
+
+ gic_dist_init(gic, irq_start);
+ gic_cpu_init(gic);
++ gic_pm_init(gic);
+ }
+
+ void __cpuinit gic_secondary_init(unsigned int gic_nr)
+diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
+index 435d3f8..c562705 100644
+--- a/arch/arm/include/asm/hardware/gic.h
++++ b/arch/arm/include/asm/hardware/gic.h
+@@ -46,6 +46,14 @@ struct gic_chip_data {
+ unsigned int irq_offset;
+ void __iomem *dist_base;
+ void __iomem *cpu_base;
++#ifdef CONFIG_CPU_PM
++ u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)];
++ u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)];
++ u32 saved_spi_target[DIV_ROUND_UP(1020, 4)];
++ u32 __percpu *saved_ppi_enable;
++ u32 __percpu *saved_ppi_conf;
++#endif
++ unsigned int gic_irqs;
+ };
+ #endif
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0153-ARM-7011-1-Add-ARM-cpu-topology-definition.patch b/patches.kzm9g/0153-ARM-7011-1-Add-ARM-cpu-topology-definition.patch
new file mode 100644
index 00000000000000..f61fa457bdfa19
--- /dev/null
+++ b/patches.kzm9g/0153-ARM-7011-1-Add-ARM-cpu-topology-definition.patch
@@ -0,0 +1,351 @@
+From b20aa3f7ccd0f3add1c52a930cac2efa98acda7d Mon Sep 17 00:00:00 2001
+From: Vincent Guittot <vincent.guittot@linaro.org>
+Date: Mon, 8 Aug 2011 13:21:59 +0100
+Subject: ARM: 7011/1: Add ARM cpu topology definition
+
+The affinity between ARM processors is defined in the MPIDR register.
+We can identify which processors are in the same cluster,
+and which ones have performance interdependency. We can define the
+cpu topology of ARM platform, that is then used by sched_mc and sched_smt.
+
+The default state of sched_mc and sched_smt config is disable.
+When enabled, the behavior of the scheduler can be modified with
+sched_mc_power_savings and sched_smt_power_savings sysfs interfaces.
+
+Changes since v4 :
+* Remove unnecessary parentheses and blank lines
+
+Changes since v3 :
+* Update the format of printk message
+* Remove blank line
+
+Changes since v2 :
+* Update the commit message and some comments
+
+Changes since v1 :
+* Update the commit message
+* Add read_cpuid_mpidr in arch/arm/include/asm/cputype.h
+* Modify header of arch/arm/kernel/topology.c
+* Modify tests and manipulation of MPIDR's bitfields
+* Modify the place and dependancy of the config
+* Modify Noop functions
+
+Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
+Reviewed-by: Amit Kucheria <amit.kucheria@linaro.org>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+(cherry picked from commit c9018aab8eee24b993c12c7aff7fc99d3d73f298)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/Kconfig | 25 +++++++
+ arch/arm/include/asm/cputype.h | 6 ++
+ arch/arm/include/asm/topology.h | 33 +++++++++
+ arch/arm/kernel/Makefile | 1 +
+ arch/arm/kernel/smp.c | 5 ++
+ arch/arm/kernel/topology.c | 148 ++++++++++++++++++++++++++++++++++++++++
+ 6 files changed, 218 insertions(+)
+ create mode 100644 arch/arm/kernel/topology.c
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index d7f1a02..7692bca 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1370,6 +1370,31 @@ config SMP_ON_UP
+
+ If you don't know what to do here, say Y.
+
++config ARM_CPU_TOPOLOGY
++ bool "Support cpu topology definition"
++ depends on SMP && CPU_V7
++ default y
++ help
++ Support ARM cpu topology definition. The MPIDR register defines
++ affinity between processors which is then used to describe the cpu
++ topology of an ARM System.
++
++config SCHED_MC
++ bool "Multi-core scheduler support"
++ depends on ARM_CPU_TOPOLOGY
++ help
++ Multi-core scheduler support improves the CPU scheduler's decision
++ making when dealing with multi-core CPU chips at a cost of slightly
++ increased overhead in some places. If unsure say N here.
++
++config SCHED_SMT
++ bool "SMT scheduler support"
++ depends on ARM_CPU_TOPOLOGY
++ help
++ Improves the CPU scheduler's decision making when dealing with
++ MultiThreading at a cost of slightly increased overhead in some
++ places. If unsure say N here.
++
+ config HAVE_ARM_SCU
+ bool
+ depends on SMP
+diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
+index cd4458f..cb47d28 100644
+--- a/arch/arm/include/asm/cputype.h
++++ b/arch/arm/include/asm/cputype.h
+@@ -8,6 +8,7 @@
+ #define CPUID_CACHETYPE 1
+ #define CPUID_TCM 2
+ #define CPUID_TLBTYPE 3
++#define CPUID_MPIDR 5
+
+ #define CPUID_EXT_PFR0 "c1, 0"
+ #define CPUID_EXT_PFR1 "c1, 1"
+@@ -70,6 +71,11 @@ static inline unsigned int __attribute_const__ read_cpuid_tcmstatus(void)
+ return read_cpuid(CPUID_TCM);
+ }
+
++static inline unsigned int __attribute_const__ read_cpuid_mpidr(void)
++{
++ return read_cpuid(CPUID_MPIDR);
++}
++
+ /*
+ * Intel's XScale3 core supports some v6 features (supersections, L2)
+ * but advertises itself as v5 as it does not support the v6 ISA. For
+diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h
+index accbd7c..a7e457e 100644
+--- a/arch/arm/include/asm/topology.h
++++ b/arch/arm/include/asm/topology.h
+@@ -1,6 +1,39 @@
+ #ifndef _ASM_ARM_TOPOLOGY_H
+ #define _ASM_ARM_TOPOLOGY_H
+
++#ifdef CONFIG_ARM_CPU_TOPOLOGY
++
++#include <linux/cpumask.h>
++
++struct cputopo_arm {
++ int thread_id;
++ int core_id;
++ int socket_id;
++ cpumask_t thread_sibling;
++ cpumask_t core_sibling;
++};
++
++extern struct cputopo_arm cpu_topology[NR_CPUS];
++
++#define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id)
++#define topology_core_id(cpu) (cpu_topology[cpu].core_id)
++#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling)
++#define topology_thread_cpumask(cpu) (&cpu_topology[cpu].thread_sibling)
++
++#define mc_capable() (cpu_topology[0].socket_id != -1)
++#define smt_capable() (cpu_topology[0].thread_id != -1)
++
++void init_cpu_topology(void);
++void store_cpu_topology(unsigned int cpuid);
++const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
++
++#else
++
++static inline void init_cpu_topology(void) { }
++static inline void store_cpu_topology(unsigned int cpuid) { }
++
++#endif
++
+ #include <asm-generic/topology.h>
+
+ #endif /* _ASM_ARM_TOPOLOGY_H */
+diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
+index a5b31af..816a481 100644
+--- a/arch/arm/kernel/Makefile
++++ b/arch/arm/kernel/Makefile
+@@ -61,6 +61,7 @@ obj-$(CONFIG_IWMMXT) += iwmmxt.o
+ obj-$(CONFIG_CPU_HAS_PMU) += pmu.o
+ obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
+ AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
++obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
+
+ ifneq ($(CONFIG_ARCH_EBSA110),y)
+ obj-y += io.o
+diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
+index e7f92a4..8e3a000 100644
+--- a/arch/arm/kernel/smp.c
++++ b/arch/arm/kernel/smp.c
+@@ -31,6 +31,7 @@
+ #include <asm/cacheflush.h>
+ #include <asm/cpu.h>
+ #include <asm/cputype.h>
++#include <asm/topology.h>
+ #include <asm/mmu_context.h>
+ #include <asm/pgtable.h>
+ #include <asm/pgalloc.h>
+@@ -268,6 +269,8 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
+ struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
+
+ cpu_info->loops_per_jiffy = loops_per_jiffy;
++
++ store_cpu_topology(cpuid);
+ }
+
+ /*
+@@ -358,6 +361,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
+ {
+ unsigned int ncores = num_possible_cpus();
+
++ init_cpu_topology();
++
+ smp_store_cpu_info(smp_processor_id());
+
+ /*
+diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
+new file mode 100644
+index 0000000..1040c00
+--- /dev/null
++++ b/arch/arm/kernel/topology.c
+@@ -0,0 +1,148 @@
++/*
++ * arch/arm/kernel/topology.c
++ *
++ * Copyright (C) 2011 Linaro Limited.
++ * Written by: Vincent Guittot
++ *
++ * based on arch/sh/kernel/topology.c
++ *
++ * 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/cpu.h>
++#include <linux/cpumask.h>
++#include <linux/init.h>
++#include <linux/percpu.h>
++#include <linux/node.h>
++#include <linux/nodemask.h>
++#include <linux/sched.h>
++
++#include <asm/cputype.h>
++#include <asm/topology.h>
++
++#define MPIDR_SMP_BITMASK (0x3 << 30)
++#define MPIDR_SMP_VALUE (0x2 << 30)
++
++#define MPIDR_MT_BITMASK (0x1 << 24)
++
++/*
++ * These masks reflect the current use of the affinity levels.
++ * The affinity level can be up to 16 bits according to ARM ARM
++ */
++
++#define MPIDR_LEVEL0_MASK 0x3
++#define MPIDR_LEVEL0_SHIFT 0
++
++#define MPIDR_LEVEL1_MASK 0xF
++#define MPIDR_LEVEL1_SHIFT 8
++
++#define MPIDR_LEVEL2_MASK 0xFF
++#define MPIDR_LEVEL2_SHIFT 16
++
++struct cputopo_arm cpu_topology[NR_CPUS];
++
++const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
++{
++ return &cpu_topology[cpu].core_sibling;
++}
++
++/*
++ * store_cpu_topology is called at boot when only one cpu is running
++ * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
++ * which prevents simultaneous write access to cpu_topology array
++ */
++void store_cpu_topology(unsigned int cpuid)
++{
++ struct cputopo_arm *cpuid_topo = &cpu_topology[cpuid];
++ unsigned int mpidr;
++ unsigned int cpu;
++
++ /* If the cpu topology has been already set, just return */
++ if (cpuid_topo->core_id != -1)
++ return;
++
++ mpidr = read_cpuid_mpidr();
++
++ /* create cpu topology mapping */
++ if ((mpidr & MPIDR_SMP_BITMASK) == MPIDR_SMP_VALUE) {
++ /*
++ * This is a multiprocessor system
++ * multiprocessor format & multiprocessor mode field are set
++ */
++
++ if (mpidr & MPIDR_MT_BITMASK) {
++ /* core performance interdependency */
++ cpuid_topo->thread_id = (mpidr >> MPIDR_LEVEL0_SHIFT)
++ & MPIDR_LEVEL0_MASK;
++ cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL1_SHIFT)
++ & MPIDR_LEVEL1_MASK;
++ cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL2_SHIFT)
++ & MPIDR_LEVEL2_MASK;
++ } else {
++ /* largely independent cores */
++ cpuid_topo->thread_id = -1;
++ cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL0_SHIFT)
++ & MPIDR_LEVEL0_MASK;
++ cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL1_SHIFT)
++ & MPIDR_LEVEL1_MASK;
++ }
++ } else {
++ /*
++ * This is an uniprocessor system
++ * we are in multiprocessor format but uniprocessor system
++ * or in the old uniprocessor format
++ */
++ cpuid_topo->thread_id = -1;
++ cpuid_topo->core_id = 0;
++ cpuid_topo->socket_id = -1;
++ }
++
++ /* update core and thread sibling masks */
++ for_each_possible_cpu(cpu) {
++ struct cputopo_arm *cpu_topo = &cpu_topology[cpu];
++
++ if (cpuid_topo->socket_id == cpu_topo->socket_id) {
++ cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
++ if (cpu != cpuid)
++ cpumask_set_cpu(cpu,
++ &cpuid_topo->core_sibling);
++
++ if (cpuid_topo->core_id == cpu_topo->core_id) {
++ cpumask_set_cpu(cpuid,
++ &cpu_topo->thread_sibling);
++ if (cpu != cpuid)
++ cpumask_set_cpu(cpu,
++ &cpuid_topo->thread_sibling);
++ }
++ }
++ }
++ smp_wmb();
++
++ printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
++ cpuid, cpu_topology[cpuid].thread_id,
++ cpu_topology[cpuid].core_id,
++ cpu_topology[cpuid].socket_id, mpidr);
++}
++
++/*
++ * init_cpu_topology is called at boot when only one cpu is running
++ * which prevent simultaneous write access to cpu_topology array
++ */
++void init_cpu_topology(void)
++{
++ unsigned int cpu;
++
++ /* init core mask */
++ for_each_possible_cpu(cpu) {
++ struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]);
++
++ cpu_topo->thread_id = -1;
++ cpu_topo->core_id = -1;
++ cpu_topo->socket_id = -1;
++ cpumask_clear(&cpu_topo->core_sibling);
++ cpumask_clear(&cpu_topo->thread_sibling);
++ }
++ smp_wmb();
++}
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0154-ARM-7060-1-smp-populate-logical-CPU-mapping-during-b.patch b/patches.kzm9g/0154-ARM-7060-1-smp-populate-logical-CPU-mapping-during-b.patch
new file mode 100644
index 00000000000000..8fca38f510a270
--- /dev/null
+++ b/patches.kzm9g/0154-ARM-7060-1-smp-populate-logical-CPU-mapping-during-b.patch
@@ -0,0 +1,74 @@
+From febe036de3201edeaadd1290d3cee9544b1b05f3 Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Tue, 23 Aug 2011 22:19:29 +0100
+Subject: ARM: 7060/1: smp: populate logical CPU mapping during boot
+
+To allow booting Linux on a CPU with physical ID != 0, we need to
+provide a mapping from the logical CPU number to the physical CPU
+number.
+
+This patch adds such a mapping and populates it during boot.
+
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+(cherry picked from commit d6257288c4052465feeff7e283e35ec0ed06ca03)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/include/asm/smp.h | 6 ++++++
+ arch/arm/kernel/smp.c | 15 +++++++++++++++
+ 2 files changed, 21 insertions(+)
+
+diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
+index e42d96a..674ebcd 100644
+--- a/arch/arm/include/asm/smp.h
++++ b/arch/arm/include/asm/smp.h
+@@ -66,6 +66,12 @@ extern void platform_secondary_init(unsigned int cpu);
+ extern void platform_smp_prepare_cpus(unsigned int);
+
+ /*
++ * Logical CPU mapping.
++ */
++extern int __cpu_logical_map[NR_CPUS];
++#define cpu_logical_map(cpu) __cpu_logical_map[cpu]
++
++/*
+ * Initial data for bringing up a secondary CPU.
+ */
+ struct secondary_data {
+diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
+index 8e3a000..4db266c 100644
+--- a/arch/arm/kernel/smp.c
++++ b/arch/arm/kernel/smp.c
+@@ -40,6 +40,7 @@
+ #include <asm/tlbflush.h>
+ #include <asm/ptrace.h>
+ #include <asm/localtimer.h>
++#include <asm/smp_plat.h>
+
+ /*
+ * as from 2.5, kernels no longer have an init_tasks structure
+@@ -260,6 +261,20 @@ void __ref cpu_die(void)
+ }
+ #endif /* CONFIG_HOTPLUG_CPU */
+
++int __cpu_logical_map[NR_CPUS];
++
++void __init smp_setup_processor_id(void)
++{
++ int i;
++ u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0;
++
++ cpu_logical_map(0) = cpu;
++ for (i = 1; i < NR_CPUS; ++i)
++ cpu_logical_map(i) = i == cpu ? 0 : i;
++
++ printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu);
++}
++
+ /*
+ * Called by both boot and secondaries to move global data into
+ * per-processor storage.
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0155-ARM-gic-Allow-gic-arch-extensions-to-provide-irqchip.patch b/patches.kzm9g/0155-ARM-gic-Allow-gic-arch-extensions-to-provide-irqchip.patch
new file mode 100644
index 00000000000000..d913adce00a8eb
--- /dev/null
+++ b/patches.kzm9g/0155-ARM-gic-Allow-gic-arch-extensions-to-provide-irqchip.patch
@@ -0,0 +1,35 @@
+From 601c8c40dd8e17083b060418bb630c87e168be86 Mon Sep 17 00:00:00 2001
+From: Colin Cross <ccross@android.com>
+Date: Mon, 13 Jun 2011 00:45:59 +0000
+Subject: ARM: gic: Allow gic arch extensions to provide irqchip flags
+
+Tegra can benefit from the IRQCHIP_MASK_ON_SUSPEND flag, allow it
+to be passed to the gic irq chip.
+
+Signed-off-by: Colin Cross <ccross@android.com>
+Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
+Reviewed-by: Kevin Hilman <khilman@ti.com>
+Tested-and-Acked-by: Shawn Guo <shawn.guo@linaro.org>
+Tested-by: Vishwanath BS <vishwanath.bs@ti.com>
+(cherry picked from commit 9c12845ee49716209cb2b087c0b47c3e37096bde)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/common/gic.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index 66c7c48..734db99 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -544,6 +544,7 @@ void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
+ if (gic_nr == 0)
+ gic_cpu_base_addr = cpu_base;
+
++ gic_chip.flags |= gic_arch_extn.flags;
+ gic_dist_init(gic, irq_start);
+ gic_cpu_init(gic);
+ gic_pm_init(gic);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0156-ARM-7061-1-gic-convert-logical-CPU-numbers-into-phys.patch b/patches.kzm9g/0156-ARM-7061-1-gic-convert-logical-CPU-numbers-into-phys.patch
new file mode 100644
index 00000000000000..35ff5eafc18b63
--- /dev/null
+++ b/patches.kzm9g/0156-ARM-7061-1-gic-convert-logical-CPU-numbers-into-phys.patch
@@ -0,0 +1,67 @@
+From 0ff6ee62ebe17adfa97c1847cc1d7aea76b49d55 Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Tue, 23 Aug 2011 22:20:03 +0100
+Subject: ARM: 7061/1: gic: convert logical CPU numbers into physical numbers
+
+The GIC driver must convert logical CPU numbers passed in from Linux
+into physical CPU numbers that are understood by the hardware.
+
+This patch uses the new cpu_logical_map macro for performing the
+conversion inside the GIC driver.
+
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+(cherry picked from commit 267840f3397fd9f6a2bdde14de38b9d29d525d7b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/common/gic.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index 734db99..8b5be72 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -181,7 +181,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
+ return -EINVAL;
+
+ mask = 0xff << shift;
+- bit = 1 << (cpu + shift);
++ bit = 1 << (cpu_logical_map(cpu) + shift);
+
+ spin_lock(&irq_controller_lock);
+ val = readl_relaxed(reg) & ~mask;
+@@ -260,9 +260,15 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
+ unsigned int irq_start)
+ {
+ unsigned int gic_irqs, irq_limit, i;
++ u32 cpumask;
+ void __iomem *base = gic->dist_base;
+- u32 cpumask = 1 << smp_processor_id();
++ u32 cpu = 0;
+
++#ifdef CONFIG_SMP
++ cpu = cpu_logical_map(smp_processor_id());
++#endif
++
++ cpumask = 1 << cpu;
+ cpumask |= cpumask << 8;
+ cpumask |= cpumask << 16;
+
+@@ -570,7 +576,12 @@ void __cpuinit gic_enable_ppi(unsigned int irq)
+ #ifdef CONFIG_SMP
+ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
+ {
+- unsigned long map = *cpus_addr(*mask);
++ int cpu;
++ unsigned long map = 0;
++
++ /* Convert our logical CPU mask into a physical one. */
++ for_each_cpu(cpu, mask)
++ map |= 1 << cpu_logical_map(cpu);
+
+ /*
+ * Ensure that stores to Normal memory are visible to the
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0157-ARM-7123-1-smp-Add-an-IPI-handler-callable-from-C-co.patch b/patches.kzm9g/0157-ARM-7123-1-smp-Add-an-IPI-handler-callable-from-C-co.patch
new file mode 100644
index 00000000000000..6f64a72920a5a6
--- /dev/null
+++ b/patches.kzm9g/0157-ARM-7123-1-smp-Add-an-IPI-handler-callable-from-C-co.patch
@@ -0,0 +1,53 @@
+From 32e451b349e7eb7f702b46dd50e57585b0471889 Mon Sep 17 00:00:00 2001
+From: Shawn Guo <shawn.guo@linaro.org>
+Date: Thu, 6 Oct 2011 15:18:14 +0100
+Subject: ARM: 7123/1: smp: Add an IPI handler callable from C code
+
+In order to be able to handle IPI directly from C code instead of
+assembly code, introduce handle_IPI(), which is modeled after handle_IRQ().
+
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+(cherry picked from commit 0b5a1b95dcdfa451125132d5ce3f79a27ffb0950)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/include/asm/smp.h | 5 +++++
+ arch/arm/kernel/smp.c | 5 +++++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
+index 674ebcd..0a17b62 100644
+--- a/arch/arm/include/asm/smp.h
++++ b/arch/arm/include/asm/smp.h
+@@ -33,6 +33,11 @@ extern void show_ipi_list(struct seq_file *, int);
+ asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);
+
+ /*
++ * Called from C code, this handles an IPI.
++ */
++void handle_IPI(int ipinr, struct pt_regs *regs);
++
++/*
+ * Setup the set of possible CPUs (via set_cpu_possible)
+ */
+ extern void smp_init_cpus(void);
+diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
+index 4db266c..74ac4bb 100644
+--- a/arch/arm/kernel/smp.c
++++ b/arch/arm/kernel/smp.c
+@@ -580,6 +580,11 @@ static void ipi_cpu_stop(unsigned int cpu)
+ */
+ asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
+ {
++ handle_IPI(ipinr, regs);
++}
++
++void handle_IPI(int ipinr, struct pt_regs *regs)
++{
+ unsigned int cpu = smp_processor_id();
+ struct pt_regs *old_regs = set_irq_regs(regs);
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0158-ARM-7124-1-smp-Add-a-localtimer-handler-callable-fro.patch b/patches.kzm9g/0158-ARM-7124-1-smp-Add-a-localtimer-handler-callable-fro.patch
new file mode 100644
index 00000000000000..d260cb8b62f735
--- /dev/null
+++ b/patches.kzm9g/0158-ARM-7124-1-smp-Add-a-localtimer-handler-callable-fro.patch
@@ -0,0 +1,53 @@
+From 3a88e40dec05b0d5d376ba18a7f6833b3f6d7be5 Mon Sep 17 00:00:00 2001
+From: Shawn Guo <shawn.guo@linaro.org>
+Date: Thu, 6 Oct 2011 15:19:14 +0100
+Subject: ARM: 7124/1: smp: Add a localtimer handler callable from C code
+
+In order to be able to handle localtimer directly from C code instead of
+assembly code, introduce handle_local_timer(), which is modeled after
+handle_IRQ().
+
+Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+(cherry picked from commit 0af8aa0069e43f90d59666510342c05e97d8c4b8)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/include/asm/localtimer.h | 4 ++++
+ arch/arm/kernel/smp.c | 5 +++++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
+index 080d74f..3306f28 100644
+--- a/arch/arm/include/asm/localtimer.h
++++ b/arch/arm/include/asm/localtimer.h
+@@ -22,6 +22,10 @@ void percpu_timer_setup(void);
+ */
+ asmlinkage void do_local_timer(struct pt_regs *);
+
++/*
++ * Called from C code
++ */
++void handle_local_timer(struct pt_regs *);
+
+ #ifdef CONFIG_LOCAL_TIMERS
+
+diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
+index 74ac4bb..53aaa59 100644
+--- a/arch/arm/kernel/smp.c
++++ b/arch/arm/kernel/smp.c
+@@ -473,6 +473,11 @@ static void ipi_timer(void)
+ #ifdef CONFIG_LOCAL_TIMERS
+ asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
+ {
++ handle_local_timer(regs);
++}
++
++void handle_local_timer(struct pt_regs *regs)
++{
+ struct pt_regs *old_regs = set_irq_regs(regs);
+ int cpu = smp_processor_id();
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0159-ARM-gic-consolidate-PPI-handling.patch b/patches.kzm9g/0159-ARM-gic-consolidate-PPI-handling.patch
new file mode 100644
index 00000000000000..28b7f97e736e35
--- /dev/null
+++ b/patches.kzm9g/0159-ARM-gic-consolidate-PPI-handling.patch
@@ -0,0 +1,561 @@
+From c05f2488f4b9c5a88e74afd7b22a986c4378fb2b Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <marc.zyngier@arm.com>
+Date: Wed, 20 Jul 2011 16:24:14 +0100
+Subject: ARM: gic: consolidate PPI handling
+
+PPI handling is a bit of an odd beast. It uses its own low level
+handling code and is hardwired to the local timers (hence lacking
+a registration interface).
+
+Instead, switch the low handling to the normal SPI handling code.
+PPIs are handled by the handle_percpu_devid_irq flow.
+
+This also allows the removal of some duplicated code.
+
+Cc: Kukjin Kim <kgene.kim@samsung.com>
+Cc: David Brown <davidb@codeaurora.org>
+Cc: Bryan Huntsman <bryanh@codeaurora.org>
+Cc: Tony Lindgren <tony@atomide.com>
+Cc: Paul Mundt <lethal@linux-sh.org>
+Cc: Magnus Damm <magnus.damm@gmail.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: David Brown <davidb@codeaurora.org>
+Tested-by: David Brown <davidb@codeaurora.org>
+Tested-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+(cherry picked from commit 292b293ceef2eda1f96f0c90b96e954d7bdabd1c)
+
+Conflicts:
+
+ arch/arm/mach-exynos4/include/mach/entry-macro.S
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/common/gic.c | 75 ++++++++++++++++++++++-
+ arch/arm/include/asm/entry-macro-multi.S | 7 ---
+ arch/arm/include/asm/hardirq.h | 3 -
+ arch/arm/include/asm/hardware/entry-macro-gic.S | 19 +-----
+ arch/arm/include/asm/localtimer.h | 11 ++--
+ arch/arm/include/asm/smp.h | 5 --
+ arch/arm/kernel/irq.c | 3 -
+ arch/arm/kernel/smp.c | 32 ++--------
+ arch/arm/mach-exynos4/include/mach/entry-macro.S | 13 +---
+ arch/arm/mach-msm/board-msm8x60.c | 11 ----
+ arch/arm/mach-msm/include/mach/entry-macro-qgic.S | 73 +---------------------
+ arch/arm/mach-omap2/include/mach/entry-macro.S | 14 +----
+ arch/arm/mach-shmobile/entry-intc.S | 3 -
+ arch/arm/mach-shmobile/include/mach/entry-macro.S | 3 -
+ 14 files changed, 88 insertions(+), 184 deletions(-)
+
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index 8b5be72..95ad8d1 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -29,10 +29,14 @@
+ #include <linux/cpu_pm.h>
+ #include <linux/cpumask.h>
+ #include <linux/io.h>
++#include <linux/interrupt.h>
++#include <linux/percpu.h>
++#include <linux/slab.h>
+
+ #include <asm/irq.h>
+ #include <asm/mach/irq.h>
+ #include <asm/hardware/gic.h>
++#include <asm/localtimer.h>
+
+ static DEFINE_SPINLOCK(irq_controller_lock);
+
+@@ -256,6 +260,32 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
+ irq_set_chained_handler(irq, gic_handle_cascade_irq);
+ }
+
++#ifdef CONFIG_LOCAL_TIMERS
++#define gic_ppi_handler percpu_timer_handler
++#else
++static irqreturn_t gic_ppi_handler(int irq, void *dev_id)
++{
++ return IRQ_NONE;
++}
++#endif
++
++#define PPI_IRQACT(nr) \
++ { \
++ .handler = gic_ppi_handler, \
++ .flags = IRQF_PERCPU | IRQF_TIMER, \
++ .irq = nr, \
++ .name = "PPI-" # nr, \
++ }
++
++static struct irqaction ppi_irqaction_template[16] __initdata = {
++ PPI_IRQACT(0), PPI_IRQACT(1), PPI_IRQACT(2), PPI_IRQACT(3),
++ PPI_IRQACT(4), PPI_IRQACT(5), PPI_IRQACT(6), PPI_IRQACT(7),
++ PPI_IRQACT(8), PPI_IRQACT(9), PPI_IRQACT(10), PPI_IRQACT(11),
++ PPI_IRQACT(12), PPI_IRQACT(13), PPI_IRQACT(14), PPI_IRQACT(15),
++};
++
++static struct irqaction *ppi_irqaction;
++
+ static void __init gic_dist_init(struct gic_chip_data *gic,
+ unsigned int irq_start)
+ {
+@@ -263,6 +293,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
+ u32 cpumask;
+ void __iomem *base = gic->dist_base;
+ u32 cpu = 0;
++ u32 nrppis = 0, ppi_base = 0;
+
+ #ifdef CONFIG_SMP
+ cpu = cpu_logical_map(smp_processor_id());
+@@ -286,6 +317,33 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
+ gic->gic_irqs = gic_irqs;
+
+ /*
++ * Nobody would be insane enough to use PPIs on a secondary
++ * GIC, right?
++ */
++ if (gic == &gic_data[0]) {
++ nrppis = (32 - irq_start) & 31;
++
++ /* The GIC only supports up to 16 PPIs. */
++ if (nrppis > 16)
++ BUG();
++
++ ppi_base = gic->irq_offset + 32 - nrppis;
++
++ ppi_irqaction = kmemdup(&ppi_irqaction_template[16 - nrppis],
++ sizeof(*ppi_irqaction) * nrppis,
++ GFP_KERNEL);
++
++ if (nrppis && !ppi_irqaction) {
++ pr_err("GIC: Can't allocate PPI memory");
++ nrppis = 0;
++ ppi_base = 0;
++ }
++ }
++
++ pr_info("Configuring GIC with %d sources (%d PPIs)\n",
++ gic_irqs, (gic == &gic_data[0]) ? nrppis : 0);
++
++ /*
+ * Set all global interrupts to be level triggered, active low.
+ */
+ for (i = 32; i < gic_irqs; i += 16)
+@@ -320,7 +378,22 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
+ /*
+ * Setup the Linux IRQ subsystem.
+ */
+- for (i = irq_start; i < irq_limit; i++) {
++ for (i = 0; i < nrppis; i++) {
++ int ppi = i + ppi_base;
++ int err;
++
++ irq_set_percpu_devid(ppi);
++ irq_set_chip_and_handler(ppi, &gic_chip,
++ handle_percpu_devid_irq);
++ irq_set_chip_data(ppi, gic);
++ set_irq_flags(ppi, IRQF_VALID | IRQF_NOAUTOEN);
++
++ err = setup_percpu_irq(ppi, &ppi_irqaction[i]);
++ if (err)
++ pr_err("GIC: can't setup PPI%d (%d)\n", ppi, err);
++ }
++
++ for (i = irq_start + nrppis; i < irq_limit; i++) {
+ irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq);
+ irq_set_chip_data(i, gic);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S
+index 2f1e209..88d6181 100644
+--- a/arch/arm/include/asm/entry-macro-multi.S
++++ b/arch/arm/include/asm/entry-macro-multi.S
+@@ -25,13 +25,6 @@
+ movne r1, sp
+ adrne lr, BSYM(1b)
+ bne do_IPI
+-
+-#ifdef CONFIG_LOCAL_TIMERS
+- test_for_ltirq r0, r2, r6, lr
+- movne r0, sp
+- adrne lr, BSYM(1b)
+- bne do_local_timer
+-#endif
+ #endif
+ 9997:
+ .endm
+diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h
+index 89ad180..ddf07a9 100644
+--- a/arch/arm/include/asm/hardirq.h
++++ b/arch/arm/include/asm/hardirq.h
+@@ -9,9 +9,6 @@
+
+ typedef struct {
+ unsigned int __softirq_pending;
+-#ifdef CONFIG_LOCAL_TIMERS
+- unsigned int local_timer_irqs;
+-#endif
+ #ifdef CONFIG_SMP
+ unsigned int ipi_irqs[NR_IPI];
+ #endif
+diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S
+index c115b82..74ebc80 100644
+--- a/arch/arm/include/asm/hardware/entry-macro-gic.S
++++ b/arch/arm/include/asm/hardware/entry-macro-gic.S
+@@ -22,15 +22,11 @@
+ * interrupt controller spec. To wit:
+ *
+ * Interrupts 0-15 are IPI
+- * 16-28 are reserved
+- * 29-31 are local. We allow 30 to be used for the watchdog.
++ * 16-31 are local. We allow 30 to be used for the watchdog.
+ * 32-1020 are global
+ * 1021-1022 are reserved
+ * 1023 is "spurious" (no interrupt)
+ *
+- * For now, we ignore all local interrupts so only return an interrupt if it's
+- * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
+- *
+ * A simple read from the controller will tell us the number of the highest
+ * priority enabled interrupt. We then just need to check whether it is in the
+ * valid range for an IRQ (30-1020 inclusive).
+@@ -43,7 +39,7 @@
+
+ ldr \tmp, =1021
+ bic \irqnr, \irqstat, #0x1c00
+- cmp \irqnr, #29
++ cmp \irqnr, #15
+ cmpcc \irqnr, \irqnr
+ cmpne \irqnr, \tmp
+ cmpcs \irqnr, \irqnr
+@@ -62,14 +58,3 @@
+ strcc \irqstat, [\base, #GIC_CPU_EOI]
+ cmpcs \irqnr, \irqnr
+ .endm
+-
+-/* As above, this assumes that irqstat and base are preserved.. */
+-
+- .macro test_for_ltirq, irqnr, irqstat, base, tmp
+- bic \irqnr, \irqstat, #0x1c00
+- mov \tmp, #0
+- cmp \irqnr, #29
+- moveq \tmp, #1
+- streq \irqstat, [\base, #GIC_CPU_EOI]
+- cmp \tmp, #0
+- .endm
+diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
+index 3306f28..5c8acb4 100644
+--- a/arch/arm/include/asm/localtimer.h
++++ b/arch/arm/include/asm/localtimer.h
+@@ -10,6 +10,8 @@
+ #ifndef __ASM_ARM_LOCALTIMER_H
+ #define __ASM_ARM_LOCALTIMER_H
+
++#include <linux/interrupt.h>
++
+ struct clock_event_device;
+
+ /*
+@@ -18,14 +20,9 @@ struct clock_event_device;
+ void percpu_timer_setup(void);
+
+ /*
+- * Called from assembly, this is the local timer IRQ handler
+- */
+-asmlinkage void do_local_timer(struct pt_regs *);
+-
+-/*
+- * Called from C code
++ * Per-cpu timer IRQ handler
+ */
+-void handle_local_timer(struct pt_regs *);
++irqreturn_t percpu_timer_handler(int irq, void *dev_id);
+
+ #ifdef CONFIG_LOCAL_TIMERS
+
+diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
+index 0a17b62..1e5717a 100644
+--- a/arch/arm/include/asm/smp.h
++++ b/arch/arm/include/asm/smp.h
+@@ -99,9 +99,4 @@ extern void platform_cpu_enable(unsigned int cpu);
+ extern void arch_send_call_function_single_ipi(int cpu);
+ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+
+-/*
+- * show local interrupt info
+- */
+-extern void show_local_irqs(struct seq_file *, int);
+-
+ #endif /* ifndef __ASM_ARM_SMP_H */
+diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
+index 3e34b1f..0ad5e98 100644
+--- a/arch/arm/kernel/irq.c
++++ b/arch/arm/kernel/irq.c
+@@ -59,9 +59,6 @@ int arch_show_interrupts(struct seq_file *p, int prec)
+ #ifdef CONFIG_SMP
+ show_ipi_list(p, prec);
+ #endif
+-#ifdef CONFIG_LOCAL_TIMERS
+- show_local_irqs(p, prec);
+-#endif
+ seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
+ return 0;
+ }
+diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
+index 53aaa59..7db7120 100644
+--- a/arch/arm/kernel/smp.c
++++ b/arch/arm/kernel/smp.c
+@@ -450,10 +450,6 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
+ for (i = 0; i < NR_IPI; i++)
+ sum += __get_irq_stat(cpu, ipi_irqs[i]);
+
+-#ifdef CONFIG_LOCAL_TIMERS
+- sum += __get_irq_stat(cpu, local_timer_irqs);
+-#endif
+-
+ return sum;
+ }
+
+@@ -471,34 +467,16 @@ static void ipi_timer(void)
+ }
+
+ #ifdef CONFIG_LOCAL_TIMERS
+-asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
+-{
+- handle_local_timer(regs);
+-}
+-
+-void handle_local_timer(struct pt_regs *regs)
++irqreturn_t percpu_timer_handler(int irq, void *dev_id)
+ {
+- struct pt_regs *old_regs = set_irq_regs(regs);
+- int cpu = smp_processor_id();
++ struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent);
+
+ if (local_timer_ack()) {
+- __inc_irq_stat(cpu, local_timer_irqs);
+- ipi_timer();
++ evt->event_handler(evt);
++ return IRQ_HANDLED;
+ }
+
+- set_irq_regs(old_regs);
+-}
+-
+-void show_local_irqs(struct seq_file *p, int prec)
+-{
+- unsigned int cpu;
+-
+- seq_printf(p, "%*s: ", prec, "LOC");
+-
+- for_each_present_cpu(cpu)
+- seq_printf(p, "%10u ", __get_irq_stat(cpu, local_timer_irqs));
+-
+- seq_printf(p, " Local timer interrupts\n");
++ return IRQ_NONE;
+ }
+ #endif
+
+diff --git a/arch/arm/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos4/include/mach/entry-macro.S
+index d8f38c2..9be072f 100644
+--- a/arch/arm/mach-exynos4/include/mach/entry-macro.S
++++ b/arch/arm/mach-exynos4/include/mach/entry-macro.S
+@@ -50,7 +50,7 @@
+
+ bic \irqnr, \irqstat, #0x1c00
+
+- cmp \irqnr, #29
++ cmp \irqnr, #15
+ cmpcc \irqnr, \irqnr
+ cmpne \irqnr, \tmp
+ cmpcs \irqnr, \irqnr
+@@ -71,14 +71,3 @@
+ strcc \irqstat, [\base, #GIC_CPU_EOI]
+ cmpcs \irqnr, \irqnr
+ .endm
+-
+- /* As above, this assumes that irqstat and base are preserved.. */
+-
+- .macro test_for_ltirq, irqnr, irqstat, base, tmp
+- bic \irqnr, \irqstat, #0x1c00
+- mov \tmp, #0
+- cmp \irqnr, #29
+- moveq \tmp, #1
+- streq \irqstat, [\base, #GIC_CPU_EOI]
+- cmp \tmp, #0
+- .endm
+diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
+index 1163b6f..d70a2f6 100644
+--- a/arch/arm/mach-msm/board-msm8x60.c
++++ b/arch/arm/mach-msm/board-msm8x60.c
+@@ -36,8 +36,6 @@ static void __init msm8x60_map_io(void)
+
+ static void __init msm8x60_init_irq(void)
+ {
+- unsigned int i;
+-
+ gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
+ (void *)MSM_QGIC_CPU_BASE);
+
+@@ -49,15 +47,6 @@ static void __init msm8x60_init_irq(void)
+ */
+ if (!machine_is_msm8x60_sim())
+ writel(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
+-
+- /* FIXME: Not installing AVS_SVICINT and AVS_SVICINTSWDONE yet
+- * as they are configured as level, which does not play nice with
+- * handle_percpu_irq.
+- */
+- for (i = GIC_PPI_START; i < GIC_SPI_START; i++) {
+- if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE)
+- irq_set_handler(i, handle_percpu_irq);
+- }
+ }
+
+ static void __init msm8x60_init(void)
+diff --git a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S
+index 1246715..717076f 100644
+--- a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S
++++ b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S
+@@ -8,81 +8,10 @@
+ * warranty of any kind, whether express or implied.
+ */
+
+-#include <mach/hardware.h>
+-#include <asm/hardware/gic.h>
++#include <asm/hardware/entry-macro-gic.S>
+
+ .macro disable_fiq
+ .endm
+
+- .macro get_irqnr_preamble, base, tmp
+- ldr \base, =gic_cpu_base_addr
+- ldr \base, [\base]
+- .endm
+-
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+-
+- /*
+- * The interrupt numbering scheme is defined in the
+- * interrupt controller spec. To wit:
+- *
+- * Migrated the code from ARM MP port to be more consistent
+- * with interrupt processing , the following still holds true
+- * however, all interrupts are treated the same regardless of
+- * if they are local IPI or PPI
+- *
+- * Interrupts 0-15 are IPI
+- * 16-31 are PPI
+- * (16-18 are the timers)
+- * 32-1020 are global
+- * 1021-1022 are reserved
+- * 1023 is "spurious" (no interrupt)
+- *
+- * A simple read from the controller will tell us the number of the
+- * highest priority enabled interrupt. We then just need to check
+- * whether it is in the valid range for an IRQ (0-1020 inclusive).
+- *
+- * Base ARM code assumes that the local (private) peripheral interrupts
+- * are not valid, we treat them differently, in that the privates are
+- * handled like normal shared interrupts with the exception that only
+- * one processor can register the interrupt and the handler must be
+- * the same for all processors.
+- */
+-
+- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+-
+- ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 =srcCPU,
+- 9-0 =int # */
+-
+- bic \irqnr, \irqstat, #0x1c00 @mask src
+- cmp \irqnr, #15
+- ldr \tmp, =1021
+- cmpcc \irqnr, \irqnr
+- cmpne \irqnr, \tmp
+- cmpcs \irqnr, \irqnr
+-
+- .endm
+-
+- /* We assume that irqstat (the raw value of the IRQ acknowledge
+- * register) is preserved from the macro above.
+- * If there is an IPI, we immediately signal end of interrupt on the
+- * controller, since this requires the original irqstat value which
+- * we won't easily be able to recreate later.
+- */
+- .macro test_for_ipi, irqnr, irqstat, base, tmp
+- bic \irqnr, \irqstat, #0x1c00
+- cmp \irqnr, #16
+- strcc \irqstat, [\base, #GIC_CPU_EOI]
+- cmpcs \irqnr, \irqnr
+- .endm
+-
+- /* As above, this assumes that irqstat and base are preserved.. */
+-
+- .macro test_for_ltirq, irqnr, irqstat, base, tmp
+- bic \irqnr, \irqstat, #0x1c00
+- mov \tmp, #0
+- cmp \irqnr, #16
+- moveq \tmp, #1
+- streq \irqstat, [\base, #GIC_CPU_EOI]
+- cmp \tmp, #0
+- .endm
+diff --git a/arch/arm/mach-omap2/include/mach/entry-macro.S b/arch/arm/mach-omap2/include/mach/entry-macro.S
+index a48690b..22d86ef 100644
+--- a/arch/arm/mach-omap2/include/mach/entry-macro.S
++++ b/arch/arm/mach-omap2/include/mach/entry-macro.S
+@@ -78,7 +78,7 @@
+ 4401: ldr \irqstat, [\base, #GIC_CPU_INTACK]
+ ldr \tmp, =1021
+ bic \irqnr, \irqstat, #0x1c00
+- cmp \irqnr, #29
++ cmp \irqnr, #15
+ cmpcc \irqnr, \irqnr
+ cmpne \irqnr, \tmp
+ cmpcs \irqnr, \irqnr
+@@ -101,18 +101,6 @@
+ it cs
+ cmpcs \irqnr, \irqnr
+ .endm
+-
+- /* As above, this assumes that irqstat and base are preserved */
+-
+- .macro test_for_ltirq, irqnr, irqstat, base, tmp
+- bic \irqnr, \irqstat, #0x1c00
+- mov \tmp, #0
+- cmp \irqnr, #29
+- itt eq
+- moveq \tmp, #1
+- streq \irqstat, [\base, #GIC_CPU_EOI]
+- cmp \tmp, #0
+- .endm
+ #endif /* CONFIG_SMP */
+
+ #else /* MULTI_OMAP2 */
+diff --git a/arch/arm/mach-shmobile/entry-intc.S b/arch/arm/mach-shmobile/entry-intc.S
+index cac0a7a..1a1c00c 100644
+--- a/arch/arm/mach-shmobile/entry-intc.S
++++ b/arch/arm/mach-shmobile/entry-intc.S
+@@ -51,7 +51,4 @@
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ .endm
+
+- .macro test_for_ltirq, irqnr, irqstat, base, tmp
+- .endm
+-
+ arch_irq_handler shmobile_handle_irq_intc
+diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro.S b/arch/arm/mach-shmobile/include/mach/entry-macro.S
+index d791f10..8d4a416 100644
+--- a/arch/arm/mach-shmobile/include/mach/entry-macro.S
++++ b/arch/arm/mach-shmobile/include/mach/entry-macro.S
+@@ -27,8 +27,5 @@
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ .endm
+
+- .macro test_for_ltirq, irqnr, irqstat, base, tmp
+- .endm
+-
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0160-ARM-GIC-Add-global-gic_handle_irq-function.patch b/patches.kzm9g/0160-ARM-GIC-Add-global-gic_handle_irq-function.patch
new file mode 100644
index 00000000000000..3b5ba5af83e05a
--- /dev/null
+++ b/patches.kzm9g/0160-ARM-GIC-Add-global-gic_handle_irq-function.patch
@@ -0,0 +1,81 @@
+From a0ef51f4b57f8a01b252ac767519d2a4002d2a4c Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <marc.zyngier@arm.com>
+Date: Tue, 6 Sep 2011 09:56:17 +0100
+Subject: ARM: GIC: Add global gic_handle_irq() function
+
+Provide the GIC code with a low level handler that can be used
+by platforms using CONFIG_MULTI_IRQ_HANDLER.
+
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+(cherry picked from commit 562e0027d21bf64838178e2f5157df3d5833972e)
+
+Conflicts:
+
+ arch/arm/common/gic.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/common/gic.c | 27 ++++++++++++++++++++++++++-
+ arch/arm/include/asm/hardware/gic.h | 1 +
+ 2 files changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index 95ad8d1..7a73799 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -26,7 +26,6 @@
+ #include <linux/kernel.h>
+ #include <linux/list.h>
+ #include <linux/smp.h>
+-#include <linux/cpu_pm.h>
+ #include <linux/cpumask.h>
+ #include <linux/io.h>
+ #include <linux/interrupt.h>
+@@ -211,6 +210,32 @@ static int gic_set_wake(struct irq_data *d, unsigned int on)
+ #define gic_set_wake NULL
+ #endif
+
++asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
++{
++ u32 irqstat, irqnr;
++ struct gic_chip_data *gic = &gic_data[0];
++ void __iomem *cpu_base = gic->cpu_base;
++
++ do {
++ irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);
++ irqnr = irqstat & ~0x1c00;
++
++ if (likely(irqnr > 15 && irqnr < 1021)) {
++ //irqnr = irqnr + gic->irq_offset;
++ handle_IRQ(irqnr, regs);
++ continue;
++ }
++ if (irqnr < 16) {
++ writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
++#ifdef CONFIG_SMP
++ handle_IPI(irqnr, regs);
++#endif
++ continue;
++ }
++ break;
++ } while (1);
++}
++
+ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
+ {
+ struct gic_chip_data *chip_data = irq_get_handler_data(irq);
+diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
+index c562705..615c336 100644
+--- a/arch/arm/include/asm/hardware/gic.h
++++ b/arch/arm/include/asm/hardware/gic.h
+@@ -38,6 +38,7 @@ extern struct irq_chip gic_arch_extn;
+
+ void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
+ void gic_secondary_init(unsigned int);
++void gic_handle_irq(struct pt_regs *regs);
+ void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
+ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
+ void gic_enable_ppi(unsigned int);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0161-ARM-twd-register-clockevents-device-before-enabling-.patch b/patches.kzm9g/0161-ARM-twd-register-clockevents-device-before-enabling-.patch
new file mode 100644
index 00000000000000..d48fa9face4e46
--- /dev/null
+++ b/patches.kzm9g/0161-ARM-twd-register-clockevents-device-before-enabling-.patch
@@ -0,0 +1,41 @@
+From 1322ac36bc746ca63e1968e96b8945ee1ab85fff Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Wed, 20 Jul 2011 14:18:46 +0100
+Subject: ARM: twd: register clockevents device before enabling PPI
+
+The smp_twd clockevents driver currently enables the local timer PPI
+before the clockevents device is registered. This can lead to a kernel
+panic if a spurious timer interrupt is generated before registration
+has completed since the kernel will treat it as an IPI timer.
+
+This patch moves the clockevents device registration before the IRQ
+unmasking so that we can always handle timer interrupts once they can
+occur.
+
+Acked-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+(cherry picked from commit dfc40b24c0a37593724f3317cd485c73ee878c18)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/kernel/smp_twd.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
+index 2c277d4..01c1862 100644
+--- a/arch/arm/kernel/smp_twd.c
++++ b/arch/arm/kernel/smp_twd.c
+@@ -137,8 +137,8 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
+ clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);
+ clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
+
++ clockevents_register_device(clk);
++
+ /* Make sure our local interrupt controller has this enabled */
+ gic_enable_ppi(clk->irq);
+-
+- clockevents_register_device(clk);
+ }
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0162-ARM-EXYNOS4-set-the-affinity-of-mct1-interrupt-using.patch b/patches.kzm9g/0162-ARM-EXYNOS4-set-the-affinity-of-mct1-interrupt-using.patch
new file mode 100644
index 00000000000000..248a87aa58227b
--- /dev/null
+++ b/patches.kzm9g/0162-ARM-EXYNOS4-set-the-affinity-of-mct1-interrupt-using.patch
@@ -0,0 +1,36 @@
+From bf7b78d246e27b2b276b600fb145f8ccef7246e7 Mon Sep 17 00:00:00 2001
+From: Changhwan Youn <chaos.youn@samsung.com>
+Date: Sat, 16 Jul 2011 10:49:44 +0900
+Subject: ARM: EXYNOS4: set the affinity of mct1 interrupt using IRQ_MCT_L1
+
+IRQ_MCT_L1 is connected directly to GIC in external GIC mapping,
+while in internal GIC mapping, it is connected to GIC through
+interrupt combiner. Therfore the affinity for mct1 event timer
+interrupt should be changed through IRQ_MCT_L1.
+
+Signed-off-by: Changhwan Youn <chaos.youn@samsung.com>
+Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
+(cherry picked from commit a8769a594a6d061f8018048a7cd1546924c61a5c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-exynos4/mct.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos4/mct.c
+index 14ac10b..1ae059b 100644
+--- a/arch/arm/mach-exynos4/mct.c
++++ b/arch/arm/mach-exynos4/mct.c
+@@ -383,8 +383,8 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
+ setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq);
+ } else {
+ mct_tick1_event_irq.dev_id = &mct_tick[cpu];
+- irq_set_affinity(IRQ_MCT1, cpumask_of(1));
+ setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq);
++ irq_set_affinity(IRQ_MCT_L1, cpumask_of(1));
+ }
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0163-genirq-percpu-allow-interrupt-type-to-be-set-at-enab.patch b/patches.kzm9g/0163-genirq-percpu-allow-interrupt-type-to-be-set-at-enab.patch
new file mode 100644
index 00000000000000..d60c9da5ca867a
--- /dev/null
+++ b/patches.kzm9g/0163-genirq-percpu-allow-interrupt-type-to-be-set-at-enab.patch
@@ -0,0 +1,75 @@
+From 34377e3bf1795c5e592b3135913ae0f7147bbb85 Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <marc.zyngier@arm.com>
+Date: Fri, 30 Sep 2011 10:48:47 +0100
+Subject: genirq: percpu: allow interrupt type to be set at enable time
+
+As request_percpu_irq() doesn't allow for a percpu interrupt to have
+its type configured (it is generally impossible to configure it on all
+CPUs at once), add a 'type' argument to enable_percpu_irq().
+
+This allows some low-level, board specific init code to be switched to
+a generic API.
+
+[ tglx: Added WARN_ON argument ]
+
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Cc: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+(cherry picked from commit 1e7c5fd29487ee88cb3abac945bafa60ae026146)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ include/linux/interrupt.h | 2 +-
+ kernel/irq/manage.c | 15 ++++++++++++++-
+ 2 files changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
+index 6fe4e3c..8854a4c 100644
+--- a/include/linux/interrupt.h
++++ b/include/linux/interrupt.h
+@@ -226,7 +226,7 @@ extern void disable_irq_nosync(unsigned int irq);
+ extern void disable_irq(unsigned int irq);
+ extern void disable_percpu_irq(unsigned int irq);
+ extern void enable_irq(unsigned int irq);
+-extern void enable_percpu_irq(unsigned int irq);
++extern void enable_percpu_irq(unsigned int irq, unsigned int type);
+
+ /* The following three functions are for the core kernel use only. */
+ #ifdef CONFIG_GENERIC_HARDIRQS
+diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
+index 7923849..fea7c71 100644
+--- a/kernel/irq/manage.c
++++ b/kernel/irq/manage.c
+@@ -1454,7 +1454,7 @@ int request_any_context_irq(unsigned int irq, irq_handler_t handler,
+ }
+ EXPORT_SYMBOL_GPL(request_any_context_irq);
+
+-void enable_percpu_irq(unsigned int irq)
++void enable_percpu_irq(unsigned int irq, unsigned int type)
+ {
+ unsigned int cpu = smp_processor_id();
+ unsigned long flags;
+@@ -1463,7 +1463,20 @@ void enable_percpu_irq(unsigned int irq)
+ if (!desc)
+ return;
+
++ type &= IRQ_TYPE_SENSE_MASK;
++ if (type != IRQ_TYPE_NONE) {
++ int ret;
++
++ ret = __irq_set_trigger(desc, irq, type);
++
++ if (ret) {
++ WARN(1, "failed to set type for IRQ%d\n, irq");
++ goto out;
++ }
++ }
++
+ irq_percpu_enable(desc, cpu);
++out:
+ irq_put_desc_unlock(desc, flags);
+ }
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0164-ARM-gic-local-timers-use-the-request_percpu_irq-inte.patch b/patches.kzm9g/0164-ARM-gic-local-timers-use-the-request_percpu_irq-inte.patch
new file mode 100644
index 00000000000000..e01ad13c8e072e
--- /dev/null
+++ b/patches.kzm9g/0164-ARM-gic-local-timers-use-the-request_percpu_irq-inte.patch
@@ -0,0 +1,508 @@
+From f14b02ced1783bf8d9c2825ab79c26cd5d6bc635 Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <marc.zyngier@arm.com>
+Date: Fri, 22 Jul 2011 12:52:37 +0100
+Subject: ARM: gic, local timers: use the request_percpu_irq() interface
+
+This patch remove the hardcoded link between local timers and PPIs,
+and convert the PPI users (TWD, MCT and MSM timers) to the new
+*_percpu_irq interface. Also some collateral cleanup
+(local_timer_ack() is gone, and the interrupt handler is strictly
+private to each driver).
+
+PPIs are now useable for more than just the local timers.
+
+Additional testing by David Brown (msm8250 and msm8660) and
+Shawn Guo (imx6q).
+
+Cc: David Brown <davidb@codeaurora.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: David Brown <davidb@codeaurora.org>
+Tested-by: David Brown <davidb@codeaurora.org>
+Tested-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+(cherry picked from commit 28af690a284dfcb627bd69d0963db1c0f412cb8c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/common/gic.c | 52 ----------------------------
+ arch/arm/include/asm/hardware/gic.h | 1 -
+ arch/arm/include/asm/localtimer.h | 16 ++++-----
+ arch/arm/include/asm/smp_twd.h | 2 +-
+ arch/arm/kernel/smp.c | 16 +--------
+ arch/arm/kernel/smp_twd.c | 47 +++++++++++++++++++++++--
+ arch/arm/mach-exynos4/mct.c | 7 ++--
+ arch/arm/mach-msm/timer.c | 69 +++++++++++++++++++++----------------
+ 8 files changed, 99 insertions(+), 111 deletions(-)
+
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index 7a73799..5f7b4e2 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -35,7 +35,6 @@
+ #include <asm/irq.h>
+ #include <asm/mach/irq.h>
+ #include <asm/hardware/gic.h>
+-#include <asm/localtimer.h>
+
+ static DEFINE_SPINLOCK(irq_controller_lock);
+
+@@ -285,32 +284,6 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
+ irq_set_chained_handler(irq, gic_handle_cascade_irq);
+ }
+
+-#ifdef CONFIG_LOCAL_TIMERS
+-#define gic_ppi_handler percpu_timer_handler
+-#else
+-static irqreturn_t gic_ppi_handler(int irq, void *dev_id)
+-{
+- return IRQ_NONE;
+-}
+-#endif
+-
+-#define PPI_IRQACT(nr) \
+- { \
+- .handler = gic_ppi_handler, \
+- .flags = IRQF_PERCPU | IRQF_TIMER, \
+- .irq = nr, \
+- .name = "PPI-" # nr, \
+- }
+-
+-static struct irqaction ppi_irqaction_template[16] __initdata = {
+- PPI_IRQACT(0), PPI_IRQACT(1), PPI_IRQACT(2), PPI_IRQACT(3),
+- PPI_IRQACT(4), PPI_IRQACT(5), PPI_IRQACT(6), PPI_IRQACT(7),
+- PPI_IRQACT(8), PPI_IRQACT(9), PPI_IRQACT(10), PPI_IRQACT(11),
+- PPI_IRQACT(12), PPI_IRQACT(13), PPI_IRQACT(14), PPI_IRQACT(15),
+-};
+-
+-static struct irqaction *ppi_irqaction;
+-
+ static void __init gic_dist_init(struct gic_chip_data *gic,
+ unsigned int irq_start)
+ {
+@@ -353,16 +326,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
+ BUG();
+
+ ppi_base = gic->irq_offset + 32 - nrppis;
+-
+- ppi_irqaction = kmemdup(&ppi_irqaction_template[16 - nrppis],
+- sizeof(*ppi_irqaction) * nrppis,
+- GFP_KERNEL);
+-
+- if (nrppis && !ppi_irqaction) {
+- pr_err("GIC: Can't allocate PPI memory");
+- nrppis = 0;
+- ppi_base = 0;
+- }
+ }
+
+ pr_info("Configuring GIC with %d sources (%d PPIs)\n",
+@@ -405,17 +368,12 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
+ */
+ for (i = 0; i < nrppis; i++) {
+ int ppi = i + ppi_base;
+- int err;
+
+ irq_set_percpu_devid(ppi);
+ irq_set_chip_and_handler(ppi, &gic_chip,
+ handle_percpu_devid_irq);
+ irq_set_chip_data(ppi, gic);
+ set_irq_flags(ppi, IRQF_VALID | IRQF_NOAUTOEN);
+-
+- err = setup_percpu_irq(ppi, &ppi_irqaction[i]);
+- if (err)
+- pr_err("GIC: can't setup PPI%d (%d)\n", ppi, err);
+ }
+
+ for (i = irq_start + nrppis; i < irq_limit; i++) {
+@@ -661,16 +619,6 @@ void __cpuinit gic_secondary_init(unsigned int gic_nr)
+ gic_cpu_init(&gic_data[gic_nr]);
+ }
+
+-void __cpuinit gic_enable_ppi(unsigned int irq)
+-{
+- unsigned long flags;
+-
+- local_irq_save(flags);
+- irq_set_status_flags(irq, IRQ_NOPROBE);
+- gic_unmask_irq(irq_get_irq_data(irq));
+- local_irq_restore(flags);
+-}
+-
+ #ifdef CONFIG_SMP
+ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
+ {
+diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
+index 615c336..a61f11e 100644
+--- a/arch/arm/include/asm/hardware/gic.h
++++ b/arch/arm/include/asm/hardware/gic.h
+@@ -41,7 +41,6 @@ void gic_secondary_init(unsigned int);
+ void gic_handle_irq(struct pt_regs *regs);
+ void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
+ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
+-void gic_enable_ppi(unsigned int);
+
+ struct gic_chip_data {
+ unsigned int irq_offset;
+diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
+index 5c8acb4..f5e1cec 100644
+--- a/arch/arm/include/asm/localtimer.h
++++ b/arch/arm/include/asm/localtimer.h
+@@ -19,26 +19,20 @@ struct clock_event_device;
+ */
+ void percpu_timer_setup(void);
+
+-/*
+- * Per-cpu timer IRQ handler
+- */
+-irqreturn_t percpu_timer_handler(int irq, void *dev_id);
+-
+ #ifdef CONFIG_LOCAL_TIMERS
+
+ #ifdef CONFIG_HAVE_ARM_TWD
+
+ #include "smp_twd.h"
+
+-#define local_timer_ack() twd_timer_ack()
++#define local_timer_stop(c) twd_timer_stop((c))
+
+ #else
+
+ /*
+- * Platform provides this to acknowledge a local timer IRQ.
+- * Returns true if the local timer IRQ is to be processed.
++ * Stop the local timer
+ */
+-int local_timer_ack(void);
++void local_timer_stop(struct clock_event_device *);
+
+ #endif
+
+@@ -53,6 +47,10 @@ static inline int local_timer_setup(struct clock_event_device *evt)
+ {
+ return -ENXIO;
+ }
++
++static inline void local_timer_stop(struct clock_event_device *evt)
++{
++}
+ #endif
+
+ #endif
+diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
+index fed9981..ef9ffba9 100644
+--- a/arch/arm/include/asm/smp_twd.h
++++ b/arch/arm/include/asm/smp_twd.h
+@@ -22,7 +22,7 @@ struct clock_event_device;
+
+ extern void __iomem *twd_base;
+
+-int twd_timer_ack(void);
+ void twd_timer_setup(struct clock_event_device *);
++void twd_timer_stop(struct clock_event_device *);
+
+ #endif
+diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
+index 7db7120..083d36e 100644
+--- a/arch/arm/kernel/smp.c
++++ b/arch/arm/kernel/smp.c
+@@ -466,20 +466,6 @@ static void ipi_timer(void)
+ irq_exit();
+ }
+
+-#ifdef CONFIG_LOCAL_TIMERS
+-irqreturn_t percpu_timer_handler(int irq, void *dev_id)
+-{
+- struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent);
+-
+- if (local_timer_ack()) {
+- evt->event_handler(evt);
+- return IRQ_HANDLED;
+- }
+-
+- return IRQ_NONE;
+-}
+-#endif
+-
+ #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+ static void smp_timer_broadcast(const struct cpumask *mask)
+ {
+@@ -530,7 +516,7 @@ static void percpu_timer_stop(void)
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
+
+- evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
++ local_timer_stop(evt);
+ }
+ #endif
+
+diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
+index 01c1862..a8a6682 100644
+--- a/arch/arm/kernel/smp_twd.c
++++ b/arch/arm/kernel/smp_twd.c
+@@ -19,6 +19,7 @@
+ #include <linux/io.h>
+
+ #include <asm/smp_twd.h>
++#include <asm/localtimer.h>
+ #include <asm/hardware/gic.h>
+
+ /* set up by the platform code */
+@@ -26,6 +27,8 @@ void __iomem *twd_base;
+
+ static unsigned long twd_timer_rate;
+
++static struct clock_event_device __percpu **twd_evt;
++
+ static void twd_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *clk)
+ {
+@@ -80,6 +83,12 @@ int twd_timer_ack(void)
+ return 0;
+ }
+
++void twd_timer_stop(struct clock_event_device *clk)
++{
++ twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
++ disable_percpu_irq(clk->irq);
++}
++
+ static void __cpuinit twd_calibrate_rate(void)
+ {
+ unsigned long count;
+@@ -119,11 +128,43 @@ static void __cpuinit twd_calibrate_rate(void)
+ }
+ }
+
++static irqreturn_t twd_handler(int irq, void *dev_id)
++{
++ struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
++
++ if (twd_timer_ack()) {
++ evt->event_handler(evt);
++ return IRQ_HANDLED;
++ }
++
++ return IRQ_NONE;
++}
++
+ /*
+ * Setup the local clock events for a CPU.
+ */
+ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
+ {
++ struct clock_event_device **this_cpu_clk;
++
++ if (!twd_evt) {
++ int err;
++
++ twd_evt = alloc_percpu(struct clock_event_device *);
++ if (!twd_evt) {
++ pr_err("twd: can't allocate memory\n");
++ return;
++ }
++
++ err = request_percpu_irq(clk->irq, twd_handler,
++ "twd", twd_evt);
++ if (err) {
++ pr_err("twd: can't register interrupt %d (%d)\n",
++ clk->irq, err);
++ return;
++ }
++ }
++
+ twd_calibrate_rate();
+
+ clk->name = "local_timer";
+@@ -137,8 +178,10 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
+ clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);
+ clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
+
++ this_cpu_clk = __this_cpu_ptr(twd_evt);
++ *this_cpu_clk = clk;
++
+ clockevents_register_device(clk);
+
+- /* Make sure our local interrupt controller has this enabled */
+- gic_enable_ppi(clk->irq);
++ enable_percpu_irq(clk->irq, 0);
+ }
+diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos4/mct.c
+index 1ae059b..85a1bb7 100644
+--- a/arch/arm/mach-exynos4/mct.c
++++ b/arch/arm/mach-exynos4/mct.c
+@@ -380,9 +380,11 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
+
+ if (cpu == 0) {
+ mct_tick0_event_irq.dev_id = &mct_tick[cpu];
++ evt->irq = IRQ_MCT_L0;
+ setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq);
+ } else {
+ mct_tick1_event_irq.dev_id = &mct_tick[cpu];
++ evt->irq = IRQ_MCT_L1;
+ setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq);
+ irq_set_affinity(IRQ_MCT_L1, cpumask_of(1));
+ }
+@@ -394,9 +396,10 @@ void __cpuinit local_timer_setup(struct clock_event_device *evt)
+ exynos4_mct_tick_init(evt);
+ }
+
+-int local_timer_ack(void)
++void local_timer_stop(struct clock_event_device *evt)
+ {
+- return 0;
++ evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
++ disable_irq(evt->irq);
+ }
+
+ #endif /* CONFIG_LOCAL_TIMERS */
+diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
+index 63621f1..afeeca5 100644
+--- a/arch/arm/mach-msm/timer.c
++++ b/arch/arm/mach-msm/timer.c
+@@ -71,12 +71,16 @@ enum timer_location {
+ struct msm_clock {
+ struct clock_event_device clockevent;
+ struct clocksource clocksource;
+- struct irqaction irq;
++ unsigned int irq;
+ void __iomem *regbase;
+ uint32_t freq;
+ uint32_t shift;
+ void __iomem *global_counter;
+ void __iomem *local_counter;
++ union {
++ struct clock_event_device *evt;
++ struct clock_event_device __percpu **percpu_evt;
++ };
+ };
+
+ enum {
+@@ -87,13 +91,10 @@ enum {
+
+
+ static struct msm_clock msm_clocks[];
+-static struct clock_event_device *local_clock_event;
+
+ static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
+ {
+- struct clock_event_device *evt = dev_id;
+- if (smp_processor_id() != 0)
+- evt = local_clock_event;
++ struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
+ if (evt->event_handler == NULL)
+ return IRQ_HANDLED;
+ evt->event_handler(evt);
+@@ -171,13 +172,7 @@ static struct msm_clock msm_clocks[] = {
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ },
+- .irq = {
+- .name = "gp_timer",
+- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING,
+- .handler = msm_timer_interrupt,
+- .dev_id = &msm_clocks[0].clockevent,
+- .irq = INT_GP_TIMER_EXP
+- },
++ .irq = INT_GP_TIMER_EXP,
+ .freq = GPT_HZ,
+ },
+ [MSM_CLOCK_DGT] = {
+@@ -196,13 +191,7 @@ static struct msm_clock msm_clocks[] = {
+ .mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ },
+- .irq = {
+- .name = "dg_timer",
+- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING,
+- .handler = msm_timer_interrupt,
+- .dev_id = &msm_clocks[1].clockevent,
+- .irq = INT_DEBUG_TIMER_EXP
+- },
++ .irq = INT_DEBUG_TIMER_EXP,
+ .freq = DGT_HZ >> MSM_DGT_SHIFT,
+ .shift = MSM_DGT_SHIFT,
+ }
+@@ -261,10 +250,30 @@ static void __init msm_timer_init(void)
+ printk(KERN_ERR "msm_timer_init: clocksource_register "
+ "failed for %s\n", cs->name);
+
+- res = setup_irq(clock->irq.irq, &clock->irq);
++ ce->irq = clock->irq;
++ if (cpu_is_msm8x60() || cpu_is_msm8960()) {
++ clock->percpu_evt = alloc_percpu(struct clock_event_device *);
++ if (!clock->percpu_evt) {
++ pr_err("msm_timer_init: memory allocation "
++ "failed for %s\n", ce->name);
++ continue;
++ }
++
++ *__this_cpu_ptr(clock->percpu_evt) = ce;
++ res = request_percpu_irq(ce->irq, msm_timer_interrupt,
++ ce->name, clock->percpu_evt);
++ if (!res)
++ enable_percpu_irq(ce->irq, 0);
++ } else {
++ clock->evt = ce;
++ res = request_irq(ce->irq, msm_timer_interrupt,
++ IRQF_TIMER | IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
++ ce->name, &clock->evt);
++ }
++
+ if (res)
+- printk(KERN_ERR "msm_timer_init: setup_irq "
+- "failed for %s\n", cs->name);
++ pr_err("msm_timer_init: request_irq failed for %s\n",
++ ce->name);
+
+ clockevents_register_device(ce);
+ }
+@@ -273,6 +282,7 @@ static void __init msm_timer_init(void)
+ #ifdef CONFIG_SMP
+ int __cpuinit local_timer_setup(struct clock_event_device *evt)
+ {
++ static bool local_timer_inited;
+ struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER];
+
+ /* Use existing clock_event for cpu 0 */
+@@ -281,12 +291,13 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
+
+ writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
+
+- if (!local_clock_event) {
++ if (!local_timer_inited) {
+ writel(0, clock->regbase + TIMER_ENABLE);
+ writel(0, clock->regbase + TIMER_CLEAR);
+ writel(~0, clock->regbase + TIMER_MATCH_VAL);
++ local_timer_inited = true;
+ }
+- evt->irq = clock->irq.irq;
++ evt->irq = clock->irq;
+ evt->name = "local_timer";
+ evt->features = CLOCK_EVT_FEAT_ONESHOT;
+ evt->rating = clock->clockevent.rating;
+@@ -298,17 +309,17 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
+ clockevent_delta2ns(0xf0000000 >> clock->shift, evt);
+ evt->min_delta_ns = clockevent_delta2ns(4, evt);
+
+- local_clock_event = evt;
+-
+- gic_enable_ppi(clock->irq.irq);
++ *__this_cpu_ptr(clock->percpu_evt) = evt;
++ enable_percpu_irq(evt->irq, 0);
+
+ clockevents_register_device(evt);
+ return 0;
+ }
+
+-inline int local_timer_ack(void)
++void local_timer_stop(struct clock_event_device *evt)
+ {
+- return 1;
++ evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
++ disable_percpu_irq(evt->irq);
+ }
+
+ #endif
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0165-ARM-gic-add-irq_domain-support.patch b/patches.kzm9g/0165-ARM-gic-add-irq_domain-support.patch
new file mode 100644
index 00000000000000..8d19407bf44649
--- /dev/null
+++ b/patches.kzm9g/0165-ARM-gic-add-irq_domain-support.patch
@@ -0,0 +1,288 @@
+From 6e52acb78212f9cfc7fb843fb01cb197a06d1b3e Mon Sep 17 00:00:00 2001
+From: Rob Herring <rob.herring@calxeda.com>
+Date: Wed, 28 Sep 2011 21:25:31 -0500
+Subject: ARM: gic: add irq_domain support
+
+Convert the gic interrupt controller to use irq domains in preparation
+for device-tree binding and MULTI_IRQ. This allows for translation between
+GIC interrupt IDs and Linux irq numbers.
+
+The meaning of irq_offset has changed. It now is just the number of skipped
+GIC interrupt IDs for the controller. It will be 16 for primary GIC and 32
+for secondary GICs.
+
+Signed-off-by: Rob Herring <rob.herring@calxeda.com>
+Cc: Marc Zyngier <marc.zyngier@arm.com>
+Reviewed-by: Jamie Iles <jamie@jamieiles.com>
+Tested-by: Thomas Abraham <thomas.abraham@linaro.org>
+Acked-by: Grant Likely <grant.likely@secretlab.ca>
+(cherry picked from commit 4294f8baaf174c9aa57886e7ed27caf4b02578f6)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/common/Kconfig | 1 +
+ arch/arm/common/gic.c | 118 +++++++++++++++++-------------------
+ arch/arm/include/asm/hardware/gic.h | 7 ++-
+ 3 files changed, 63 insertions(+), 63 deletions(-)
+
+diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
+index 4b71766..74df9ca 100644
+--- a/arch/arm/common/Kconfig
++++ b/arch/arm/common/Kconfig
+@@ -1,4 +1,5 @@
+ config ARM_GIC
++ select IRQ_DOMAIN
+ bool
+
+ config ARM_VIC
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index 5f7b4e2..7286e89 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -24,10 +24,12 @@
+ */
+ #include <linux/init.h>
+ #include <linux/kernel.h>
++#include <linux/export.h>
+ #include <linux/list.h>
+ #include <linux/smp.h>
+ #include <linux/cpumask.h>
+ #include <linux/io.h>
++#include <linux/irqdomain.h>
+ #include <linux/interrupt.h>
+ #include <linux/percpu.h>
+ #include <linux/slab.h>
+@@ -74,8 +76,7 @@ static inline void __iomem *gic_cpu_base(struct irq_data *d)
+
+ static inline unsigned int gic_irq(struct irq_data *d)
+ {
+- struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
+- return d->irq - gic_data->irq_offset;
++ return d->hwirq;
+ }
+
+ /*
+@@ -83,7 +84,7 @@ static inline unsigned int gic_irq(struct irq_data *d)
+ */
+ static void gic_mask_irq(struct irq_data *d)
+ {
+- u32 mask = 1 << (d->irq % 32);
++ u32 mask = 1 << (gic_irq(d) % 32);
+
+ spin_lock(&irq_controller_lock);
+ writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4);
+@@ -94,7 +95,7 @@ static void gic_mask_irq(struct irq_data *d)
+
+ static void gic_unmask_irq(struct irq_data *d)
+ {
+- u32 mask = 1 << (d->irq % 32);
++ u32 mask = 1 << (gic_irq(d) % 32);
+
+ spin_lock(&irq_controller_lock);
+ if (gic_arch_extn.irq_unmask)
+@@ -175,7 +176,7 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
+ bool force)
+ {
+ void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
+- unsigned int shift = (d->irq % 4) * 8;
++ unsigned int shift = (gic_irq(d) % 4) * 8;
+ unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
+ u32 val, mask, bit;
+
+@@ -252,7 +253,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
+ if (gic_irq == 1023)
+ goto out;
+
+- cascade_irq = gic_irq + chip_data->irq_offset;
++ cascade_irq = irq_domain_to_irq(&chip_data->domain, gic_irq);
+ if (unlikely(gic_irq < 32 || gic_irq > 1020 || cascade_irq >= NR_IRQS))
+ do_bad_IRQ(cascade_irq, desc);
+ else
+@@ -284,14 +285,14 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
+ irq_set_chained_handler(irq, gic_handle_cascade_irq);
+ }
+
+-static void __init gic_dist_init(struct gic_chip_data *gic,
+- unsigned int irq_start)
++static void __init gic_dist_init(struct gic_chip_data *gic)
+ {
+- unsigned int gic_irqs, irq_limit, i;
++ unsigned int i, irq;
+ u32 cpumask;
++ unsigned int gic_irqs = gic->gic_irqs;
++ struct irq_domain *domain = &gic->domain;
+ void __iomem *base = gic->dist_base;
+ u32 cpu = 0;
+- u32 nrppis = 0, ppi_base = 0;
+
+ #ifdef CONFIG_SMP
+ cpu = cpu_logical_map(smp_processor_id());
+@@ -304,34 +305,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
+ writel_relaxed(0, base + GIC_DIST_CTRL);
+
+ /*
+- * Find out how many interrupts are supported.
+- * The GIC only supports up to 1020 interrupt sources.
+- */
+- gic_irqs = readl_relaxed(base + GIC_DIST_CTR) & 0x1f;
+- gic_irqs = (gic_irqs + 1) * 32;
+- if (gic_irqs > 1020)
+- gic_irqs = 1020;
+-
+- gic->gic_irqs = gic_irqs;
+-
+- /*
+- * Nobody would be insane enough to use PPIs on a secondary
+- * GIC, right?
+- */
+- if (gic == &gic_data[0]) {
+- nrppis = (32 - irq_start) & 31;
+-
+- /* The GIC only supports up to 16 PPIs. */
+- if (nrppis > 16)
+- BUG();
+-
+- ppi_base = gic->irq_offset + 32 - nrppis;
+- }
+-
+- pr_info("Configuring GIC with %d sources (%d PPIs)\n",
+- gic_irqs, (gic == &gic_data[0]) ? nrppis : 0);
+-
+- /*
+ * Set all global interrupts to be level triggered, active low.
+ */
+ for (i = 32; i < gic_irqs; i += 16)
+@@ -357,29 +330,20 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
+ writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
+
+ /*
+- * Limit number of interrupts registered to the platform maximum
+- */
+- irq_limit = gic->irq_offset + gic_irqs;
+- if (WARN_ON(irq_limit > NR_IRQS))
+- irq_limit = NR_IRQS;
+-
+- /*
+ * Setup the Linux IRQ subsystem.
+ */
+- for (i = 0; i < nrppis; i++) {
+- int ppi = i + ppi_base;
+-
+- irq_set_percpu_devid(ppi);
+- irq_set_chip_and_handler(ppi, &gic_chip,
+- handle_percpu_devid_irq);
+- irq_set_chip_data(ppi, gic);
+- set_irq_flags(ppi, IRQF_VALID | IRQF_NOAUTOEN);
+- }
+-
+- for (i = irq_start + nrppis; i < irq_limit; i++) {
+- irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq);
+- irq_set_chip_data(i, gic);
+- set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
++ irq_domain_for_each_irq(domain, i, irq) {
++ if (i < 32) {
++ irq_set_percpu_devid(irq);
++ irq_set_chip_and_handler(irq, &gic_chip,
++ handle_percpu_devid_irq);
++ set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
++ } else {
++ irq_set_chip_and_handler(irq, &gic_chip,
++ handle_fasteoi_irq);
++ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
++ }
++ irq_set_chip_data(irq, gic);
+ }
+
+ writel_relaxed(1, base + GIC_DIST_CTRL);
+@@ -591,23 +555,53 @@ static void __init gic_pm_init(struct gic_chip_data *gic)
+ }
+ #endif
+
++const struct irq_domain_ops gic_irq_domain_ops = {
++};
++
+ void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
+ void __iomem *dist_base, void __iomem *cpu_base)
+ {
+ struct gic_chip_data *gic;
++ struct irq_domain *domain;
++ int gic_irqs;
+
+ BUG_ON(gic_nr >= MAX_GIC_NR);
+
+ gic = &gic_data[gic_nr];
++ domain = &gic->domain;
+ gic->dist_base = dist_base;
+ gic->cpu_base = cpu_base;
+- gic->irq_offset = (irq_start - 1) & ~31;
+
+- if (gic_nr == 0)
++ /*
++ * For primary GICs, skip over SGIs.
++ * For secondary GICs, skip over PPIs, too.
++ */
++ if (gic_nr == 0) {
+ gic_cpu_base_addr = cpu_base;
++ domain->hwirq_base = 16;
++ irq_start = (irq_start & ~31) + 16;
++ } else
++ domain->hwirq_base = 32;
++
++ /*
++ * Find out how many interrupts are supported.
++ * The GIC only supports up to 1020 interrupt sources.
++ */
++ gic_irqs = readl_relaxed(dist_base + GIC_DIST_CTR) & 0x1f;
++ gic_irqs = (gic_irqs + 1) * 32;
++ if (gic_irqs > 1020)
++ gic_irqs = 1020;
++ gic->gic_irqs = gic_irqs;
++
++ domain->nr_irq = gic_irqs - domain->hwirq_base;
++ domain->irq_base = irq_alloc_descs(-1, irq_start, domain->nr_irq,
++ numa_node_id());
++ domain->priv = gic;
++ domain->ops = &gic_irq_domain_ops;
++ irq_domain_add(domain);
+
+ gic_chip.flags |= gic_arch_extn.flags;
+- gic_dist_init(gic, irq_start);
++ gic_dist_init(gic);
+ gic_cpu_init(gic);
+ gic_pm_init(gic);
+ }
+diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
+index a61f11e..06a540b 100644
+--- a/arch/arm/include/asm/hardware/gic.h
++++ b/arch/arm/include/asm/hardware/gic.h
+@@ -33,6 +33,9 @@
+ #define GIC_DIST_SOFTINT 0xf00
+
+ #ifndef __ASSEMBLY__
++#include <linux/irqdomain.h>
++struct device_node;
++
+ extern void __iomem *gic_cpu_base_addr;
+ extern struct irq_chip gic_arch_extn;
+
+@@ -43,7 +46,6 @@ void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
+ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
+
+ struct gic_chip_data {
+- unsigned int irq_offset;
+ void __iomem *dist_base;
+ void __iomem *cpu_base;
+ #ifdef CONFIG_CPU_PM
+@@ -53,6 +55,9 @@ struct gic_chip_data {
+ u32 __percpu *saved_ppi_enable;
+ u32 __percpu *saved_ppi_conf;
+ #endif
++#ifdef CONFIG_IRQ_DOMAIN
++ struct irq_domain domain;
++#endif
+ unsigned int gic_irqs;
+ };
+ #endif
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0166-ARM-gic-add-OF-based-initialization.patch b/patches.kzm9g/0166-ARM-gic-add-OF-based-initialization.patch
new file mode 100644
index 00000000000000..58570564418f2d
--- /dev/null
+++ b/patches.kzm9g/0166-ARM-gic-add-OF-based-initialization.patch
@@ -0,0 +1,195 @@
+From 5f7a0ce78ca6151ea78331f4f474e4984e9d70a1 Mon Sep 17 00:00:00 2001
+From: Rob Herring <rob.herring@calxeda.com>
+Date: Wed, 28 Sep 2011 21:27:52 -0500
+Subject: ARM: gic: add OF based initialization
+
+This adds ARM gic interrupt controller initialization using device tree
+data.
+
+The initialization function is intended to be called by of_irq_init
+function like this:
+
+const static struct of_device_id irq_match[] = {
+ { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
+ {}
+};
+
+static void __init init_irqs(void)
+{
+ of_irq_init(irq_match);
+}
+
+Signed-off-by: Rob Herring <rob.herring@calxeda.com>
+Reviewed-by: Jamie Iles <jamie@jamieiles.com>
+Tested-by: Thomas Abraham <thomas.abraham@linaro.org>
+Acked-by: Grant Likely <grant.likely@secretlab.ca>
+(cherry picked from commit b3f7ed0324091e2cb23fe1b3c10570700f614014)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ Documentation/devicetree/bindings/arm/gic.txt | 55 ++++++++++++++++++++++++
+ arch/arm/common/gic.c | 61 +++++++++++++++++++++++++++
+ arch/arm/include/asm/hardware/gic.h | 1 +
+ 3 files changed, 117 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/arm/gic.txt
+
+diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt
+new file mode 100644
+index 0000000..52916b4
+--- /dev/null
++++ b/Documentation/devicetree/bindings/arm/gic.txt
+@@ -0,0 +1,55 @@
++* ARM Generic Interrupt Controller
++
++ARM SMP cores are often associated with a GIC, providing per processor
++interrupts (PPI), shared processor interrupts (SPI) and software
++generated interrupts (SGI).
++
++Primary GIC is attached directly to the CPU and typically has PPIs and SGIs.
++Secondary GICs are cascaded into the upward interrupt controller and do not
++have PPIs or SGIs.
++
++Main node required properties:
++
++- compatible : should be one of:
++ "arm,cortex-a9-gic"
++ "arm,arm11mp-gic"
++- interrupt-controller : Identifies the node as an interrupt controller
++- #interrupt-cells : Specifies the number of cells needed to encode an
++ interrupt source. The type shall be a <u32> and the value shall be 3.
++
++ The 1st cell is the interrupt type; 0 for SPI interrupts, 1 for PPI
++ interrupts.
++
++ The 2nd cell contains the interrupt number for the interrupt type.
++ SPI interrupts are in the range [0-987]. PPI interrupts are in the
++ range [0-15].
++
++ The 3rd cell is the flags, encoded as follows:
++ bits[3:0] trigger type and level flags.
++ 1 = low-to-high edge triggered
++ 2 = high-to-low edge triggered
++ 4 = active high level-sensitive
++ 8 = active low level-sensitive
++ bits[15:8] PPI interrupt cpu mask. Each bit corresponds to each of
++ the 8 possible cpus attached to the GIC. A bit set to '1' indicated
++ the interrupt is wired to that CPU. Only valid for PPI interrupts.
++
++- reg : Specifies base physical address(s) and size of the GIC registers. The
++ first region is the GIC distributor register base and size. The 2nd region is
++ the GIC cpu interface register base and size.
++
++Optional
++- interrupts : Interrupt source of the parent interrupt controller. Only
++ present on secondary GICs.
++
++Example:
++
++ intc: interrupt-controller@fff11000 {
++ compatible = "arm,cortex-a9-gic";
++ #interrupt-cells = <3>;
++ #address-cells = <1>;
++ interrupt-controller;
++ reg = <0xfff11000 0x1000>,
++ <0xfff10100 0x100>;
++ };
++
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index 7286e89..0976555 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -29,6 +29,9 @@
+ #include <linux/smp.h>
+ #include <linux/cpumask.h>
+ #include <linux/io.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_irq.h>
+ #include <linux/irqdomain.h>
+ #include <linux/interrupt.h>
+ #include <linux/percpu.h>
+@@ -555,7 +558,33 @@ static void __init gic_pm_init(struct gic_chip_data *gic)
+ }
+ #endif
+
++#ifdef CONFIG_OF
++static int gic_irq_domain_dt_translate(struct irq_domain *d,
++ struct device_node *controller,
++ const u32 *intspec, unsigned int intsize,
++ unsigned long *out_hwirq, unsigned int *out_type)
++{
++ if (d->of_node != controller)
++ return -EINVAL;
++ if (intsize < 3)
++ return -EINVAL;
++
++ /* Get the interrupt number and add 16 to skip over SGIs */
++ *out_hwirq = intspec[1] + 16;
++
++ /* For SPIs, we need to add 16 more to get the GIC irq ID number */
++ if (!intspec[0])
++ *out_hwirq += 16;
++
++ *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
++ return 0;
++}
++#endif
++
+ const struct irq_domain_ops gic_irq_domain_ops = {
++#ifdef CONFIG_OF
++ .dt_translate = gic_irq_domain_dt_translate,
++#endif
+ };
+
+ void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
+@@ -633,3 +662,35 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
+ writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
+ }
+ #endif
++
++#ifdef CONFIG_OF
++static int gic_cnt __initdata = 0;
++
++int __init gic_of_init(struct device_node *node, struct device_node *parent)
++{
++ void __iomem *cpu_base;
++ void __iomem *dist_base;
++ int irq;
++ struct irq_domain *domain = &gic_data[gic_cnt].domain;
++
++ if (WARN_ON(!node))
++ return -ENODEV;
++
++ dist_base = of_iomap(node, 0);
++ WARN(!dist_base, "unable to map gic dist registers\n");
++
++ cpu_base = of_iomap(node, 1);
++ WARN(!cpu_base, "unable to map gic cpu registers\n");
++
++ domain->of_node = of_node_get(node);
++
++ gic_init(gic_cnt, 16, dist_base, cpu_base);
++
++ if (parent) {
++ irq = irq_of_parse_and_map(node, 0);
++ gic_cascade_irq(gic_cnt, irq);
++ }
++ gic_cnt++;
++ return 0;
++}
++#endif
+diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
+index 06a540b..da822f6 100644
+--- a/arch/arm/include/asm/hardware/gic.h
++++ b/arch/arm/include/asm/hardware/gic.h
+@@ -40,6 +40,7 @@ extern void __iomem *gic_cpu_base_addr;
+ extern struct irq_chip gic_arch_extn;
+
+ void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
++int gic_of_init(struct device_node *node, struct device_node *parent);
+ void gic_secondary_init(unsigned int);
+ void gic_handle_irq(struct pt_regs *regs);
+ void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0167-ARM-gic-fix-irq_alloc_descs-handling-for-sparse-irq.patch b/patches.kzm9g/0167-ARM-gic-fix-irq_alloc_descs-handling-for-sparse-irq.patch
new file mode 100644
index 00000000000000..3ca00b31596a53
--- /dev/null
+++ b/patches.kzm9g/0167-ARM-gic-fix-irq_alloc_descs-handling-for-sparse-irq.patch
@@ -0,0 +1,99 @@
+From 69c8cbbe40b940304234d68ffa5092a8f1197f45 Mon Sep 17 00:00:00 2001
+From: Rob Herring <rob.herring@calxeda.com>
+Date: Fri, 21 Oct 2011 17:14:27 -0500
+Subject: ARM: gic: fix irq_alloc_descs handling for sparse irq
+
+Commit "ARM: gic: add irq_domain support" (b49b6ff) breaks SPARSE_IRQ
+on platforms with GIC. When SPARSE_IRQ is enabled, all NR_IRQS or
+mach_desc->nr_irqs will be allocated by arch_probe_nr_irqs(). This caused
+irq_alloc_descs to allocate irq_descs after the pre-allocated space.
+
+Make irq_alloc_descs search for an exact irq range and assume it has
+been pre-allocated on failure. For DT probing dynamic allocation is used.
+DT enabled platforms should set their nr_irqs to NR_IRQ_LEGACY and have all
+irq_chips allocate their irq_descs with irq_alloc_descs if SPARSE_IRQ is
+enabled.
+
+gic_init irq_start param is changed to be signed with negative meaning do
+dynamic Linux irq assigment.
+
+Signed-off-by: Rob Herring <rob.herring@calxeda.com>
+(cherry picked from commit f37a53cc5d8a8fb199e41386d125d8c2ed9e54ef)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/common/gic.c | 15 +++++++++++----
+ arch/arm/include/asm/hardware/gic.h | 2 +-
+ 2 files changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index 0976555..0ad3584 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -24,6 +24,7 @@
+ */
+ #include <linux/init.h>
+ #include <linux/kernel.h>
++#include <linux/err.h>
+ #include <linux/export.h>
+ #include <linux/list.h>
+ #include <linux/smp.h>
+@@ -587,7 +588,7 @@ const struct irq_domain_ops gic_irq_domain_ops = {
+ #endif
+ };
+
+-void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
++void __init gic_init(unsigned int gic_nr, int irq_start,
+ void __iomem *dist_base, void __iomem *cpu_base)
+ {
+ struct gic_chip_data *gic;
+@@ -608,7 +609,8 @@ void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
+ if (gic_nr == 0) {
+ gic_cpu_base_addr = cpu_base;
+ domain->hwirq_base = 16;
+- irq_start = (irq_start & ~31) + 16;
++ if (irq_start > 0)
++ irq_start = (irq_start & ~31) + 16;
+ } else
+ domain->hwirq_base = 32;
+
+@@ -623,8 +625,13 @@ void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
+ gic->gic_irqs = gic_irqs;
+
+ domain->nr_irq = gic_irqs - domain->hwirq_base;
+- domain->irq_base = irq_alloc_descs(-1, irq_start, domain->nr_irq,
++ domain->irq_base = irq_alloc_descs(irq_start, 16, domain->nr_irq,
+ numa_node_id());
++ if (IS_ERR_VALUE(domain->irq_base)) {
++ WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
++ irq_start);
++ domain->irq_base = irq_start;
++ }
+ domain->priv = gic;
+ domain->ops = &gic_irq_domain_ops;
+ irq_domain_add(domain);
+@@ -684,7 +691,7 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent)
+
+ domain->of_node = of_node_get(node);
+
+- gic_init(gic_cnt, 16, dist_base, cpu_base);
++ gic_init(gic_cnt, -1, dist_base, cpu_base);
+
+ if (parent) {
+ irq = irq_of_parse_and_map(node, 0);
+diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
+index da822f6..b7641d6 100644
+--- a/arch/arm/include/asm/hardware/gic.h
++++ b/arch/arm/include/asm/hardware/gic.h
+@@ -39,7 +39,7 @@ struct device_node;
+ extern void __iomem *gic_cpu_base_addr;
+ extern struct irq_chip gic_arch_extn;
+
+-void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
++void gic_init(unsigned int, int, void __iomem *, void __iomem *);
+ int gic_of_init(struct device_node *node, struct device_node *parent);
+ void gic_secondary_init(unsigned int);
+ void gic_handle_irq(struct pt_regs *regs);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0168-ARM-gic-use-module.h-instead-of-export.h.patch b/patches.kzm9g/0168-ARM-gic-use-module.h-instead-of-export.h.patch
new file mode 100644
index 00000000000000..57daec9d76260e
--- /dev/null
+++ b/patches.kzm9g/0168-ARM-gic-use-module.h-instead-of-export.h.patch
@@ -0,0 +1,32 @@
+From 821b37ef872cbc43bfd3b3c3d9b85aeebe863349 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Tue, 1 Nov 2011 00:28:37 +0100
+Subject: ARM: gic: use module.h instead of export.h
+
+The module.h cleanup series is not merged at this point, so use the
+older header file for now, to make it build either way.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+(cherry picked from commit 7e1efcf5d2039fb7a91e21df32f4175dbca4d61c)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/common/gic.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index 0ad3584..f4b2864 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -25,7 +25,7 @@
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/err.h>
+-#include <linux/export.h>
++#include <linux/module.h>
+ #include <linux/list.h>
+ #include <linux/smp.h>
+ #include <linux/cpumask.h>
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0169-ARM-7176-1-cpu_pm-register-GIC-PM-notifier-only-once.patch b/patches.kzm9g/0169-ARM-7176-1-cpu_pm-register-GIC-PM-notifier-only-once.patch
new file mode 100644
index 00000000000000..2f1510de03f150
--- /dev/null
+++ b/patches.kzm9g/0169-ARM-7176-1-cpu_pm-register-GIC-PM-notifier-only-once.patch
@@ -0,0 +1,44 @@
+From c17eb62ef5e57dbca9e3789f931edae8d0af6247 Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <Marc.Zyngier@arm.com>
+Date: Fri, 25 Nov 2011 17:58:19 +0100
+Subject: ARM: 7176/1: cpu_pm: register GIC PM notifier only once
+
+When multiple GICs exist on a platform (RealView PB1176/11MP),
+we must make sure the PM notifier block is only registered
+once, otherwise we end up corrupting the PM notifier list.
+
+The fix is to only register the notifier when initializing
+the first GIC, as the power management functions seem
+to iterate over all the registered GICs.
+
+Tested on PB11MP and PB1176.
+
+Reported-by: Will Deacon <will.deacon@arm.com>
+Tested-by: Will Deacon <will.deacon@arm.com>
+Cc: Colin Cross <ccross@android.com>
+Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+(cherry picked from commit abdd7b91dab2f8b2e32e90e4b7e809ffb462a662)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/common/gic.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index f4b2864..432c879 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -551,7 +551,8 @@ static void __init gic_pm_init(struct gic_chip_data *gic)
+ sizeof(u32));
+ BUG_ON(!gic->saved_ppi_conf);
+
+- cpu_pm_register_notifier(&gic_notifier_block);
++ if (gic == &gic_data[0])
++ cpu_pm_register_notifier(&gic_notifier_block);
+ }
+ #else
+ static void __init gic_pm_init(struct gic_chip_data *gic)
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0170-ARM-7177-1-GIC-avoid-skipping-non-existent-PPIs-in-i.patch b/patches.kzm9g/0170-ARM-7177-1-GIC-avoid-skipping-non-existent-PPIs-in-i.patch
new file mode 100644
index 00000000000000..5ee8e3eb9bf4b4
--- /dev/null
+++ b/patches.kzm9g/0170-ARM-7177-1-GIC-avoid-skipping-non-existent-PPIs-in-i.patch
@@ -0,0 +1,52 @@
+From c7dd20bb08c673ce9ce055074c77d92760bc03ac Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Fri, 25 Nov 2011 19:23:36 +0100
+Subject: ARM: 7177/1: GIC: avoid skipping non-existent PPIs in irq_start
+ calculation
+
+Commit 4294f8baa ("ARM: gic: add irq_domain support") defines irq_start
+as irq_start = (irq_start & ~31) + 16; On a platform with a GIC and a
+CPU without PPIs, this results in irq_start being off by 16.
+
+This patch fixes gic_init so that we only carve out a PPI space when
+PPIs exist for the GIC being initialised.
+
+Cc: Rob Herring <rob.herring@calxeda.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+(cherry picked from commit fe41db7b3aca512e19b8ef4fbd5ad55545005d25)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/common/gic.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
+index 432c879..0b95dc5 100644
+--- a/arch/arm/common/gic.c
++++ b/arch/arm/common/gic.c
+@@ -607,13 +607,16 @@ void __init gic_init(unsigned int gic_nr, int irq_start,
+ * For primary GICs, skip over SGIs.
+ * For secondary GICs, skip over PPIs, too.
+ */
++ domain->hwirq_base = 32;
+ if (gic_nr == 0) {
+ gic_cpu_base_addr = cpu_base;
+- domain->hwirq_base = 16;
+- if (irq_start > 0)
+- irq_start = (irq_start & ~31) + 16;
+- } else
+- domain->hwirq_base = 32;
++
++ if ((irq_start & 31) > 0) {
++ domain->hwirq_base = 16;
++ if (irq_start != -1)
++ irq_start = (irq_start & ~31) + 16;
++ }
++ }
+
+ /*
+ * Find out how many interrupts are supported.
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0171-ARM-mach-shmobile-clock-sh73a0-tidyup-CKSCR-main-clo.patch b/patches.kzm9g/0171-ARM-mach-shmobile-clock-sh73a0-tidyup-CKSCR-main-clo.patch
new file mode 100644
index 00000000000000..4cdc9a6b45eb52
--- /dev/null
+++ b/patches.kzm9g/0171-ARM-mach-shmobile-clock-sh73a0-tidyup-CKSCR-main-clo.patch
@@ -0,0 +1,32 @@
+From f62259f22080ff97053936c271bb057b6cd2b7b1 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Fri, 26 Aug 2011 07:27:45 +0000
+Subject: ARM: mach-shmobile: clock-sh73a0: tidyup CKSCR main clock selecter
+
+MAINCKSEL is [29:28], not [27:24]
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 86d84083cfb15dd9594eefff7859e982770930d0)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-sh73a0.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
+index 9fc2830..44a923d 100644
+--- a/arch/arm/mach-shmobile/clock-sh73a0.c
++++ b/arch/arm/mach-shmobile/clock-sh73a0.c
+@@ -365,7 +365,7 @@ void __init sh73a0_clock_init(void)
+ __raw_writel(0x108, SD2CKCR);
+
+ /* detect main clock parent */
+- switch ((__raw_readl(CKSCR) >> 24) & 0x03) {
++ switch ((__raw_readl(CKSCR) >> 28) & 0x03) {
+ case 0:
+ main_clk.parent = &sh73a0_extal1_clk;
+ break;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0172-ARM-mach-shmobile-sh73a0-PFC-pull-up-support-for-SDH.patch b/patches.kzm9g/0172-ARM-mach-shmobile-sh73a0-PFC-pull-up-support-for-SDH.patch
new file mode 100644
index 00000000000000..6eaaca6e91668a
--- /dev/null
+++ b/patches.kzm9g/0172-ARM-mach-shmobile-sh73a0-PFC-pull-up-support-for-SDH.patch
@@ -0,0 +1,189 @@
+From 78057d7b664fb1d2f584807f5511dca73e595df9 Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Thu, 18 Aug 2011 04:32:08 +0000
+Subject: ARM: mach-shmobile: sh73a0 PFC pull-up support for SDHI0+2
+
+Extend the existing sh73a0 PFC code with pull-ups for
+SDHI0 and SDHI2. Without this patch only SDHI1 has
+pull-up support on sh73a0. Needed by boards that make
+use of the internal pull-up resistor support built in
+the SoC.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 09dafe9e4e266c7868454a532c9ca762aa5c40a5)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/include/mach/sh73a0.h | 13 +++++
+ arch/arm/mach-shmobile/pfc-sh73a0.c | 77 ++++++++++++++++++++++------
+ 2 files changed, 75 insertions(+), 15 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h
+index 216c3d6..b385e97 100644
+--- a/arch/arm/mach-shmobile/include/mach/sh73a0.h
++++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h
+@@ -451,11 +451,23 @@ enum {
+ GPIO_FN_KEYIN5_PU,
+ GPIO_FN_KEYIN6_PU,
+ GPIO_FN_KEYIN7_PU,
++ GPIO_FN_SDHICD0_PU,
++ GPIO_FN_SDHID0_0_PU,
++ GPIO_FN_SDHID0_1_PU,
++ GPIO_FN_SDHID0_2_PU,
++ GPIO_FN_SDHID0_3_PU,
++ GPIO_FN_SDHICMD0_PU,
++ GPIO_FN_SDHIWP0_PU,
+ GPIO_FN_SDHID1_0_PU,
+ GPIO_FN_SDHID1_1_PU,
+ GPIO_FN_SDHID1_2_PU,
+ GPIO_FN_SDHID1_3_PU,
+ GPIO_FN_SDHICMD1_PU,
++ GPIO_FN_SDHID2_0_PU,
++ GPIO_FN_SDHID2_1_PU,
++ GPIO_FN_SDHID2_2_PU,
++ GPIO_FN_SDHID2_3_PU,
++ GPIO_FN_SDHICMD2_PU,
+ GPIO_FN_MMCCMD0_PU,
+ GPIO_FN_MMCCMD1_PU,
+ GPIO_FN_FSIACK_PU,
+@@ -463,6 +475,7 @@ enum {
+ GPIO_FN_FSIAIBT_PU,
+ GPIO_FN_FSIAISLD_PU,
+ };
++
+ /* DMA slave IDs */
+ enum {
+ SHDMA_SLAVE_INVALID,
+diff --git a/arch/arm/mach-shmobile/pfc-sh73a0.c b/arch/arm/mach-shmobile/pfc-sh73a0.c
+index d8915c6..599016e 100644
+--- a/arch/arm/mach-shmobile/pfc-sh73a0.c
++++ b/arch/arm/mach-shmobile/pfc-sh73a0.c
+@@ -476,13 +476,26 @@ enum {
+ KEYIN5_PU_MARK,
+ KEYIN6_PU_MARK,
+ KEYIN7_PU_MARK,
++ SDHICD0_PU_MARK,
++ SDHID0_0_PU_MARK,
++ SDHID0_1_PU_MARK,
++ SDHID0_2_PU_MARK,
++ SDHID0_3_PU_MARK,
++ SDHICMD0_PU_MARK,
++ SDHIWP0_PU_MARK,
+ SDHID1_0_PU_MARK,
+ SDHID1_1_PU_MARK,
+ SDHID1_2_PU_MARK,
+ SDHID1_3_PU_MARK,
+ SDHICMD1_PU_MARK,
++ SDHID2_0_PU_MARK,
++ SDHID2_1_PU_MARK,
++ SDHID2_2_PU_MARK,
++ SDHID2_3_PU_MARK,
++ SDHICMD2_PU_MARK,
+ MMCCMD0_PU_MARK,
+ MMCCMD1_PU_MARK,
++ FSIBISLD_PU_MARK,
+ FSIACK_PU_MARK,
+ FSIAILR_PU_MARK,
+ FSIAIBT_PU_MARK,
+@@ -1336,19 +1349,28 @@ static pinmux_enum_t pinmux_data[] = {
+ PINMUX_DATA(TS_SCK4_MARK, PORT268_FN3),
+ PINMUX_DATA(SDHICMD2_MARK, PORT269_FN1),
+ PINMUX_DATA(MMCCLK0_MARK, PORT270_FN1, MSEL4CR_MSEL15_0),
+- PINMUX_DATA(MMCD0_0_MARK, PORT271_FN1, MSEL4CR_MSEL15_0),
+- PINMUX_DATA(MMCD0_1_MARK, PORT272_FN1, MSEL4CR_MSEL15_0),
+- PINMUX_DATA(MMCD0_2_MARK, PORT273_FN1, MSEL4CR_MSEL15_0),
+- PINMUX_DATA(MMCD0_3_MARK, PORT274_FN1, MSEL4CR_MSEL15_0),
+- PINMUX_DATA(MMCD0_4_MARK, PORT275_FN1, MSEL4CR_MSEL15_0), \
++ PINMUX_DATA(MMCD0_0_MARK, PORT271_FN1, PORT271_IN_PU,
++ MSEL4CR_MSEL15_0),
++ PINMUX_DATA(MMCD0_1_MARK, PORT272_FN1, PORT272_IN_PU,
++ MSEL4CR_MSEL15_0),
++ PINMUX_DATA(MMCD0_2_MARK, PORT273_FN1, PORT273_IN_PU,
++ MSEL4CR_MSEL15_0),
++ PINMUX_DATA(MMCD0_3_MARK, PORT274_FN1, PORT274_IN_PU,
++ MSEL4CR_MSEL15_0),
++ PINMUX_DATA(MMCD0_4_MARK, PORT275_FN1, PORT275_IN_PU,
++ MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(TS_SPSYNC5_MARK, PORT275_FN3),
+- PINMUX_DATA(MMCD0_5_MARK, PORT276_FN1, MSEL4CR_MSEL15_0), \
++ PINMUX_DATA(MMCD0_5_MARK, PORT276_FN1, PORT276_IN_PU,
++ MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(TS_SDAT5_MARK, PORT276_FN3),
+- PINMUX_DATA(MMCD0_6_MARK, PORT277_FN1, MSEL4CR_MSEL15_0), \
++ PINMUX_DATA(MMCD0_6_MARK, PORT277_FN1, PORT277_IN_PU,
++ MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(TS_SDEN5_MARK, PORT277_FN3),
+- PINMUX_DATA(MMCD0_7_MARK, PORT278_FN1, MSEL4CR_MSEL15_0), \
++ PINMUX_DATA(MMCD0_7_MARK, PORT278_FN1, PORT278_IN_PU,
++ MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(TS_SCK5_MARK, PORT278_FN3),
+- PINMUX_DATA(MMCCMD0_MARK, PORT279_FN1, MSEL4CR_MSEL15_0),
++ PINMUX_DATA(MMCCMD0_MARK, PORT279_FN1, PORT279_IN_PU,
++ MSEL4CR_MSEL15_0),
+ PINMUX_DATA(RESETOUTS__MARK, PORT281_FN1), \
+ PINMUX_DATA(EXTAL2OUT_MARK, PORT281_FN2),
+ PINMUX_DATA(MCP_WAIT__MCP_FRB_MARK, PORT288_FN1),
+@@ -1465,16 +1487,29 @@ static pinmux_enum_t pinmux_data[] = {
+ PINMUX_DATA(KEYIN6_PU_MARK, PORT72_FN2, PORT72_IN_PU),
+ PINMUX_DATA(KEYIN7_PU_MARK, PORT73_FN2, PORT73_IN_PU),
+
+- PINMUX_DATA(SDHID1_0_PU_MARK, PORT259_IN_PU, PORT259_FN1),
+- PINMUX_DATA(SDHID1_1_PU_MARK, PORT260_IN_PU, PORT260_FN1),
+- PINMUX_DATA(SDHID1_2_PU_MARK, PORT261_IN_PU, PORT261_FN1),
+- PINMUX_DATA(SDHID1_3_PU_MARK, PORT262_IN_PU, PORT262_FN1),
+- PINMUX_DATA(SDHICMD1_PU_MARK, PORT263_IN_PU, PORT263_FN1),
++ PINMUX_DATA(SDHICD0_PU_MARK, PORT251_FN1, PORT251_IN_PU),
++ PINMUX_DATA(SDHID0_0_PU_MARK, PORT252_FN1, PORT252_IN_PU),
++ PINMUX_DATA(SDHID0_1_PU_MARK, PORT253_FN1, PORT253_IN_PU),
++ PINMUX_DATA(SDHID0_2_PU_MARK, PORT254_FN1, PORT254_IN_PU),
++ PINMUX_DATA(SDHID0_3_PU_MARK, PORT255_FN1, PORT255_IN_PU),
++ PINMUX_DATA(SDHICMD0_PU_MARK, PORT256_FN1, PORT256_IN_PU),
++ PINMUX_DATA(SDHIWP0_PU_MARK, PORT257_FN1, PORT256_IN_PU),
++ PINMUX_DATA(SDHID1_0_PU_MARK, PORT259_FN1, PORT259_IN_PU),
++ PINMUX_DATA(SDHID1_1_PU_MARK, PORT260_FN1, PORT260_IN_PU),
++ PINMUX_DATA(SDHID1_2_PU_MARK, PORT261_FN1, PORT261_IN_PU),
++ PINMUX_DATA(SDHID1_3_PU_MARK, PORT262_FN1, PORT262_IN_PU),
++ PINMUX_DATA(SDHICMD1_PU_MARK, PORT263_FN1, PORT263_IN_PU),
++ PINMUX_DATA(SDHID2_0_PU_MARK, PORT265_FN1, PORT265_IN_PU),
++ PINMUX_DATA(SDHID2_1_PU_MARK, PORT266_FN1, PORT266_IN_PU),
++ PINMUX_DATA(SDHID2_2_PU_MARK, PORT267_FN1, PORT267_IN_PU),
++ PINMUX_DATA(SDHID2_3_PU_MARK, PORT268_FN1, PORT268_IN_PU),
++ PINMUX_DATA(SDHICMD2_PU_MARK, PORT269_FN1, PORT269_IN_PU),
+
+ PINMUX_DATA(MMCCMD0_PU_MARK, PORT279_FN1, PORT279_IN_PU,
+ MSEL4CR_MSEL15_0),
+- PINMUX_DATA(MMCCMD1_PU_MARK, PORT297_FN2, PORT279_IN_PU,
++ PINMUX_DATA(MMCCMD1_PU_MARK, PORT297_FN2, PORT297_IN_PU,
+ MSEL4CR_MSEL15_1),
++ PINMUX_DATA(FSIBISLD_PU_MARK, PORT39_FN1, PORT39_IN_PU),
+ PINMUX_DATA(FSIACK_PU_MARK, PORT49_FN1, PORT49_IN_PU),
+ PINMUX_DATA(FSIAILR_PU_MARK, PORT50_FN5, PORT50_IN_PU),
+ PINMUX_DATA(FSIAIBT_PU_MARK, PORT51_FN5, PORT51_IN_PU),
+@@ -2126,11 +2161,23 @@ static struct pinmux_gpio pinmux_gpios[] = {
+ GPIO_FN(KEYIN5_PU),
+ GPIO_FN(KEYIN6_PU),
+ GPIO_FN(KEYIN7_PU),
++ GPIO_FN(SDHICD0_PU),
++ GPIO_FN(SDHID0_0_PU),
++ GPIO_FN(SDHID0_1_PU),
++ GPIO_FN(SDHID0_2_PU),
++ GPIO_FN(SDHID0_3_PU),
++ GPIO_FN(SDHICMD0_PU),
++ GPIO_FN(SDHIWP0_PU),
+ GPIO_FN(SDHID1_0_PU),
+ GPIO_FN(SDHID1_1_PU),
+ GPIO_FN(SDHID1_2_PU),
+ GPIO_FN(SDHID1_3_PU),
+ GPIO_FN(SDHICMD1_PU),
++ GPIO_FN(SDHID2_0_PU),
++ GPIO_FN(SDHID2_1_PU),
++ GPIO_FN(SDHID2_2_PU),
++ GPIO_FN(SDHID2_3_PU),
++ GPIO_FN(SDHICMD2_PU),
+ GPIO_FN(MMCCMD0_PU),
+ GPIO_FN(MMCCMD1_PU),
+ GPIO_FN(FSIACK_PU),
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0173-ARM-shmobile-convert-logical-CPU-numbers-to-physical.patch b/patches.kzm9g/0173-ARM-shmobile-convert-logical-CPU-numbers-to-physical.patch
new file mode 100644
index 00000000000000..b5b7d6d9163127
--- /dev/null
+++ b/patches.kzm9g/0173-ARM-shmobile-convert-logical-CPU-numbers-to-physical.patch
@@ -0,0 +1,51 @@
+From 99e07f2cb417d9c739ff222b73d8a4040486249f Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Tue, 9 Aug 2011 12:13:53 +0100
+Subject: ARM: shmobile: convert logical CPU numbers to physical numbers
+
+This patch uses the new cpu_logical_map() macro for converting logical
+CPU numbers into physical numbers when dealing with the SCU in the SMP
+boot path for sh73a0.
+
+Cc: Magnus Damm <magnus.damm@gmail.com>
+Cc: Paul Mundt <lethal@linux-sh.org>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+(cherry picked from commit f80ca52cab8f999246ed2e4daa90eb40cb810822)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/smp-sh73a0.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
+index 3ffdbc9..be1ade7 100644
+--- a/arch/arm/mach-shmobile/smp-sh73a0.c
++++ b/arch/arm/mach-shmobile/smp-sh73a0.c
+@@ -74,6 +74,8 @@ void __cpuinit sh73a0_secondary_init(unsigned int cpu)
+
+ int __cpuinit sh73a0_boot_secondary(unsigned int cpu)
+ {
++ cpu = cpu_logical_map(cpu);
++
+ /* enable cache coherency */
+ modify_scu_cpu_psr(0, 3 << (cpu * 8));
+
+@@ -87,6 +89,8 @@ int __cpuinit sh73a0_boot_secondary(unsigned int cpu)
+
+ void __init sh73a0_smp_prepare_cpus(void)
+ {
++ int cpu = cpu_logical_map(0);
++
+ scu_enable(scu_base_addr());
+
+ /* Map the reset vector (in headsmp.S) */
+@@ -94,5 +98,5 @@ void __init sh73a0_smp_prepare_cpus(void)
+ __raw_writel(__pa(shmobile_secondary_vector), __io(SBAR));
+
+ /* enable cache coherency on CPU0 */
+- modify_scu_cpu_psr(0, 3 << (0 * 8));
++ modify_scu_cpu_psr(0, 3 << (cpu * 8));
+ }
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0174-ARM-mach-shmobile-sh73a0-GPIO-IRQ-support.patch b/patches.kzm9g/0174-ARM-mach-shmobile-sh73a0-GPIO-IRQ-support.patch
new file mode 100644
index 00000000000000..176239b986de4e
--- /dev/null
+++ b/patches.kzm9g/0174-ARM-mach-shmobile-sh73a0-GPIO-IRQ-support.patch
@@ -0,0 +1,91 @@
+From ce81dcdbb5efaf6b9e1662138e6ce62833cb584d Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Wed, 28 Sep 2011 16:55:45 +0900
+Subject: ARM: mach-shmobile: sh73a0 GPIO IRQ support
+
+This patch adds support for sh73a0 GPIO IRQs by making use
+of the PFC GPIO IRQ feature. Only IRQ pins are supported
+at this time. In the future when PINT interrupts also are
+supported properly we can easily extend the table with such
+information. Also, the sh73a0 is currently making use of
+the GIC for external interrupt which is rather unflexible
+when it comes to triggering configuration at this point.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 13fc7e7c2cd08a884f76eeb940957160b296d5c3)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/pfc-sh73a0.c | 41 +++++++++++++++++++++++++++++++++++++
+ 1 file changed, 41 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/pfc-sh73a0.c b/arch/arm/mach-shmobile/pfc-sh73a0.c
+index 599016e..0e24ac4 100644
+--- a/arch/arm/mach-shmobile/pfc-sh73a0.c
++++ b/arch/arm/mach-shmobile/pfc-sh73a0.c
+@@ -22,6 +22,7 @@
+ #include <linux/kernel.h>
+ #include <linux/gpio.h>
+ #include <mach/sh73a0.h>
++#include <mach/irqs.h>
+
+ #define CPU_ALL_PORT(fn, pfx, sfx) \
+ PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx), \
+@@ -2698,6 +2699,43 @@ static struct pinmux_data_reg pinmux_data_regs[] = {
+ { },
+ };
+
++#define EXT_IRQ(n) gic_spi((n) + 1) /* GIC SPI starting from 1 for IRQ0 */
++
++static struct pinmux_irq pinmux_irqs[] = {
++ PINMUX_IRQ(EXT_IRQ(19), PORT9_FN0),
++ PINMUX_IRQ(EXT_IRQ(1), PORT10_FN0),
++ PINMUX_IRQ(EXT_IRQ(0), PORT11_FN0),
++ PINMUX_IRQ(EXT_IRQ(18), PORT13_FN0),
++ PINMUX_IRQ(EXT_IRQ(20), PORT14_FN0),
++ PINMUX_IRQ(EXT_IRQ(21), PORT15_FN0),
++ PINMUX_IRQ(EXT_IRQ(31), PORT26_FN0),
++ PINMUX_IRQ(EXT_IRQ(30), PORT27_FN0),
++ PINMUX_IRQ(EXT_IRQ(29), PORT28_FN0),
++ PINMUX_IRQ(EXT_IRQ(22), PORT40_FN0),
++ PINMUX_IRQ(EXT_IRQ(23), PORT53_FN0),
++ PINMUX_IRQ(EXT_IRQ(10), PORT54_FN0),
++ PINMUX_IRQ(EXT_IRQ(9), PORT56_FN0),
++ PINMUX_IRQ(EXT_IRQ(26), PORT115_FN0),
++ PINMUX_IRQ(EXT_IRQ(27), PORT116_FN0),
++ PINMUX_IRQ(EXT_IRQ(28), PORT117_FN0),
++ PINMUX_IRQ(EXT_IRQ(24), PORT118_FN0),
++ PINMUX_IRQ(EXT_IRQ(6), PORT147_FN0),
++ PINMUX_IRQ(EXT_IRQ(2), PORT149_FN0),
++ PINMUX_IRQ(EXT_IRQ(7), PORT150_FN0),
++ PINMUX_IRQ(EXT_IRQ(12), PORT156_FN0),
++ PINMUX_IRQ(EXT_IRQ(4), PORT159_FN0),
++ PINMUX_IRQ(EXT_IRQ(25), PORT164_FN0),
++ PINMUX_IRQ(EXT_IRQ(8), PORT223_FN0),
++ PINMUX_IRQ(EXT_IRQ(3), PORT224_FN0),
++ PINMUX_IRQ(EXT_IRQ(5), PORT227_FN0),
++ PINMUX_IRQ(EXT_IRQ(17), PORT234_FN0),
++ PINMUX_IRQ(EXT_IRQ(11), PORT238_FN0),
++ PINMUX_IRQ(EXT_IRQ(13), PORT239_FN0),
++ PINMUX_IRQ(EXT_IRQ(16), PORT249_FN0),
++ PINMUX_IRQ(EXT_IRQ(14), PORT251_FN0),
++ PINMUX_IRQ(EXT_IRQ(9), PORT308_FN0),
++};
++
+ static struct pinmux_info sh73a0_pinmux_info = {
+ .name = "sh73a0_pfc",
+ .reserved_id = PINMUX_RESERVED,
+@@ -2718,6 +2756,9 @@ static struct pinmux_info sh73a0_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 sh73a0_pinmux_init(void)
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0175-ARM-mach-shmobile-Use-common-INTC-IRQ-code-on-sh73a0.patch b/patches.kzm9g/0175-ARM-mach-shmobile-Use-common-INTC-IRQ-code-on-sh73a0.patch
new file mode 100644
index 00000000000000..40dc2454aad3d4
--- /dev/null
+++ b/patches.kzm9g/0175-ARM-mach-shmobile-Use-common-INTC-IRQ-code-on-sh73a0.patch
@@ -0,0 +1,259 @@
+From 3c8de348dc6f41d179ea079f2530837ce0808d97 Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Wed, 12 Oct 2011 16:21:42 +0900
+Subject: ARM: mach-shmobile: Use common INTC IRQ code on sh73a0
+
+Improve IRQ triggering support by making use of the macro
+INTC_IRQ_PINS_32() for INTCA on sh73a0. Unfortunately it
+is not as easy as just using the macro as-is, we need to
+do mask and unmaks in the GIC but configure other bits
+and ack in INTCA. Update GPIO IRQ mappings while at it.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit a1993055efcc14fd6d213b936d28a41ea52e1d3d)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/intc-sh73a0.c | 122 +++++++++++++++++++++++++++++++++++
+ arch/arm/mach-shmobile/pfc-sh73a0.c | 68 +++++++++----------
+ 2 files changed, 157 insertions(+), 33 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c
+index a911a60..836e815 100644
+--- a/arch/arm/mach-shmobile/intc-sh73a0.c
++++ b/arch/arm/mach-shmobile/intc-sh73a0.c
+@@ -22,6 +22,7 @@
+ #include <linux/irq.h>
+ #include <linux/io.h>
+ #include <linux/sh_intc.h>
++#include <mach/intc.h>
+ #include <asm/hardware/gic.h>
+ #include <asm/mach-types.h>
+ #include <asm/mach/arch.h>
+@@ -255,20 +256,141 @@ static int sh73a0_set_wake(struct irq_data *data, unsigned int on)
+ return 0; /* always allow wakeup */
+ }
+
++#define RELOC_BASE 0x1000
++
++/* INTCA IRQ pins at INTCS + 0x1000 to make space for GIC+INTC handling */
++#define INTCS_VECT_RELOC(n, vect) INTCS_VECT((n), (vect) + RELOC_BASE)
++
++INTC_IRQ_PINS_32(intca_irq_pins, 0xe6900000,
++ INTCS_VECT_RELOC, "sh73a0-intca-irq-pins");
++
++static int to_gic_irq(struct irq_data *data)
++{
++ unsigned int vect = irq2evt(data->irq) - INTCS_VECT_BASE;
++
++ if (vect >= 0x3200)
++ vect -= 0x3000;
++ else
++ vect -= 0x0200;
++
++ return gic_spi((vect >> 5) + 1);
++}
++
++static int to_intca_reloc_irq(struct irq_data *data)
++{
++ return data->irq + (RELOC_BASE >> 5);
++}
++
++#define irq_cb(cb, irq) irq_get_chip(irq)->cb(irq_get_irq_data(irq))
++#define irq_cbp(cb, irq, p...) irq_get_chip(irq)->cb(irq_get_irq_data(irq), p)
++
++static void intca_gic_enable(struct irq_data *data)
++{
++ irq_cb(irq_unmask, to_intca_reloc_irq(data));
++ irq_cb(irq_unmask, to_gic_irq(data));
++}
++
++static void intca_gic_disable(struct irq_data *data)
++{
++ irq_cb(irq_mask, to_gic_irq(data));
++ irq_cb(irq_mask, to_intca_reloc_irq(data));
++}
++
++static void intca_gic_mask_ack(struct irq_data *data)
++{
++ irq_cb(irq_mask, to_gic_irq(data));
++ irq_cb(irq_mask_ack, to_intca_reloc_irq(data));
++}
++
++static void intca_gic_eoi(struct irq_data *data)
++{
++ irq_cb(irq_eoi, to_gic_irq(data));
++}
++
++static int intca_gic_set_type(struct irq_data *data, unsigned int type)
++{
++ return irq_cbp(irq_set_type, to_intca_reloc_irq(data), type);
++}
++
++static int intca_gic_set_wake(struct irq_data *data, unsigned int on)
++{
++ return irq_cbp(irq_set_wake, to_intca_reloc_irq(data), on);
++}
++
++#ifdef CONFIG_SMP
++static int intca_gic_set_affinity(struct irq_data *data,
++ const struct cpumask *cpumask,
++ bool force)
++{
++ return irq_cbp(irq_set_affinity, to_gic_irq(data), cpumask, force);
++}
++#endif
++
++struct irq_chip intca_gic_irq_chip = {
++ .name = "INTCA-GIC",
++ .irq_mask = intca_gic_disable,
++ .irq_unmask = intca_gic_enable,
++ .irq_mask_ack = intca_gic_mask_ack,
++ .irq_eoi = intca_gic_eoi,
++ .irq_enable = intca_gic_enable,
++ .irq_disable = intca_gic_disable,
++ .irq_shutdown = intca_gic_disable,
++ .irq_set_type = intca_gic_set_type,
++ .irq_set_wake = intca_gic_set_wake,
++#ifdef CONFIG_SMP
++ .irq_set_affinity = intca_gic_set_affinity,
++#endif
++};
++
++static int to_intc_vect(int irq)
++{
++ unsigned int irq_pin = irq - gic_spi(1);
++ unsigned int offs;
++
++ if (irq_pin < 16)
++ offs = 0x0200;
++ else
++ offs = 0x3000;
++
++ return offs + (irq_pin << 5);
++}
++
++static irqreturn_t sh73a0_irq_pin_demux(int irq, void *dev_id)
++{
++ generic_handle_irq(intcs_evt2irq(to_intc_vect(irq)));
++ return IRQ_HANDLED;
++}
++
++static struct irqaction sh73a0_irq_pin_cascade[32];
++
+ void __init sh73a0_init_irq(void)
+ {
+ void __iomem *gic_dist_base = __io(0xf0001000);
+ void __iomem *gic_cpu_base = __io(0xf0000100);
+ void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
++ int k, n;
+
+ gic_init(0, 29, gic_dist_base, gic_cpu_base);
+ gic_arch_extn.irq_set_wake = sh73a0_set_wake;
+
+ register_intc_controller(&intcs_desc);
++ register_intc_controller(&intca_irq_pins_desc);
+
+ /* demux using INTEVTSA */
+ sh73a0_intcs_cascade.name = "INTCS cascade";
+ sh73a0_intcs_cascade.handler = sh73a0_intcs_demux;
+ sh73a0_intcs_cascade.dev_id = intevtsa;
+ setup_irq(gic_spi(50), &sh73a0_intcs_cascade);
++
++ /* IRQ pins require special handling through INTCA and GIC */
++ for (k = 0; k < 32; k++) {
++ sh73a0_irq_pin_cascade[k].name = "INTCA-GIC cascade";
++ sh73a0_irq_pin_cascade[k].handler = sh73a0_irq_pin_demux;
++ setup_irq(gic_spi(1 + k), &sh73a0_irq_pin_cascade[k]);
++
++ n = intcs_evt2irq(to_intc_vect(gic_spi(1 + k)));
++ irq_set_chip_and_handler_name(n, &intca_gic_irq_chip,
++ handle_level_irq, "level");
++ set_irq_flags(n, IRQF_VALID); /* yuck */
++ }
+ }
+diff --git a/arch/arm/mach-shmobile/pfc-sh73a0.c b/arch/arm/mach-shmobile/pfc-sh73a0.c
+index 0e24ac4..cf7c7bb 100644
+--- a/arch/arm/mach-shmobile/pfc-sh73a0.c
++++ b/arch/arm/mach-shmobile/pfc-sh73a0.c
+@@ -2699,41 +2699,43 @@ static struct pinmux_data_reg pinmux_data_regs[] = {
+ { },
+ };
+
+-#define EXT_IRQ(n) gic_spi((n) + 1) /* GIC SPI starting from 1 for IRQ0 */
++/* IRQ pins through INTCS with IRQ0->15 from 0x200 and IRQ16-31 from 0x3200 */
++#define EXT_IRQ16L(n) intcs_evt2irq(0x200 + ((n) << 5))
++#define EXT_IRQ16H(n) intcs_evt2irq(0x3200 + ((n - 16) << 5))
+
+ static struct pinmux_irq pinmux_irqs[] = {
+- PINMUX_IRQ(EXT_IRQ(19), PORT9_FN0),
+- PINMUX_IRQ(EXT_IRQ(1), PORT10_FN0),
+- PINMUX_IRQ(EXT_IRQ(0), PORT11_FN0),
+- PINMUX_IRQ(EXT_IRQ(18), PORT13_FN0),
+- PINMUX_IRQ(EXT_IRQ(20), PORT14_FN0),
+- PINMUX_IRQ(EXT_IRQ(21), PORT15_FN0),
+- PINMUX_IRQ(EXT_IRQ(31), PORT26_FN0),
+- PINMUX_IRQ(EXT_IRQ(30), PORT27_FN0),
+- PINMUX_IRQ(EXT_IRQ(29), PORT28_FN0),
+- PINMUX_IRQ(EXT_IRQ(22), PORT40_FN0),
+- PINMUX_IRQ(EXT_IRQ(23), PORT53_FN0),
+- PINMUX_IRQ(EXT_IRQ(10), PORT54_FN0),
+- PINMUX_IRQ(EXT_IRQ(9), PORT56_FN0),
+- PINMUX_IRQ(EXT_IRQ(26), PORT115_FN0),
+- PINMUX_IRQ(EXT_IRQ(27), PORT116_FN0),
+- PINMUX_IRQ(EXT_IRQ(28), PORT117_FN0),
+- PINMUX_IRQ(EXT_IRQ(24), PORT118_FN0),
+- PINMUX_IRQ(EXT_IRQ(6), PORT147_FN0),
+- PINMUX_IRQ(EXT_IRQ(2), PORT149_FN0),
+- PINMUX_IRQ(EXT_IRQ(7), PORT150_FN0),
+- PINMUX_IRQ(EXT_IRQ(12), PORT156_FN0),
+- PINMUX_IRQ(EXT_IRQ(4), PORT159_FN0),
+- PINMUX_IRQ(EXT_IRQ(25), PORT164_FN0),
+- PINMUX_IRQ(EXT_IRQ(8), PORT223_FN0),
+- PINMUX_IRQ(EXT_IRQ(3), PORT224_FN0),
+- PINMUX_IRQ(EXT_IRQ(5), PORT227_FN0),
+- PINMUX_IRQ(EXT_IRQ(17), PORT234_FN0),
+- PINMUX_IRQ(EXT_IRQ(11), PORT238_FN0),
+- PINMUX_IRQ(EXT_IRQ(13), PORT239_FN0),
+- PINMUX_IRQ(EXT_IRQ(16), PORT249_FN0),
+- PINMUX_IRQ(EXT_IRQ(14), PORT251_FN0),
+- PINMUX_IRQ(EXT_IRQ(9), PORT308_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(19), PORT9_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(1), PORT10_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(0), PORT11_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(18), PORT13_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(20), PORT14_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(21), PORT15_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(31), PORT26_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(30), PORT27_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(29), PORT28_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(22), PORT40_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(23), PORT53_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(10), PORT54_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(9), PORT56_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(26), PORT115_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(27), PORT116_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(28), PORT117_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(24), PORT118_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(6), PORT147_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(2), PORT149_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(7), PORT150_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(12), PORT156_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(4), PORT159_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(25), PORT164_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(8), PORT223_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(3), PORT224_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(5), PORT227_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(17), PORT234_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(11), PORT238_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(13), PORT239_FN0),
++ PINMUX_IRQ(EXT_IRQ16H(16), PORT249_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(14), PORT251_FN0),
++ PINMUX_IRQ(EXT_IRQ16L(9), PORT308_FN0),
+ };
+
+ static struct pinmux_info sh73a0_pinmux_info = {
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0176-ARM-mach-shmobile-sh73a0-and-AG5EVM-PINT-support.patch b/patches.kzm9g/0176-ARM-mach-shmobile-sh73a0-and-AG5EVM-PINT-support.patch
new file mode 100644
index 00000000000000..743aebd5c9a5fb
--- /dev/null
+++ b/patches.kzm9g/0176-ARM-mach-shmobile-sh73a0-and-AG5EVM-PINT-support.patch
@@ -0,0 +1,174 @@
+From ba8cc79e847a7743d3c835c92fb2f73c32871f3d Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Mon, 17 Oct 2011 18:00:52 +0900
+Subject: ARM: mach-shmobile: sh73a0 and AG5EVM PINT support
+
+Support PINT on sh73a0 and AG5EVM using INTC PINT macros.
+
+With this patch applied the AG5EVM ethernet is handled
+through one of the chained sh73a0 PINT interrupt controllers.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 566aad39df77211467078e0b3dcd62100f56b5e4)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-ag5evm.c | 17 +-------
+ arch/arm/mach-shmobile/include/mach/sh73a0.h | 4 ++
+ arch/arm/mach-shmobile/intc-sh73a0.c | 65 ++++++++++++++++++++++++++++
+ 3 files changed, 71 insertions(+), 15 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
+index f04ee16..430c723 100644
+--- a/arch/arm/mach-shmobile/board-ag5evm.c
++++ b/arch/arm/mach-shmobile/board-ag5evm.c
+@@ -59,7 +59,7 @@ static struct resource smsc9220_resources[] = {
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+- .start = gic_spi(33), /* PINT1 */
++ .start = SH73A0_PINT0_IRQ(2), /* PINTA2 */
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+@@ -445,19 +445,6 @@ static void __init ag5evm_map_io(void)
+ shmobile_setup_console();
+ }
+
+-#define PINTC_ADDR 0xe6900000
+-#define PINTER0A (PINTC_ADDR + 0xa0)
+-#define PINTCR0A (PINTC_ADDR + 0xb0)
+-
+-void __init ag5evm_init_irq(void)
+-{
+- sh73a0_init_irq();
+-
+- /* setup PINT: enable PINTA2 as active low */
+- __raw_writel(__raw_readl(PINTER0A) | (1<<29), PINTER0A);
+- __raw_writew(__raw_readw(PINTCR0A) | (2<<10), PINTCR0A);
+-}
+-
+ #define DSI0PHYCR 0xe615006c
+
+ static void __init ag5evm_init(void)
+@@ -584,7 +571,7 @@ struct sys_timer ag5evm_timer = {
+
+ MACHINE_START(AG5EVM, "ag5evm")
+ .map_io = ag5evm_map_io,
+- .init_irq = ag5evm_init_irq,
++ .init_irq = sh73a0_init_irq,
+ .handle_irq = shmobile_handle_irq_gic,
+ .init_machine = ag5evm_init,
+ .timer = &ag5evm_timer,
+diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h
+index b385e97..18ae6a9 100644
+--- a/arch/arm/mach-shmobile/include/mach/sh73a0.h
++++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h
+@@ -507,4 +507,8 @@ enum {
+ SHDMA_SLAVE_MMCIF_RX,
+ };
+
++/* PINT interrupts are located at Linux IRQ 768 and up */
++#define SH73A0_PINT0_IRQ(irq) ((irq) + 768)
++#define SH73A0_PINT1_IRQ(irq) ((irq) + 800)
++
+ #endif /* __ASM_SH73A0_H__ */
+diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c
+index 836e815..1eda6b0 100644
+--- a/arch/arm/mach-shmobile/intc-sh73a0.c
++++ b/arch/arm/mach-shmobile/intc-sh73a0.c
+@@ -23,6 +23,7 @@
+ #include <linux/io.h>
+ #include <linux/sh_intc.h>
+ #include <mach/intc.h>
++#include <mach/sh73a0.h>
+ #include <asm/hardware/gic.h>
+ #include <asm/mach-types.h>
+ #include <asm/mach/arch.h>
+@@ -363,6 +364,59 @@ static irqreturn_t sh73a0_irq_pin_demux(int irq, void *dev_id)
+
+ static struct irqaction sh73a0_irq_pin_cascade[32];
+
++#define PINTER0 0xe69000a0
++#define PINTER1 0xe69000a4
++#define PINTRR0 0xe69000d0
++#define PINTRR1 0xe69000d4
++
++#define PINT0A_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq))
++#define PINT0B_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq + 8))
++#define PINT0C_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq + 16))
++#define PINT0D_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT0_IRQ(irq + 24))
++#define PINT1E_IRQ(n, irq) INTC_IRQ((n), SH73A0_PINT1_IRQ(irq))
++
++INTC_PINT(intc_pint0, PINTER0, 0xe69000b0, "sh73a0-pint0", \
++ INTC_PINT_E(A), INTC_PINT_E(B), INTC_PINT_E(C), INTC_PINT_E(D), \
++ INTC_PINT_V(A, PINT0A_IRQ), INTC_PINT_V(B, PINT0B_IRQ), \
++ INTC_PINT_V(C, PINT0C_IRQ), INTC_PINT_V(D, PINT0D_IRQ), \
++ INTC_PINT_E(A), INTC_PINT_E(B), INTC_PINT_E(C), INTC_PINT_E(D), \
++ INTC_PINT_E(A), INTC_PINT_E(B), INTC_PINT_E(C), INTC_PINT_E(D));
++
++INTC_PINT(intc_pint1, PINTER1, 0xe69000c0, "sh73a0-pint1", \
++ INTC_PINT_E(E), INTC_PINT_E_EMPTY, INTC_PINT_E_EMPTY, INTC_PINT_E_EMPTY, \
++ INTC_PINT_V(E, PINT1E_IRQ), INTC_PINT_V_NONE, \
++ INTC_PINT_V_NONE, INTC_PINT_V_NONE, \
++ INTC_PINT_E_NONE, INTC_PINT_E_NONE, INTC_PINT_E_NONE, INTC_PINT_E(E), \
++ INTC_PINT_E(E), INTC_PINT_E_NONE, INTC_PINT_E_NONE, INTC_PINT_E_NONE);
++
++static struct irqaction sh73a0_pint0_cascade;
++static struct irqaction sh73a0_pint1_cascade;
++
++static void pint_demux(unsigned long rr, unsigned long er, int base_irq)
++{
++ unsigned long value = ioread32(rr) & ioread32(er);
++ int k;
++
++ for (k = 0; k < 32; k++) {
++ if (value & (1 << (31 - k))) {
++ generic_handle_irq(base_irq + k);
++ iowrite32(~(1 << (31 - k)), rr);
++ }
++ }
++}
++
++static irqreturn_t sh73a0_pint0_demux(int irq, void *dev_id)
++{
++ pint_demux(PINTRR0, PINTER0, SH73A0_PINT0_IRQ(0));
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t sh73a0_pint1_demux(int irq, void *dev_id)
++{
++ pint_demux(PINTRR1, PINTER1, SH73A0_PINT1_IRQ(0));
++ return IRQ_HANDLED;
++}
++
+ void __init sh73a0_init_irq(void)
+ {
+ void __iomem *gic_dist_base = __io(0xf0001000);
+@@ -375,6 +429,8 @@ void __init sh73a0_init_irq(void)
+
+ register_intc_controller(&intcs_desc);
+ register_intc_controller(&intca_irq_pins_desc);
++ register_intc_controller(&intc_pint0_desc);
++ register_intc_controller(&intc_pint1_desc);
+
+ /* demux using INTEVTSA */
+ sh73a0_intcs_cascade.name = "INTCS cascade";
+@@ -393,4 +449,13 @@ void __init sh73a0_init_irq(void)
+ handle_level_irq, "level");
+ set_irq_flags(n, IRQF_VALID); /* yuck */
+ }
++
++ /* PINT pins are sanely tied to the GIC as SPI */
++ sh73a0_pint0_cascade.name = "PINT0 cascade";
++ sh73a0_pint0_cascade.handler = sh73a0_pint0_demux;
++ setup_irq(gic_spi(33), &sh73a0_pint0_cascade);
++
++ sh73a0_pint1_cascade.name = "PINT1 cascade";
++ sh73a0_pint1_cascade.handler = sh73a0_pint1_demux;
++ setup_irq(gic_spi(34), &sh73a0_pint1_cascade);
+ }
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0177-ARM-mach-shmobile-Kota2-TPU-LED-platform-data.patch b/patches.kzm9g/0177-ARM-mach-shmobile-Kota2-TPU-LED-platform-data.patch
new file mode 100644
index 00000000000000..fa192b7c37d745
--- /dev/null
+++ b/patches.kzm9g/0177-ARM-mach-shmobile-Kota2-TPU-LED-platform-data.patch
@@ -0,0 +1,88 @@
+From 9335e7d7f5827af9446ac83c09eef75942d2cc90 Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Tue, 22 Nov 2011 15:44:58 +0900
+Subject: ARM: mach-shmobile: Kota2 TPU LED platform data
+
+This patch updates the Kota2 board support code to
+use the recently merged TPU LED driver whenever
+possible.
+
+The sh73a0 SoC has 5 TPU hardware blocks each with
+4 timer channels which in theory allows a total of
+20 LEDs to be controlled by "leds-renesas-tpu"
+driver instances. The Kota2 board has 4 LEDs connected
+to GPIO pins that also come with TPU pin functions, so
+this patch ties up these 4 LEDS and leaves the remaining
+3 LEDS for the GPIO based LED driver.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 33661c9e2062865acde9d421c971f1c142cf99ca)
+
+Conflicts:
+
+ arch/arm/mach-shmobile/board-kota2.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-sh73a0.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
+index 44a923d..7df1f11 100644
+--- a/arch/arm/mach-shmobile/clock-sh73a0.c
++++ b/arch/arm/mach-shmobile/clock-sh73a0.c
+@@ -113,6 +113,12 @@ static struct clk main_clk = {
+ .ops = &main_clk_ops,
+ };
+
++/* Divide Main clock by two */
++static struct clk main_div2_clk = {
++ .ops = &div2_clk_ops,
++ .parent = &main_clk,
++};
++
+ /* PLL0, PLL1, PLL2, PLL3 */
+ static unsigned long pll_recalc(struct clk *clk)
+ {
+@@ -181,6 +187,7 @@ static struct clk *main_clks[] = {
+ &extal1_div2_clk,
+ &extal2_div2_clk,
+ &main_clk,
++ &main_div2_clk,
+ &pll0_clk,
+ &pll1_clk,
+ &pll2_clk,
+@@ -268,6 +275,7 @@ enum { MSTP001,
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+ MSTP331, MSTP329, MSTP325, MSTP323, MSTP318,
+ MSTP314, MSTP313, MSTP312, MSTP311,
++ MSTP303, MSTP302, MSTP301, MSTP300,
+ MSTP411, MSTP410, MSTP403,
+ MSTP_NR };
+
+@@ -301,6 +309,10 @@ static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
+ [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
+ [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
++ [MSTP303] = MSTP(&main_div2_clk, SMSTPCR3, 3, 0), /* TPU1 */
++ [MSTP302] = MSTP(&main_div2_clk, SMSTPCR3, 2, 0), /* TPU2 */
++ [MSTP301] = MSTP(&main_div2_clk, SMSTPCR3, 1, 0), /* TPU3 */
++ [MSTP300] = MSTP(&main_div2_clk, SMSTPCR3, 0, 0), /* TPU4 */
+ [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
+ [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
+ [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
+@@ -350,6 +362,10 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
+ CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
++ CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */
++ CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */
++ CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */
++ CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
+ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0178-ARM-mach-shmobile-SH73A0-external-Ethernet-fix.patch b/patches.kzm9g/0178-ARM-mach-shmobile-SH73A0-external-Ethernet-fix.patch
new file mode 100644
index 00000000000000..1b5f95e33a0a48
--- /dev/null
+++ b/patches.kzm9g/0178-ARM-mach-shmobile-SH73A0-external-Ethernet-fix.patch
@@ -0,0 +1,38 @@
+From 1eb5e4702a14dfefa6593c24c5bea8c6d3184407 Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Tue, 22 Nov 2011 15:23:17 +0900
+Subject: ARM: mach-shmobile: SH73A0 external Ethernet fix
+
+Keep the ZB clock enabled on sh73a0 to allow the BSC
+to access external peripherals hooked up to CS signals.
+
+This is needed to unbreak Ethernet support on sh73a0 boards
+such as AG5EVM and Kota2 together with the following patch:
+
+ 794d78f drivers: sh: late disabling of clocks V2
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 9bcc0a5d0de137b3a154dc951c5ff70dce815879)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-sh73a0.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
+index 7df1f11..2985363 100644
+--- a/arch/arm/mach-shmobile/clock-sh73a0.c
++++ b/arch/arm/mach-shmobile/clock-sh73a0.c
+@@ -250,7 +250,7 @@ static struct clk div6_clks[DIV6_NR] = {
+ [DIV6_VCK1] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR1, 0),
+ [DIV6_VCK2] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR2, 0),
+ [DIV6_VCK3] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR3, 0),
+- [DIV6_ZB1] = SH_CLK_DIV6(&pll1_div2_clk, ZBCKCR, 0),
++ [DIV6_ZB1] = SH_CLK_DIV6(&pll1_div2_clk, ZBCKCR, CLK_ENABLE_ON_INIT),
+ [DIV6_FLCTL] = SH_CLK_DIV6(&pll1_div2_clk, FLCKCR, 0),
+ [DIV6_SDHI0] = SH_CLK_DIV6(&pll1_div2_clk, SD0CKCR, 0),
+ [DIV6_SDHI1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0),
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0179-sh-clkfwk-clock-sh73a0-all-div6_clks-use-SH_CLK_DIV6.patch b/patches.kzm9g/0179-sh-clkfwk-clock-sh73a0-all-div6_clks-use-SH_CLK_DIV6.patch
new file mode 100644
index 00000000000000..ac00157228b01d
--- /dev/null
+++ b/patches.kzm9g/0179-sh-clkfwk-clock-sh73a0-all-div6_clks-use-SH_CLK_DIV6.patch
@@ -0,0 +1,233 @@
+From bad42bcc41d498bed5fd01177b1073d32e551584 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 5 Dec 2011 22:29:15 -0800
+Subject: sh: clkfwk: clock-sh73a0: all div6_clks use SH_CLK_DIV6_EXT()
+
+Current div6 clocks can specify their current parent clocks
+from its register value if it is registered
+by sh_clk_div6_reparent_register().
+This patch modifies all div6 clocks into SH_CLK_DIV6_EXT().
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit d4775356bb39eaa305844cc6cc4c267236535956)
+
+Conflicts:
+
+ arch/arm/mach-shmobile/clock-sh73a0.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-sh73a0.c | 141 ++++++++++++++++++++++-----
+ arch/arm/mach-shmobile/include/mach/common.h | 2 +
+ 2 files changed, 120 insertions(+), 23 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
+index 2985363..462a964 100644
+--- a/arch/arm/mach-shmobile/clock-sh73a0.c
++++ b/arch/arm/mach-shmobile/clock-sh73a0.c
+@@ -92,6 +92,24 @@ static struct clk_ops div2_clk_ops = {
+ .recalc = div2_recalc,
+ };
+
++static unsigned long div7_recalc(struct clk *clk)
++{
++ return clk->parent->rate / 7;
++}
++
++static struct clk_ops div7_clk_ops = {
++ .recalc = div7_recalc,
++};
++
++static unsigned long div13_recalc(struct clk *clk)
++{
++ return clk->parent->rate / 13;
++}
++
++static struct clk_ops div13_clk_ops = {
++ .recalc = div13_recalc,
++};
++
+ /* Divide extal1 by two */
+ static struct clk extal1_div2_clk = {
+ .ops = &div2_clk_ops,
+@@ -113,7 +131,6 @@ static struct clk main_clk = {
+ .ops = &main_clk_ops,
+ };
+
+-/* Divide Main clock by two */
+ static struct clk main_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &main_clk,
+@@ -174,12 +191,29 @@ static struct clk pll3_clk = {
+ .enable_bit = 3,
+ };
+
+-/* Divide PLL1 by two */
++/* Divide PLL */
+ static struct clk pll1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &pll1_clk,
+ };
+
++static struct clk pll1_div7_clk = {
++ .ops = &div7_clk_ops,
++ .parent = &pll1_clk,
++};
++
++static struct clk pll1_div13_clk = {
++ .ops = &div13_clk_ops,
++ .parent = &pll1_clk,
++};
++
++/* External input clock */
++struct clk sh73a0_extcki_clk = {
++};
++
++struct clk sh73a0_extalr_clk = {
++};
++
+ static struct clk *main_clks[] = {
+ &r_clk,
+ &sh73a0_extal1_clk,
+@@ -193,6 +227,10 @@ static struct clk *main_clks[] = {
+ &pll2_clk,
+ &pll3_clk,
+ &pll1_div2_clk,
++ &pll1_div7_clk,
++ &pll1_div13_clk,
++ &sh73a0_extcki_clk,
++ &sh73a0_extalr_clk,
+ };
+
+ static void div4_kick(struct clk *clk)
+@@ -246,27 +284,84 @@ enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
+ DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
+ DIV6_NR };
+
++static struct clk *vck_parent[8] = {
++ [0] = &pll1_div2_clk,
++ [1] = &pll2_clk,
++ [2] = &sh73a0_extcki_clk,
++ [3] = &sh73a0_extal2_clk,
++ [4] = &main_div2_clk,
++ [5] = &sh73a0_extalr_clk,
++ [6] = &main_clk,
++};
++
++static struct clk *pll_parent[4] = {
++ [0] = &pll1_div2_clk,
++ [1] = &pll2_clk,
++ [2] = &pll1_div13_clk,
++};
++
++static struct clk *hsi_parent[4] = {
++ [0] = &pll1_div2_clk,
++ [1] = &pll2_clk,
++ [2] = &pll1_div7_clk,
++};
++
++static struct clk *pll_extal2_parent[] = {
++ [0] = &pll1_div2_clk,
++ [1] = &pll2_clk,
++ [2] = &sh73a0_extal2_clk,
++ [3] = &sh73a0_extal2_clk,
++};
++
++static struct clk *dsi_parent[8] = {
++ [0] = &pll1_div2_clk,
++ [1] = &pll2_clk,
++ [2] = &main_clk,
++ [3] = &sh73a0_extal2_clk,
++ [4] = &sh73a0_extcki_clk,
++};
++
+ static struct clk div6_clks[DIV6_NR] = {
+- [DIV6_VCK1] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR1, 0),
+- [DIV6_VCK2] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR2, 0),
+- [DIV6_VCK3] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR3, 0),
+- [DIV6_ZB1] = SH_CLK_DIV6(&pll1_div2_clk, ZBCKCR, CLK_ENABLE_ON_INIT),
+- [DIV6_FLCTL] = SH_CLK_DIV6(&pll1_div2_clk, FLCKCR, 0),
+- [DIV6_SDHI0] = SH_CLK_DIV6(&pll1_div2_clk, SD0CKCR, 0),
+- [DIV6_SDHI1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0),
+- [DIV6_SDHI2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
+- [DIV6_FSIA] = SH_CLK_DIV6(&pll1_div2_clk, FSIACKCR, 0),
+- [DIV6_FSIB] = SH_CLK_DIV6(&pll1_div2_clk, FSIBCKCR, 0),
+- [DIV6_SUB] = SH_CLK_DIV6(&sh73a0_extal2_clk, SUBCKCR, 0),
+- [DIV6_SPUA] = SH_CLK_DIV6(&pll1_div2_clk, SPUACKCR, 0),
+- [DIV6_SPUV] = SH_CLK_DIV6(&pll1_div2_clk, SPUVCKCR, 0),
+- [DIV6_MSU] = SH_CLK_DIV6(&pll1_div2_clk, MSUCKCR, 0),
+- [DIV6_HSI] = SH_CLK_DIV6(&pll1_div2_clk, HSICKCR, 0),
+- [DIV6_MFG1] = SH_CLK_DIV6(&pll1_div2_clk, MFCK1CR, 0),
+- [DIV6_MFG2] = SH_CLK_DIV6(&pll1_div2_clk, MFCK2CR, 0),
+- [DIV6_DSIT] = SH_CLK_DIV6(&pll1_div2_clk, DSITCKCR, 0),
+- [DIV6_DSI0P] = SH_CLK_DIV6(&pll1_div2_clk, DSI0PCKCR, 0),
+- [DIV6_DSI1P] = SH_CLK_DIV6(&pll1_div2_clk, DSI1PCKCR, 0),
++ [DIV6_VCK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
++ vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
++ [DIV6_VCK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
++ vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
++ [DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0,
++ vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
++ [DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, 0,
++ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
++ [DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0,
++ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
++ [DIV6_SDHI0] = SH_CLK_DIV6_EXT(SD0CKCR, 0,
++ pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
++ [DIV6_SDHI1] = SH_CLK_DIV6_EXT(SD1CKCR, 0,
++ pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
++ [DIV6_SDHI2] = SH_CLK_DIV6_EXT(SD2CKCR, 0,
++ pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
++ [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
++ pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
++ [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
++ pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
++ [DIV6_SUB] = SH_CLK_DIV6_EXT(SUBCKCR, 0,
++ pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
++ [DIV6_SPUA] = SH_CLK_DIV6_EXT(SPUACKCR, 0,
++ pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
++ [DIV6_SPUV] = SH_CLK_DIV6_EXT(SPUVCKCR, 0,
++ pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
++ [DIV6_MSU] = SH_CLK_DIV6_EXT(MSUCKCR, 0,
++ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
++ [DIV6_HSI] = SH_CLK_DIV6_EXT(HSICKCR, 0,
++ hsi_parent, ARRAY_SIZE(hsi_parent), 6, 2),
++ [DIV6_MFG1] = SH_CLK_DIV6_EXT(MFCK1CR, 0,
++ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
++ [DIV6_MFG2] = SH_CLK_DIV6_EXT(MFCK2CR, 0,
++ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
++ [DIV6_DSIT] = SH_CLK_DIV6_EXT(DSITCKCR, 0,
++ pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
++ [DIV6_DSI0P] = SH_CLK_DIV6_EXT(DSI0PCKCR, 0,
++ dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
++ [DIV6_DSI1P] = SH_CLK_DIV6_EXT(DSI1PCKCR, 0,
++ dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
+ };
+
+ enum { MSTP001,
+@@ -403,7 +498,7 @@ void __init sh73a0_clock_init(void)
+ ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+ if (!ret)
+- ret = sh_clk_div6_register(div6_clks, DIV6_NR);
++ ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
+
+ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
+index 2e21a77..6ccc1a5 100644
+--- a/arch/arm/mach-shmobile/include/mach/common.h
++++ b/arch/arm/mach-shmobile/include/mach/common.h
+@@ -48,6 +48,8 @@ extern void sh73a0_clock_init(void);
+ extern void sh73a0_pinmux_init(void);
+ extern struct clk sh73a0_extal1_clk;
+ extern struct clk sh73a0_extal2_clk;
++extern struct clk sh73a0_extcki_clk;
++extern struct clk sh73a0_extalr_clk;
+
+ extern unsigned int sh73a0_get_core_count(void);
+ extern void sh73a0_secondary_init(unsigned int cpu);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0180-arm-mach-shmobile-add-a-resource-name-for-shdma.patch b/patches.kzm9g/0180-arm-mach-shmobile-add-a-resource-name-for-shdma.patch
new file mode 100644
index 00000000000000..df953d69a43572
--- /dev/null
+++ b/patches.kzm9g/0180-arm-mach-shmobile-add-a-resource-name-for-shdma.patch
@@ -0,0 +1,62 @@
+From 40c376c78cee48972ac8e0486c07f5908c96bc32 Mon Sep 17 00:00:00 2001
+From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com>
+Date: Tue, 10 Jan 2012 14:21:31 +0900
+Subject: arm: mach-shmobile: add a resource name for shdma
+
+Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 20052462948795914011f2fea0e77767d55cb48b)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/setup-sh7372.c | 6 +++---
+ arch/arm/mach-shmobile/setup-sh73a0.c | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
+index cd807ee..8ddef91 100644
+--- a/arch/arm/mach-shmobile/setup-sh7372.c
++++ b/arch/arm/mach-shmobile/setup-sh7372.c
+@@ -503,7 +503,7 @@ static struct resource sh7372_dmae0_resources[] = {
+ .flags = IORESOURCE_MEM,
+ },
+ {
+- /* DMA error IRQ */
++ .name = "error_irq",
+ .start = evt2irq(0x20c0),
+ .end = evt2irq(0x20c0),
+ .flags = IORESOURCE_IRQ,
+@@ -531,7 +531,7 @@ static struct resource sh7372_dmae1_resources[] = {
+ .flags = IORESOURCE_MEM,
+ },
+ {
+- /* DMA error IRQ */
++ .name = "error_irq",
+ .start = evt2irq(0x21c0),
+ .end = evt2irq(0x21c0),
+ .flags = IORESOURCE_IRQ,
+@@ -559,7 +559,7 @@ static struct resource sh7372_dmae2_resources[] = {
+ .flags = IORESOURCE_MEM,
+ },
+ {
+- /* DMA error IRQ */
++ .name = "error_irq",
+ .start = evt2irq(0x22c0),
+ .end = evt2irq(0x22c0),
+ .flags = IORESOURCE_IRQ,
+diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
+index e46821c..20e71e5 100644
+--- a/arch/arm/mach-shmobile/setup-sh73a0.c
++++ b/arch/arm/mach-shmobile/setup-sh73a0.c
+@@ -607,7 +607,7 @@ static struct resource sh73a0_dmae_resources[] = {
+ .flags = IORESOURCE_MEM,
+ },
+ {
+- /* DMA error IRQ */
++ .name = "error_irq",
+ .start = gic_spi(129),
+ .end = gic_spi(129),
+ .flags = IORESOURCE_IRQ,
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0181-ARM-mach-shmobile-sh73a0-PINT-IRQ-base-fix.patch b/patches.kzm9g/0181-ARM-mach-shmobile-sh73a0-PINT-IRQ-base-fix.patch
new file mode 100644
index 00000000000000..664a4e23ed16ab
--- /dev/null
+++ b/patches.kzm9g/0181-ARM-mach-shmobile-sh73a0-PINT-IRQ-base-fix.patch
@@ -0,0 +1,39 @@
+From 4e5dece84e3d3a529290121151c5acddcdf54c2f Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Tue, 17 Jan 2012 20:05:40 +0900
+Subject: ARM: mach-shmobile: sh73a0 PINT IRQ base fix
+
+Bump up the sh73a0 PINT IRQ base from 768 to 800 to avoid
+collision with INTCS vectors for IRQ16->IRQ32 at 0x3xxx.
+
+Without this fix the sh73a0 IRQ pin handling code collides
+with the PINT code which results in hangs on Kota2 during boot.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 0df1a838d678fc6ab49f983a19e905f6a42297a0)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/include/mach/sh73a0.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h
+index 18ae6a9..8567d65 100644
+--- a/arch/arm/mach-shmobile/include/mach/sh73a0.h
++++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h
+@@ -507,8 +507,8 @@ enum {
+ SHDMA_SLAVE_MMCIF_RX,
+ };
+
+-/* PINT interrupts are located at Linux IRQ 768 and up */
+-#define SH73A0_PINT0_IRQ(irq) ((irq) + 768)
+-#define SH73A0_PINT1_IRQ(irq) ((irq) + 800)
++/* PINT interrupts are located at Linux IRQ 800 and up */
++#define SH73A0_PINT0_IRQ(irq) ((irq) + 800)
++#define SH73A0_PINT1_IRQ(irq) ((irq) + 832)
+
+ #endif /* __ASM_SH73A0_H__ */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0182-ARM-mach-shmobile-sh73a0-IRQ-sparse-alloc-fix.patch b/patches.kzm9g/0182-ARM-mach-shmobile-sh73a0-IRQ-sparse-alloc-fix.patch
new file mode 100644
index 00000000000000..7728a5fe6f71b7
--- /dev/null
+++ b/patches.kzm9g/0182-ARM-mach-shmobile-sh73a0-IRQ-sparse-alloc-fix.patch
@@ -0,0 +1,44 @@
+From 10188333a01d34499c18ef18f31d7d44fcd1cd83 Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Tue, 17 Jan 2012 20:10:49 +0900
+Subject: ARM: mach-shmobile: sh73a0 IRQ sparse alloc fix
+
+Fix the sh73a0 external IRQ pin code to properly support
+CONFIG_SPARSE_IRQ=y by allocating IRQ descriptors for the
+cascaded IRQs associated with external IRQ pins.
+
+Without this fix it is impossible to request IRQ0->IRQ31
+on the Kota2 board when sparse IRQs are enabled.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit e2c31b3fdd48274e9deb450e21279e54dfa02ccd)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/intc-sh73a0.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c
+index 1eda6b0..9857595 100644
+--- a/arch/arm/mach-shmobile/intc-sh73a0.c
++++ b/arch/arm/mach-shmobile/intc-sh73a0.c
+@@ -19,6 +19,7 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
++#include <linux/module.h>
+ #include <linux/irq.h>
+ #include <linux/io.h>
+ #include <linux/sh_intc.h>
+@@ -445,6 +446,7 @@ void __init sh73a0_init_irq(void)
+ setup_irq(gic_spi(1 + k), &sh73a0_irq_pin_cascade[k]);
+
+ n = intcs_evt2irq(to_intc_vect(gic_spi(1 + k)));
++ WARN_ON(irq_alloc_desc_at(n, numa_node_id()) != n);
+ irq_set_chip_and_handler_name(n, &intca_gic_irq_chip,
+ handle_level_irq, "level");
+ set_irq_flags(n, IRQF_VALID); /* yuck */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0183-ARM-mach-shmobile-clock-sh73a0-add-DSIxPHY-clock-sup.patch b/patches.kzm9g/0183-ARM-mach-shmobile-clock-sh73a0-add-DSIxPHY-clock-sup.patch
new file mode 100644
index 00000000000000..6fa182efb75a9b
--- /dev/null
+++ b/patches.kzm9g/0183-ARM-mach-shmobile-clock-sh73a0-add-DSIxPHY-clock-sup.patch
@@ -0,0 +1,159 @@
+From 90907d664dd2f682cef86afd0ebe8f638f20d01c Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 22 Jan 2012 21:10:02 -0800
+Subject: ARM: mach-shmobile: clock-sh73a0: add DSIxPHY clock support
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit f5948bac5f22e7697fc782e45bdca20a27368512)
+
+Conflicts:
+
+ arch/arm/mach-shmobile/board-ag5evm.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-sh73a0.c | 113 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 113 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
+index 462a964..4d8d140 100644
+--- a/arch/arm/mach-shmobile/clock-sh73a0.c
++++ b/arch/arm/mach-shmobile/clock-sh73a0.c
+@@ -364,6 +364,114 @@ static struct clk div6_clks[DIV6_NR] = {
+ dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
+ };
+
++/* DSI DIV */
++static unsigned long dsiphy_recalc(struct clk *clk)
++{
++ u32 value;
++
++ value = __raw_readl(clk->mapping->base);
++
++ /* FIXME */
++ if (!(value & 0x000B8000))
++ return clk->parent->rate;
++
++ value &= 0x3f;
++ value += 1;
++
++ if ((value < 12) ||
++ (value > 33)) {
++ pr_err("DSIPHY has wrong value (%d)", value);
++ return 0;
++ }
++
++ return clk->parent->rate / value;
++}
++
++static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
++{
++ return clk_rate_mult_range_round(clk, 12, 33, rate);
++}
++
++static void dsiphy_disable(struct clk *clk)
++{
++ u32 value;
++
++ value = __raw_readl(clk->mapping->base);
++ value &= ~0x000B8000;
++
++ __raw_writel(value , clk->mapping->base);
++}
++
++static int dsiphy_enable(struct clk *clk)
++{
++ u32 value;
++ int multi;
++
++ value = __raw_readl(clk->mapping->base);
++ multi = (value & 0x3f) + 1;
++
++ if ((multi < 12) || (multi > 33))
++ return -EIO;
++
++ __raw_writel(value | 0x000B8000, clk->mapping->base);
++
++ return 0;
++}
++
++static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
++{
++ u32 value;
++ int idx;
++
++ idx = rate / clk->parent->rate;
++ if ((idx < 12) || (idx > 33))
++ return -EINVAL;
++
++ idx += -1;
++
++ value = __raw_readl(clk->mapping->base);
++ value = (value & ~0x3f) + idx;
++
++ __raw_writel(value, clk->mapping->base);
++
++ return 0;
++}
++
++static struct clk_ops dsiphy_clk_ops = {
++ .recalc = dsiphy_recalc,
++ .round_rate = dsiphy_round_rate,
++ .set_rate = dsiphy_set_rate,
++ .enable = dsiphy_enable,
++ .disable = dsiphy_disable,
++};
++
++static struct clk_mapping dsi0phy_clk_mapping = {
++ .phys = DSI0PHYCR,
++ .len = 4,
++};
++
++static struct clk_mapping dsi1phy_clk_mapping = {
++ .phys = DSI1PHYCR,
++ .len = 4,
++};
++
++static struct clk dsi0phy_clk = {
++ .ops = &dsiphy_clk_ops,
++ .parent = &div6_clks[DIV6_DSI0P], /* late install */
++ .mapping = &dsi0phy_clk_mapping,
++};
++
++static struct clk dsi1phy_clk = {
++ .ops = &dsiphy_clk_ops,
++ .parent = &div6_clks[DIV6_DSI1P], /* late install */
++ .mapping = &dsi1phy_clk_mapping,
++};
++
++static struct clk *late_main_clks[] = {
++ &dsi0phy_clk,
++ &dsi1phy_clk,
++};
++
+ enum { MSTP001,
+ MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
+ MSTP219,
+@@ -428,6 +536,8 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
+ CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
+ CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
++ CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
++ CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
+
+ /* MSTP32 clocks */
+ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
+@@ -503,6 +613,9 @@ void __init sh73a0_clock_init(void)
+ 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.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0184-ARM-shmobile-remove-NR_IRQS.patch b/patches.kzm9g/0184-ARM-shmobile-remove-NR_IRQS.patch
new file mode 100644
index 00000000000000..6d89d574930bd1
--- /dev/null
+++ b/patches.kzm9g/0184-ARM-shmobile-remove-NR_IRQS.patch
@@ -0,0 +1,54 @@
+From c62cfb4b929686d7bf2c9854d00677c2e9448648 Mon Sep 17 00:00:00 2001
+From: Rob Herring <rob.herring@calxeda.com>
+Date: Tue, 3 Jan 2012 16:57:33 -0600
+Subject: ARM: shmobile: remove NR_IRQS
+
+Remove NR_IRQS and explicitly include mach/irqs.h as needed. shmobile
+properly allocates irq_descs for each irqchip, so setting .nr_irqs for
+each machine is not needed.
+
+Signed-off-by: Rob Herring <rob.herring@calxeda.com>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+(cherry picked from commit 250a27237e0e0694f8f8451594a0f03e0a4f5a73)
+
+Conflicts:
+
+ arch/arm/mach-shmobile/board-ag5evm.c
+ arch/arm/mach-shmobile/board-bonito.c
+ arch/arm/mach-shmobile/board-g3evm.c
+ arch/arm/mach-shmobile/board-g4evm.c
+ arch/arm/mach-shmobile/board-kota2.c
+ arch/arm/mach-shmobile/board-mackerel.c
+ arch/arm/mach-shmobile/board-marzen.c
+ arch/arm/mach-shmobile/include/mach/irqs.h
+ arch/arm/mach-shmobile/intc-r8a7740.c
+ arch/arm/mach-shmobile/intc-sh7367.c
+ arch/arm/mach-shmobile/intc-sh7372.c
+ arch/arm/mach-shmobile/intc-sh7377.c
+ arch/arm/mach-shmobile/setup-r8a7740.c
+ arch/arm/mach-shmobile/setup-r8a7779.c
+ arch/arm/mach-shmobile/setup-sh7367.c
+ arch/arm/mach-shmobile/setup-sh7372.c
+ arch/arm/mach-shmobile/setup-sh7377.c
+ arch/arm/mach-shmobile/setup-sh73a0.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/setup-sh73a0.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
+index 20e71e5..7bf740e 100644
+--- a/arch/arm/mach-shmobile/setup-sh73a0.c
++++ b/arch/arm/mach-shmobile/setup-sh73a0.c
+@@ -31,6 +31,7 @@
+ #include <linux/sh_intc.h>
+ #include <linux/sh_timer.h>
+ #include <mach/hardware.h>
++#include <mach/irqs.h>
+ #include <mach/sh73a0.h>
+ #include <asm/mach-types.h>
+ #include <asm/mach/arch.h>
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0185-ARM-mach-shmobile-sh73a0-PSTR-32-bit-access-fix.patch b/patches.kzm9g/0185-ARM-mach-shmobile-sh73a0-PSTR-32-bit-access-fix.patch
new file mode 100644
index 00000000000000..9bd9e8bce9fedb
--- /dev/null
+++ b/patches.kzm9g/0185-ARM-mach-shmobile-sh73a0-PSTR-32-bit-access-fix.patch
@@ -0,0 +1,34 @@
+From 0a9ecd90d97895db2561a1dbaa0d106b293c52e0 Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Mon, 30 Jan 2012 11:03:49 +0900
+Subject: ARM: mach-shmobile: sh73a0 PSTR 32-bit access fix
+
+Convert the sh73a0 SMP code to use 32-bit PSTR access.
+
+This fixes wakeup from deep sleep for sh73a0 secondary CPUs.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 689189fb014203965ed89833d8d5566424540c9d)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/smp-sh73a0.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
+index be1ade7..55d58c5 100644
+--- a/arch/arm/mach-shmobile/smp-sh73a0.c
++++ b/arch/arm/mach-shmobile/smp-sh73a0.c
+@@ -79,7 +79,7 @@ int __cpuinit sh73a0_boot_secondary(unsigned int cpu)
+ /* enable cache coherency */
+ modify_scu_cpu_psr(0, 3 << (cpu * 8));
+
+- if (((__raw_readw(__io(PSTR)) >> (4 * cpu)) & 3) == 3)
++ if (((__raw_readl(__io(PSTR)) >> (4 * cpu)) & 3) == 3)
+ __raw_writel(1 << cpu, __io(WUPCR)); /* wake up */
+ else
+ __raw_writel(1 << cpu, __io(SRESCR)); /* reset */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0186-ARM-mach-shmobile-sh73a0-sh_clk_ops-rename.patch b/patches.kzm9g/0186-ARM-mach-shmobile-sh73a0-sh_clk_ops-rename.patch
new file mode 100644
index 00000000000000..85ca1f56af2f27
--- /dev/null
+++ b/patches.kzm9g/0186-ARM-mach-shmobile-sh73a0-sh_clk_ops-rename.patch
@@ -0,0 +1,77 @@
+From f60efe916f290bb106e6578b3653af1f253f2dc6 Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Wed, 29 Feb 2012 22:16:52 +0900
+Subject: ARM: mach-shmobile: sh73a0 sh_clk_ops rename
+
+Convert sh73a0 to use sh_clk_ops.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 7bcda508bfd9715c1a6a0589107c8c9d508f732e)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-sh73a0.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
+index 4d8d140..41f8293 100644
+--- a/arch/arm/mach-shmobile/clock-sh73a0.c
++++ b/arch/arm/mach-shmobile/clock-sh73a0.c
+@@ -88,7 +88,7 @@ static unsigned long div2_recalc(struct clk *clk)
+ return clk->parent->rate / 2;
+ }
+
+-static struct clk_ops div2_clk_ops = {
++static struct sh_clk_ops div2_clk_ops = {
+ .recalc = div2_recalc,
+ };
+
+@@ -97,7 +97,7 @@ static unsigned long div7_recalc(struct clk *clk)
+ return clk->parent->rate / 7;
+ }
+
+-static struct clk_ops div7_clk_ops = {
++static struct sh_clk_ops div7_clk_ops = {
+ .recalc = div7_recalc,
+ };
+
+@@ -106,7 +106,7 @@ static unsigned long div13_recalc(struct clk *clk)
+ return clk->parent->rate / 13;
+ }
+
+-static struct clk_ops div13_clk_ops = {
++static struct sh_clk_ops div13_clk_ops = {
+ .recalc = div13_recalc,
+ };
+
+@@ -122,7 +122,7 @@ static struct clk extal2_div2_clk = {
+ .parent = &sh73a0_extal2_clk,
+ };
+
+-static struct clk_ops main_clk_ops = {
++static struct sh_clk_ops main_clk_ops = {
+ .recalc = followparent_recalc,
+ };
+
+@@ -155,7 +155,7 @@ static unsigned long pll_recalc(struct clk *clk)
+ return clk->parent->rate * mult;
+ }
+
+-static struct clk_ops pll_clk_ops = {
++static struct sh_clk_ops pll_clk_ops = {
+ .recalc = pll_recalc,
+ };
+
+@@ -437,7 +437,7 @@ static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
+ return 0;
+ }
+
+-static struct clk_ops dsiphy_clk_ops = {
++static struct sh_clk_ops dsiphy_clk_ops = {
+ .recalc = dsiphy_recalc,
+ .round_rate = dsiphy_round_rate,
+ .set_rate = dsiphy_set_rate,
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0187-ARM-mach-shmobile-sh73a0-map_io-and-init_early-updat.patch b/patches.kzm9g/0187-ARM-mach-shmobile-sh73a0-map_io-and-init_early-updat.patch
new file mode 100644
index 00000000000000..6f774b9048f285
--- /dev/null
+++ b/patches.kzm9g/0187-ARM-mach-shmobile-sh73a0-map_io-and-init_early-updat.patch
@@ -0,0 +1,129 @@
+From c46683358d9052c0bfb2388c2f046aeb20d3716b Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Wed, 29 Feb 2012 21:37:27 +0900
+Subject: ARM: mach-shmobile: sh73a0 map_io and init_early update
+
+Update the sh73a0 SoC and the AG5EVM and Kota2 boards to make use
+of the functions sh73a0_map_io() and sh73a0_add_early_devices().
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 50e15c34f0072324fee9faaae71b129e8b419913)
+
+Conflicts:
+
+ arch/arm/mach-shmobile/board-ag5evm.c
+ arch/arm/mach-shmobile/board-kota2.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-ag5evm.c | 24 +-----------------------
+ arch/arm/mach-shmobile/include/mach/common.h | 1 +
+ arch/arm/mach-shmobile/setup-sh73a0.c | 22 ++++++++++++++++++++++
+ 3 files changed, 24 insertions(+), 23 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
+index 430c723..7f50dab 100644
+--- a/arch/arm/mach-shmobile/board-ag5evm.c
++++ b/arch/arm/mach-shmobile/board-ag5evm.c
+@@ -46,7 +46,6 @@
+ #include <mach/common.h>
+ #include <asm/mach-types.h>
+ #include <asm/mach/arch.h>
+-#include <asm/mach/map.h>
+ #include <asm/mach/time.h>
+ #include <asm/hardware/gic.h>
+ #include <asm/hardware/cache-l2x0.h>
+@@ -424,27 +423,6 @@ static struct platform_device *ag5evm_devices[] __initdata = {
+ &sdhi1_device,
+ };
+
+-static struct map_desc ag5evm_io_desc[] __initdata = {
+- /* create a 1:1 entity map for 0xe6xxxxxx
+- * used by CPGA, INTC and PFC.
+- */
+- {
+- .virtual = 0xe6000000,
+- .pfn = __phys_to_pfn(0xe6000000),
+- .length = 256 << 20,
+- .type = MT_DEVICE_NONSHARED
+- },
+-};
+-
+-static void __init ag5evm_map_io(void)
+-{
+- iotable_init(ag5evm_io_desc, ARRAY_SIZE(ag5evm_io_desc));
+-
+- /* setup early devices and console here as well */
+- sh73a0_add_early_devices();
+- shmobile_setup_console();
+-}
+-
+ #define DSI0PHYCR 0xe615006c
+
+ static void __init ag5evm_init(void)
+@@ -570,7 +548,7 @@ struct sys_timer ag5evm_timer = {
+ };
+
+ MACHINE_START(AG5EVM, "ag5evm")
+- .map_io = ag5evm_map_io,
++ .map_io = sh73a0_map_io,
+ .init_irq = sh73a0_init_irq,
+ .handle_irq = shmobile_handle_irq_gic,
+ .init_machine = ag5evm_init,
+diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
+index 6ccc1a5..c77b3a1 100644
+--- a/arch/arm/mach-shmobile/include/mach/common.h
++++ b/arch/arm/mach-shmobile/include/mach/common.h
+@@ -42,6 +42,7 @@ extern struct clk sh7372_extal1_clk;
+ extern struct clk sh7372_extal2_clk;
+
+ extern void sh73a0_init_irq(void);
++extern void sh73a0_map_io(void);
+ extern void sh73a0_add_early_devices(void);
+ extern void sh73a0_add_standard_devices(void);
+ extern void sh73a0_clock_init(void);
+diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
+index 7bf740e..ce9d5c8 100644
+--- a/arch/arm/mach-shmobile/setup-sh73a0.c
++++ b/arch/arm/mach-shmobile/setup-sh73a0.c
+@@ -33,9 +33,28 @@
+ #include <mach/hardware.h>
+ #include <mach/irqs.h>
+ #include <mach/sh73a0.h>
++#include <mach/common.h>
+ #include <asm/mach-types.h>
++#include <asm/mach/map.h>
+ #include <asm/mach/arch.h>
+
++static struct map_desc sh73a0_io_desc[] __initdata = {
++ /* create a 1:1 entity map for 0xe6xxxxxx
++ * used by CPGA, INTC and PFC.
++ */
++ {
++ .virtual = 0xe6000000,
++ .pfn = __phys_to_pfn(0xe6000000),
++ .length = 256 << 20,
++ .type = MT_DEVICE_NONSHARED
++ },
++};
++
++void __init sh73a0_map_io(void)
++{
++ iotable_init(sh73a0_io_desc, ARRAY_SIZE(sh73a0_io_desc));
++}
++
+ static struct plat_sci_port scif0_platform_data = {
+ .mapbase = 0xe6c40000,
+ .flags = UPF_BOOT_AUTOCONF,
+@@ -672,4 +691,7 @@ void __init sh73a0_add_early_devices(void)
+ {
+ early_platform_add_devices(sh73a0_early_devices,
+ ARRAY_SIZE(sh73a0_early_devices));
++
++ /* setup early console here as well */
++ shmobile_setup_console();
+ }
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0188-ARM-mach-shmobile-sh73a0-AG5EVM-and-Kota2-timer-rewo.patch b/patches.kzm9g/0188-ARM-mach-shmobile-sh73a0-AG5EVM-and-Kota2-timer-rewo.patch
new file mode 100644
index 00000000000000..eddd543811fe87
--- /dev/null
+++ b/patches.kzm9g/0188-ARM-mach-shmobile-sh73a0-AG5EVM-and-Kota2-timer-rewo.patch
@@ -0,0 +1,95 @@
+From c646dee2f2e54015d3930520d89364374e2b86ec Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Tue, 6 Mar 2012 17:36:45 +0900
+Subject: ARM: mach-shmobile: sh73a0, AG5EVM and Kota2 timer rework
+
+Move the SoC specific timer code from AG5EVM and Kota2
+to sh73a0 setup code. This makes is possible to share
+the SoC specific timer code across boards and it also
+removes the need for a board specific timer structure.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 3be26fdba82a2ae8ed568ab5d4a0a2e252f18b13)
+
+Conflicts:
+
+ arch/arm/mach-shmobile/board-kota2.c
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-ag5evm.c | 14 +-------------
+ arch/arm/mach-shmobile/setup-sh73a0.c | 10 ++++++++++
+ 2 files changed, 11 insertions(+), 13 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
+index 7f50dab..5c2fa46 100644
+--- a/arch/arm/mach-shmobile/board-ag5evm.c
++++ b/arch/arm/mach-shmobile/board-ag5evm.c
+@@ -46,7 +46,6 @@
+ #include <mach/common.h>
+ #include <asm/mach-types.h>
+ #include <asm/mach/arch.h>
+-#include <asm/mach/time.h>
+ #include <asm/hardware/gic.h>
+ #include <asm/hardware/cache-l2x0.h>
+ #include <asm/traps.h>
+@@ -536,21 +535,10 @@ static void __init ag5evm_init(void)
+ platform_add_devices(ag5evm_devices, ARRAY_SIZE(ag5evm_devices));
+ }
+
+-static void __init ag5evm_timer_init(void)
+-{
+- sh73a0_clock_init();
+- shmobile_timer.init();
+- return;
+-}
+-
+-struct sys_timer ag5evm_timer = {
+- .init = ag5evm_timer_init,
+-};
+-
+ MACHINE_START(AG5EVM, "ag5evm")
+ .map_io = sh73a0_map_io,
+ .init_irq = sh73a0_init_irq,
+ .handle_irq = shmobile_handle_irq_gic,
+ .init_machine = ag5evm_init,
+- .timer = &ag5evm_timer,
++ .timer = &shmobile_timer,
+ MACHINE_END
+diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
+index ce9d5c8..5bebffc 100644
+--- a/arch/arm/mach-shmobile/setup-sh73a0.c
++++ b/arch/arm/mach-shmobile/setup-sh73a0.c
+@@ -37,6 +37,7 @@
+ #include <asm/mach-types.h>
+ #include <asm/mach/map.h>
+ #include <asm/mach/arch.h>
++#include <asm/mach/time.h>
+
+ static struct map_desc sh73a0_io_desc[] __initdata = {
+ /* create a 1:1 entity map for 0xe6xxxxxx
+@@ -687,6 +688,12 @@ void __init sh73a0_add_standard_devices(void)
+ ARRAY_SIZE(sh73a0_late_devices));
+ }
+
++static void __init sh73a0_earlytimer_init(void)
++{
++ sh73a0_clock_init();
++ shmobile_earlytimer_init();
++}
++
+ void __init sh73a0_add_early_devices(void)
+ {
+ early_platform_add_devices(sh73a0_early_devices,
+@@ -694,4 +701,7 @@ void __init sh73a0_add_early_devices(void)
+
+ /* setup early console here as well */
+ shmobile_setup_console();
++
++ /* override timer setup with soc-specific code */
++ shmobile_timer.init = sh73a0_earlytimer_init;
+ }
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0189-ARM-mach-shmobile-sh73a0-add-MMC-data-pin-pull-up.patch b/patches.kzm9g/0189-ARM-mach-shmobile-sh73a0-add-MMC-data-pin-pull-up.patch
new file mode 100644
index 00000000000000..3b19b6c94a84c8
--- /dev/null
+++ b/patches.kzm9g/0189-ARM-mach-shmobile-sh73a0-add-MMC-data-pin-pull-up.patch
@@ -0,0 +1,130 @@
+From 9cdeaf23e42138066404492c82f3c7b1f0d1de64 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 10 Nov 2011 18:44:24 -0800
+Subject: ARM: mach-shmobile: sh73a0: add MMC data pin pull-up
+
+This patch adds MMC data pin pull-up option for pfc-sh73a0.c,
+and select it on ag5evm board.
+The MMC read/write will be error without this patch.
+
+Cc: Takashi YOSHII <takashi.yoshii.zj@renesas.com>
+Tested-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Paul Mundt <lethal@linux-sh.org>
+(cherry picked from commit 052008edf31383f866b2ec1b12604fc411c2d986)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-ag5evm.c | 16 ++++++-------
+ arch/arm/mach-shmobile/include/mach/sh73a0.h | 8 +++++++
+ arch/arm/mach-shmobile/pfc-sh73a0.c | 34 ++++++++++++++++++++++++++++
+ 3 files changed, 50 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
+index 5c2fa46..6574235 100644
+--- a/arch/arm/mach-shmobile/board-ag5evm.c
++++ b/arch/arm/mach-shmobile/board-ag5evm.c
+@@ -463,14 +463,14 @@ static void __init ag5evm_init(void)
+ /* enable MMCIF */
+ gpio_request(GPIO_FN_MMCCLK0, NULL);
+ gpio_request(GPIO_FN_MMCCMD0_PU, NULL);
+- gpio_request(GPIO_FN_MMCD0_0, NULL);
+- gpio_request(GPIO_FN_MMCD0_1, NULL);
+- gpio_request(GPIO_FN_MMCD0_2, NULL);
+- gpio_request(GPIO_FN_MMCD0_3, NULL);
+- gpio_request(GPIO_FN_MMCD0_4, NULL);
+- gpio_request(GPIO_FN_MMCD0_5, NULL);
+- gpio_request(GPIO_FN_MMCD0_6, NULL);
+- gpio_request(GPIO_FN_MMCD0_7, NULL);
++ gpio_request(GPIO_FN_MMCD0_0_PU, NULL);
++ gpio_request(GPIO_FN_MMCD0_1_PU, NULL);
++ gpio_request(GPIO_FN_MMCD0_2_PU, NULL);
++ gpio_request(GPIO_FN_MMCD0_3_PU, NULL);
++ gpio_request(GPIO_FN_MMCD0_4_PU, NULL);
++ gpio_request(GPIO_FN_MMCD0_5_PU, NULL);
++ gpio_request(GPIO_FN_MMCD0_6_PU, NULL);
++ gpio_request(GPIO_FN_MMCD0_7_PU, NULL);
+ gpio_request(GPIO_PORT208, NULL); /* Reset */
+ gpio_direction_output(GPIO_PORT208, 1);
+
+diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h
+index 8567d65..cad5757 100644
+--- a/arch/arm/mach-shmobile/include/mach/sh73a0.h
++++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h
+@@ -470,6 +470,14 @@ enum {
+ GPIO_FN_SDHICMD2_PU,
+ GPIO_FN_MMCCMD0_PU,
+ GPIO_FN_MMCCMD1_PU,
++ GPIO_FN_MMCD0_0_PU,
++ GPIO_FN_MMCD0_1_PU,
++ GPIO_FN_MMCD0_2_PU,
++ GPIO_FN_MMCD0_3_PU,
++ GPIO_FN_MMCD0_4_PU,
++ GPIO_FN_MMCD0_5_PU,
++ GPIO_FN_MMCD0_6_PU,
++ GPIO_FN_MMCD0_7_PU,
+ GPIO_FN_FSIACK_PU,
+ GPIO_FN_FSIAILR_PU,
+ GPIO_FN_FSIAIBT_PU,
+diff --git a/arch/arm/mach-shmobile/pfc-sh73a0.c b/arch/arm/mach-shmobile/pfc-sh73a0.c
+index cf7c7bb..e05634c 100644
+--- a/arch/arm/mach-shmobile/pfc-sh73a0.c
++++ b/arch/arm/mach-shmobile/pfc-sh73a0.c
+@@ -496,6 +496,14 @@ enum {
+ SDHICMD2_PU_MARK,
+ MMCCMD0_PU_MARK,
+ MMCCMD1_PU_MARK,
++ MMCD0_0_PU_MARK,
++ MMCD0_1_PU_MARK,
++ MMCD0_2_PU_MARK,
++ MMCD0_3_PU_MARK,
++ MMCD0_4_PU_MARK,
++ MMCD0_5_PU_MARK,
++ MMCD0_6_PU_MARK,
++ MMCD0_7_PU_MARK,
+ FSIBISLD_PU_MARK,
+ FSIACK_PU_MARK,
+ FSIAILR_PU_MARK,
+@@ -1510,6 +1518,24 @@ static pinmux_enum_t pinmux_data[] = {
+ MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCCMD1_PU_MARK, PORT297_FN2, PORT297_IN_PU,
+ MSEL4CR_MSEL15_1),
++
++ PINMUX_DATA(MMCD0_0_PU_MARK,
++ PORT271_FN1, PORT271_IN_PU, MSEL4CR_MSEL15_0),
++ PINMUX_DATA(MMCD0_1_PU_MARK,
++ PORT272_FN1, PORT272_IN_PU, MSEL4CR_MSEL15_0),
++ PINMUX_DATA(MMCD0_2_PU_MARK,
++ PORT273_FN1, PORT273_IN_PU, MSEL4CR_MSEL15_0),
++ PINMUX_DATA(MMCD0_3_PU_MARK,
++ PORT274_FN1, PORT274_IN_PU, MSEL4CR_MSEL15_0),
++ PINMUX_DATA(MMCD0_4_PU_MARK,
++ PORT275_FN1, PORT275_IN_PU, MSEL4CR_MSEL15_0),
++ PINMUX_DATA(MMCD0_5_PU_MARK,
++ PORT276_FN1, PORT276_IN_PU, MSEL4CR_MSEL15_0),
++ PINMUX_DATA(MMCD0_6_PU_MARK,
++ PORT277_FN1, PORT277_IN_PU, MSEL4CR_MSEL15_0),
++ PINMUX_DATA(MMCD0_7_PU_MARK,
++ PORT278_FN1, PORT278_IN_PU, MSEL4CR_MSEL15_0),
++
+ PINMUX_DATA(FSIBISLD_PU_MARK, PORT39_FN1, PORT39_IN_PU),
+ PINMUX_DATA(FSIACK_PU_MARK, PORT49_FN1, PORT49_IN_PU),
+ PINMUX_DATA(FSIAILR_PU_MARK, PORT50_FN5, PORT50_IN_PU),
+@@ -2181,6 +2207,14 @@ static struct pinmux_gpio pinmux_gpios[] = {
+ GPIO_FN(SDHICMD2_PU),
+ GPIO_FN(MMCCMD0_PU),
+ GPIO_FN(MMCCMD1_PU),
++ GPIO_FN(MMCD0_0_PU),
++ GPIO_FN(MMCD0_1_PU),
++ GPIO_FN(MMCD0_2_PU),
++ GPIO_FN(MMCD0_3_PU),
++ GPIO_FN(MMCD0_4_PU),
++ GPIO_FN(MMCD0_5_PU),
++ GPIO_FN(MMCD0_6_PU),
++ GPIO_FN(MMCD0_7_PU),
+ GPIO_FN(FSIACK_PU),
+ GPIO_FN(FSIAILR_PU),
+ GPIO_FN(FSIAIBT_PU),
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0190-ARM-Update-mach-types.patch b/patches.kzm9g/0190-ARM-Update-mach-types.patch
new file mode 100644
index 00000000000000..ddd8004441b3bb
--- /dev/null
+++ b/patches.kzm9g/0190-ARM-Update-mach-types.patch
@@ -0,0 +1,640 @@
+From cfb81e862a2f3eca3aa5225ed4a103da16ae27c4 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@arm.linux.org.uk>
+Date: Thu, 26 Apr 2012 08:44:25 +0100
+Subject: ARM: Update mach-types
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+(cherry picked from commit d098bc7d58ebda22a6554b6c9df1056802d9900f)
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/tools/mach-types | 505 +++++++++++++++++++++++++---------------------
+ 1 file changed, 271 insertions(+), 234 deletions(-)
+
+diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
+index f9c9f33..2997e56 100644
+--- a/arch/arm/tools/mach-types
++++ b/arch/arm/tools/mach-types
+@@ -16,7 +16,7 @@
+ # are merged into mainline or have been edited in the machine database
+ # within the last 12 months. References to machine_is_NAME() do not count!
+ #
+-# Last update: Tue Dec 6 11:07:38 2011
++# Last update: Thu Apr 26 08:44:23 2012
+ #
+ # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
+ #
+@@ -205,6 +205,7 @@ omap_fsample MACH_OMAP_FSAMPLE OMAP_FSAMPLE 970
+ snapper_cl15 MACH_SNAPPER_CL15 SNAPPER_CL15 986
+ omap_palmz71 MACH_OMAP_PALMZ71 OMAP_PALMZ71 993
+ smdk2412 MACH_SMDK2412 SMDK2412 1009
++bkde303 MACH_BKDE303 BKDE303 1021
+ smdk2413 MACH_SMDK2413 SMDK2413 1022
+ aml_m5900 MACH_AML_M5900 AML_M5900 1024
+ balloon3 MACH_BALLOON3 BALLOON3 1029
+@@ -381,8 +382,6 @@ davinci_da850_evm MACH_DAVINCI_DA850_EVM DAVINCI_DA850_EVM 2157
+ at91sam9g10ek MACH_AT91SAM9G10EK AT91SAM9G10EK 2159
+ omap_4430sdp MACH_OMAP_4430SDP OMAP_4430SDP 2160
+ magx_zn5 MACH_MAGX_ZN5 MAGX_ZN5 2162
+-btmavb101 MACH_BTMAVB101 BTMAVB101 2172
+-btmawb101 MACH_BTMAWB101 BTMAWB101 2173
+ tx25 MACH_TX25 TX25 2177
+ omap3_torpedo MACH_OMAP3_TORPEDO OMAP3_TORPEDO 2178
+ anw6410 MACH_ANW6410 ANW6410 2183
+@@ -397,7 +396,6 @@ net2big_v2 MACH_NET2BIG_V2 NET2BIG_V2 2204
+ net5big_v2 MACH_NET5BIG_V2 NET5BIG_V2 2206
+ inetspace_v2 MACH_INETSPACE_V2 INETSPACE_V2 2208
+ at91sam9g45ekes MACH_AT91SAM9G45EKES AT91SAM9G45EKES 2212
+-pc7302 MACH_PC7302 PC7302 2220
+ spear600 MACH_SPEAR600 SPEAR600 2236
+ spear300 MACH_SPEAR300 SPEAR300 2237
+ lilly1131 MACH_LILLY1131 LILLY1131 2239
+@@ -407,7 +405,6 @@ d2net MACH_D2NET D2NET 2282
+ bigdisk MACH_BIGDISK BIGDISK 2283
+ at91sam9g20ek_2mmc MACH_AT91SAM9G20EK_2MMC AT91SAM9G20EK_2MMC 2288
+ bcmring MACH_BCMRING BCMRING 2289
+-dp6xx MACH_DP6XX DP6XX 2302
+ mahimahi MACH_MAHIMAHI MAHIMAHI 2304
+ smdk6442 MACH_SMDK6442 SMDK6442 2324
+ openrd_base MACH_OPENRD_BASE OPENRD_BASE 2325
+@@ -444,8 +441,6 @@ mx28evk MACH_MX28EVK MX28EVK 2531
+ smartq5 MACH_SMARTQ5 SMARTQ5 2534
+ davinci_dm6467tevm MACH_DAVINCI_DM6467TEVM DAVINCI_DM6467TEVM 2548
+ mxt_td60 MACH_MXT_TD60 MXT_TD60 2550
+-riot_bei2 MACH_RIOT_BEI2 RIOT_BEI2 2576
+-riot_x37 MACH_RIOT_X37 RIOT_X37 2578
+ pca101 MACH_PCA101 PCA101 2595
+ capc7117 MACH_CAPC7117 CAPC7117 2612
+ icontrol MACH_ICONTROL ICONTROL 2624
+@@ -460,7 +455,6 @@ spear320 MACH_SPEAR320 SPEAR320 2661
+ aquila MACH_AQUILA AQUILA 2676
+ esata_sheevaplug MACH_ESATA_SHEEVAPLUG ESATA_SHEEVAPLUG 2678
+ msm7x30_surf MACH_MSM7X30_SURF MSM7X30_SURF 2679
+-ea2478devkit MACH_EA2478DEVKIT EA2478DEVKIT 2683
+ terastation_wxl MACH_TERASTATION_WXL TERASTATION_WXL 2697
+ msm7x25_surf MACH_MSM7X25_SURF MSM7X25_SURF 2703
+ msm7x25_ffa MACH_MSM7X25_FFA MSM7X25_FFA 2704
+@@ -479,8 +473,6 @@ wbd222 MACH_WBD222 WBD222 2753
+ msm8x60_surf MACH_MSM8X60_SURF MSM8X60_SURF 2755
+ msm8x60_sim MACH_MSM8X60_SIM MSM8X60_SIM 2756
+ tcc8000_sdk MACH_TCC8000_SDK TCC8000_SDK 2758
+-nanos MACH_NANOS NANOS 2759
+-stamp9g45 MACH_STAMP9G45 STAMP9G45 2761
+ cns3420vb MACH_CNS3420VB CNS3420VB 2776
+ omap4_panda MACH_OMAP4_PANDA OMAP4_PANDA 2791
+ ti8168evm MACH_TI8168EVM TI8168EVM 2800
+@@ -490,12 +482,9 @@ eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35SD EUKREA_CPUIMX35SD 2821
+ eukrea_cpuimx51sd MACH_EUKREA_CPUIMX51SD EUKREA_CPUIMX51SD 2822
+ eukrea_cpuimx51 MACH_EUKREA_CPUIMX51 EUKREA_CPUIMX51 2823
+ smdkc210 MACH_SMDKC210 SMDKC210 2838
+-pca102 MACH_PCA102 PCA102 2843
++pcaal1 MACH_PCAAL1 PCAAL1 2843
+ t5325 MACH_T5325 T5325 2846
+ income MACH_INCOME INCOME 2849
+-vvbox_sdorig2 MACH_VVBOX_SDORIG2 VVBOX_SDORIG2 2857
+-vvbox_sdlite2 MACH_VVBOX_SDLITE2 VVBOX_SDLITE2 2858
+-vvbox_sdpro4 MACH_VVBOX_SDPRO4 VVBOX_SDPRO4 2859
+ mx257sx MACH_MX257SX MX257SX 2861
+ goni MACH_GONI GONI 2862
+ bv07 MACH_BV07 BV07 2882
+@@ -504,6 +493,7 @@ devixp MACH_DEVIXP DEVIXP 2885
+ miccpt MACH_MICCPT MICCPT 2886
+ mic256 MACH_MIC256 MIC256 2887
+ u5500 MACH_U5500 U5500 2890
++pov15hd MACH_POV15HD POV15HD 2910
+ linkstation_lschl MACH_LINKSTATION_LSCHL LINKSTATION_LSCHL 2913
+ smdkv310 MACH_SMDKV310 SMDKV310 2925
+ wm8505_7in_netbook MACH_WM8505_7IN_NETBOOK WM8505_7IN_NETBOOK 2928
+@@ -537,243 +527,24 @@ trimslice MACH_TRIMSLICE TRIMSLICE 3209
+ mackerel MACH_MACKEREL MACKEREL 3211
+ kaen MACH_KAEN KAEN 3217
+ nokia_rm680 MACH_NOKIA_RM680 NOKIA_RM680 3220
+-dm6446_adbox MACH_DM6446_ADBOX DM6446_ADBOX 3226
+-quad_salsa MACH_QUAD_SALSA QUAD_SALSA 3227
+-abb_gma_1_1 MACH_ABB_GMA_1_1 ABB_GMA_1_1 3228
+-svcid MACH_SVCID SVCID 3229
+ msm8960_sim MACH_MSM8960_SIM MSM8960_SIM 3230
+ msm8960_rumi3 MACH_MSM8960_RUMI3 MSM8960_RUMI3 3231
+-icon_g MACH_ICON_G ICON_G 3232
+-mb3 MACH_MB3 MB3 3233
+ gsia18s MACH_GSIA18S GSIA18S 3234
+-pivicc MACH_PIVICC PIVICC 3235
+-pcm048 MACH_PCM048 PCM048 3236
+-dds MACH_DDS DDS 3237
+-chalten_xa1 MACH_CHALTEN_XA1 CHALTEN_XA1 3238
+-ts48xx MACH_TS48XX TS48XX 3239
+-tonga2_tfttimer MACH_TONGA2_TFTTIMER TONGA2_TFTTIMER 3240
+-whistler MACH_WHISTLER WHISTLER 3241
+-asl_phoenix MACH_ASL_PHOENIX ASL_PHOENIX 3242
+-at91sam9263otlite MACH_AT91SAM9263OTLITE AT91SAM9263OTLITE 3243
+-ddplug MACH_DDPLUG DDPLUG 3244
+-d2plug MACH_D2PLUG D2PLUG 3245
+-kzm9d MACH_KZM9D KZM9D 3246
+-verdi_lte MACH_VERDI_LTE VERDI_LTE 3247
+-nanozoom MACH_NANOZOOM NANOZOOM 3248
+-dm3730_som_lv MACH_DM3730_SOM_LV DM3730_SOM_LV 3249
+-dm3730_torpedo MACH_DM3730_TORPEDO DM3730_TORPEDO 3250
+-anchovy MACH_ANCHOVY ANCHOVY 3251
+-re2rev20 MACH_RE2REV20 RE2REV20 3253
+-re2rev21 MACH_RE2REV21 RE2REV21 3254
+-cns21xx MACH_CNS21XX CNS21XX 3255
+-rider MACH_RIDER RIDER 3257
+-nsk330 MACH_NSK330 NSK330 3258
+-cns2133evb MACH_CNS2133EVB CNS2133EVB 3259
+-z3_816x_mod MACH_Z3_816X_MOD Z3_816X_MOD 3260
+-z3_814x_mod MACH_Z3_814X_MOD Z3_814X_MOD 3261
+-beect MACH_BEECT BEECT 3262
+-dma_thunderbug MACH_DMA_THUNDERBUG DMA_THUNDERBUG 3263
+-omn_at91sam9g20 MACH_OMN_AT91SAM9G20 OMN_AT91SAM9G20 3264
+-mx25_e2s_uc MACH_MX25_E2S_UC MX25_E2S_UC 3265
+-mione MACH_MIONE MIONE 3266
+-top9000_tcu MACH_TOP9000_TCU TOP9000_TCU 3267
+-top9000_bsl MACH_TOP9000_BSL TOP9000_BSL 3268
+-kingdom MACH_KINGDOM KINGDOM 3269
+-armadillo460 MACH_ARMADILLO460 ARMADILLO460 3270
+-lq2 MACH_LQ2 LQ2 3271
+-sweda_tms2 MACH_SWEDA_TMS2 SWEDA_TMS2 3272
+ mx53_loco MACH_MX53_LOCO MX53_LOCO 3273
+-acer_a8 MACH_ACER_A8 ACER_A8 3275
+-acer_gauguin MACH_ACER_GAUGUIN ACER_GAUGUIN 3276
+-guppy MACH_GUPPY GUPPY 3277
+-mx61_ard MACH_MX61_ARD MX61_ARD 3278
+ tx53 MACH_TX53 TX53 3279
+-omapl138_case_a3 MACH_OMAPL138_CASE_A3 OMAPL138_CASE_A3 3280
+-uemd MACH_UEMD UEMD 3281
+-ccwmx51mut MACH_CCWMX51MUT CCWMX51MUT 3282
+-rockhopper MACH_ROCKHOPPER ROCKHOPPER 3283
+ encore MACH_ENCORE ENCORE 3284
+-hkdkc100 MACH_HKDKC100 HKDKC100 3285
+-ts42xx MACH_TS42XX TS42XX 3286
+-aebl MACH_AEBL AEBL 3287
+ wario MACH_WARIO WARIO 3288
+-gfs_spm MACH_GFS_SPM GFS_SPM 3289
+ cm_t3730 MACH_CM_T3730 CM_T3730 3290
+-isc3 MACH_ISC3 ISC3 3291
+-rascal MACH_RASCAL RASCAL 3292
+ hrefv60 MACH_HREFV60 HREFV60 3293
+-tpt_2_0 MACH_TPT_2_0 TPT_2_0 3294
+-splendor MACH_SPLENDOR SPLENDOR 3296
+-msm8x60_qt MACH_MSM8X60_QT MSM8X60_QT 3298
+-htc_hd_mini MACH_HTC_HD_MINI HTC_HD_MINI 3299
+-athene MACH_ATHENE ATHENE 3300
+-deep_r_ek_1 MACH_DEEP_R_EK_1 DEEP_R_EK_1 3301
+-vivow_ct MACH_VIVOW_CT VIVOW_CT 3302
+-nery_1000 MACH_NERY_1000 NERY_1000 3303
+-rfl109145_ssrv MACH_RFL109145_SSRV RFL109145_SSRV 3304
+-nmh MACH_NMH NMH 3305
+-wn802t MACH_WN802T WN802T 3306
+-dragonet MACH_DRAGONET DRAGONET 3307
+-at91sam9263desk16l MACH_AT91SAM9263DESK16L AT91SAM9263DESK16L 3309
+-bcmhana_sv MACH_BCMHANA_SV BCMHANA_SV 3310
+-bcmhana_tablet MACH_BCMHANA_TABLET BCMHANA_TABLET 3311
+-koi MACH_KOI KOI 3312
+-ts4800 MACH_TS4800 TS4800 3313
+-tqma9263 MACH_TQMA9263 TQMA9263 3314
+-holiday MACH_HOLIDAY HOLIDAY 3315
+-pcats_overlay MACH_PCATS_OVERLAY PCATS_OVERLAY 3317
+-hwgw6410 MACH_HWGW6410 HWGW6410 3318
+-shenzhou MACH_SHENZHOU SHENZHOU 3319
+-cwme9210 MACH_CWME9210 CWME9210 3320
+-cwme9210js MACH_CWME9210JS CWME9210JS 3321
+-colibri_tegra2 MACH_COLIBRI_TEGRA2 COLIBRI_TEGRA2 3323
+-w21 MACH_W21 W21 3324
+-polysat1 MACH_POLYSAT1 POLYSAT1 3325
+-dataway MACH_DATAWAY DATAWAY 3326
+-cobral138 MACH_COBRAL138 COBRAL138 3327
+-roverpcs8 MACH_ROVERPCS8 ROVERPCS8 3328
+-marvelc MACH_MARVELC MARVELC 3329
+-navefihid MACH_NAVEFIHID NAVEFIHID 3330
+-dm365_cv100 MACH_DM365_CV100 DM365_CV100 3331
+-able MACH_ABLE ABLE 3332
+-legacy MACH_LEGACY LEGACY 3333
+-icong MACH_ICONG ICONG 3334
+-rover_g8 MACH_ROVER_G8 ROVER_G8 3335
+-t5388p MACH_T5388P T5388P 3336
+-dingo MACH_DINGO DINGO 3337
+-goflexhome MACH_GOFLEXHOME GOFLEXHOME 3338
+-lanreadyfn511 MACH_LANREADYFN511 LANREADYFN511 3340
+-omap3_baia MACH_OMAP3_BAIA OMAP3_BAIA 3341
+-omap3smartdisplay MACH_OMAP3SMARTDISPLAY OMAP3SMARTDISPLAY 3342
+-xilinx MACH_XILINX XILINX 3343
+-a2f MACH_A2F A2F 3344
+-sky25 MACH_SKY25 SKY25 3345
+-ccmx53 MACH_CCMX53 CCMX53 3346
+-ccmx53js MACH_CCMX53JS CCMX53JS 3347
+-ccwmx53 MACH_CCWMX53 CCWMX53 3348
+-ccwmx53js MACH_CCWMX53JS CCWMX53JS 3349
+-frisms MACH_FRISMS FRISMS 3350
+-msm7x27a_ffa MACH_MSM7X27A_FFA MSM7X27A_FFA 3351
+-msm7x27a_surf MACH_MSM7X27A_SURF MSM7X27A_SURF 3352
+-msm7x27a_rumi3 MACH_MSM7X27A_RUMI3 MSM7X27A_RUMI3 3353
+-dimmsam9g20 MACH_DIMMSAM9G20 DIMMSAM9G20 3354
+-dimm_imx28 MACH_DIMM_IMX28 DIMM_IMX28 3355
+-amk_a4 MACH_AMK_A4 AMK_A4 3356
+-gnet_sgme MACH_GNET_SGME GNET_SGME 3357
+-shooter_u MACH_SHOOTER_U SHOOTER_U 3358
+-vmx53 MACH_VMX53 VMX53 3359
+-rhino MACH_RHINO RHINO 3360
+ armlex4210 MACH_ARMLEX4210 ARMLEX4210 3361
+-swarcoextmodem MACH_SWARCOEXTMODEM SWARCOEXTMODEM 3362
+ snowball MACH_SNOWBALL SNOWBALL 3363
+-pcm049 MACH_PCM049 PCM049 3364
+-vigor MACH_VIGOR VIGOR 3365
+-oslo_amundsen MACH_OSLO_AMUNDSEN OSLO_AMUNDSEN 3366
+-gsl_diamond MACH_GSL_DIAMOND GSL_DIAMOND 3367
+-cv2201 MACH_CV2201 CV2201 3368
+-cv2202 MACH_CV2202 CV2202 3369
+-cv2203 MACH_CV2203 CV2203 3370
+-vit_ibox MACH_VIT_IBOX VIT_IBOX 3371
+-dm6441_esp MACH_DM6441_ESP DM6441_ESP 3372
+-at91sam9x5ek MACH_AT91SAM9X5EK AT91SAM9X5EK 3373
+-libra MACH_LIBRA LIBRA 3374
+-easycrrh MACH_EASYCRRH EASYCRRH 3375
+-tripel MACH_TRIPEL TRIPEL 3376
+-endian_mini MACH_ENDIAN_MINI ENDIAN_MINI 3377
+ xilinx_ep107 MACH_XILINX_EP107 XILINX_EP107 3378
+ nuri MACH_NURI NURI 3379
+-janus MACH_JANUS JANUS 3380
+-ddnas MACH_DDNAS DDNAS 3381
+-tag MACH_TAG TAG 3382
+-tagw MACH_TAGW TAGW 3383
+-nitrogen_vm_imx51 MACH_NITROGEN_VM_IMX51 NITROGEN_VM_IMX51 3384
+-viprinet MACH_VIPRINET VIPRINET 3385
+-bockw MACH_BOCKW BOCKW 3386
+-eva2000 MACH_EVA2000 EVA2000 3387
+-steelyard MACH_STEELYARD STEELYARD 3388
+-nsslsboard MACH_NSSLSBOARD NSSLSBOARD 3392
+-geneva_b5 MACH_GENEVA_B5 GENEVA_B5 3393
+-spear1340 MACH_SPEAR1340 SPEAR1340 3394
+-rexmas MACH_REXMAS REXMAS 3395
+-msm8960_cdp MACH_MSM8960_CDP MSM8960_CDP 3396
+-msm8960_fluid MACH_MSM8960_FLUID MSM8960_FLUID 3398
+-msm8960_apq MACH_MSM8960_APQ MSM8960_APQ 3399
+-helios_v2 MACH_HELIOS_V2 HELIOS_V2 3400
+-mif10p MACH_MIF10P MIF10P 3401
+-iam28 MACH_IAM28 IAM28 3402
+-picasso MACH_PICASSO PICASSO 3403
+-mr301a MACH_MR301A MR301A 3404
+-notle MACH_NOTLE NOTLE 3405
+-eelx2 MACH_EELX2 EELX2 3406
+-moon MACH_MOON MOON 3407
+-ruby MACH_RUBY RUBY 3408
+-goldengate MACH_GOLDENGATE GOLDENGATE 3409
+-ctbu_gen2 MACH_CTBU_GEN2 CTBU_GEN2 3410
+-kmp_am17_01 MACH_KMP_AM17_01 KMP_AM17_01 3411
+ wtplug MACH_WTPLUG WTPLUG 3412
+-mx27su2 MACH_MX27SU2 MX27SU2 3413
+-nb31 MACH_NB31 NB31 3414
+-hjsdu MACH_HJSDU HJSDU 3415
+-td3_rev1 MACH_TD3_REV1 TD3_REV1 3416
+-eag_ci4000 MACH_EAG_CI4000 EAG_CI4000 3417
+-net5big_nand_v2 MACH_NET5BIG_NAND_V2 NET5BIG_NAND_V2 3418
+-cpx2 MACH_CPX2 CPX2 3419
+-net2big_nand_v2 MACH_NET2BIG_NAND_V2 NET2BIG_NAND_V2 3420
+-ecuv5 MACH_ECUV5 ECUV5 3421
+-hsgx6d MACH_HSGX6D HSGX6D 3422
+-dawad7 MACH_DAWAD7 DAWAD7 3423
+-sam9repeater MACH_SAM9REPEATER SAM9REPEATER 3424
+-gt_i5700 MACH_GT_I5700 GT_I5700 3425
+-ctera_plug_c2 MACH_CTERA_PLUG_C2 CTERA_PLUG_C2 3426
+-marvelct MACH_MARVELCT MARVELCT 3427
+-ag11005 MACH_AG11005 AG11005 3428
+-vangogh MACH_VANGOGH VANGOGH 3430
+-matrix505 MACH_MATRIX505 MATRIX505 3431
+-oce_nigma MACH_OCE_NIGMA OCE_NIGMA 3432
+-t55 MACH_T55 T55 3433
+-bio3k MACH_BIO3K BIO3K 3434
+-expressct MACH_EXPRESSCT EXPRESSCT 3435
+-cardhu MACH_CARDHU CARDHU 3436
+-aruba MACH_ARUBA ARUBA 3437
+-bonaire MACH_BONAIRE BONAIRE 3438
+-nuc700evb MACH_NUC700EVB NUC700EVB 3439
+-nuc710evb MACH_NUC710EVB NUC710EVB 3440
+-nuc740evb MACH_NUC740EVB NUC740EVB 3441
+-nuc745evb MACH_NUC745EVB NUC745EVB 3442
+-transcede MACH_TRANSCEDE TRANSCEDE 3443
+-mora MACH_MORA MORA 3444
+-nda_evm MACH_NDA_EVM NDA_EVM 3445
+-timu MACH_TIMU TIMU 3446
+-expressh MACH_EXPRESSH EXPRESSH 3447
+ veridis_a300 MACH_VERIDIS_A300 VERIDIS_A300 3448
+-dm368_leopard MACH_DM368_LEOPARD DM368_LEOPARD 3449
+-omap_mcop MACH_OMAP_MCOP OMAP_MCOP 3450
+-tritip MACH_TRITIP TRITIP 3451
+-sm1k MACH_SM1K SM1K 3452
+-monch MACH_MONCH MONCH 3453
+-curacao MACH_CURACAO CURACAO 3454
+ origen MACH_ORIGEN ORIGEN 3455
+-epc10 MACH_EPC10 EPC10 3456
+-sgh_i740 MACH_SGH_I740 SGH_I740 3457
+-tuna MACH_TUNA TUNA 3458
+-mx51_tulip MACH_MX51_TULIP MX51_TULIP 3459
+-mx51_aster7 MACH_MX51_ASTER7 MX51_ASTER7 3460
+-acro37xbrd MACH_ACRO37XBRD ACRO37XBRD 3461
+-elke MACH_ELKE ELKE 3462
+-sbc6000x MACH_SBC6000X SBC6000X 3463
+-r1801e MACH_R1801E R1801E 3464
+-h1600 MACH_H1600 H1600 3465
+-mini210 MACH_MINI210 MINI210 3466
+-mini8168 MACH_MINI8168 MINI8168 3467
+-pc7308 MACH_PC7308 PC7308 3468
+-kmm2m01 MACH_KMM2M01 KMM2M01 3470
+-mx51erebus MACH_MX51EREBUS MX51EREBUS 3471
+ wm8650refboard MACH_WM8650REFBOARD WM8650REFBOARD 3472
+-tuxrail MACH_TUXRAIL TUXRAIL 3473
+-arthur MACH_ARTHUR ARTHUR 3474
+-doorboy MACH_DOORBOY DOORBOY 3475
+ xarina MACH_XARINA XARINA 3476
+-roverx7 MACH_ROVERX7 ROVERX7 3477
+ sdvr MACH_SDVR SDVR 3478
+ acer_maya MACH_ACER_MAYA ACER_MAYA 3479
+ pico MACH_PICO PICO 3480
+@@ -999,6 +770,7 @@ promwad_jade MACH_PROMWAD_JADE PROMWAD_JADE 3708
+ amp MACH_AMP AMP 3709
+ gnet_amp MACH_GNET_AMP GNET_AMP 3710
+ toques MACH_TOQUES TOQUES 3711
++apx4devkit MACH_APX4DEVKIT APX4DEVKIT 3712
+ dct_storm MACH_DCT_STORM DCT_STORM 3713
+ owl MACH_OWL OWL 3715
+ cogent_csb1741 MACH_COGENT_CSB1741 COGENT_CSB1741 3716
+@@ -1063,7 +835,6 @@ shelter MACH_SHELTER SHELTER 3778
+ omap3_devkit8500 MACH_OMAP3_DEVKIT8500 OMAP3_DEVKIT8500 3779
+ edgetd MACH_EDGETD EDGETD 3780
+ copperyard MACH_COPPERYARD COPPERYARD 3781
+-edge MACH_EDGE EDGE 3782
+ edge_u MACH_EDGE_U EDGE_U 3783
+ edge_td MACH_EDGE_TD EDGE_TD 3784
+ wdss MACH_WDSS WDSS 3785
+@@ -1169,3 +940,269 @@ elite_ulk MACH_ELITE_ULK ELITE_ULK 3888
+ pov2 MACH_POV2 POV2 3889
+ ipod_touch_2g MACH_IPOD_TOUCH_2G IPOD_TOUCH_2G 3890
+ da850_pqab MACH_DA850_PQAB DA850_PQAB 3891
++fermi MACH_FERMI FERMI 3892
++ccardwmx28 MACH_CCARDWMX28 CCARDWMX28 3893
++ccardmx28 MACH_CCARDMX28 CCARDMX28 3894
++fs20_fcm2050 MACH_FS20_FCM2050 FS20_FCM2050 3895
++kinetis MACH_KINETIS KINETIS 3896
++kai MACH_KAI KAI 3897
++bcthb2 MACH_BCTHB2 BCTHB2 3898
++inels3_cu MACH_INELS3_CU INELS3_CU 3899
++da850_apollo MACH_DA850_APOLLO DA850_APOLLO 3901
++tracnas MACH_TRACNAS TRACNAS 3902
++mityarm335x MACH_MITYARM335X MITYARM335X 3903
++xcgz7x MACH_XCGZ7X XCGZ7X 3904
++cubox MACH_CUBOX CUBOX 3905
++terminator MACH_TERMINATOR TERMINATOR 3906
++eye03 MACH_EYE03 EYE03 3907
++kota3 MACH_KOTA3 KOTA3 3908
++pscpe MACH_PSCPE PSCPE 3910
++akt1100 MACH_AKT1100 AKT1100 3911
++pcaaxl2 MACH_PCAAXL2 PCAAXL2 3912
++primodd_ct MACH_PRIMODD_CT PRIMODD_CT 3913
++nsbc MACH_NSBC NSBC 3914
++meson2_skt MACH_MESON2_SKT MESON2_SKT 3915
++meson2_ref MACH_MESON2_REF MESON2_REF 3916
++ccardwmx28js MACH_CCARDWMX28JS CCARDWMX28JS 3917
++ccardmx28js MACH_CCARDMX28JS CCARDMX28JS 3918
++indico MACH_INDICO INDICO 3919
++msm8960dt MACH_MSM8960DT MSM8960DT 3920
++primods MACH_PRIMODS PRIMODS 3921
++beluga_m1388 MACH_BELUGA_M1388 BELUGA_M1388 3922
++primotd MACH_PRIMOTD PRIMOTD 3923
++varan_master MACH_VARAN_MASTER VARAN_MASTER 3924
++primodd MACH_PRIMODD PRIMODD 3925
++jetduo MACH_JETDUO JETDUO 3926
++mx53_umobo MACH_MX53_UMOBO MX53_UMOBO 3927
++trats MACH_TRATS TRATS 3928
++starcraft MACH_STARCRAFT STARCRAFT 3929
++qseven_tegra2 MACH_QSEVEN_TEGRA2 QSEVEN_TEGRA2 3930
++lichee_sun4i_devbd MACH_LICHEE_SUN4I_DEVBD LICHEE_SUN4I_DEVBD 3931
++movenow MACH_MOVENOW MOVENOW 3932
++golf_u MACH_GOLF_U GOLF_U 3933
++msm7627a_evb MACH_MSM7627A_EVB MSM7627A_EVB 3934
++rambo MACH_RAMBO RAMBO 3935
++golfu MACH_GOLFU GOLFU 3936
++mango310 MACH_MANGO310 MANGO310 3937
++dns343 MACH_DNS343 DNS343 3938
++var_som_om44 MACH_VAR_SOM_OM44 VAR_SOM_OM44 3939
++naon MACH_NAON NAON 3940
++vp4000 MACH_VP4000 VP4000 3941
++impcard MACH_IMPCARD IMPCARD 3942
++smoovcam MACH_SMOOVCAM SMOOVCAM 3943
++cobham3725 MACH_COBHAM3725 COBHAM3725 3944
++cobham3730 MACH_COBHAM3730 COBHAM3730 3945
++cobham3703 MACH_COBHAM3703 COBHAM3703 3946
++quetzal MACH_QUETZAL QUETZAL 3947
++apq8064_cdp MACH_APQ8064_CDP APQ8064_CDP 3948
++apq8064_mtp MACH_APQ8064_MTP APQ8064_MTP 3949
++apq8064_fluid MACH_APQ8064_FLUID APQ8064_FLUID 3950
++apq8064_liquid MACH_APQ8064_LIQUID APQ8064_LIQUID 3951
++mango210 MACH_MANGO210 MANGO210 3952
++mango100 MACH_MANGO100 MANGO100 3953
++mango24 MACH_MANGO24 MANGO24 3954
++mango64 MACH_MANGO64 MANGO64 3955
++nsa320 MACH_NSA320 NSA320 3956
++elv_ccu2 MACH_ELV_CCU2 ELV_CCU2 3957
++triton_x00 MACH_TRITON_X00 TRITON_X00 3958
++triton_1500_2000 MACH_TRITON_1500_2000 TRITON_1500_2000 3959
++pogoplugv4 MACH_POGOPLUGV4 POGOPLUGV4 3960
++venus_cl MACH_VENUS_CL VENUS_CL 3961
++vulcano_g20 MACH_VULCANO_G20 VULCANO_G20 3962
++sgs_i9100 MACH_SGS_I9100 SGS_I9100 3963
++stsv2 MACH_STSV2 STSV2 3964
++csb1724 MACH_CSB1724 CSB1724 3965
++omapl138_lcdk MACH_OMAPL138_LCDK OMAPL138_LCDK 3966
++pvd_mx25 MACH_PVD_MX25 PVD_MX25 3968
++meson6_skt MACH_MESON6_SKT MESON6_SKT 3969
++meson6_ref MACH_MESON6_REF MESON6_REF 3970
++pxm MACH_PXM PXM 3971
++pogoplugv3 MACH_POGOPLUGV3 POGOPLUGV3 3973
++mlp89626 MACH_MLP89626 MLP89626 3974
++iomegahmndce MACH_IOMEGAHMNDCE IOMEGAHMNDCE 3975
++pogoplugv3pci MACH_POGOPLUGV3PCI POGOPLUGV3PCI 3976
++bntv250 MACH_BNTV250 BNTV250 3977
++mx53_qseven MACH_MX53_QSEVEN MX53_QSEVEN 3978
++gtl_it1100 MACH_GTL_IT1100 GTL_IT1100 3979
++mx6q_sabresd MACH_MX6Q_SABRESD MX6Q_SABRESD 3980
++mt4 MACH_MT4 MT4 3981
++jumbo_d MACH_JUMBO_D JUMBO_D 3982
++jumbo_i MACH_JUMBO_I JUMBO_I 3983
++fs20_dmp MACH_FS20_DMP FS20_DMP 3984
++dns320 MACH_DNS320 DNS320 3985
++mx28bacos MACH_MX28BACOS MX28BACOS 3986
++tl80 MACH_TL80 TL80 3987
++polatis_nic_1001 MACH_POLATIS_NIC_1001 POLATIS_NIC_1001 3988
++tely MACH_TELY TELY 3989
++u8520 MACH_U8520 U8520 3990
++manta MACH_MANTA MANTA 3991
++mpq8064_cdp MACH_MPQ8064_CDP MPQ8064_CDP 3993
++mpq8064_dtv MACH_MPQ8064_DTV MPQ8064_DTV 3995
++dm368som MACH_DM368SOM DM368SOM 3996
++gprisb2 MACH_GPRISB2 GPRISB2 3997
++chammid MACH_CHAMMID CHAMMID 3998
++seoul2 MACH_SEOUL2 SEOUL2 3999
++omap4_nooktablet MACH_OMAP4_NOOKTABLET OMAP4_NOOKTABLET 4000
++aalto MACH_AALTO AALTO 4001
++metro MACH_METRO METRO 4002
++cydm3730 MACH_CYDM3730 CYDM3730 4003
++tqma53 MACH_TQMA53 TQMA53 4004
++msm7627a_qrd3 MACH_MSM7627A_QRD3 MSM7627A_QRD3 4005
++mx28_canby MACH_MX28_CANBY MX28_CANBY 4006
++tiger MACH_TIGER TIGER 4007
++pcats_9307_type_a MACH_PCATS_9307_TYPE_A PCATS_9307_TYPE_A 4008
++pcats_9307_type_o MACH_PCATS_9307_TYPE_O PCATS_9307_TYPE_O 4009
++pcats_9307_type_r MACH_PCATS_9307_TYPE_R PCATS_9307_TYPE_R 4010
++streamplug MACH_STREAMPLUG STREAMPLUG 4011
++icechicken_dev MACH_ICECHICKEN_DEV ICECHICKEN_DEV 4012
++hedgehog MACH_HEDGEHOG HEDGEHOG 4013
++yusend_obc MACH_YUSEND_OBC YUSEND_OBC 4014
++imxninja MACH_IMXNINJA IMXNINJA 4015
++omap4_jarod MACH_OMAP4_JAROD OMAP4_JAROD 4016
++eco5_pk MACH_ECO5_PK ECO5_PK 4017
++qj2440 MACH_QJ2440 QJ2440 4018
++mx6q_mercury MACH_MX6Q_MERCURY MX6Q_MERCURY 4019
++cm6810 MACH_CM6810 CM6810 4020
++omap4_torpedo MACH_OMAP4_TORPEDO OMAP4_TORPEDO 4021
++nsa310 MACH_NSA310 NSA310 4022
++tmx536 MACH_TMX536 TMX536 4023
++ktt20 MACH_KTT20 KTT20 4024
++dragonix MACH_DRAGONIX DRAGONIX 4025
++lungching MACH_LUNGCHING LUNGCHING 4026
++bulogics MACH_BULOGICS BULOGICS 4027
++mx535_sx MACH_MX535_SX MX535_SX 4028
++ngui3250 MACH_NGUI3250 NGUI3250 4029
++salutec_dac MACH_SALUTEC_DAC SALUTEC_DAC 4030
++loco MACH_LOCO LOCO 4031
++ctera_plug_usi MACH_CTERA_PLUG_USI CTERA_PLUG_USI 4032
++scepter MACH_SCEPTER SCEPTER 4033
++sga MACH_SGA SGA 4034
++p_81_j5 MACH_P_81_J5 P_81_J5 4035
++p_81_o4 MACH_P_81_O4 P_81_O4 4036
++msm8625_surf MACH_MSM8625_SURF MSM8625_SURF 4037
++carallon_shark MACH_CARALLON_SHARK CARALLON_SHARK 4038
++ordog MACH_ORDOG ORDOG 4040
++puente_io MACH_PUENTE_IO PUENTE_IO 4041
++msm8625_evb MACH_MSM8625_EVB MSM8625_EVB 4042
++ev_am1707 MACH_EV_AM1707 EV_AM1707 4043
++ev_am1707e2 MACH_EV_AM1707E2 EV_AM1707E2 4044
++ev_am3517e2 MACH_EV_AM3517E2 EV_AM3517E2 4045
++calabria MACH_CALABRIA CALABRIA 4046
++ev_imx287 MACH_EV_IMX287 EV_IMX287 4047
++erau MACH_ERAU ERAU 4048
++sichuan MACH_SICHUAN SICHUAN 4049
++davinci_da850 MACH_DAVINCI_DA850 DAVINCI_DA850 4051
++omap138_trunarc MACH_OMAP138_TRUNARC OMAP138_TRUNARC 4052
++bcm4761 MACH_BCM4761 BCM4761 4053
++picasso_e2 MACH_PICASSO_E2 PICASSO_E2 4054
++picasso_mf MACH_PICASSO_MF PICASSO_MF 4055
++miro MACH_MIRO MIRO 4056
++at91sam9g20ewon3 MACH_AT91SAM9G20EWON3 AT91SAM9G20EWON3 4057
++yoyo MACH_YOYO YOYO 4058
++windjkl MACH_WINDJKL WINDJKL 4059
++monarudo MACH_MONARUDO MONARUDO 4060
++batan MACH_BATAN BATAN 4061
++tadao MACH_TADAO TADAO 4062
++baso MACH_BASO BASO 4063
++mahon MACH_MAHON MAHON 4064
++villec2 MACH_VILLEC2 VILLEC2 4065
++asi1230 MACH_ASI1230 ASI1230 4066
++alaska MACH_ALASKA ALASKA 4067
++swarco_shdsl2 MACH_SWARCO_SHDSL2 SWARCO_SHDSL2 4068
++oxrtu MACH_OXRTU OXRTU 4069
++omap5_panda MACH_OMAP5_PANDA OMAP5_PANDA 4070
++c8000 MACH_C8000 C8000 4072
++bje_display3_5 MACH_BJE_DISPLAY3_5 BJE_DISPLAY3_5 4073
++picomod7 MACH_PICOMOD7 PICOMOD7 4074
++picocom5 MACH_PICOCOM5 PICOCOM5 4075
++qblissa8 MACH_QBLISSA8 QBLISSA8 4076
++armstonea8 MACH_ARMSTONEA8 ARMSTONEA8 4077
++netdcu14 MACH_NETDCU14 NETDCU14 4078
++at91sam9x5_epiphan MACH_AT91SAM9X5_EPIPHAN AT91SAM9X5_EPIPHAN 4079
++p2u MACH_P2U P2U 4080
++doris MACH_DORIS DORIS 4081
++j49 MACH_J49 J49 4082
++vdss2e MACH_VDSS2E VDSS2E 4083
++vc300 MACH_VC300 VC300 4084
++ns115_pad_test MACH_NS115_PAD_TEST NS115_PAD_TEST 4085
++ns115_pad_ref MACH_NS115_PAD_REF NS115_PAD_REF 4086
++ns115_phone_test MACH_NS115_PHONE_TEST NS115_PHONE_TEST 4087
++ns115_phone_ref MACH_NS115_PHONE_REF NS115_PHONE_REF 4088
++golfc MACH_GOLFC GOLFC 4089
++xerox_olympus MACH_XEROX_OLYMPUS XEROX_OLYMPUS 4090
++mx6sl_arm2 MACH_MX6SL_ARM2 MX6SL_ARM2 4091
++csb1701_csb1726 MACH_CSB1701_CSB1726 CSB1701_CSB1726 4092
++at91sam9xeek MACH_AT91SAM9XEEK AT91SAM9XEEK 4093
++ebv210 MACH_EBV210 EBV210 4094
++msm7627a_qrd7 MACH_MSM7627A_QRD7 MSM7627A_QRD7 4095
++svthin MACH_SVTHIN SVTHIN 4096
++duovero MACH_DUOVERO DUOVERO 4097
++chupacabra MACH_CHUPACABRA CHUPACABRA 4098
++scorpion MACH_SCORPION SCORPION 4099
++davinci_he_hmi10 MACH_DAVINCI_HE_HMI10 DAVINCI_HE_HMI10 4100
++topkick MACH_TOPKICK TOPKICK 4101
++m3_auguestrush MACH_M3_AUGUESTRUSH M3_AUGUESTRUSH 4102
++ipc335x MACH_IPC335X IPC335X 4103
++sun4i MACH_SUN4I SUN4I 4104
++imx233_olinuxino MACH_IMX233_OLINUXINO IMX233_OLINUXINO 4105
++k2_wl MACH_K2_WL K2_WL 4106
++k2_ul MACH_K2_UL K2_UL 4107
++k2_cl MACH_K2_CL K2_CL 4108
++minbari_w MACH_MINBARI_W MINBARI_W 4109
++minbari_m MACH_MINBARI_M MINBARI_M 4110
++k035 MACH_K035 K035 4111
++ariel MACH_ARIEL ARIEL 4112
++arielsaarc MACH_ARIELSAARC ARIELSAARC 4113
++arieldkb MACH_ARIELDKB ARIELDKB 4114
++armadillo810 MACH_ARMADILLO810 ARMADILLO810 4115
++tam335x MACH_TAM335X TAM335X 4116
++grouper MACH_GROUPER GROUPER 4117
++mpcsa21_9g20 MACH_MPCSA21_9G20 MPCSA21_9G20 4118
++m6u_cpu MACH_M6U_CPU M6U_CPU 4119
++davinci_dp10 MACH_DAVINCI_DP10 DAVINCI_DP10 4120
++ginkgo MACH_GINKGO GINKGO 4121
++cgt_qmx6 MACH_CGT_QMX6 CGT_QMX6 4122
++profpga MACH_PROFPGA PROFPGA 4123
++acfx100oc MACH_ACFX100OC ACFX100OC 4124
++acfx100nb MACH_ACFX100NB ACFX100NB 4125
++capricorn MACH_CAPRICORN CAPRICORN 4126
++pisces MACH_PISCES PISCES 4127
++aries MACH_ARIES ARIES 4128
++cancer MACH_CANCER CANCER 4129
++leo MACH_LEO LEO 4130
++virgo MACH_VIRGO VIRGO 4131
++sagittarius MACH_SAGITTARIUS SAGITTARIUS 4132
++devil MACH_DEVIL DEVIL 4133
++ballantines MACH_BALLANTINES BALLANTINES 4134
++omap3_procerusvpu MACH_OMAP3_PROCERUSVPU OMAP3_PROCERUSVPU 4135
++my27 MACH_MY27 MY27 4136
++sun6i MACH_SUN6I SUN6I 4137
++sun5i MACH_SUN5I SUN5I 4138
++mx512_mx MACH_MX512_MX MX512_MX 4139
++kzm9g MACH_KZM9G KZM9G 4140
++vdstbn MACH_VDSTBN VDSTBN 4141
++cfa10036 MACH_CFA10036 CFA10036 4142
++cfa10049 MACH_CFA10049 CFA10049 4143
++pcm051 MACH_PCM051 PCM051 4144
++vybrid_vf7xx MACH_VYBRID_VF7XX VYBRID_VF7XX 4145
++vybrid_vf6xx MACH_VYBRID_VF6XX VYBRID_VF6XX 4146
++vybrid_vf5xx MACH_VYBRID_VF5XX VYBRID_VF5XX 4147
++vybrid_vf4xx MACH_VYBRID_VF4XX VYBRID_VF4XX 4148
++aria_g25 MACH_ARIA_G25 ARIA_G25 4149
++bcm21553 MACH_BCM21553 BCM21553 4150
++smdk5410 MACH_SMDK5410 SMDK5410 4151
++lpc18xx MACH_LPC18XX LPC18XX 4152
++oratisparty MACH_ORATISPARTY ORATISPARTY 4153
++qseven MACH_QSEVEN QSEVEN 4154
++gmv_generic MACH_GMV_GENERIC GMV_GENERIC 4155
++th_link_eth MACH_TH_LINK_ETH TH_LINK_ETH 4156
++tn_muninn MACH_TN_MUNINN TN_MUNINN 4157
++rampage MACH_RAMPAGE RAMPAGE 4158
++visstrim_mv10 MACH_VISSTRIM_MV10 VISSTRIM_MV10 4159
++mx28_wilma MACH_MX28_WILMA MX28_WILMA 4164
++msm8625_ffa MACH_MSM8625_FFA MSM8625_FFA 4166
++vpu101 MACH_VPU101 VPU101 4167
++baileys MACH_BAILEYS BAILEYS 4169
++familybox MACH_FAMILYBOX FAMILYBOX 4170
++ensemble_mx35 MACH_ENSEMBLE_MX35 ENSEMBLE_MX35 4171
++sc_sps_1 MACH_SC_SPS_1 SC_SPS_1 4172
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0191-ARM-mach-shmobile-add-KZM-A9-GT-board-support.patch b/patches.kzm9g/0191-ARM-mach-shmobile-add-KZM-A9-GT-board-support.patch
new file mode 100644
index 00000000000000..5dc9d3b14ed7ab
--- /dev/null
+++ b/patches.kzm9g/0191-ARM-mach-shmobile-add-KZM-A9-GT-board-support.patch
@@ -0,0 +1,126 @@
+From c3845eb19812059fd44fb6a6993c5bef692ee796 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 10 Apr 2012 20:57:31 -0700
+Subject: ARM: mach-shmobile: add KZM-A9-GT board support
+
+This adds very basic KZM-A9-GT board (SH73a0) 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 5935278004610be17b89eab399d35ea0527bb6b2)
+
+Conflicts:
+
+ arch/arm/mach-shmobile/Kconfig
+ arch/arm/mach-shmobile/Makefile
+ arch/arm/mach-shmobile/board-kzm9g.c
+
+N.B: Not present in mainline yet
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/Kconfig | 5 +++
+ arch/arm/mach-shmobile/Makefile | 1 +
+ arch/arm/mach-shmobile/board-kzm9g.c | 60 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 66 insertions(+)
+ create mode 100644 arch/arm/mach-shmobile/board-kzm9g.c
+
+diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
+index 91a4f32..23be741 100644
+--- a/arch/arm/mach-shmobile/Kconfig
++++ b/arch/arm/mach-shmobile/Kconfig
+@@ -81,6 +81,11 @@ config MACH_ARMADILLO800EVA
+ select ARCH_REQUIRE_GPIOLIB
+ select SND_SOC_WM8978 if SND_SIMPLE_CARD
+
++config MACH_KZM9G
++ bool "KZM-A9-GT board"
++ depends on ARCH_SH73A0
++ select ARCH_REQUIRE_GPIOLIB
++
+ comment "SH-Mobile System Configuration"
+
+ config CPU_HAS_INTEVT
+diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
+index c599c5c..36bd37d 100644
+--- a/arch/arm/mach-shmobile/Makefile
++++ b/arch/arm/mach-shmobile/Makefile
+@@ -45,6 +45,7 @@ obj-$(CONFIG_MACH_AP4EVB) += board-ap4evb.o
+ obj-$(CONFIG_MACH_AG5EVM) += board-ag5evm.o
+ obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o
+ obj-$(CONFIG_MACH_ARMADILLO800EVA) += board-armadillo800eva.o
++obj-$(CONFIG_MACH_KZM9G) += board-kzm9g.o
+
+ # Framework support
+ obj-$(CONFIG_SMP) += $(smp-y)
+diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
+new file mode 100644
+index 0000000..a7f05f6
+--- /dev/null
++++ b/arch/arm/mach-shmobile/board-kzm9g.c
+@@ -0,0 +1,60 @@
++/*
++ * KZM-A9-GT board support
++ *
++ * 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/gpio.h>
++#include <linux/io.h>
++#include <linux/irq.h>
++#include <linux/platform_device.h>
++#include <mach/sh73a0.h>
++#include <mach/common.h>
++#include <asm/hardware/cache-l2x0.h>
++#include <asm/hardware/gic.h>
++#include <asm/mach-types.h>
++#include <asm/mach/arch.h>
++
++static struct platform_device *kzm_devices[] __initdata = {
++};
++
++static void __init kzm_init(void)
++{
++ sh73a0_pinmux_init();
++
++ /* enable SCIFA4 */
++ gpio_request(GPIO_FN_SCIFA4_TXD, NULL);
++ gpio_request(GPIO_FN_SCIFA4_RXD, NULL);
++ gpio_request(GPIO_FN_SCIFA4_RTS_, NULL);
++ gpio_request(GPIO_FN_SCIFA4_CTS_, NULL);
++
++#ifdef CONFIG_CACHE_L2X0
++ /* Early BRESP enable, Shared attribute override enable, 64K*8way */
++ l2x0_init(__io(0xf0100000), 0x40460000, 0x82000fff);
++#endif
++
++ sh73a0_add_standard_devices();
++ platform_add_devices(kzm_devices, ARRAY_SIZE(kzm_devices));
++}
++
++MACHINE_START(KZM9G, "kzm9g")
++ .map_io = sh73a0_map_io,
++ .init_early = sh73a0_add_early_devices,
++ .nr_irqs = NR_IRQS_LEGACY,
++ .init_irq = sh73a0_init_irq,
++ .handle_irq = gic_handle_irq,
++ .init_machine = kzm_init,
++ .timer = &shmobile_timer,
++MACHINE_END
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0192-ARM-mach-shmobile-kzm9g-add-defconfig.patch b/patches.kzm9g/0192-ARM-mach-shmobile-kzm9g-add-defconfig.patch
new file mode 100644
index 00000000000000..14a7dd42b1c4b0
--- /dev/null
+++ b/patches.kzm9g/0192-ARM-mach-shmobile-kzm9g-add-defconfig.patch
@@ -0,0 +1,155 @@
+From ed3eb21cec58c7403ba87eaf5b9a1fa79fc82432 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 10 Apr 2012 20:57:45 -0700
+Subject: ARM: mach-shmobile: kzm9g: 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 e9ea2fb38c9d5f8cb80e359cc853fb6449f3635a)
+
+N.B: Not present in mainline yet
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/configs/kzm9g_defconfig | 127 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 127 insertions(+)
+ create mode 100644 arch/arm/configs/kzm9g_defconfig
+
+diff --git a/arch/arm/configs/kzm9g_defconfig b/arch/arm/configs/kzm9g_defconfig
+new file mode 100644
+index 0000000..164c5d2
+--- /dev/null
++++ b/arch/arm/configs/kzm9g_defconfig
+@@ -0,0 +1,127 @@
++# CONFIG_ARM_PATCH_PHYS_VIRT is not set
++CONFIG_EXPERIMENTAL=y
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SYSVIPC=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++CONFIG_NAMESPACES=y
++# 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_NET_NS is not set
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_EMBEDDED=y
++CONFIG_SLAB=y
++CONFIG_MODULES=y
++CONFIG_MODULE_FORCE_LOAD=y
++CONFIG_MODULE_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_SH73A0=y
++CONFIG_MACH_KZM9G=y
++CONFIG_MEMORY_START=0x41000000
++CONFIG_MEMORY_SIZE=0x1f000000
++CONFIG_ARM_ERRATA_743622=y
++CONFIG_ARM_ERRATA_754322=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_PREEMPT=y
++CONFIG_AEABI=y
++# CONFIG_OABI_COMPAT is not set
++CONFIG_HIGHMEM=y
++CONFIG_ZBOOT_ROM_TEXT=0x0
++CONFIG_ZBOOT_ROM_BSS=0x0
++CONFIG_CMDLINE="console=tty0 console=ttySC4,115200 root=/dev/nfs ip=dhcp ignore_loglevel earlyprintk=serial"
++CONFIG_KEXEC=y
++CONFIG_VFP=y
++CONFIG_NEON=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_PM_RUNTIME=y
++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_IRDA=y
++CONFIG_SH_IRDA=y
++# CONFIG_WIRELESS is not set
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_SCSI=y
++CONFIG_BLK_DEV_SD=y
++CONFIG_NETDEVICES=y
++CONFIG_SMSC911X=y
++# CONFIG_WLAN is not set
++CONFIG_INPUT_SPARSEKMAP=y
++# CONFIG_INPUT_MOUSEDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_KEYBOARD_ATKBD is not set
++CONFIG_KEYBOARD_GPIO=y
++CONFIG_KEYBOARD_SH_KEYSC=y
++# CONFIG_INPUT_MOUSE is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++CONFIG_TOUCHSCREEN_ST1232=y
++# CONFIG_LEGACY_PTYS is not set
++CONFIG_SERIAL_SH_SCI=y
++CONFIG_SERIAL_SH_SCI_NR_UARTS=9
++CONFIG_SERIAL_SH_SCI_CONSOLE=y
++# CONFIG_HW_RANDOM is not set
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_SH_MOBILE=y
++CONFIG_POWER_SUPPLY=y
++# CONFIG_HWMON is not set
++CONFIG_FB=y
++CONFIG_FB_SH_MOBILE_LCDC=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++CONFIG_LOGO=y
++CONFIG_FB_SH_MOBILE_MERAM=y
++# CONFIG_HID_SUPPORT is not set
++CONFIG_USB=y
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_R8A66597_HCD=y
++CONFIG_USB_STORAGE=y
++CONFIG_MMC=y
++# CONFIG_MMC_BLOCK_BOUNCE is not set
++CONFIG_MMC_SDHI=y
++CONFIG_MMC_SH_MMCIF=y
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++CONFIG_RTC_CLASS=y
++CONFIG_DMADEVICES=y
++CONFIG_SH_DMAE=y
++CONFIG_ASYNC_TX_DMA=y
++CONFIG_STAGING=y
++# CONFIG_DNOTIFY is not set
++# CONFIG_INOTIFY_USER is not set
++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_MAGIC_SYSRQ=y
++CONFIG_DETECT_HUNG_TASK=y
++CONFIG_DEBUG_INFO=y
++# CONFIG_FTRACE is not set
++CONFIG_DEBUG_USER=y
++CONFIG_CRYPTO=y
++CONFIG_CRYPTO_CBC=y
++CONFIG_CRYPTO_MD5=y
++CONFIG_CRYPTO_DES=y
++CONFIG_CRC16=y
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0193-ARM-mach-shmobile-Invalidate-caches-when-booting-sec.patch b/patches.kzm9g/0193-ARM-mach-shmobile-Invalidate-caches-when-booting-sec.patch
new file mode 100644
index 00000000000000..b473444b3267d9
--- /dev/null
+++ b/patches.kzm9g/0193-ARM-mach-shmobile-Invalidate-caches-when-booting-sec.patch
@@ -0,0 +1,97 @@
+From 2a87f8d5cd1d9ca2c80e4dcdab9adff42185567d Mon Sep 17 00:00:00 2001
+From: Magnus Damm <damm@opensource.se>
+Date: Wed, 9 May 2012 16:24:59 +0900
+Subject: ARM / mach-shmobile: Invalidate caches when booting secondary cores
+
+Make sure L1 caches are invalidated when booting secondary
+cores. Needed to boot all mach-shmobile SMP systems that
+are using Cortex-A9 including sh73a0, r8a7779 and EMEV2.
+
+Thanks to imx and tegra guys for actual code.
+
+Signed-off-by: Magnus Damm <damm@opensource.se>
+Tested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
+(cherry picked from commit 5fab7b501bf29c08c5b01627b496b6b766bd0165)
+
+N.B: Not present in mainline yet
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/headsmp.S | 56 +++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 55 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S
+index 26079d9..75abb74 100644
+--- a/arch/arm/mach-shmobile/headsmp.S
++++ b/arch/arm/mach-shmobile/headsmp.S
+@@ -16,6 +16,59 @@
+
+ __INIT
+
++/* Cache invalidation nicked from arch/arm/mach-imx/head-v7.S, thanks!
++ *
++ * The secondary kernel init calls v7_flush_dcache_all before it enables
++ * the L1; however, the L1 comes out of reset in an undefined state, so
++ * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
++ * of cache lines with uninitialized data and uninitialized tags to get
++ * written out to memory, which does really unpleasant things to the main
++ * processor. We fix this by performing an invalidate, rather than a
++ * clean + invalidate, before jumping into the kernel.
++ *
++ * This funciton is cloned from arch/arm/mach-tegra/headsmp.S, and needs
++ * to be called for both secondary cores startup and primary core resume
++ * procedures. Ideally, it should be moved into arch/arm/mm/cache-v7.S.
++ */
++ENTRY(v7_invalidate_l1)
++ mov r0, #0
++ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
++ mcr p15, 2, r0, c0, c0, 0
++ mrc p15, 1, r0, c0, c0, 0
++
++ ldr r1, =0x7fff
++ and r2, r1, r0, lsr #13
++
++ ldr r1, =0x3ff
++
++ and r3, r1, r0, lsr #3 @ NumWays - 1
++ add r2, r2, #1 @ NumSets
++
++ and r0, r0, #0x7
++ add r0, r0, #4 @ SetShift
++
++ clz r1, r3 @ WayShift
++ add r4, r3, #1 @ NumWays
++1: sub r2, r2, #1 @ NumSets--
++ mov r3, r4 @ Temp = NumWays
++2: subs r3, r3, #1 @ Temp--
++ mov r5, r3, lsl r1
++ mov r6, r2, lsl r0
++ orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
++ mcr p15, 0, r5, c7, c6, 2
++ bgt 2b
++ cmp r2, #0
++ bgt 1b
++ dsb
++ isb
++ mov pc, lr
++ENDPROC(v7_invalidate_l1)
++
++ENTRY(shmobile_invalidate_start)
++ bl v7_invalidate_l1
++ b secondary_startup
++ENDPROC(shmobile_invalidate_start)
++
+ /*
+ * Reset vector for secondary CPUs.
+ * This will be mapped at address 0 by SBAR register.
+@@ -24,4 +77,5 @@
+ .align 12
+ ENTRY(shmobile_secondary_vector)
+ ldr pc, 1f
+-1: .long secondary_startup - PAGE_OFFSET + PLAT_PHYS_OFFSET
++1: .long shmobile_invalidate_start - PAGE_OFFSET + PLAT_PHYS_OFFSET
++ENDPROC(shmobile_secondary_vector)
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0194-ARM-mach-shmobile-kzm9g-enable-SMP-boot.patch b/patches.kzm9g/0194-ARM-mach-shmobile-kzm9g-enable-SMP-boot.patch
new file mode 100644
index 00000000000000..c1400e4c840887
--- /dev/null
+++ b/patches.kzm9g/0194-ARM-mach-shmobile-kzm9g-enable-SMP-boot.patch
@@ -0,0 +1,92 @@
+From 1b1b557076119efd097b7d294dd0a28b36e8842c Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Thu, 10 May 2012 00:10:29 -0700
+Subject: ARM: mach-shmobile: kzm9g: enable SMP boot
+
+Update the KZM9G defconfig and the code in platsmp.c to support SMP on
+the sh73a0 based KZM9G board. Also fix up the earlyprintk setting that
+was previously incorrect.
+
+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 1f3bcdd68cf4b27bddb128c401466c9fc7ba96bd)
+
+Conflicts:
+
+ arch/arm/mach-shmobile/platsmp.c
+
+N.B: Not present in mainline yet
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/configs/kzm9g_defconfig | 4 +++-
+ arch/arm/mach-shmobile/platsmp.c | 10 ++++++----
+ 2 files changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/arch/arm/configs/kzm9g_defconfig b/arch/arm/configs/kzm9g_defconfig
+index 164c5d2..de8712b 100644
+--- a/arch/arm/configs/kzm9g_defconfig
++++ b/arch/arm/configs/kzm9g_defconfig
+@@ -30,13 +30,15 @@ CONFIG_ARM_ERRATA_743622=y
+ CONFIG_ARM_ERRATA_754322=y
+ CONFIG_NO_HZ=y
+ CONFIG_HIGH_RES_TIMERS=y
++CONFIG_SMP=y
++CONFIG_SCHED_MC=y
+ CONFIG_PREEMPT=y
+ CONFIG_AEABI=y
+ # CONFIG_OABI_COMPAT is not set
+ CONFIG_HIGHMEM=y
+ CONFIG_ZBOOT_ROM_TEXT=0x0
+ CONFIG_ZBOOT_ROM_BSS=0x0
+-CONFIG_CMDLINE="console=tty0 console=ttySC4,115200 root=/dev/nfs ip=dhcp ignore_loglevel earlyprintk=serial"
++CONFIG_CMDLINE="console=tty0 console=ttySC4,115200 root=/dev/nfs ip=dhcp ignore_loglevel earlyprintk=sh-sci.4,115200"
+ CONFIG_KEXEC=y
+ CONFIG_VFP=y
+ CONFIG_NEON=y
+diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
+index f3888fe..2cc8930 100644
+--- a/arch/arm/mach-shmobile/platsmp.c
++++ b/arch/arm/mach-shmobile/platsmp.c
+@@ -21,9 +21,11 @@
+ #include <asm/mach-types.h>
+ #include <mach/common.h>
+
++#define is_sh73a0() (machine_is_ag5evm() || machine_is_kzm9g())
++
+ static unsigned int __init shmobile_smp_get_core_count(void)
+ {
+- if (machine_is_ag5evm())
++ if (is_sh73a0())
+ return sh73a0_get_core_count();
+
+ return 1;
+@@ -31,7 +33,7 @@ static unsigned int __init shmobile_smp_get_core_count(void)
+
+ static void __init shmobile_smp_prepare_cpus(void)
+ {
+- if (machine_is_ag5evm())
++ if (is_sh73a0())
+ sh73a0_smp_prepare_cpus();
+ }
+
+@@ -39,13 +41,13 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
+ {
+ trace_hardirqs_off();
+
+- if (machine_is_ag5evm())
++ if (is_sh73a0())
+ sh73a0_secondary_init(cpu);
+ }
+
+ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+ {
+- if (machine_is_ag5evm())
++ if (is_sh73a0())
+ return sh73a0_boot_secondary(cpu);
+
+ return -ENOSYS;
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0195-ARM-mach-shmobile-kzm9g-add-LCDC-support.patch b/patches.kzm9g/0195-ARM-mach-shmobile-kzm9g-add-LCDC-support.patch
new file mode 100644
index 00000000000000..35748e50b4e097
--- /dev/null
+++ b/patches.kzm9g/0195-ARM-mach-shmobile-kzm9g-add-LCDC-support.patch
@@ -0,0 +1,204 @@
+From 769707e6bbe540cf277c165031d34f12fdd38f13 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 10 Apr 2012 20:58:33 -0700
+Subject: ARM: mach-shmobile: kzm9g: add LCDC support
+
+AS3711 chip initalization is required for enabling LCDC backlight,
+but there is no driver for this chip.
+So, this patch sends its settings when boot.
+
+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>
+
+Conflicts:
+
+ arch/arm/mach-shmobile/board-kzm9g.c
+
+N.B: Not present in mainline yet
+
+Signed-off-by; Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-kzm9g.c | 144 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 144 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
+index a7f05f6..3e3da46 100644
+--- a/arch/arm/mach-shmobile/board-kzm9g.c
++++ b/arch/arm/mach-shmobile/board-kzm9g.c
+@@ -16,20 +16,133 @@
+ * 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/delay.h>
+ #include <linux/gpio.h>
+ #include <linux/io.h>
+ #include <linux/irq.h>
+ #include <linux/platform_device.h>
++#include <linux/videodev2.h>
++#include <mach/irqs.h>
+ #include <mach/sh73a0.h>
+ #include <mach/common.h>
+ #include <asm/hardware/cache-l2x0.h>
+ #include <asm/hardware/gic.h>
+ #include <asm/mach-types.h>
+ #include <asm/mach/arch.h>
++#include <video/sh_mobile_lcdc.h>
++
++/* LCDC */
++static struct fb_videomode kzm_lcdc_mode = {
++ .name = "WVGA Panel",
++ .xres = 800,
++ .yres = 480,
++ .left_margin = 220,
++ .right_margin = 110,
++ .hsync_len = 70,
++ .upper_margin = 20,
++ .lower_margin = 5,
++ .vsync_len = 5,
++ .sync = 0,
++};
++
++static struct sh_mobile_lcdc_info lcdc_info = {
++ .clock_source = LCDC_CLK_BUS,
++ .ch[0] = {
++ .chan = LCDC_CHAN_MAINLCD,
++ .fourcc = V4L2_PIX_FMT_RGB565,
++ .interface_type = RGB24,
++ .lcd_modes = &kzm_lcdc_mode,
++ .num_modes = 1,
++ .clock_divider = 5,
++ .flags = 0,
++ .panel_cfg = {
++ .width = 152,
++ .height = 91,
++ },
++ }
++};
++
++static struct resource lcdc_resources[] = {
++ [0] = {
++ .name = "LCDC",
++ .start = 0xfe940000,
++ .end = 0xfe943fff,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = intcs_evt2irq(0x580),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device lcdc_device = {
++ .name = "sh_mobile_lcdc_fb",
++ .num_resources = ARRAY_SIZE(lcdc_resources),
++ .resource = lcdc_resources,
++ .dev = {
++ .platform_data = &lcdc_info,
++ .coherent_dma_mask = ~0,
++ },
++};
+
+ static struct platform_device *kzm_devices[] __initdata = {
++ &lcdc_device,
+ };
+
++/*
++ * FIXME
++ *
++ * This is quick hack for enabling LCDC backlight
++ */
++static int __init as3711_enable_lcdc_backlight(void)
++{
++ struct i2c_adapter *a = i2c_get_adapter(0);
++ struct i2c_msg msg;
++ int i, ret;
++ __u8 magic[] = {
++ 0x40, 0x2a,
++ 0x43, 0x3c,
++ 0x44, 0x3c,
++ 0x45, 0x3c,
++ 0x54, 0x03,
++ 0x51, 0x00,
++ 0x51, 0x01,
++ 0xff, 0x00, /* wait */
++ 0x43, 0xf0,
++ 0x44, 0xf0,
++ 0x45, 0xf0,
++ };
++
++ if (!machine_is_kzm9g())
++ return 0;
++
++ if (!a)
++ return 0;
++
++ msg.addr = 0x40;
++ msg.len = 2;
++ msg.flags = 0;
++
++ for (i = 0; i < ARRAY_SIZE(magic); i += 2) {
++ msg.buf = magic + i;
++
++ if (0xff == msg.buf[0]) {
++ udelay(500);
++ continue;
++ }
++
++ ret = i2c_transfer(a, &msg, 1);
++ if (ret < 0) {
++ pr_err("i2c transfer fail\n");
++ break;
++ }
++ }
++
++ return 0;
++}
++device_initcall(as3711_enable_lcdc_backlight);
++
+ static void __init kzm_init(void)
+ {
+ sh73a0_pinmux_init();
+@@ -40,6 +153,37 @@ static void __init kzm_init(void)
+ gpio_request(GPIO_FN_SCIFA4_RTS_, NULL);
+ gpio_request(GPIO_FN_SCIFA4_CTS_, NULL);
+
++ /* LCDC */
++ gpio_request(GPIO_FN_LCDD23, NULL);
++ gpio_request(GPIO_FN_LCDD22, NULL);
++ gpio_request(GPIO_FN_LCDD21, NULL);
++ gpio_request(GPIO_FN_LCDD20, NULL);
++ gpio_request(GPIO_FN_LCDD19, NULL);
++ gpio_request(GPIO_FN_LCDD18, NULL);
++ gpio_request(GPIO_FN_LCDD17, NULL);
++ gpio_request(GPIO_FN_LCDD16, NULL);
++ gpio_request(GPIO_FN_LCDD15, NULL);
++ gpio_request(GPIO_FN_LCDD14, NULL);
++ gpio_request(GPIO_FN_LCDD13, NULL);
++ gpio_request(GPIO_FN_LCDD12, NULL);
++ gpio_request(GPIO_FN_LCDD11, NULL);
++ gpio_request(GPIO_FN_LCDD10, NULL);
++ gpio_request(GPIO_FN_LCDD9, NULL);
++ gpio_request(GPIO_FN_LCDD8, NULL);
++ gpio_request(GPIO_FN_LCDD7, NULL);
++ gpio_request(GPIO_FN_LCDD6, NULL);
++ gpio_request(GPIO_FN_LCDD5, NULL);
++ gpio_request(GPIO_FN_LCDD4, NULL);
++ gpio_request(GPIO_FN_LCDD3, NULL);
++ gpio_request(GPIO_FN_LCDD2, NULL);
++ gpio_request(GPIO_FN_LCDD1, NULL);
++ gpio_request(GPIO_FN_LCDD0, NULL);
++ gpio_request(GPIO_FN_LCDDISP, NULL);
++ gpio_request(GPIO_FN_LCDDCK, NULL);
++
++ gpio_request(GPIO_PORT222, NULL);
++ gpio_direction_output(GPIO_PORT222, 1);
++
+ #ifdef CONFIG_CACHE_L2X0
+ /* Early BRESP enable, Shared attribute override enable, 64K*8way */
+ l2x0_init(__io(0xf0100000), 0x40460000, 0x82000fff);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0196-ARM-mach-shmobile-kzm9g-add-ST1232-Touchscreen-suppo.patch b/patches.kzm9g/0196-ARM-mach-shmobile-kzm9g-add-ST1232-Touchscreen-suppo.patch
new file mode 100644
index 00000000000000..a01de3958ec6f4
--- /dev/null
+++ b/patches.kzm9g/0196-ARM-mach-shmobile-kzm9g-add-ST1232-Touchscreen-suppo.patch
@@ -0,0 +1,65 @@
+From ce9a312895c8fb5fc0115d5ed5f4434382d4ed8c Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Tue, 10 Apr 2012 20:58:45 -0700
+Subject: ARM: mach-shmobile: kzm9g: add ST1232 Touchscreen 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 3ab21c0e494efe064b425d48ac985cde5ee7f84b)
+
+N.B: Not present in mainline yet
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-kzm9g.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
+index 3e3da46..f6a0b4f 100644
+--- a/arch/arm/mach-shmobile/board-kzm9g.c
++++ b/arch/arm/mach-shmobile/board-kzm9g.c
+@@ -21,6 +21,7 @@
+ #include <linux/gpio.h>
+ #include <linux/io.h>
+ #include <linux/irq.h>
++#include <linux/i2c.h>
+ #include <linux/platform_device.h>
+ #include <linux/videodev2.h>
+ #include <mach/irqs.h>
+@@ -86,6 +87,13 @@ static struct platform_device lcdc_device = {
+ },
+ };
+
++static struct i2c_board_info i2c1_devices[] = {
++ {
++ I2C_BOARD_INFO("st1232-ts", 0x55),
++ .irq = intcs_evt2irq(0x300), /* IRQ8 */
++ },
++};
++
+ static struct platform_device *kzm_devices[] __initdata = {
+ &lcdc_device,
+ };
+@@ -184,11 +192,17 @@ static void __init kzm_init(void)
+ gpio_request(GPIO_PORT222, NULL);
+ gpio_direction_output(GPIO_PORT222, 1);
+
++ /* Touchscreen */
++ gpio_request(GPIO_PORT223, NULL); /* IRQ8 */
++ gpio_direction_input(GPIO_PORT223);
++
+ #ifdef CONFIG_CACHE_L2X0
+ /* Early BRESP enable, Shared attribute override enable, 64K*8way */
+ l2x0_init(__io(0xf0100000), 0x40460000, 0x82000fff);
+ #endif
+
++ i2c_register_board_info(1, i2c1_devices, ARRAY_SIZE(i2c1_devices));
++
+ sh73a0_add_standard_devices();
+ platform_add_devices(kzm_devices, ARRAY_SIZE(kzm_devices));
+ }
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0197-ARM-mach-shmobile-pfc-sh73a0-fixup-MSEL2CR-MSEL18-fo.patch b/patches.kzm9g/0197-ARM-mach-shmobile-pfc-sh73a0-fixup-MSEL2CR-MSEL18-fo.patch
new file mode 100644
index 00000000000000..2c262cfbe501ab
--- /dev/null
+++ b/patches.kzm9g/0197-ARM-mach-shmobile-pfc-sh73a0-fixup-MSEL2CR-MSEL18-fo.patch
@@ -0,0 +1,44 @@
+From 035b90a42dfd87de422594b3f28649d5d8473bbf Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 22 Apr 2012 23:52:48 -0700
+Subject: ARM: mach-shmobile: pfc-sh73a0: fixup MSEL2CR MSEL18 for I2C-3
+
+MSEL2CR MSEL18 should be 1 if I2C-3
+
+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 0abfeea3f3664f55f21691ac37e9570a60733d4a)
+
+N.B: Not present in mainline yet
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/pfc-sh73a0.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-shmobile/pfc-sh73a0.c b/arch/arm/mach-shmobile/pfc-sh73a0.c
+index e05634c..4a547b8 100644
+--- a/arch/arm/mach-shmobile/pfc-sh73a0.c
++++ b/arch/arm/mach-shmobile/pfc-sh73a0.c
+@@ -829,14 +829,14 @@ static pinmux_enum_t pinmux_data[] = {
+ PINMUX_DATA(PORT27_I2C_SCL2_MARK, PORT27_FN2, MSEL2CR_MSEL17_0,
+ MSEL2CR_MSEL16_1), \
+ PINMUX_DATA(PORT27_I2C_SCL3_MARK, PORT27_FN3, MSEL2CR_MSEL19_0,
+- MSEL2CR_MSEL18_0), \
++ MSEL2CR_MSEL18_1), \
+ PINMUX_DATA(MFG0_OUT1_MARK, PORT27_FN4), \
+ PINMUX_DATA(PORT27_IROUT_MARK, PORT27_FN7),
+ PINMUX_DATA(XDVFS2_MARK, PORT28_FN1), \
+ PINMUX_DATA(PORT28_I2C_SDA2_MARK, PORT28_FN2, MSEL2CR_MSEL17_0,
+ MSEL2CR_MSEL16_1), \
+ PINMUX_DATA(PORT28_I2C_SDA3_MARK, PORT28_FN3, MSEL2CR_MSEL19_0,
+- MSEL2CR_MSEL18_0), \
++ MSEL2CR_MSEL18_1), \
+ PINMUX_DATA(PORT28_TPU1TO1_MARK, PORT28_FN7),
+ PINMUX_DATA(SIM_RST_MARK, PORT29_FN1), \
+ PINMUX_DATA(PORT29_TPU1TO1_MARK, PORT29_FN4),
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0198-ARM-mach-shmobile-sh73a0.h-add-GPIO_NR.patch b/patches.kzm9g/0198-ARM-mach-shmobile-sh73a0.h-add-GPIO_NR.patch
new file mode 100644
index 00000000000000..16e18fa18327ac
--- /dev/null
+++ b/patches.kzm9g/0198-ARM-mach-shmobile-sh73a0.h-add-GPIO_NR.patch
@@ -0,0 +1,38 @@
+From 69ba92bca9d23c243e05e120711d7f08684b6ab6 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 22 Apr 2012 23:53:07 -0700
+Subject: ARM: mach-shmobile: sh73a0.h: add GPIO_NR
+
+GPIO_NR is added in order to clarify end of GPIO array.
+We can add extra GPIO from it.
+
+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 9f75dc78817e88353e37fab381b26e7e2d825f82)
+
+N.B: Not present in mainline yet
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/include/mach/sh73a0.h | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h
+index cad5757..ac75857 100644
+--- a/arch/arm/mach-shmobile/include/mach/sh73a0.h
++++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h
+@@ -482,6 +482,9 @@ enum {
+ GPIO_FN_FSIAILR_PU,
+ GPIO_FN_FSIAIBT_PU,
+ GPIO_FN_FSIAISLD_PU,
++
++ /* end of GPIO */
++ GPIO_NR,
+ };
+
+ /* DMA slave IDs */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0199-ARM-mach-shmobile-kzm9g-correct-screen-direction.patch b/patches.kzm9g/0199-ARM-mach-shmobile-kzm9g-correct-screen-direction.patch
new file mode 100644
index 00000000000000..4fee96b17089ab
--- /dev/null
+++ b/patches.kzm9g/0199-ARM-mach-shmobile-kzm9g-correct-screen-direction.patch
@@ -0,0 +1,40 @@
+From d2ff6b7cebae68d0d9214c3da5494392fc7fca86 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 22 Apr 2012 23:53:24 -0700
+Subject: ARM: mach-shmobile: kzm9g: correct screen direction
+
+The correct screen direction of KZM9G board needs
+PORT226/SC settings.
+
+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 d0e0f1d0aa08fc01530ce48dce490a4401d35a5d)
+
+N.B: Not present in mainline yet
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-kzm9g.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
+index f6a0b4f..5674147 100644
+--- a/arch/arm/mach-shmobile/board-kzm9g.c
++++ b/arch/arm/mach-shmobile/board-kzm9g.c
+@@ -189,8 +189,10 @@ static void __init kzm_init(void)
+ gpio_request(GPIO_FN_LCDDISP, NULL);
+ gpio_request(GPIO_FN_LCDDCK, NULL);
+
+- gpio_request(GPIO_PORT222, NULL);
++ gpio_request(GPIO_PORT222, NULL); /* LCDCDON */
++ gpio_request(GPIO_PORT226, NULL); /* SC */
+ gpio_direction_output(GPIO_PORT222, 1);
++ gpio_direction_output(GPIO_PORT226, 1);
+
+ /* Touchscreen */
+ gpio_request(GPIO_PORT223, NULL); /* IRQ8 */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0200-ARM-mach-shmobile-kzm9g-add-MMCIF-support.patch b/patches.kzm9g/0200-ARM-mach-shmobile-kzm9g-add-MMCIF-support.patch
new file mode 100644
index 00000000000000..9537d6f6f2dddc
--- /dev/null
+++ b/patches.kzm9g/0200-ARM-mach-shmobile-kzm9g-add-MMCIF-support.patch
@@ -0,0 +1,106 @@
+From 29e424292a84c4db615e64beff9ed6ee66b11ca5 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 22 Apr 2012 23:53:40 -0700
+Subject: ARM: mach-shmobile: kzm9g: 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 9cf94db3e4281bd6597d6bb585253106226882f3)
+
+Conflicts:
+
+ arch/arm/mach-shmobile/board-kzm9g.c
+
+N.B: Not present in mainline yet
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-kzm9g.c | 49 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 49 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
+index 5674147..5b486ae 100644
+--- a/arch/arm/mach-shmobile/board-kzm9g.c
++++ b/arch/arm/mach-shmobile/board-kzm9g.c
+@@ -22,6 +22,8 @@
+ #include <linux/io.h>
+ #include <linux/irq.h>
+ #include <linux/i2c.h>
++#include <linux/mmc/host.h>
++#include <linux/mmc/sh_mmcif.h>
+ #include <linux/platform_device.h>
+ #include <linux/videodev2.h>
+ #include <mach/irqs.h>
+@@ -87,6 +89,40 @@ static struct platform_device lcdc_device = {
+ },
+ };
+
++/* MMCIF */
++static struct resource sh_mmcif_resources[] = {
++ [0] = {
++ .name = "MMCIF",
++ .start = 0xe6bd0000,
++ .end = 0xe6bd00ff,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = gic_spi(141),
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ .start = gic_spi(140),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct sh_mmcif_plat_data sh_mmcif_platdata = {
++ .ocr = MMC_VDD_165_195,
++ .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
++};
++
++static struct platform_device mmc_device = {
++ .name = "sh_mmcif",
++ .dev = {
++ .dma_mask = NULL,
++ .coherent_dma_mask = 0xffffffff,
++ .platform_data = &sh_mmcif_platdata,
++ },
++ .num_resources = ARRAY_SIZE(sh_mmcif_resources),
++ .resource = sh_mmcif_resources,
++};
++
+ static struct i2c_board_info i2c1_devices[] = {
+ {
+ I2C_BOARD_INFO("st1232-ts", 0x55),
+@@ -96,6 +132,7 @@ static struct i2c_board_info i2c1_devices[] = {
+
+ static struct platform_device *kzm_devices[] __initdata = {
+ &lcdc_device,
++ &mmc_device,
+ };
+
+ /*
+@@ -198,6 +235,18 @@ static void __init kzm_init(void)
+ gpio_request(GPIO_PORT223, NULL); /* IRQ8 */
+ gpio_direction_input(GPIO_PORT223);
+
++ /* enable MMCIF */
++ gpio_request(GPIO_FN_MMCCLK0, NULL);
++ gpio_request(GPIO_FN_MMCCMD0_PU, NULL);
++ gpio_request(GPIO_FN_MMCD0_0_PU, NULL);
++ gpio_request(GPIO_FN_MMCD0_1_PU, NULL);
++ gpio_request(GPIO_FN_MMCD0_2_PU, NULL);
++ gpio_request(GPIO_FN_MMCD0_3_PU, NULL);
++ gpio_request(GPIO_FN_MMCD0_4_PU, NULL);
++ gpio_request(GPIO_FN_MMCD0_5_PU, NULL);
++ gpio_request(GPIO_FN_MMCD0_6_PU, NULL);
++ gpio_request(GPIO_FN_MMCD0_7_PU, NULL);
++
+ #ifdef CONFIG_CACHE_L2X0
+ /* Early BRESP enable, Shared attribute override enable, 64K*8way */
+ l2x0_init(__io(0xf0100000), 0x40460000, 0x82000fff);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0201-ARM-mach-shmobile-kzm9g-add-SDHI-support.patch b/patches.kzm9g/0201-ARM-mach-shmobile-kzm9g-add-SDHI-support.patch
new file mode 100644
index 00000000000000..07c931e3a0a8e0
--- /dev/null
+++ b/patches.kzm9g/0201-ARM-mach-shmobile-kzm9g-add-SDHI-support.patch
@@ -0,0 +1,110 @@
+From 27b7da290bfcf60ddaac4156bebd710b96cfdcc0 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 22 Apr 2012 23:53:59 -0700
+Subject: ARM: mach-shmobile: kzm9g: add SDHI 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 d80a008054f895469e955975740bf07751c1449f)
+
+N.B: Not present in mainline yet
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-kzm9g.c | 57 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 57 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
+index 5b486ae..a964e56 100644
+--- a/arch/arm/mach-shmobile/board-kzm9g.c
++++ b/arch/arm/mach-shmobile/board-kzm9g.c
+@@ -24,6 +24,8 @@
+ #include <linux/i2c.h>
+ #include <linux/mmc/host.h>
+ #include <linux/mmc/sh_mmcif.h>
++#include <linux/mmc/sh_mobile_sdhi.h>
++#include <linux/mfd/tmio.h>
+ #include <linux/platform_device.h>
+ #include <linux/videodev2.h>
+ #include <mach/irqs.h>
+@@ -123,6 +125,47 @@ static struct platform_device mmc_device = {
+ .resource = sh_mmcif_resources,
+ };
+
++/* SDHI */
++static struct sh_mobile_sdhi_info sdhi0_info = {
++ .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT,
++ .tmio_caps = MMC_CAP_SD_HIGHSPEED,
++ .tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
++};
++
++static struct resource sdhi0_resources[] = {
++ [0] = {
++ .name = "SDHI0",
++ .start = 0xee100000,
++ .end = 0xee1000ff,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .name = SH_MOBILE_SDHI_IRQ_CARD_DETECT,
++ .start = gic_spi(83),
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ .name = SH_MOBILE_SDHI_IRQ_SDCARD,
++ .start = gic_spi(84),
++ .flags = IORESOURCE_IRQ,
++ },
++ [3] = {
++ .name = SH_MOBILE_SDHI_IRQ_SDIO,
++ .start = gic_spi(85),
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++static struct platform_device sdhi0_device = {
++ .name = "sh_mobile_sdhi",
++ .num_resources = ARRAY_SIZE(sdhi0_resources),
++ .resource = sdhi0_resources,
++ .dev = {
++ .platform_data = &sdhi0_info,
++ },
++};
++
++/* I2C */
+ static struct i2c_board_info i2c1_devices[] = {
+ {
+ I2C_BOARD_INFO("st1232-ts", 0x55),
+@@ -133,6 +176,7 @@ static struct i2c_board_info i2c1_devices[] = {
+ static struct platform_device *kzm_devices[] __initdata = {
+ &lcdc_device,
+ &mmc_device,
++ &sdhi0_device,
+ };
+
+ /*
+@@ -247,6 +291,19 @@ static void __init kzm_init(void)
+ gpio_request(GPIO_FN_MMCD0_6_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_7_PU, NULL);
+
++ /* enable SD */
++ gpio_request(GPIO_FN_SDHIWP0, NULL);
++ gpio_request(GPIO_FN_SDHICD0, NULL);
++ gpio_request(GPIO_FN_SDHICMD0, NULL);
++ gpio_request(GPIO_FN_SDHICLK0, NULL);
++ gpio_request(GPIO_FN_SDHID0_3, NULL);
++ gpio_request(GPIO_FN_SDHID0_2, NULL);
++ gpio_request(GPIO_FN_SDHID0_1, NULL);
++ gpio_request(GPIO_FN_SDHID0_0, NULL);
++ gpio_request(GPIO_FN_SDHI0_VCCQ_MC0_ON, NULL);
++ gpio_request(GPIO_PORT15, NULL);
++ gpio_direction_output(GPIO_PORT15, 1); /* power */
++
+ #ifdef CONFIG_CACHE_L2X0
+ /* Early BRESP enable, Shared attribute override enable, 64K*8way */
+ l2x0_init(__io(0xf0100000), 0x40460000, 0x82000fff);
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0202-ARM-mach-shmobile-kzm9g-add-PCF8757-gpio-key.patch b/patches.kzm9g/0202-ARM-mach-shmobile-kzm9g-add-PCF8757-gpio-key.patch
new file mode 100644
index 00000000000000..5f9909fbcc14c3
--- /dev/null
+++ b/patches.kzm9g/0202-ARM-mach-shmobile-kzm9g-add-PCF8757-gpio-key.patch
@@ -0,0 +1,140 @@
+From f1f2cdcdd22c1c750f6cee76e6af0ce531fa5b21 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Sun, 22 Apr 2012 23:54:14 -0700
+Subject: ARM: mach-shmobile: kzm9g: add PCF8757 gpio-key
+
+This patch adds extra GPIO via PCF8757 chip,
+and use it as 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 d5fbabd3d5ab8c06d4f576efb63cd2af65a729ae)
+
+Conflicts:
+
+ arch/arm/mach-shmobile/board-kzm9g.c
+
+N.B: Not present in mainline yet
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/board-kzm9g.c | 59 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 59 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
+index a964e56..7289ed5 100644
+--- a/arch/arm/mach-shmobile/board-kzm9g.c
++++ b/arch/arm/mach-shmobile/board-kzm9g.c
+@@ -19,9 +19,12 @@
+
+ #include <linux/delay.h>
+ #include <linux/gpio.h>
++#include <linux/gpio_keys.h>
+ #include <linux/io.h>
+ #include <linux/irq.h>
+ #include <linux/i2c.h>
++#include <linux/i2c/pcf857x.h>
++#include <linux/input.h>
+ #include <linux/mmc/host.h>
+ #include <linux/mmc/sh_mmcif.h>
+ #include <linux/mmc/sh_mobile_sdhi.h>
+@@ -37,6 +40,18 @@
+ #include <asm/mach/arch.h>
+ #include <video/sh_mobile_lcdc.h>
+
++/*
++ * external GPIO
++ */
++#define GPIO_PCF8575_BASE (GPIO_NR)
++#define GPIO_PCF8575_PORT10 (GPIO_NR + 8)
++#define GPIO_PCF8575_PORT11 (GPIO_NR + 9)
++#define GPIO_PCF8575_PORT12 (GPIO_NR + 10)
++#define GPIO_PCF8575_PORT13 (GPIO_NR + 11)
++#define GPIO_PCF8575_PORT14 (GPIO_NR + 12)
++#define GPIO_PCF8575_PORT15 (GPIO_NR + 13)
++#define GPIO_PCF8575_PORT16 (GPIO_NR + 14)
++
+ /* LCDC */
+ static struct fb_videomode kzm_lcdc_mode = {
+ .name = "WVGA Panel",
+@@ -165,7 +180,38 @@ static struct platform_device sdhi0_device = {
+ },
+ };
+
++/* 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_BACK, GPIO_PCF8575_PORT10, "SW3"),
++ GPIO_KEY(KEY_RIGHT, GPIO_PCF8575_PORT11, "SW2-R"),
++ GPIO_KEY(KEY_LEFT, GPIO_PCF8575_PORT12, "SW2-L"),
++ GPIO_KEY(KEY_ENTER, GPIO_PCF8575_PORT13, "SW2-P"),
++ GPIO_KEY(KEY_UP, GPIO_PCF8575_PORT14, "SW2-U"),
++ GPIO_KEY(KEY_DOWN, GPIO_PCF8575_PORT15, "SW2-D"),
++ GPIO_KEY(KEY_HOME, GPIO_PCF8575_PORT16, "SW1"),
++};
++
++static struct gpio_keys_platform_data gpio_key_info = {
++ .buttons = gpio_buttons,
++ .nbuttons = ARRAY_SIZE(gpio_buttons),
++ .poll_interval = 250, /* poling at this point */
++};
++
++static struct platform_device gpio_keys_device = {
++ /* gpio-pcf857x.c driver doesn't support gpio_to_irq() */
++ .name = "gpio-keys-polled",
++ .dev = {
++ .platform_data = &gpio_key_info,
++ },
++};
++
+ /* I2C */
++static struct pcf857x_platform_data pcf8575_pdata = {
++ .gpio_base = GPIO_PCF8575_BASE,
++};
++
+ static struct i2c_board_info i2c1_devices[] = {
+ {
+ I2C_BOARD_INFO("st1232-ts", 0x55),
+@@ -173,10 +219,18 @@ static struct i2c_board_info i2c1_devices[] = {
+ },
+ };
+
++static struct i2c_board_info i2c3_devices[] = {
++ {
++ I2C_BOARD_INFO("pcf8575", 0x20),
++ .platform_data = &pcf8575_pdata,
++ },
++};
++
+ static struct platform_device *kzm_devices[] __initdata = {
+ &lcdc_device,
+ &mmc_device,
+ &sdhi0_device,
++ &gpio_keys_device,
+ };
+
+ /*
+@@ -304,12 +358,17 @@ static void __init kzm_init(void)
+ gpio_request(GPIO_PORT15, NULL);
+ gpio_direction_output(GPIO_PORT15, 1); /* power */
+
++ /* I2C 3 */
++ gpio_request(GPIO_FN_PORT27_I2C_SCL3, NULL);
++ gpio_request(GPIO_FN_PORT28_I2C_SDA3, NULL);
++
+ #ifdef CONFIG_CACHE_L2X0
+ /* Early BRESP enable, Shared attribute override enable, 64K*8way */
+ l2x0_init(__io(0xf0100000), 0x40460000, 0x82000fff);
+ #endif
+
+ i2c_register_board_info(1, i2c1_devices, ARRAY_SIZE(i2c1_devices));
++ i2c_register_board_info(3, i2c3_devices, ARRAY_SIZE(i2c3_devices));
+
+ sh73a0_add_standard_devices();
+ platform_add_devices(kzm_devices, ARRAY_SIZE(kzm_devices));
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0203-ARM-mach-shmobile-kzm9g-defconfig-update.patch b/patches.kzm9g/0203-ARM-mach-shmobile-kzm9g-defconfig-update.patch
new file mode 100644
index 00000000000000..1ccf5bdd609a8c
--- /dev/null
+++ b/patches.kzm9g/0203-ARM-mach-shmobile-kzm9g-defconfig-update.patch
@@ -0,0 +1,88 @@
+From 68fa5ce1e0101a7d9d78d485dd3245b583ef88f6 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Wed, 25 Apr 2012 20:58:06 -0700
+Subject: ARM: mach-shmobile: kzm9g: defconfig update
+
+This patch enable GPIO-KEY/FSI,
+and remove debug settings,
+and be 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 cc2504524b5b14dc03682dc1f04fb1644f692767)
+
+N.B: Not present in mainline yet
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/configs/kzm9g_defconfig | 24 +++++++++++++++++-------
+ 1 file changed, 17 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/configs/kzm9g_defconfig b/arch/arm/configs/kzm9g_defconfig
+index de8712b..e3ebc20 100644
+--- a/arch/arm/configs/kzm9g_defconfig
++++ b/arch/arm/configs/kzm9g_defconfig
+@@ -22,6 +22,7 @@ CONFIG_MODULE_UNLOAD=y
+ # CONFIG_IOSCHED_DEADLINE is not set
+ # CONFIG_IOSCHED_CFQ is not set
+ CONFIG_ARCH_SHMOBILE=y
++CONFIG_KEYBOARD_GPIO_POLLED=y
+ CONFIG_ARCH_SH73A0=y
+ CONFIG_MACH_KZM9G=y
+ CONFIG_MEMORY_START=0x41000000
+@@ -69,8 +70,6 @@ CONFIG_INPUT_SPARSEKMAP=y
+ # CONFIG_INPUT_MOUSEDEV is not set
+ CONFIG_INPUT_EVDEV=y
+ # CONFIG_KEYBOARD_ATKBD is not set
+-CONFIG_KEYBOARD_GPIO=y
+-CONFIG_KEYBOARD_SH_KEYSC=y
+ # CONFIG_INPUT_MOUSE is not set
+ CONFIG_INPUT_TOUCHSCREEN=y
+ CONFIG_TOUCHSCREEN_ST1232=y
+@@ -81,13 +80,22 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
+ # CONFIG_HW_RANDOM is not set
+ CONFIG_I2C_CHARDEV=y
+ CONFIG_I2C_SH_MOBILE=y
+-CONFIG_POWER_SUPPLY=y
++CONFIG_GPIO_PCF857X=y
+ # CONFIG_HWMON is not set
+ CONFIG_FB=y
+ CONFIG_FB_SH_MOBILE_LCDC=y
+ CONFIG_FRAMEBUFFER_CONSOLE=y
+ CONFIG_LOGO=y
+ CONFIG_FB_SH_MOBILE_MERAM=y
++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_USB is not set
++CONFIG_SND_SOC=y
++CONFIG_SND_SOC_SH4_FSI=y
+ # CONFIG_HID_SUPPORT is not set
+ CONFIG_USB=y
+ CONFIG_USB_DEVICEFS=y
+@@ -117,11 +125,13 @@ CONFIG_NFS_V4_1=y
+ CONFIG_ROOT_NFS=y
+ CONFIG_NLS_CODEPAGE_437=y
+ CONFIG_NLS_ISO8859_1=y
+-CONFIG_MAGIC_SYSRQ=y
+-CONFIG_DETECT_HUNG_TASK=y
+-CONFIG_DEBUG_INFO=y
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++# CONFIG_ENABLE_MUST_CHECK is not set
++# CONFIG_SCHED_DEBUG is not set
++# CONFIG_DEBUG_PREEMPT is not set
++# CONFIG_DEBUG_BUGVERBOSE is not set
+ # CONFIG_FTRACE is not set
+-CONFIG_DEBUG_USER=y
++# CONFIG_ARM_UNWIND is not set
+ CONFIG_CRYPTO=y
+ CONFIG_CRYPTO_CBC=y
+ CONFIG_CRYPTO_MD5=y
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0204-ARM-mach-shmobile-clock-sh73a0-add-FSI-clock.patch b/patches.kzm9g/0204-ARM-mach-shmobile-clock-sh73a0-add-FSI-clock.patch
new file mode 100644
index 00000000000000..270f943c78bf72
--- /dev/null
+++ b/patches.kzm9g/0204-ARM-mach-shmobile-clock-sh73a0-add-FSI-clock.patch
@@ -0,0 +1,46 @@
+From 390deea0373e34a3e2f85ca0917ebb7c595f84fb Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 23 Apr 2012 00:03:10 -0700
+Subject: ARM: mach-shmobile: clock-sh73a0: add FSI clock
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+
+N.B: Not present upstream
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/clock-sh73a0.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
+index 41f8293..012b284 100644
+--- a/arch/arm/mach-shmobile/clock-sh73a0.c
++++ b/arch/arm/mach-shmobile/clock-sh73a0.c
+@@ -476,7 +476,7 @@ enum { MSTP001,
+ MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
+ MSTP219,
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+- MSTP331, MSTP329, MSTP325, MSTP323, MSTP318,
++ MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP318,
+ MSTP314, MSTP313, MSTP312, MSTP311,
+ MSTP303, MSTP302, MSTP301, MSTP300,
+ MSTP411, MSTP410, MSTP403,
+@@ -505,6 +505,7 @@ static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
+ [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
+ [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
++ [MSTP328] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /*FSI*/
+ [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
+ [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
+ [MSTP318] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 18, 0), /* SY-DMAC */
+@@ -560,6 +561,7 @@ static struct clk_lookup lookups[] = {
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
+ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
+ CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
++ CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
+ CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
+ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
+ CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP318]), /* SY-DMAC */
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/patches.kzm9g/0205-ARM-mach-shmobile-kzm9g-add-FSI-AK4648-support.patch b/patches.kzm9g/0205-ARM-mach-shmobile-kzm9g-add-FSI-AK4648-support.patch
new file mode 100644
index 00000000000000..6c75eb1ffbbb74
--- /dev/null
+++ b/patches.kzm9g/0205-ARM-mach-shmobile-kzm9g-add-FSI-AK4648-support.patch
@@ -0,0 +1,162 @@
+From 850ebb2205ed29cae92c91419d06fb9e91a2cafa Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Mon, 23 Apr 2012 00:03:25 -0700
+Subject: ARM: mach-shmobile: kzm9g: add FSI-AK4648 support
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+
+Conflicts:
+
+ arch/arm/mach-shmobile/board-kzm9g.c
+
+N.B: Not present upstream
+
+Signed-off-by: Simon Horman <horms@verge.net.au>
+---
+ arch/arm/mach-shmobile/Kconfig | 1 +
+ arch/arm/mach-shmobile/board-kzm9g.c | 79 ++++++++++++++++++++++++++++++++++++
+ 2 files changed, 80 insertions(+)
+
+diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
+index 23be741..9020c1b 100644
+--- a/arch/arm/mach-shmobile/Kconfig
++++ b/arch/arm/mach-shmobile/Kconfig
+@@ -85,6 +85,7 @@ config MACH_KZM9G
+ bool "KZM-A9-GT board"
+ depends on ARCH_SH73A0
+ select ARCH_REQUIRE_GPIOLIB
++ select SND_SOC_AK4642 if SND_SIMPLE_CARD
+
+ comment "SH-Mobile System Configuration"
+
+diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
+index 7289ed5..855ae85 100644
+--- a/arch/arm/mach-shmobile/board-kzm9g.c
++++ b/arch/arm/mach-shmobile/board-kzm9g.c
+@@ -31,6 +31,8 @@
+ #include <linux/mfd/tmio.h>
+ #include <linux/platform_device.h>
+ #include <linux/videodev2.h>
++#include <sound/sh_fsi.h>
++#include <sound/simple_card.h>
+ #include <mach/irqs.h>
+ #include <mach/sh73a0.h>
+ #include <mach/common.h>
+@@ -52,6 +54,14 @@
+ #define GPIO_PCF8575_PORT15 (GPIO_NR + 13)
+ #define GPIO_PCF8575_PORT16 (GPIO_NR + 14)
+
++/*
++ * FSI-AK4648
++ *
++ * this command is required when playback.
++ *
++ * # amixer set "LINEOUT Mixer DACL" on
++ */
++
+ /* LCDC */
+ static struct fb_videomode kzm_lcdc_mode = {
+ .name = "WVGA Panel",
+@@ -207,11 +217,70 @@ static struct platform_device gpio_keys_device = {
+ },
+ };
+
++/* FSI-AK4648 */
++static struct sh_fsi_platform_info fsi_info = {
++ .port_a = {
++ },
++};
++
++static struct resource fsi_resources[] = {
++ [0] = {
++ .name = "FSI",
++ .start = 0xEC230000,
++ .end = 0xEC230400 - 1,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = gic_spi(146),
++ .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,
++ },
++};
++
++static struct asoc_simple_dai_init_info fsi2_ak4648_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_ak4648_info = {
++ .name = "AK4648",
++ .card = "FSI2A-AK4648",
++ .cpu_dai = "fsia-dai",
++ .codec = "ak4642-codec.0-0012",
++ .platform = "sh_fsi2",
++ .codec_dai = "ak4642-hifi",
++ .init = &fsi2_ak4648_init_info,
++};
++
++static struct platform_device fsi_ak4648_device = {
++ .name = "asoc-simple-card",
++ .dev = {
++ .platform_data = &fsi2_ak4648_info,
++ },
++};
++
+ /* I2C */
+ static struct pcf857x_platform_data pcf8575_pdata = {
+ .gpio_base = GPIO_PCF8575_BASE,
+ };
+
++static struct i2c_board_info i2c0_devices[] = {
++ {
++ I2C_BOARD_INFO("ak4648", 0x12),
++ }
++};
++
+ static struct i2c_board_info i2c1_devices[] = {
+ {
+ I2C_BOARD_INFO("st1232-ts", 0x55),
+@@ -231,6 +300,8 @@ static struct platform_device *kzm_devices[] __initdata = {
+ &mmc_device,
+ &sdhi0_device,
+ &gpio_keys_device,
++ &fsi_device,
++ &fsi_ak4648_device,
+ };
+
+ /*
+@@ -362,11 +433,19 @@ static void __init kzm_init(void)
+ gpio_request(GPIO_FN_PORT27_I2C_SCL3, NULL);
+ gpio_request(GPIO_FN_PORT28_I2C_SDA3, NULL);
+
++ /* enable FSI2 port A (ak4648) */
++ gpio_request(GPIO_FN_FSIACK, NULL);
++ gpio_request(GPIO_FN_FSIAILR, NULL);
++ gpio_request(GPIO_FN_FSIAIBT, NULL);
++ gpio_request(GPIO_FN_FSIAISLD, NULL);
++ gpio_request(GPIO_FN_FSIAOSLD, NULL);
++
+ #ifdef CONFIG_CACHE_L2X0
+ /* Early BRESP enable, Shared attribute override enable, 64K*8way */
+ l2x0_init(__io(0xf0100000), 0x40460000, 0x82000fff);
+ #endif
+
++ i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
+ i2c_register_board_info(1, i2c1_devices, ARRAY_SIZE(i2c1_devices));
+ i2c_register_board_info(3, i2c3_devices, ARRAY_SIZE(i2c3_devices));
+
+--
+1.7.10.2.565.gbd578b5
+
diff --git a/series b/series
index 533cbfdc293aae..595c637789d3b6 100644
--- a/series
+++ b/series
@@ -584,3 +584,210 @@ patches.pramfs/14-pramfs-memory-write-protection.patch
patches.pramfs/15-pramfs-test-module.patch
patches.pramfs/16-pramfs-ioctl-operations.patch
patches.pramfs/17-pramfs-makefile-and-kconfig.patch
+
+
+patches.kzm9g/0001-net-remove-mm.h-inclusion-from-netdevice.h.patch
+patches.kzm9g/0002-Include-linux-dma-mapping.h-in-linux-dmaengine.h.patch
+patches.kzm9g/0003-dmaengine-failure-to-get-a-specific-DMA-channel-is-n.patch
+patches.kzm9g/0004-Improve-slave-cyclic-DMA-engine-documentation.patch
+patches.kzm9g/0005-dmaengine-use-DEFINE_IDR-for-static-initialization.patch
+patches.kzm9g/0006-dmaengine-add-helper-function-for-slave_single.patch
+patches.kzm9g/0007-dmaengine-remove-struct-scatterlist-for-header.patch
+patches.kzm9g/0008-dmaengine-add-new-enum-dma_transfer_direction.patch
+patches.kzm9g/0009-linux-dmaengine.h-fix-implicit-use-of-bitmap.h-and-a.patch
+patches.kzm9g/0010-DMAEngine-Define-interleaved-transfer-request-api.patch
+patches.kzm9g/0011-dmaengine-add-DMA_TRANS_NONE-to-dma_transfer_directi.patch
+patches.kzm9g/0012-dmaengine-Add-flow-controller-information-to-dma_sla.patch
+patches.kzm9g/0013-dma-dmaengine-Distinguish-between-dmaengine-failed-t.patch
+patches.kzm9g/0014-dmaengine-add-private-header-file.patch
+patches.kzm9g/0015-dmaengine-dma_slave-introduce-inline-wrappers.patch
+patches.kzm9g/0016-ARM-Add-init_consistent_dma_size.patch
+patches.kzm9g/0017-mmc-add-a-card-hotplug-handler-context.patch
+patches.kzm9g/0018-mmc-add-a-generic-GPIO-card-detect-helper.patch
+patches.kzm9g/0019-mmc-simplify-mmc_cd_gpio_request-by-removing-two-par.patch
+patches.kzm9g/0020-mmc-Standardize-header-file-inclusion-checks.patch
+patches.kzm9g/0021-mmc-tmio-name-0xd8-as-CTL_DMA_ENABLE.patch
+patches.kzm9g/0022-mmc-tmio-Share-register-access-functions.patch
+patches.kzm9g/0023-mmc-sdhi-Add-write16_hook.patch
+patches.kzm9g/0024-mmc-tmio-Fix-race-condition-resulting-in-spurious-in.patch
+patches.kzm9g/0025-mmc-tmio-fix-recursive-spinlock-don-t-schedule-with-.patch
+patches.kzm9g/0026-mmc-tmio-maximize-power-saving.patch
+patches.kzm9g/0027-mmc-tmio-fix-a-recently-introduced-bug-in-DMA-code.patch
+patches.kzm9g/0028-mmc-tmio-fix-a-deadlock.patch
+patches.kzm9g/0029-net-remove-mm.h-inclusion-from-netdevice.h.patch
+patches.kzm9g/0030-MMC-TMIO-Fix-build-issue-related-to-struct-scatterli.patch
+patches.kzm9g/0031-mmc-tmio-eliminate-unused-variable-mmc-warning.patch
+patches.kzm9g/0032-mmc-sdhi-initialise-mmc_data-flags-before-use.patch
+patches.kzm9g/0033-mmc-tmio-Cache-interrupt-masks.patch
+patches.kzm9g/0034-mmc-tmio-Provide-separate-interrupt-handlers.patch
+patches.kzm9g/0035-mmc-sdhi-Allow-named-IRQs-to-use-specific-handlers.patch
+patches.kzm9g/0036-mmc-irq-Remove-IRQF_DISABLED.patch
+patches.kzm9g/0037-mmc-Add-module.h-to-drivers-mmc-users-assuming-impli.patch
+patches.kzm9g/0038-mmc-replace-printk-with-appropriate-display-macro.patch
+patches.kzm9g/0039-mmc-tmio-fix-clock-gating-on-platforms-with-a-.set_p.patch
+patches.kzm9g/0040-mmc-convert-drivers-mmc-host-to-use-module_platform_.patch
+patches.kzm9g/0041-mmc-remove-the-second-argument-of-k-un-map_atomic.patch
+patches.kzm9g/0042-mmc-tmio_mmc-Hotplug-code-regrouping.patch
+patches.kzm9g/0043-mmc-host-move-to-dma_transfer_direction.patch
+patches.kzm9g/0044-mmc-tmio_mmc-fix-card-eject-during-IO-with-DMA.patch
+patches.kzm9g/0045-mmc-tmio_mmc-do-not-enable-card-hotplug-interrupts-i.patch
+patches.kzm9g/0046-mmc-tmio-calculate-the-native-hotplug-condition-only.patch
+patches.kzm9g/0047-mmc-tmio_mmc-support-the-generic-MMC-GPIO-card-hotpl.patch
+patches.kzm9g/0048-mmc-sh_mobile_sdhi-pass-card-hotplug-GPIO-number-to-.patch
+patches.kzm9g/0049-mmc-tmio_mmc-power-status-flag-doesn-t-have-to-be-ex.patch
+patches.kzm9g/0050-mmc-tmio_mmc-remove-unused-sdio_irq_enabled-flag.patch
+patches.kzm9g/0051-mmc-sh_mobile_sdhi-do-not-manage-PM-clocks-manually.patch
+patches.kzm9g/0052-mmc-tmio-cosmetic-prettify-the-tmio_mmc_set_ios-func.patch
+patches.kzm9g/0053-mmc-sh_mobile_sdhi-add-a-callback-for-board-specific.patch
+patches.kzm9g/0054-mmc-sh_mobile_sdhi-support-modular-mmc-core-with-non.patch
+patches.kzm9g/0055-mmc-Standardize-header-file-inclusion-checks.patch
+patches.kzm9g/0056-mmc-sh_mmcif-maximize-power-saving.patch
+patches.kzm9g/0057-mmc-sh_mmcif-simplify-platform-data.patch
+patches.kzm9g/0058-mmc-Add-module.h-to-drivers-mmc-users-assuming-impli.patch
+patches.kzm9g/0059-mmc-host-move-to-dma_transfer_direction.patch
+patches.kzm9g/0060-mmc-sh_mmcif-fix-clock-gating-on-platforms-with-a-.d.patch
+patches.kzm9g/0061-mmc-sh_mmcif-simplify-clock-divisor-calculation.patch
+patches.kzm9g/0062-mmc-convert-drivers-mmc-host-to-use-module_platform_.patch
+patches.kzm9g/0063-mmc-sh_mmcif-process-error-interrupts-first.patch
+patches.kzm9g/0064-mmc-sh_mmcif-cosmetic-clean-up.patch
+patches.kzm9g/0065-mmc-sh_mmcif-process-requests-asynchronously.patch
+patches.kzm9g/0066-mmc-sh_mmcif-remove-now-superfluous-sh_mmcif_host-da.patch
+patches.kzm9g/0067-mmc-sh_mmcif-fix-MMC_GEN_CMD-setting.patch
+patches.kzm9g/0068-mmc-sh_mmcif-simplify-bitmask-macros.patch
+patches.kzm9g/0069-mmc-sh_mmcif-double-clock-speed.patch
+patches.kzm9g/0070-mmc-sh_mmcif-mmc-f_max-should-be-half-of-the-bus-clo.patch
+patches.kzm9g/0071-mmc-sh_mmcif-Simplify-calculation-of-mmc-f_min.patch
+patches.kzm9g/0072-ARM-mach-shmobile-clock-r8a7740-add-USB-clock.patch
+patches.kzm9g/0073-ALSA-workaround-change-the-timing-of-alsa_sound_last.patch
+patches.kzm9g/0074-ASoC-core-Optimise-and-refactor-pcm_new-to-pass-only.patch
+patches.kzm9g/0075-ASoC-core-Allow-components-to-probe-remove-in-sequen.patch
+patches.kzm9g/0076-ASoC-core-Separate-out-PCM-operations-into-new-file.patch
+patches.kzm9g/0077-ASoC-core-PCM-mutex-per-rtd.patch
+patches.kzm9g/0078-ASoC-Allow-DAI-formats-to-be-specified-in-the-dai_li.patch
+patches.kzm9g/0079-ASoC-Hold-runtime-PM-references-to-components-of-act.patch
+patches.kzm9g/0080-ASoC-sh-fsi-tidyup-parameter-of-fsi_stream_push.patch
+patches.kzm9g/0081-ASoC-sh-fsi-add-fsi_set_master_clk.patch
+patches.kzm9g/0082-ASoC-sh-fsi-irq-control-moves-to-fsi_port_start-stop.patch
+patches.kzm9g/0083-ASoC-sh-fsi-tidyup-unclear-variable-naming.patch
+patches.kzm9g/0084-ASoC-sh-fsi-remove-pm_runtime-from-fsi_dai_set_fmt.patch
+patches.kzm9g/0085-ASoC-sh-fsi-make-sure-fsi_stream_push-pop-access-by-.patch
+patches.kzm9g/0086-ASoC-sh-fsi-remove-fsi_module_init-kill.patch
+patches.kzm9g/0087-ASoC-sh-fsi-cleanup-suspend-resume.patch
+patches.kzm9g/0088-ASoC-sh-fsi-add-fsi_hw_startup-shutdown.patch
+patches.kzm9g/0089-sound-irq-Remove-IRQF_DISABLED.patch
+patches.kzm9g/0090-ASoC-sh-use-correct-__iomem-annotations.patch
+patches.kzm9g/0091-sound-Add-module.h-to-the-previously-silent-sound-us.patch
+patches.kzm9g/0092-ASoC-fsi-fixup-compile-warning.patch
+patches.kzm9g/0093-ASoC-fsi-add-valid-data-position-control-support.patch
+patches.kzm9g/0094-ASoC-Constify-snd_soc_dai_ops-structs.patch
+patches.kzm9g/0095-ASoC-fsi-ak4642-modify-specification-method-of-FSI-a.patch
+patches.kzm9g/0096-ASoC-Convert-sh-directory-to-module_platform_driver.patch
+patches.kzm9g/0097-ASoC-Use-core-pm_runtime-callbacks-for-fsi.patch
+patches.kzm9g/0098-ASoC-sh-Add-.owner-to-struct-snd_soc_card.patch
+patches.kzm9g/0099-ASoC-fsi-Remove-unneeded-empty-runtime-PM-callbacks.patch
+patches.kzm9g/0100-ASoC-fsi-reduce-runtime-calculation-by-using-pre-set.patch
+patches.kzm9g/0101-ASoC-fsi-tidyup-fsi_stream_xx-functions-were-gathere.patch
+patches.kzm9g/0102-ASoC-fsi-data-push-pop-calculation-part-was-divided.patch
+patches.kzm9g/0103-ASoC-fsi-rename-fsi_dma_soft_xxx-to-fsi_pio_xxx.patch
+patches.kzm9g/0104-ASoC-fsi-tidyup-move-fsi_fifo_init-onto-fsi_hw_start.patch
+patches.kzm9g/0105-ASoC-fsi-remove-unnecessary-parameter-from-fsi_hw_sh.patch
+patches.kzm9g/0106-ASoC-fsi-rename-fsi_stream_push-pop-to-fsi_stream_in.patch
+patches.kzm9g/0107-ASoC-fsi-modify-fsi_pio_get_area-parameter-and-using.patch
+patches.kzm9g/0108-ASoC-fsi-re-define-fsi_is_play-and-fsi_stream_is_pla.patch
+patches.kzm9g/0109-ASoC-fsi-use-fsi_stream-in-fsi_get_current_fifo_samp.patch
+patches.kzm9g/0110-ASoC-fsi-add-fsi_stream_handler-and-PIO-handler.patch
+patches.kzm9g/0111-ASoC-fsi-tidyup-fsi_pio_xxx-are-gathered.patch
+patches.kzm9g/0112-ASoC-fsi-don-t-use-is_play-as-a-parameter-of-fsi-fun.patch
+patches.kzm9g/0113-ASoC-fsi-add-.start_stop-handler-to-fsi_stream_handl.patch
+patches.kzm9g/0114-ASoC-fsi-fsi_stream_is_working-care-substream-runtim.patch
+patches.kzm9g/0115-ASoC-fsi-PortA-B-information-was-controlled-by-sh_fs.patch
+patches.kzm9g/0116-ASoC-fsi-add-.init-.quit-handler-support.patch
+patches.kzm9g/0117-ASoC-fsi-fixup-fsi_pointer-calculation-method.patch
+patches.kzm9g/0118-ASoC-fsi-Add-DMAEngine-support.patch
+patches.kzm9g/0119-ASoC-fsi-update-for-dmaengine-prep_slave_sg-fallout.patch
+patches.kzm9g/0120-ASoC-add-generic-simple-card-support.patch
+patches.kzm9g/0121-ASoC-sh-fsi-select-simple-card-on-Kconfig.patch
+patches.kzm9g/0122-ASoC-ak4642-convert-to-soc-cache.patch
+patches.kzm9g/0123-ASoC-ak4642-ak4642-was-tested.patch
+patches.kzm9g/0124-ASoC-ak4642-add-ak4642_set_bias_level.patch
+patches.kzm9g/0125-ASoC-ak4642-add-DAPM-support-for-HeadPhone-Output.patch
+patches.kzm9g/0126-ASoC-ak4642-add-headphone-mute-switch-control.patch
+patches.kzm9g/0127-ASoC-ak4642-add-Line-out-support.patch
+patches.kzm9g/0128-ASoC-ak4642-add-ak4648-support.patch
+patches.kzm9g/0129-ASoC-Remove-driver-versioning-from-ak4642.patch
+patches.kzm9g/0130-ASoC-Convert-ak4642-to-devm_kzalloc.patch
+patches.kzm9g/0131-ASoC-ak4642-fixup-HeadPhone-L-R-dapm-settings.patch
+patches.kzm9g/0132-ARM-mach-shmobile-clock-r8a7740-add-SDHI-clock.patch
+patches.kzm9g/0133-ARM-mach-shmobile-clock-r8a7740-add-MMCIF-clock.patch
+patches.kzm9g/0134-ARM-mach-shmobile-r8a7740-reserve-DMA-memory-for-the.patch
+patches.kzm9g/0135-ARM-mach-shmobile-clock-r8a7740-add-FSI-clock.patch
+patches.kzm9g/0136-ARM-mach-shmobile-armadillo800eva-add-SDHI0-support.patch
+patches.kzm9g/0137-ARM-mach-shmobile-armadillo800eva-add-SDHI1-support.patch
+patches.kzm9g/0138-ARM-mach-shmobile-armadillo800eva-add-MMCIF-support.patch
+patches.kzm9g/0139-ARM-mach-shmobile-armadillo800eva-Add-FSI-WM8978-sup.patch
+patches.kzm9g/0140-ARM-mach-shmobile-Add-support-for-PINT-though-INTC-m.patch
+patches.kzm9g/0141-irq-Track-the-owner-of-irq-descriptor.patch
+patches.kzm9g/0142-irq-add-irq_domain-translation-infrastructure.patch
+patches.kzm9g/0143-dt-irq-add-irq_domain_generate_simple-helper.patch
+patches.kzm9g/0144-irq-Add-declaration-of-irq_domain_simple_ops-to-irqd.patch
+patches.kzm9g/0145-irq-Fix-check-for-already-initialized-irq_domain-in-.patch
+patches.kzm9g/0146-irq-support-domains-with-non-zero-hwirq-base.patch
+patches.kzm9g/0147-genirq-Add-support-for-per-cpu-dev_id-interrupts.patch
+patches.kzm9g/0148-ARM-introduce-handle_IRQ-not-to-dump-exception-stack.patch
+patches.kzm9g/0149-ARM-GIC-move-gic_chip_data-structure-declaration-to-.patch
+patches.kzm9g/0150-ARM-CPU-hotplug-fix-abuse-of-irqdesc-node.patch
+patches.kzm9g/0151-ARM-GIC-avoid-routing-interrupts-to-offline-CPUs.patch
+patches.kzm9g/0152-ARM-gic-Use-cpu-pm-notifiers-to-save-gic-state.patch
+patches.kzm9g/0153-ARM-7011-1-Add-ARM-cpu-topology-definition.patch
+patches.kzm9g/0154-ARM-7060-1-smp-populate-logical-CPU-mapping-during-b.patch
+patches.kzm9g/0155-ARM-gic-Allow-gic-arch-extensions-to-provide-irqchip.patch
+patches.kzm9g/0156-ARM-7061-1-gic-convert-logical-CPU-numbers-into-phys.patch
+patches.kzm9g/0157-ARM-7123-1-smp-Add-an-IPI-handler-callable-from-C-co.patch
+patches.kzm9g/0158-ARM-7124-1-smp-Add-a-localtimer-handler-callable-fro.patch
+patches.kzm9g/0159-ARM-gic-consolidate-PPI-handling.patch
+patches.kzm9g/0160-ARM-GIC-Add-global-gic_handle_irq-function.patch
+patches.kzm9g/0161-ARM-twd-register-clockevents-device-before-enabling-.patch
+patches.kzm9g/0162-ARM-EXYNOS4-set-the-affinity-of-mct1-interrupt-using.patch
+patches.kzm9g/0163-genirq-percpu-allow-interrupt-type-to-be-set-at-enab.patch
+patches.kzm9g/0164-ARM-gic-local-timers-use-the-request_percpu_irq-inte.patch
+patches.kzm9g/0165-ARM-gic-add-irq_domain-support.patch
+patches.kzm9g/0166-ARM-gic-add-OF-based-initialization.patch
+patches.kzm9g/0167-ARM-gic-fix-irq_alloc_descs-handling-for-sparse-irq.patch
+patches.kzm9g/0168-ARM-gic-use-module.h-instead-of-export.h.patch
+patches.kzm9g/0169-ARM-7176-1-cpu_pm-register-GIC-PM-notifier-only-once.patch
+patches.kzm9g/0170-ARM-7177-1-GIC-avoid-skipping-non-existent-PPIs-in-i.patch
+patches.kzm9g/0171-ARM-mach-shmobile-clock-sh73a0-tidyup-CKSCR-main-clo.patch
+patches.kzm9g/0172-ARM-mach-shmobile-sh73a0-PFC-pull-up-support-for-SDH.patch
+patches.kzm9g/0173-ARM-shmobile-convert-logical-CPU-numbers-to-physical.patch
+patches.kzm9g/0174-ARM-mach-shmobile-sh73a0-GPIO-IRQ-support.patch
+patches.kzm9g/0175-ARM-mach-shmobile-Use-common-INTC-IRQ-code-on-sh73a0.patch
+patches.kzm9g/0176-ARM-mach-shmobile-sh73a0-and-AG5EVM-PINT-support.patch
+patches.kzm9g/0177-ARM-mach-shmobile-Kota2-TPU-LED-platform-data.patch
+patches.kzm9g/0178-ARM-mach-shmobile-SH73A0-external-Ethernet-fix.patch
+patches.kzm9g/0179-sh-clkfwk-clock-sh73a0-all-div6_clks-use-SH_CLK_DIV6.patch
+patches.kzm9g/0180-arm-mach-shmobile-add-a-resource-name-for-shdma.patch
+patches.kzm9g/0181-ARM-mach-shmobile-sh73a0-PINT-IRQ-base-fix.patch
+patches.kzm9g/0182-ARM-mach-shmobile-sh73a0-IRQ-sparse-alloc-fix.patch
+patches.kzm9g/0183-ARM-mach-shmobile-clock-sh73a0-add-DSIxPHY-clock-sup.patch
+patches.kzm9g/0184-ARM-shmobile-remove-NR_IRQS.patch
+patches.kzm9g/0185-ARM-mach-shmobile-sh73a0-PSTR-32-bit-access-fix.patch
+patches.kzm9g/0186-ARM-mach-shmobile-sh73a0-sh_clk_ops-rename.patch
+patches.kzm9g/0187-ARM-mach-shmobile-sh73a0-map_io-and-init_early-updat.patch
+patches.kzm9g/0188-ARM-mach-shmobile-sh73a0-AG5EVM-and-Kota2-timer-rewo.patch
+patches.kzm9g/0189-ARM-mach-shmobile-sh73a0-add-MMC-data-pin-pull-up.patch
+patches.kzm9g/0190-ARM-Update-mach-types.patch
+patches.kzm9g/0191-ARM-mach-shmobile-add-KZM-A9-GT-board-support.patch
+patches.kzm9g/0192-ARM-mach-shmobile-kzm9g-add-defconfig.patch
+patches.kzm9g/0193-ARM-mach-shmobile-Invalidate-caches-when-booting-sec.patch
+patches.kzm9g/0194-ARM-mach-shmobile-kzm9g-enable-SMP-boot.patch
+patches.kzm9g/0195-ARM-mach-shmobile-kzm9g-add-LCDC-support.patch
+patches.kzm9g/0196-ARM-mach-shmobile-kzm9g-add-ST1232-Touchscreen-suppo.patch
+patches.kzm9g/0197-ARM-mach-shmobile-pfc-sh73a0-fixup-MSEL2CR-MSEL18-fo.patch
+patches.kzm9g/0198-ARM-mach-shmobile-sh73a0.h-add-GPIO_NR.patch
+patches.kzm9g/0199-ARM-mach-shmobile-kzm9g-correct-screen-direction.patch
+patches.kzm9g/0200-ARM-mach-shmobile-kzm9g-add-MMCIF-support.patch
+patches.kzm9g/0201-ARM-mach-shmobile-kzm9g-add-SDHI-support.patch
+patches.kzm9g/0202-ARM-mach-shmobile-kzm9g-add-PCF8757-gpio-key.patch
+patches.kzm9g/0203-ARM-mach-shmobile-kzm9g-defconfig-update.patch
+patches.kzm9g/0204-ARM-mach-shmobile-clock-sh73a0-add-FSI-clock.patch
+patches.kzm9g/0205-ARM-mach-shmobile-kzm9g-add-FSI-AK4648-support.patch